第8章 降维
第8章 降維
寫在前面
參考書
《機器學習實戰——基于Scikit-Learn和TensorFlow》
工具
python3.5.1,Jupyter Notebook, Pycharm
數據降維的兩種主要方法
- 投影
- 流形學習
- 流形假設:也稱為流形假說,認為大多數現實世界的高維度數據集存在一個低維度的流形來重新表示。這個假設通常是憑經驗觀察的。
- 流形假設通常還伴隨著一個隱含的假設:如果能用低維空間的流形表示,手頭的任務(例如分類或者回歸)將變得更簡單。
PCA
主成分分析(PCA)是迄今為止最流行的降維算法。它先是識別出最接近數據的超平面,然后將數據投影其上。
比較原始數據集與其軸上的投影之間的均方距離,使這個均方距離最小的軸使最合理的選擇。這也正是PCA背后的簡單思想。
奇異值分解(SVD)
import numpy as npX = np.random.random((50, 2)) X_centered = X - X.mean(axis=0) U, s, V = np.linalg.svd(X_centered) c1 = V.T[:, 0] c2 = V.T[:, 1]W2 = V.T[:, :1] W2D = X_centered.dot(W2)PCA實戰
from sklearn.decomposition import PCApca = PCA(n_components=1) X2D = pca.fit_transform(X)components_:訪問主成分(它包含的主成分使水平向量)。舉例來說,第一個主成分即等于
pca.components_.T[:, 0]explained_variance_ratio_:方差解釋率。它表示每個主成分軸對整個數據集方差的貢獻度。
inverse_transform():將壓縮后的數據解壓縮回到原來的shape。原始數據和重建數據(壓縮之后解壓縮)之間的均方距離成為重建誤差。
選擇正確數量的維度:
- 設置n_components=d,若d是整數,則設置為降維后的維度數;若d是小數,則表示希望保留的方差比。
- 還可以將解釋方差繪制關于維度數量的函數(繪制np.cumsum即可)。曲線通常都會有一個拐點,說明方差停止快速增長。你可以將其視為數據集的本征維數。
增量PCA(IPCA)
增量主成分分析
可以將訓練集分成一個個小批量,一次給IPCA
import numpy as np from sklearn.decomposition import IncrementalPCA from sklearn.datasets import fetch_mldatan_batches = 100 mnist = fetch_mldata('MNIST original') X_mnist = mnist["data"]inc_pca = IncrementalPCA(n_components=154) for X_batch in np.array_split(X_mnist, n_batches):inc_pca.partial_fit(X_batch) X_mnist_reduced = inc_pca.transform(X_mnist)還可以使用Numpy的memmap類,它允許你巧妙地操控一個存儲在磁盤二進制文件的大型數組,就好似它也完全在內存里一樣,而這個類(memmap)僅在需要時加載內存中需要的數據。
內存映射,當需要存取一個很大的文件里面的小部分的數據的時候,讀入整個文件顯然是非常的浪費資源的。于是要使用到內存映射的方法。
numpy中的numpy.memmap函數的用法
X_mm = np.memmap(filename, dtype="float32", mode="readonly", shape=(m, n)) batch_size = m // n_batches inc_pca = IncrementalPCA(n_components=154, batch_size=batch_size) inc_pca.fit(X_mm)
隨機PCA
- 這是一個隨機算法,可以快速找到前d個主成分的近似值。
- 它的計算復雜度是$O(m\times d^2) + O(d^3)$,而不是$O(m \times n^2) + O(n^3)$。
- 所以當d遠小于n時,它比前面提到的算法要快得多。
- 使用時,設置PCA中的參數svd_solver=“randomized”
核主成分分析(kPCA)
將核技巧應用于PCA,使復雜的非線性投影降維成為可能。
它擅長在投影后保留實例的集群,有時甚至也能展開近似于一個扭曲流形的數據集。
from sklearn.decomposition import KernelPCArbf_pca = KernelPCA(n_components=2, kernel='rbf', gamma=0.04) X_reduced = rbf_pca.fit_transform(X)
選擇核函數核調整超參數
使用網格搜索,kPCA搭配分類器(邏輯回歸等),來找到使任務性能最佳的核和超參數。
from sklearn.model_selection import GridSearchCV from sklearn.linear_model import LogisticRegression from sklearn.decomposition import KernelPCA from sklearn.pipeline import Pipeline import numpy as npclf = Pipeline([("kpca", KernelPCA(n_components=2)),("log_reg", LogisticRegression()) ])param_grid = [{"kpca__gamma": np.linspace(0.03, 0.05, 10),"kpca__kernel": ["rbf", "sigmoid"] }]grid_search = GridSearchCV(clf, param_grid, cv=3) grid_search.fit(X, y)重建原像
還有一種完全不受監督的方法,就是選擇重建誤差最低的核和超參數。
如果我們對一個已經降維的實例進行線性PCA逆轉換,重建的點將存在于特征空間,而不是原始空間中。而這里特征空間是無限維度的,所以我們無法計算出重建點,因此也無法計算出真實的重建誤差。
我們可以在原始空間中找到一個點,使其映射接近于重建點。這被稱為重建原像。
一旦有了這個原像,你就可以測量它到原始實例的平方距離。最后,便可以選擇使這個重建原像誤差最小化的核和超參數。
執行重建的方法:訓練一個監督式回歸模型,以投影后的實例作為訓練集,并以原始實例作為目標。(設置KernelPCA中的fit_inverse_transform=True)
rbf_pca = KernelPCA(n_components=2, kernel="rbf", gamma=0.0433, fit_inverse_transform=True) X_reduced = rbf_pca.fit_transform(X) X_preimage = rbf_pca.inverse_transform(X_reduced)計算重建原像誤差:
from sklearn.metrics import mean_squared_error mean_squared_error(X, X_preimage)現在,你可以使用交叉驗證的網格搜索,來尋找使這個原像重建誤差最小的核和超參數。
局部線性嵌入(LLE,Locally Linear Embedding)
局部線性嵌入使另一種非常強大的非線性降維(NLDR)技術,不像之前的算法依賴于投影,它是一種流形學習技術。
LLE首先測量每個算法如何與其最近的鄰居線性相關,然后為訓練集尋找一個能最大程度保留這些局部關系的低維表示。
這使得它特別擅長展開彎曲的流形,特別使沒有太多噪聲時。
from sklearn.manifold import LocallyLinearEmbeddinglle = LocallyLinearEmbedding(n_components=2, n_neighbors=10) X_reduced = lle.fit_transform(X)計算復雜度:
- 尋找k個最近鄰為:$O(m log(m)n log(k))$
- 優化權重為:$O(mnk^3)$
- 構建低維表示:$O(dm^2)$
- 很不幸,最后一個表達式里的$m^2$說明這個算法很難擴展應用到大型數據集。
其他降維技巧
- 多維縮放(MDS):保持實例之間的距離,降低維度。
- 等度量映射(Isomap):將每個實例與其最近的鄰居連接起來,創建鏈接圖形,然后保留實例之間的這個測地距離,降低維度。圖中兩個節點之間的測地距離是兩個節點之間最短路徑上的節點數。
- t-分布隨機近鄰嵌入(t-SNE,T-distributed Stochastic Neighbor Embedding):在降低維度時,試圖讓相近的實例彼此靠近,不相似的實例彼此遠離。它主要用于可視化,尤其是將高維空間中的實例集群可視化。
- 線性判別式分析(Linear Discriminant Analysis,LDA):實際上是一種分類算法,但是在訓練過程中,它會學習類別之間最有區別的軸,而這個軸正好可以用來定義投影數據的超平面。這樣做的好處在于投影上的類別之間會盡可能的分開,所以在運行其他分類算法——比如SVM分類器之前,LDA是一個不錯的降維手段。
練習摘抄
降低數據集維度的主要動機是什么?有什么主要弊端?
降維的主要動機是:
- 為了加速后續的訓練算法(在某些情況下,也可能是為了消除噪聲和冗余特征,使訓練算法性能更好)。
- 為了將數據可視化,并從中獲得洞悉,了解重要的特征。
- 只是為了節省空間(壓縮)
- 丟失部分信息,可能后續訓練算法的性能降低
- 可能使計算密集型的
- 為機器學習流水線增條了些許復雜度
- 轉換后的特征往往難以解釋
什么是維度的詛咒?
維度的詛咒是指尋多在低維空間中不存在的問題,在高維空間中發生。在機器學習領域,一個常見的現象是隨機抽樣的高維向量通常非常稀疏,提升了過度擬合的風險,同時也使得在沒有充足訓練數據的情況下,要識別數據中的模式非常困難。
一旦數據集被降維,是否還有可能逆轉?如果有,怎么做?如果沒有,為什么?
一旦使用我們討論的任意算法減少了數據集的維度,幾乎不可能再將操作完美的逆轉,因為在降維過程中必然丟失了一部分信息。雖然有一些算法(例如PCA)擁有簡單的逆轉換過程,可以重建出與原始數據集相似的數據集,但是也有一些算法不能實現逆轉(例如t-SNE)。
PCA可以用來給高度非線性數據集降維么?
對大多數數據集來說,PCA可以用來進行顯著降維,即便是高度非線性的數據集,因為它至少可以消除無用的維度。但是如果不存在無用的維度(例如瑞士卷),那么使用PCA降維將會損失太多信息。你希望的是將瑞士卷展開,而不是將其壓扁。
常規PCA,增量PCA,隨機PCA及核PCA各適用于何種情況?
- 常規PCA是默認選擇,但是它僅適用于內存足夠處理訓練集的時候。
- 增量PCA對于內存無法支持的大型數據集非常有用,當時它比常規PCA要來得慢一些,所以如果內存能夠支持,還是應該使用常規PCA。當你需要隨時應用PCA來處理每次新增的實例時,增量PCA對于在線任務同樣有用。
- 當你想大大降低維度數量,并且內存足夠支持數據集時,使用隨機PCA非常有效。它比常規PCA快得多。
- 最后對于非線性數據集,使用核化PCA行之有效。
如何在你的數據集上評估降維算法的性能?
- 直觀來說,如果降維算法能夠消除許多維度并且不會丟失太多信息,那么這就算是一個好的降維算法。
- 進行衡量的方法之一是應用逆轉換然后測量重建誤差。
- 然而并不是所有的降維算法都提供了逆轉換。還有一種選擇,如果你將降維當作一個預處理過程,用在其他機器學習算法(比如隨機森林分類器)之前,那么可以通過簡單的測量第二個算法的性能來進行評估。如果降維過程沒有損失太多信息,那么第二個算法的性能應該跟使用原始數據集一樣好。
鏈接兩個不同的降維算法有意義嗎?
鏈接兩個不同的降維算法絕對是有意義的。常見的例子是使用PCA快速去除大量無用的維度,然后應用另一種更慢的降維算法,如LLE。這樣兩步走的策略產生的結果可能與僅使 用LLE相同,但是時間要短得多。
主要的弊端使:
我的CSDN:https://blog.csdn.net/qq_21579045
我的博客園:https://www.cnblogs.com/lyjun/
我的Github:https://github.com/TinyHandsome
紙上得來終覺淺,絕知此事要躬行~
歡迎大家過來OB~
by 李英俊小朋友
轉載于:https://www.cnblogs.com/lyjun/p/11424764.html
總結
- 上一篇: map拼接URL参数
- 下一篇: 卷一 内核源代码分析 第二章 异常 2.