终于下定决心,在工作之余研究下机器学习。
此文作为机器学习的开端,希望能一路下去。
一开始被机器学习背后的数学吓到,无奈之下退缩,在机器学习大门前徘徊了许久,终于下定决心,啃下数学这馒头,看看机器学习之貌。
----------------------------------
数学原理:
数据:一个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')