第一章 機器學習的基礎
1.1編程語言與開發環境
1.1.1 Python 安裝(略)
1.2.2 Python安裝包的安裝:可以選選擇安裝集成包anaconda(略)
1.1.3 IDE配置及安裝測試
IDE選擇UltraEdit高級文本編輯器,配置步驟如下:
(1)選擇“高級”-->“用戶工具”命令,如圖1.4所示。
圖1.5 配置UltraEdit步驟1
(2)在如圖1.5所示輸入各項參數,然后單擊“應用按鈕”
圖1.5 配置UltraEdit步驟2
(3)按照如圖1.6所示進行設置,然后單擊“確定”按鈕
圖1.6 配置UltraEdit步驟3
通過測試代碼,檢驗安裝效果:
#coding:utf-8 #Filename:mytest1.py import numpy as np #導入NumPy庫 from numpy import * #導入NumPy庫 import matplotlib.pyplot as plt #測試數據集————二維list dataSet = [[1,2],[3,4],[5,6],[7,8],[9,10]] dataMat = mat(dataSet).T #將數據集轉換為NumPy矩陣,並轉秩 plt.scatter(dataMat[0],dataMat[1],c = 'red',marker = 'o') #繪制數據散點圖 #繪制直線圖形 X = np.linspace(-2,2,100) #產生直線數據 #建立線性方程 Y = 2.8*X+9 plt.plot(X,Y) #繪制直線圖 plt.show() #顯示繪制效果
圖1.7 顯示執行效果
1.2 對象、矩陣與矢量化編程
1.2.1對象與維度(略)
1.2.2初識矩陣(略)
1.2.3矢量化編程與GPU運算(略)
1.2.4理解數學公式與NumPy矩陣運算
1.矩陣的初始化
#coding:utf-8 import numpy as np #導入NumPy包 #創建3*5的全0矩陣和全1的矩陣 myZero = np.zeros([3,5])#3*5的全0矩陣 print myZero myZero = np.ones([3,5])##3*5的全1矩陣 print myZero
輸出結果:
Connected to pydev debugger (build 141.1580)
[[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]]
[[ 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1.]]
#生成隨機矩陣 myRand = np.random.rand(3,4)#3行4列的0~1之間的隨機數矩陣 print myRand 輸出結果如下: [[ 0.14689327 0.15077077 0.88018968 0.75112348] [ 0.30944489 0.77563281 0.82905038 0.25430367] [ 0.53958541 0.89695376 0.90681161 0.25453046]]
#單位陣 myEye = np.eye(3)#3*3的矩陣 print myEye 輸出結果如下: [[ 1. 0. 0.] [ 0. 1. 0.] [ 0. 0. 1.]]
2.矩陣的元素運算
矩陣的元素運算是指矩陣在元素級別的加減乘除運算。
#元素的加和減:條件是矩陣的行數和列數必須相同 from numpy import *#導入NumPy包 myOnes = ones([3,3])#3*3的全1矩陣 myEye = eye(3) print myOnes+myEye print myOnes-myEye 輸出結果如下: [[ 2. 1. 1.] [ 1. 2. 1.] [ 1. 1. 2.]] [[ 0. 1. 1.] [ 1. 0. 1.] [ 1. 1. 0.]]
#矩陣乘法 mymatrix = mat([[1,2,3],[4,5,6],[7,8,9]]) a = 10 print a*mymatrix 輸出結果: [[10 20 30] [40 50 60] [70 80 90]]
#矩陣所有元素求和 mymatrix = mat([[1,2,3],[4,5,6],[7,8,9]]) print mymatrix.sum() 輸出結果: 45
''' 矩陣各元素的積:矩陣的點乘同維對應元素的相乘。 當矩陣的維度不同時,會根據一定的廣播將維數擴 充到一致的形式 ''' mymatrix1 = mat([[1,2,3],[4,5,6],[7,8,9]]) mymatrix2 = 1.5*ones([3,3]) print multiply(mymatrix1,mymatrix2) 輸出結果: [[ 1.5 3. 4.5] [ 6. 7.5 9. ] [ 10.5 12. 13.5]]
#矩陣各元素的n次冪:n=2 mymatrix1 = mat([[1,2,3],[4,5,6],[7,8,9]]) print power(mymatrix1,2) 輸出結果: [[ 1 4 9] [16 25 36] [49 64 81]]
#矩陣乘以矩陣 mymatrix1 = mat([[1,2,3],[4,5,6],[7,8,9]]) mymatrix2 = mat([[1],[2],[3]]) print mymatrix1*mymatrix2 輸出結果: [[14] [32] [50]]
#矩陣的轉置 mymatrix1 = mat([[1,2,3],[4,5,6],[7,8,9]]) print mymatrix1.T #矩陣的轉置 mymatrix1.transpose() #矩陣的轉置 print mymatrix1 輸出結果如下: [[1 4 7] [2 5 8] [3 6 9]] [[1 2 3] [4 5 6] [7 8 9]]
mymatrix = mymatrix1[0]#按行切片 print u"按行切片:",mymatrix mymatrix = mymatrix1.T[0]#按列切片 print u"按列切片:",mymatrix mymatrix = mymatrix1.copy()#矩陣的復制 print u"復制矩陣:",mymatrix #比較 print u"矩陣元素的比較:\n",mymatrix<mymatrix1.T 輸出結果: 矩陣的行數和列數: 3 3 按行切片: [[1 2 3]] 按列切片: [[1 4 7]] 復制矩陣: [[1 2 3] [4 5 6] [7 8 9]] 矩陣元素的比較: [[False True True] [False False True] [False False False]]
1.2.5 Linalg線性代數庫
在矩陣的基本運算基礎之上,NumPy的Linalg庫可以滿足大多數的線性代數運算。
.矩陣的行列式
.矩陣的逆
.矩陣的對稱
.矩陣的秩
.可逆矩陣求解線性方程
1.矩陣的行列式
In [4]: from numpy import * In [5]: #n階矩陣的行列式運算 In [6]: A = mat([[1,2,3],[4,5,6],[7,8,9]]) In [7]: print "det(A):",linalg.det(A) det(A): 6.66133814775e-16
2.矩陣的逆
In [8]: from numpy import * In [9]: A = mat([[1,2,3],[4,5,6],[7,8,9]]) In [10]: invA = linalg.inv(A)#矩陣的逆 In [11]: print "inv(A):",invA inv(A): [[ -4.50359963e+15 9.00719925e+15 -4.50359963e+15] [ 9.00719925e+15 -1.80143985e+16 9.00719925e+15] [ -4.50359963e+15 9.00719925e+15 -4.50359963e+15]]
3.矩陣的對稱
In [12]: from numpy import * In [13]: A = mat([[1,2,3],[4,5,6],[7,8,9]]) In [14]: AT= A.T In [15]: print A*AT [[ 14 32 50] [ 32 77 122] [ 50 122 194]]
4.矩陣的秩
In [16]: from numpy import * In [17]: A = mat([[1,2,3],[4,5,6],[7,8,9]]) In [18]: print linalg.matrix_rank(A)#矩陣的秩 2
5.可逆矩陣求解
1.3 機器學習的數學基礎
1.3.1 相似度的度量
范數(來自百度百科):向量的范數可以簡單、形象的理解為長度,或者向量到坐標系原點的距離,或者相應空間內兩點之間的距離。
向量的范數定義:向量的范數是一個函數||x||,滿足非負性||x||≥0,齊次性||cx|| = |c| ||x||,三角不等式||x+y||≤||x||+||y||。
L1范數:||x||為x向量各個元素絕對值之和
L2范數:||x||為x向量各個元素的平方和的開方。L2范數又稱Euclidean范數或者Frobenius范數
Lp范數:||x||為x向量各個元素絕對值p次方和的1/p次方。
L∞范數:||x||為x向量各個元素絕對值最大的元素,如下:
向量范數的運算如下:
In [27]: A = [8,1,6]
In [28]: #手工計算 In [29]: modA = sqrt(sum(power(A,2))) In [30]: #庫函數 In [31]: normA = linalg.norm(A) In [32]: print "modA:",modA,"norm(A):",normA modA: 10.0498756211 norm(A): 10.0498756211
1.3.2 各類距離的意義與Python代碼的實現 本小節所列的距離公式列表和代碼如下:
•閔可夫斯基距離(Minkowski Distance)
•歐式距離(Euclidean Distance)
•曼哈頓距離(Manhattan Distance)
•切比雪夫距離(Chebyshev Distance)
•夾角余弦(Cosine)
•漢明距離(Hamming Distance)
•傑卡德相似系數(Jaccard Similiarity Coeffcient)
1. 閔可夫斯基距離(Minkowski Distance)
嚴格意義上講,閔可夫斯基距離不是一種距離,而是一組距離的定義。
兩個n維變量A(x11,x12,...,x1n)與B(x21,x22,...,x2n)間的閔可夫斯基距離定義為:
其中p是一個變參數
•當p=1時,就是曼哈頓距離
•當p=2時,就是歐式距離
•當p=∞時,就是切比雪夫距離
根據變參數的不同,閔可供夫斯基可以表示一類的距離
2.歐式距離(Euclidean Distance)
歐氏距離(L2范數)是最易於理解的一種距離計算方法,源自歐式空間中兩點間的距離公式,如圖所示
(1)二維平面上兩點a(x1,y1)與b(x2,y2)間的歐式距離
(2)三維空間兩點A(x1,y1,z1)與B(x2,y2,z2)
(3) 兩個n維向量A(x11,x12,...,x1n)與B(x21,x22,...,x2n)間的歐氏距離:
(4)Python實現歐式距離
In [33]: from numpy import * In [34]: vector1 = mat([1,2,3]) In [35]: vector2 = mat([4,5,6]) In [36]: print sqrt((vector1-vector2)*((vector1-vector2).T)) [[ 5.19615242]]
3.曼哈頓距離(Manhattan Distance)
(1)二維平面兩點A(x1,y1)與B(x2,y2)間的曼哈頓距離:
(2)兩個n維向量A(x11,x12,...,x1n)與B(x21,x22,...,x2n)間的曼哈頓距離
(3)Python實現曼哈頓
In [1]: from numpy import * In [2]: vector1 = mat([1,2,3]) In [3]: vector2 = mat([4,5,6]) In [4]: print sum(abs(vector1-vector2)) 9
4、切比雪夫距離(Chebyshev Distance)
(1)二維平面兩點A(x1,y1)與B(x2,y2)間的切比雪夫距離:
(2)兩個n維平面兩點A(x11,y12,..,x1n)與B(x21,y22,..,x2n)間的切比雪夫距離:
這個公式的另外一種等價形式是:
(3)Python實現切比雪夫距離。
In [1]: from numpy import * In [2]: vector1 = mat([1,2,3]) In [3]: vector2 = mat([4,7,5]) In [4]: print abs(vector1-vector2).max() 5
5.夾角余弦(Consine)
幾何中的夾角余弦可用來衡量兩個向量方向的差異
(1)二維平面兩點A(x1,y1)與B(x2,y2)間的夾角余弦公式:
(2)兩個n維樣本點A(x11,x12,x13,...,x1n)與B(x21,x22,...,x2n)的夾角余弦:
即:
夾角余弦取值范圍為[-1,1]。夾角余弦越大,表示向量的夾角越小;夾角余弦越小,表示兩個向量的夾角越大。當兩個向量的方向重合時,夾角余弦取最大值1;當兩個向量的方向完全相反時,夾角余弦取值最小值-1.
(3)Python實現夾角余弦
In [7]: from numpy import * In [8]: vector1 = mat([1,2,3]) In [9]: vector2 = mat([4,7,5]) In [10]: cosV12 = dot(vector1,vector2.T)/(linalg.norm(vector1)*linalg.norm(vector2)) In [11]: print cosV12 [[ 0.92966968]]
6.漢明距離(Hamming Distance)
(1)漢明距離的定義:兩個等長的字符串s1和s2之間的漢明距離定義為將其中一個變為另外一個所需要的最小替換次數。例如字符串“111“與“1001”之間的漢明距離為2.
應用:信息編碼(為了增強容錯性,應使編碼間的最小漢明距離盡可能大)。
(2)使用Python實現漢明距離。
In [20]: from numpy import * In [21]: matV = mat([[1,1,0,1,0,1,0,0,1],[0,1,1,0,0,0,1,1,1]]) In [22]: smstr = nonzero(matV[0]-matV[1]) In [23]: smstr Out[23]: (array([0, 0, 0, 0, 0, 0], dtype=int64), array([0, 2, 3, 5, 6, 7], dtype=int64)) In [24]: print shape(smstr[0]) (6L,)
7.傑卡德相似系數(Jaccard Similarity Coefficient)
(1)傑卡德相似系數:兩個集合A和B的交集元素在A、B的並集中所占的比例,成為兩個集合的傑卡德相似系數,用符號J(A,B)表示。
傑卡德相似系數是衡量兩個集合的相似度的一種指標。
(2)傑卡德距離:與傑卡德相似系數相反的概念是傑卡德距離(Jaccard Distance),傑卡德距離可用如下的公式表示:
傑卡德距離用兩個集合中不同元素占所有元素的比例來衡量兩個集合的區分度
(3)傑卡德相似系數與傑卡德距離的應用。
可將傑卡德相似系數用在衡量樣本的相似度上。
樣本A與樣本B是兩個n維向量,而且所有維度上的取值都是0或者1.例如,A(0111)和B(1011)。我們將樣本看成一個集合,1表示該集合包含該元素,0表示集合不包含該元素。
P:樣本A與B都是1的維度的個數
q:樣本A是1、樣本B是0的維度的個數
r: 樣本A是0、樣本B是1的維度的個數
s:樣本A與B都是0的維度的個數
那么樣本A與B的傑卡德相似系數可以表示為:
這里p+q+r可以理解為A與B的並集的元素個數,而p是A與B的交集的元素個數。
(4)Python實現傑卡德距離。
In [25]: from numpy import * In [26]: import scipy.spatial.distance as dist #導入Scipy距離公式 In [27]: matV = mat([[1,1,0,1,0,1,0,0,1],[0,1,1,0,0,0,1,1,1]]) In [28]: print "dist.jaccard:",dist.pdist(matV,'jaccard') dist.jaccard: [ 0.75]
1.3.3理解隨機性(略)
1.3.4回顧概率論(略)
1.3.5多元統計基礎(略)
1.3.6特征相關性
1.相關系數
(1)相關系數定義:
(2)相關距離定義:
(3)Python實現相關系數
In [13]: from numpy import * In [14]: matV = mat([[1,1,0,1,0,1,0,0,1],[0,1,1,0,0,0,1,1,1]]) ...: In [15]: mv1 = mean(matV[0])#第一列的均值 In [16]: mv2 = mean(matV[1])#第二列的均值 In [17]: #計算兩列的標准差 In [18]: dv1 = std(matV[0]) In [19]: dv2 = std(matV[1]) In [20]: corref = mean(multiply(matV[0]-mv1,matV[1]-mv2))/(dv1*dv2) In [21]: print corref
2馬氏距離
(1)馬氏距離的定義:有M個樣本向量X1~Xm,協方差矩陣記為S,均值記為向量μ,則其中樣本向量X到μ的距離為:
而其中xi與Xj之間的馬氏距離為:
若協方差矩陣是單位矩陣(各個樣本向量之間獨立同分布),則公式變成歐式距離公式:
若協方差是對角矩陣,則公式變成可標准化的歐式距離公式
(2)馬氏距離的優點:量綱無關,排除變量之間的相關性的干擾。
(3)馬氏距離的Python計算:
In [49]: from numpy import * In [50]: matV = mat([[1,1,0,1,0,1,0,0,1],[0,1,1,0,0,0,1,1,1]]) In [51]: covinv = linalg.inv(cov(matV)) In [52]: tp =matV.T[0]-matV.T[1] In [53]: distma = sqrt(dot(dot(tp,coninv),tp.T)) In [54]: distma = sqrt(dot(dot(tp,covinv),tp.T)) In [55]: distma Out[55]: matrix([[ 2.02547873]])
1.3.7 再談矩陣-空間的變換(略)
5.特征值和特征向量
python求取矩陣的特征值和特征向量。
In [56]: A = [[8,1,6],[3,5,7],[4,9,2]] In [57]: evals,evecs = linalg.eig(A) In [58]: print '特征值:',evals,'\n特征向量:',evecs 特征值: [ 15. 4.89897949 -4.89897949] 特征向量: [[-0.57735027 -0.81305253 -0.34164801] [-0.57735027 0.47140452 -0.47140452] [-0.57735027 0.34164801 0.81305253]]
1.3.8 數據的歸一化
2.歐式距離標准化:
X* = (X-M)/S
標准化的后的值 = (標准化前的值-分量的均值)/分量的標准差
兩個n維向量的之間的標准化的歐式距離公式:
標准化歐式距離Python的實現
In [2]: from numpy import * In [3]: vectormat = mat([[1,2,3],[4,5,6]]) In [4]: v12 = vectormat[0]-vectormat[1] In [5]: print sqrt(v12*v12.T) [[ 5.19615242]] In [6]: #norm In [7]: varmat = std(vectormat.T,axis=0) In [16]: normvmat =(vectormat-mean(vectormat))/varmat.T In [17]: normv12 =normvmat[0]-normvmat[1] In [18]: sqrt( normv12* normv12.T) Out[18]: matrix([[ 8.5732141]])
1.4 數據處理和可視化
1.4.1 數據的導入和內存管理
1.數據表文件的讀取
Python讀取數據表例程:
#coding:utf-8 import sys import os from numpy import * #配置UTF-8的輸出環境 reload(sys) sys.setdefaultencoding('utf-8') #數據文件轉矩陣 #path:數據文件路徑 #delimiter:行內字段分隔符 def file2matrix(path,delimiter): recordlist = [] fp = open(path,"rb")#讀取文件內容 content = fp.read() fp.close() rowlist = content.splitlines()#按行轉化為一維表 #逐行遍歷,結果按分割符分割為行向量 recordlist = [map(eval,row.split(delimiter)) for row in rowlist if row.strip()] return mat(recordlist)#返回轉換后的矩陣形式 root = "testdata" #數據文件所在路徑 pathlist = os.listdir(root) for path in pathlist: recordmat = file2matrix(root + "/"+path," ")#文件到矩陣的轉換 print shape(recordmat)
2.對象的持久化
有時候,我們希望數據以對象的方式保存。Pytho提供了cPickle模塊支持對象的讀寫
#繼續上面的代碼 import cPickle as pickle #導入序列化庫 file_obj = open(root +"/recordmat.dat","wb") pickle.dump(recordmat[0],file_obj)#強生成的矩陣對象保存到指定的位置 file_obj.close() #c此段代碼可將剛才轉換為矩陣的數據持久化為對象的文件 #讀取序列化后的文件 read_obj = open(root+"/recordmat.dat","rb") readmat = pickle.load(read_obj) #從指定的位置讀取對象 print shape(readmat)
3.高效的讀取大文本的文件
#按行讀取文件,讀取指定的行數:nmax = 0 按行讀取全部 def readfilelines(path,nmax = 0): fp = open(path,"rb") ncount = 0 #讀取行 while True: content = fp.readline() if content == "" or (ncount>=nmax and nmax !=0):#判斷文件尾或讀完指定行數 break yield content#返回讀取的行 if nmax != 0: ncount += 1 fp.close() root = "testdata/01.txt" #數據文件所在路徑 for line in readfilelines(path,nmax=10):#讀取10行 print line.strip()
1.4.2 表與線性結構的可視化
示例代碼:
In [1]: import numpy as np In [2]: import matplotlib.pyplot as plt In [3]: #曲線數據加入噪聲 In [4]: x = np.linspace(-5,5,200) In [5]: y = np.sin(x) #給出y與x的基本關系 In [6]: yn = y+np.random.rand(1,len(y))*1.5#加入噪聲的點集 In [7]: #繪圖 In [8]: fig = plt.figure() In [9]: ax = fig.add_subplot(1,1,1) In [10]: ax.scatter(x,yn,c='blue',marker='o') Out[10]: <matplotlib.collections.PathCollection at 0x6b7f780> In [11]: ax.plot(x,y+0.75,'r') Out[11]: [<matplotlib.lines.Line2D at 0x6d510f0>] In [12]: plt.show()
1.4.3 樹與分類結構的可視化(略)
1.4.4 圖與網格結構的可視化(略)
資料來源及版權所有:《機器學習算法原理與編程實踐》鄭捷