非監督學習之PCA降維&流行學習TSNE

作者:徐瑩

1.PCA簡介

使用非監督學習的方式進行數據變換有非常廣泛的用途。最常見的目的就是對數據進行可視化,將數據進行壓縮併爲進一步處理得到一個更有效的數據表示。這其中最有效使用最廣泛的技術要數PCA(Principal Component Analysis)了。

主成分分析(PCA)是一種以某種方式旋轉數據集的方法,使得旋轉特徵在統計學上不相關。這種旋轉通常是根據它們能夠解釋數據的能力的重要性來選擇新特徵的子集。

這裏寫圖片描述

第一個圖顯示原始數據點,着色以區分點。算法首先找出最大方差的方向,標記爲“分量1“。這是數據中包含大多數信息的方向,或者換句話說,這是每一個特徵最相關的方向。然後,算法找到與第一方向正交(在直角)時包含最多信息的方向。在二維空間中,只有一個可能的方向是直角,但是在高維空間中會有無窮多個正交方向。通過這種方式找到的方向稱之爲“Principal Component”,它代表了數據方差的主要方向。

第二個圖顯示相同的數據,但現在旋轉,使得第一主成分與x軸對齊,第二主成分與y軸對齊。在旋轉之前,從數據中減去平均值,使得變換數據以零爲中心。在PCA發現的旋轉表示中,兩個軸是不相關的,這意味着該表示中的數據的相關矩陣,除了對角線之外是零。我們可以通過只保留一些主成分來使用PCA進行維數約簡。在這個例子中,我們可能只保留第一個主成分,如圖三顯示。

這將數據從二維數據集減少到一維數據集。但我們只保留了其中的一個特徵,我們發現最有趣的方向(在第一個圖的左上到右下)並保持這個方向,第一主成分。

最後,我們可以撤消旋轉,並將均值返回到數據。這將產生最後一個圖顯示的數據。這些點在原始特徵空間中,但我們只保留第一主成分中包含的信息。這種轉變有時用於去除數據中的噪聲效應,或可視化保存在主成分分析中的部分信息。


2.PCA實例

PCA 最常見的作用就是對高維數據進行可視化。我們將針對一個乳腺癌的數據集舉例。 在進行PCA處理之前,首先對數據進行scale 處理,通過StandardScaler使得數據的每一個特徵都有單位方差。

from sklearn.datasets import load_breast_cancer
cancer = load_breast_cancer()
scaler = StandardScaler()
scaler.fit(cancer.data)
X_scaled = scaler.transform(cancer.data)

接下來通過fit方法找到 principal components, 通過transform方法進行旋轉和維度約減:

from sklearn.decomposition import PCA

# keep the first two principal components of the data
pca = PCA(n_components=2)

# fit PCA model to beast cancer data
pca.fit(X_scaled)

# transform data onto the first two principal components
X_pca = pca.transform(X_scaled)
print("Original shape: %s" % str(X_scaled.shape))
print("Reduced shape: %s" % str(X_pca.shape))

Original shape: (569, 30)
Reduced shape: (569, 2)

# plot fist vs second principal component, color by class
plt.figure(figsize=(8, 8))
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=cancer.target, cmap=mglearn.tools.cm, s=60)
plt.gca().set_aspect("equal")

plt.xlabel("First principal component")
plt.ylabel("Second principal component")



這裏寫圖片描述

PCA 是一種非監督的學習方式,在旋轉的過程中不使用任何的分類信息。他只是簡單的分析數據之間的相關性。
從圖中可以看出,在二維空間中,兩類數據被很好地區分開來。

主元存儲在 components_ 屬性中:pca.components_.shape(2, 30)
components_ 屬性的每一行對應一個主元,保存着他們的重要性,每一列對應原始數據的每一個特徵。

print(pca.components_)
[[-0.22 -0.1 -0.23 -0.22 -0.14 -0.24 -0.26 -0.26 -0.14 -0.06 -0.21 -0.02
-0.21 -0.2 -0.01 -0.17 -0.15 -0.18 -0.04 -0.1 -0.23 -0.1 -0.24 -0.22
-0.13 -0.21 -0.23 -0.25 -0.12 -0.13]

[ 0.23 0.06 0.22 0.23 -0.19 -0.15 -0.06 0.03 -0.19 -0.37 0.11 -0.09
0.09 0.15 -0.2 -0.23 -0.2 -0.13 -0.18 -0.28 0.22 0.05 0.2 0.22
-0.17 -0.14 -0.1 0.01 -0.14 -0.28]]

3.T-SNE簡介

雖然PCA能夠很好地對數據進行可視化,但是受限於算法的本質,PCA的有效性大打折扣。有一類稱爲流行學習的可視化的方法,能夠承載更復雜的映射提供更好的可視化方法。

T-SNE就是其中最流行的一種。T-SNE的思想是找到數據的一種二維表達方式,同時能夠儘可能地保持點與點之間的距離。T-SNE從每個數據點的隨機二維表示開始,然後嘗試使在原始特徵空間中更接近的點更靠近,並且在原始特徵空間中相距很遠的點更遠。T-SNE更強調靠近的點,而不是保存遠點之間的距離。換句話說,它試圖保存哪些點是彼此相鄰的信息。


4.T_SNE實例

這裏舉一個scikit-learn裏面的手寫數字的數據集的例子,如下圖所示可以看到0-9的手寫數字圖。

這裏寫圖片描述

代碼:

from sklearn.manifold import TSNE
tsne = TSNE(random_state=42)

# use fit_transform instead of fit, as TSNE has no transform method:
digits_tsne = tsne.fit_transform(digits.data)
plt.figure(figsize=(10, 10))
plt.xlim(digits_tsne[:, 0].min(), digits_tsne[:, 0].max() + 1)
plt.ylim(digits_tsne[:, 1].min(), digits_tsne[:, 1].max() + 1)

for i in range(len(digits.data)):
# actually plot the digits as text instead of using scatter
    plt.text(digits_tsne[i, 0], digits_tsne[i, 1], str(digits.target[i]),
    color = colors[digits.target[i]],
    fontdict={'weight': 'bold', 'size': 9})

這裏寫圖片描述

從圖中可以看出,所有的數字類型都被很好地區分開來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章