機器學習領域中所謂的降維就是指採用某種映射方法,將原高維空間中的數據點映射到低維度的空間中。降維的本質是學習一個映射函數 f : x->y,其中x是原始數據點的表達,目前最多使用向量表達形式。 y是數據點映射後的低維向量表達,通常y的維度小於x的維度(當然提高維度也是可以的)。f可能是顯式的或隱式的、線性的或非線性的。
目前大部分降維算法處理向量表達的數據,也有一些降維算法處理高階張量表達的數據。之所以使用降維後的數據表示是因爲在原始的高維空間中,包含有冗餘信息以及噪音信息,在實際應用例如圖像識別中造成了誤差,降低了準確率;而通過降維,我們希望減少 冗餘信息 所造成的誤差,提高識別(或其他應用)的精度。又或者希望通過降維算法來尋找數據內部的本質結構特徵。
在很多算法中,降維算法成爲了數據預處理的一部分,如PCA。事實上,有一些算法如果沒有降維預處理,其實是很難得到很好的效果的。
數據降維主要分爲線性方法與非線性方法。其中線性方法主要有無監督PCA、有監督LDA。非線性方法有以保留局部特徵爲代表的基於重建權值的LLE、基於鄰接圖的拉普拉斯特徵映射等。還有保留全局特徵爲代表的基於核KPCA、基於距離保持的MDS(歐式距離)極其擴展算法Isomap(測地線距離)。以及定義數據的局部和全局結構之間的軟邊界的t-SNE。每種算法都有其適用的應用領域,具體使用那種算法極其參數設置都需要根據具體情況進行確認。
下面以digits數字圖像集爲例來對比一下各大降維算法。不過也不能完全說明問題,因爲有些算法並不適合處理此類數據,
from time import time
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import offsetbox
from sklearn import manifold, datasets, decomposition, ensemble,discriminant_analysis, random_projection
from mpl_toolkits.mplot3d import Axes3D
digits = datasets.load_digits(n_class=5)
X = digits.data
Y = digits.target
print ('樣本個數: ',X.shape[0],'樣本維度: ',X.shape[1])
n_img_per_row = 20
img = np.zeros((10 * n_img_per_row, 10 * n_img_per_row))
for i in range(n_img_per_row):
ix = 10 * i + 1
for j in range(n_img_per_row):
iy = 10 * j + 1
img[ix:ix + 8, iy:iy + 8] = X[i * n_img_per_row + j].reshape((8, 8))
plt.imshow(img, cmap=plt.cm.binary)
plt.title('data')
Algorithm_SET=[
manifold.TSNE(n_components=3),
manifold.LocallyLinearEmbedding(n_components=3),
manifold.Isomap(n_components=3),
manifold.MDS(n_components=3),
decomposition.PCA(n_components=3),
decomposition.KernelPCA(n_components=3,kernel='rbf'),
decomposition.KernelPCA(n_components=3,kernel='poly'),
decomposition.KernelPCA(n_components=3,kernel='sigmoid'),
discriminant_analysis.LinearDiscriminantAnalysis(n_components=3)
]
Name_SET=[
'TSNE',
'LLE',
'Isomap',
'MDS',
'PCA',
'KPCA-rbf',
'KPCA-poly',
'KPCA-sigmoid',
'LDA'
]
for i,Algorithm in enumerate(Algorithm_SET):
t0 = time()
X = Algorithm.fit_transform(X,Y)
#座標縮放到[0,1]區間
x_min, x_max = np.min(X,axis=0), np.max(X,axis=0)
X = (X - x_min) / (x_max - x_min)
title = Name_SET[i]+": (time %.2fs)" %(time() - t0)
fig = plt.figure(Name_SET[i])
ax = Axes3D(fig)
for j in range(X.shape[0]):
ax.text(X[j, 0], X[j, 1], X[j,2],str(Y[j]),color=plt.cm.Set1((Y[j]+1) / 10.),fontdict={'weight': 'bold', 'size': 9})
plt.title(title)
plt.show()
再看10個分類的:
感覺除了時間複雜度炸裂的t_SNE,其他的都彷彿失了智一樣。
至此,機器學習部分就先告一段落了,總體來說還是蠻難搞的,雖然強大的sklearn庫可以提供各種API以及測試數據,不過若想深入瞭解其中的原理,必須要自己一步一步的推導,一步一步的實現。比如這個:
接下來學習Deep Learning還會面臨更高的挑戰,我只能說,祝大家身體健康吧- -再見!