昨天我們稍微講了一下如何透過一些基本的圖來讓在做資料分析的時候有一個初步的認識
但有的時候我們的資料維度還是實在太多了,這個時候適當的使用一些降維技巧也可以幫助我們建立起對於資料的基本理解
明明是表示10個不同資訊的維度的資料,為什麼可以降到2維或3維呢?
其實是因為通常原始資料的不同維度之間其實不是獨立的,而在降維的過程就好像是在做圖片壓縮一樣,能用比較少的維度來表示原來資料大部分的資訊內容
對於維度特別高而每個維度所蘊含的資訊又沒有那麼密集的時候,就有可能會有維度災難的產生,因此適當的壓縮一下維度對解決這個現象有一定程度的幫助
就好像牛奶加到紅茶裡面裡面一樣,今天既然用了比較低的維度去表示原來的資料,表示幾乎一定會有一部分的資訊被遺失,而且有些降維方式並不具備可以直接反轉換回本來維度的意義,因此要如何解釋新的維度也是一個需要思考的問題。
可以拿來降維的方式有很多,我這邊主要以比較常用的四種為例子
# 範例資料使用鳶尾花資料集
iris = sns.load_dataset('iris')
iris_feature = iris.iloc[:,:4]
from sklearn.decomposition import PCA
pca = PCA(n_components=2, copy=True, whiten=False) # 建立轉換器
iris_pca = pca.fit_transform(iris_feature) # 轉換
df_tsne = pd.DataFrame({
"Dim1":iris_pca[:,0],
"Dim2":iris_pca[:,1],
"Label": iris["species"]
}) # 重建DataFrame
ax = sns.scatterplot(x="Dim1", y="Dim2", hue="Label",
data=df_tsne) # 繪圖
輸出:
# 建立tsne轉換器
from sklearn.manifold import TSNE
tsne = TSNE(n_components=2, init='pca', random_state=0,perplexity=3) # 困惑度慎選
iris_tsne = tsne.fit_transform(iris_feature)
df_tsne = pd.DataFrame({
"Dim1":iris_tsne[:,0],
"Dim2":iris_tsne[:,1],
"Label": iris["species"]
})# 重建DataFrame
ax = sns.scatterplot(x="Dim1", y="Dim2", hue="Label",
data=df_tsne)# 繪圖
輸出:
from sklearn.decomposition import TruncatedSVD
svd = TruncatedSVD(n_components=2)
iris_svd = svd.fit_transform(iris_feature)
df_svd = pd.DataFrame({
"Dim1":iris_svd[:,0],
"Dim2":iris_svd[:,1],
"Label": iris["species"]
})
ax = sns.scatterplot(x="Dim1", y="Dim2", hue="Label",
data=df_svd)
輸出:
哦對了這個轉換出來的會是離散的結果哦,稍微提醒一下
# 建立SOM
from minisom import MiniSom
som = MiniSom(x=20, y= 20, input_len= 4, random_seed=1)
som.train_batch(data=iris_feature.values.tolist(), num_iteration= 1000)
# 繪圖
plt.figure(figsize=(15,15))
plt.xlim(0, 10)
plt.ylim(10, 20)
for index, row in iris.iterrows():
x,y = som.winner(list(row[:-1]))
if row.species == "setosa":
plt.text(x,y,"A",fontdict={'weight': 'bold', 'size': 10},color = "C1")
# plt.plot(x,y,color = "C1")
elif row.species == "versicolor":
plt.text(x,y,"B",fontdict={'weight': 'bold', 'size': 10},color = "C3")
# plt.plot(x,y,color = "C3")
elif row.species == "virginica":
plt.text(x,y,"C",fontdict={'weight': 'bold', 'size': 10},color = "C4")