算术编码(多媒体实验一)
sklearn主成分分析pca用python实现(多媒体实验二)
BOW图像检索corel数据集(多媒体实验三)
手写数字识别(多媒体实验五)
原理建议看这篇博客:PCA的数学原理。写的非常清楚,弄明白 实例就差不多懂了。
但是弄明白不会写代码,那可以看看这个视频:Python 实战 PCA / 主成分分析(文刀出品)。
过程很简单,总结如下:
- 矩阵X的维度是(m,n)。表示m组数据,n维向量。
- 先对x去均值。(是否标准化看情况)
X_mean = np.mean(data, axis=0)
sdata=(data-X_mean)
- 求协方差 X T X^{T} XT的特征值(ew)和特征向量(ev)。调用np.linalg.eig()函数即可。因为已经去均值了,所以 X T X X^{T}X XTX和 C o v ( X T ) Cov(X^{T}) Cov(XT)是一样的。
- 将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵feature。
ew_order=np.argsort(ew)[::-1]#从大到小
ew_sort=ew[ew_order]
ev_sort=ev[:,ew_order]
feature=ev_sort[:,:k]
- feature最后和原矩阵相乘即为降维后的矩阵。
好了,以上为pca的实现。具体到数据集ColorHistogram.asc
可以看见需要处理一下然后成为np.mat矩阵形式。
def dataprocess(filepath='./ColorHistogram.asc'):
A = np.zeros((68040, 33))
f = open(filepath)
lines = f.readlines()
A_row = 0
for line in lines:
list1 = []
list = line.strip('\n').split(' ')
n = map(float, list)
for i in n:
list1.append(i)
A[A_row] = np.array(list1)
A_row+=1
A = A[:, 1:]
return A
我们还有可以调用一下sklearn的pca和我们写的比较一下:
pca = PCA(n_components=5)
pca.fit(Data)
Std_pca=pca.transform(Data)
取数据集前二十行比较一下:
结果可能有负号差异,因为sklearn的奇异值分解函数有所不同。参考主成分分析PCA(Principal Component Analysis)在sklearn中的应用及部分源码分析。
降维后协方差是对角矩阵,除了对角线值其余接近0。
源代码如下:
import numpy as np
from sklearn.decomposition import PCA
import os
def dataprocess(filepath='./ColorHistogram.asc'):
A = np.zeros((68040, 33))
f = open(filepath)
lines = f.readlines()
A_row = 0
for line in lines:
list1 = []
list = line.strip('\n').split(' ')
n = map(float, list)
for i in n:
list1.append(i)
A[A_row] = np.array(list1)
A_row+=1
A = A[:, 1:]
return A
Data=dataprocess()
#标准值
pca = PCA(n_components=5)
pca.fit(Data)
Std_pca=pca.transform(Data)
#my_pca
def pca(data,k):
X_mean = np.mean(data, axis=0)
sdata=(data-X_mean)
ew,ev=np.linalg.eig(sdata.T.dot(sdata))
ew_order=np.argsort(ew)[::-1]#从大到小
ew_sort=ew[ew_order]
ev_sort=ev[:,ew_order]
feature=ev_sort[:,:k]
new_data=sdata.dot(feature)
return new_data
new_data=pca(Data,5)
print('原矩阵协方差矩阵:\n',np.cov(Data.T))
print('降维后矩阵协方差矩阵:\n',np.cov(new_data.T))
for i in range(20):
print("std:",Std_pca[i])
print("my :",new_data[i])