1. 程式人生 > >機器學習之主成分分析法

機器學習之主成分分析法

終於下定決心,在工作之餘研究下機器學習。

此文作為機器學習的開端,希望能一路下去。

一開始被機器學習背後的數學嚇到,無奈之下退縮,在機器學習大門前徘徊了許久,終於下定決心,啃下數學這饅頭,看看機器學習之貌。

 

----------------------------------

數學原理:

資料:一個M*N的矩陣X(這裡省去中心化,預設X已經做了中心化的步驟,中心化的好處就是求協方差即為求新方向基)

對矩陣X求協方差,其實求協方差矩陣的最大值,就是找出矩陣X的一個N維向量基,使得矩陣X在此基的投影最大,也就是內積,這兩者是等價的。

對協方差方程求特徵值,以及特徵向量。

對特徵值進行排序,找出比重超過預設值(看看需要多少主成分)的特徵值,乘以對應的特徵向量,就能得到一個矩陣P,可用於矩陣X的降溫

XP=ND  (ND為New Data的縮寫),得到一個降維的矩陣ND,這就是最終要的結果。

*對於影象處理來說,ND比較抽象,通常會讓ND*P(T)+均值矩陣得到一個重構的矩陣R,矩陣R恢復成影象可以看到提取了主成分的影象,在視覺上是什麼效果。

 

下面貼上python原始碼,程式碼參考於網上:

 

 1 import numpy as np
 2 from numpy import *
 3 from PIL import
Image 4 5 np.set_printoptions(threshold=np.nan) 6 7 8 # 零均值化 9 def zeroMean(dataMat): 10 meanVal = np.mean(dataMat, axis=0) # 按列求均值,即求各個特徵的均值 11 newData = dataMat - meanVal 12 return newData, meanVal 13 14 15 def percentage2n(eigVals, percentage): 16 sortArray = np.sort(eigVals) #
升序 17 sortArray = sortArray[-1::-1] # 逆轉,即降序 18 arraySum = sum(sortArray) 19 tmpSum = 0 20 num = 0 21 for i in sortArray: 22 tmpSum += i 23 num += 1 24 if tmpSum >= arraySum * percentage: 25 return num 26 27 28 def pca(dataMat, percentage=0.99): 29 dataMat.size 30 newData, meanVal = zeroMean(dataMat) 31 covMat = np.cov(newData, rowvar=0) # 求協方差矩陣,return ndarray;若rowvar非0,一列代表一個樣本,為0,一行代表一個樣本 32 eigVals, eigVects = np.linalg.eig(np.mat(covMat)) # 求特徵值和特徵向量,特徵向量是按列放的,即一列代表一個特徵向量 33 print("特徵值:\n") 34 print(eigVals) 35 print("特徵向量:\n") 36 #print(eigVects) 37 n = percentage2n(eigVals, percentage) # 要達到percent的方差百分比,需要前n個特徵向量 38 # n=10 39 print("number:", n) 40 eigValIndice = np.argsort(eigVals) # 對特徵值從小到大排序 41 n_eigValIndice = eigValIndice[-1:-(n + 1):-1] # 最大的n個特徵值的下標 42 n_eigVect = eigVects[:, n_eigValIndice] # 最大的n個特徵值對應的特徵向量 43 lowDDataMat = newData * n_eigVect # 低維特徵空間的資料 44 #MatrixToImage(lowDDataMat).show() 45 reconMat = (lowDDataMat * n_eigVect.T) + meanVal # 重構資料 46 return reconMat 47 48 49 def ImageToMatrix(filename): 50 # 讀取圖片 51 im = Image.open(filename) 52 # 顯示圖片 53 # im.show() 54 width, height = im.size 55 im = im.convert("L") 56 data = im.getdata() 57 data = np.matrix(data, dtype='float') / 255.0 58 # new_data = np.reshape(data,(width,height)) 59 new_data = np.reshape(data, (height, width)) 60 return new_data 61 62 63 # new_im = Image.fromarray(new_data) 64 # # 顯示圖片 65 # new_im.show() 66 def MatrixToImage(data): 67 data = data * 255 68 new_im = Image.fromarray(data.astype(np.uint8)) 69 return new_im 70 71 72 filename = 'timg.jpg' 73 data = ImageToMatrix(filename) 74 # 75 #print(pca(data)) 76 new_im = MatrixToImage(pca(data,0.99)) 77 new_im.show() 78 new_im.save('fuck.jpg') 79 #print (data ) 80 #new_im = MatrixToImage(data) 81 #plt.imshow(data, cmap=plt.cm.gray, interpolation='nearest') 82 #new_im.show() 83 #new_im.save('lena_1.bmp')