十二種必須掌握的降維知識(Python代碼)

介紹

你是否曾經處理過具備一千多個特徵的數據集?5萬多個特徵呢?我曾經有過,讓我告訴你這是一項很是具備挑戰性的任務,特別是若是你不知道從哪裏開始的時候!擁有大量的變量既是好事,也是壞事。咱們有大量的數據用於分析,這很棒,但因爲規模太大,它變得很是具備挑戰性。算法

在微觀層面分析每一個變量是不可行的。咱們可能須要幾天或幾個月才能進行任何有意義的分析,咱們將會爲咱們的業務損失大量的時間和金錢!更不用說這將須要的計算能力。咱們須要一種更好的方法來處理高維數據,以便咱們可以快速從中提取模式和看法。那麼咱們如何處理這樣的數據集呢?編程

固然是使用降維技術。你可使用這個技術來減小數據集中的特徵數量,而沒必要丟失太多信息並保持(或改進)模型的性能。正如你將在本文中看到的,這是處理大型數據集的一種很是強大的方法。數組

這是一個能夠在實際場景中使用的各類降維技術的綜合指南。在深刻介紹我所涵蓋的12種不一樣技術以前,咱們將首先了解這個概念是什麼以及爲何要使用它。而且每種技術都有本身的Python實現代碼,讓你更好的熟悉它。安全

1.什麼是降維?

咱們天天都在生成大量的數據。事實上,世界上90%的數據都是在過去的3到4年中產生的!這些數字真的使人難以置信。如下是收集的數據的一些例子:數據結構

  • Facebook會收集你喜歡的,分享的,發佈的,訪問的地點,你喜歡的餐館等的數據。
  • 你的智能手機應用程序會收集大量有關於你的我的信息
  • 亞馬遜會收集你在其網站上購買,查看,點擊等內容的數據
  • 賭場會跟蹤每位客戶的一舉一動

隨着數據生成和收集量的不斷增長,可視化和繪製分析變得愈來愈具備挑戰性。進行可視化的最多見方法之一是經過圖表。假設咱們有2個變量,年齡Age和身高Height。咱們可使用Age和Height之間的散點圖或線圖,並輕鬆地將它們的關係可視化:app

如今考慮咱們有100個變量(p = 100)的狀況。在這種狀況下,咱們能夠有100(100-1)/ 2 = 5000個不一樣的圖。將它們分別可視化是沒有多大意義的,對吧?在咱們有大量變量的狀況下,最好選擇這些變量的一個子集(p << 100),它獲取的信息與原始變量集同樣多。dom

讓咱們用一個簡單的例子來理解這一點。考慮下面的圖像:機器學習

這裏咱們有相似物體的重量,單位爲Kg(X1)和磅(X2)。若是咱們使用這兩個變量,它們將傳達相相似的信息。所以,僅使用一個變量是有意義的。咱們能夠將數據從2D(X1和X2)轉換爲1D(Y1),以下所示:分佈式

相似地,咱們能夠將數據的p維度減小爲k維度的子集(k << n)。這稱爲降維。ide

2.爲何須要降維?

如下是將降維應用於數據集的一些好處:

  • 隨着維度數量的減小,存儲數據所需的空間會減小
  • 更少的維度致使更少的計算/訓練時間
  • 當咱們有一個大的維度時,一些算法的表現不佳。所以,須要減小這些維度才能使算法有用
  • 它經過刪除冗餘的特徵來處理多重共線性問題。例如,你有兩個變量 - 「在跑步機上花費的時間」和「燃燒的卡路里」。這些變量是高度相關的,由於你在跑步機上花費的時間越多,你燃燒的卡路里就越多。所以,存儲兩個變量都沒有意義,只有其中一個能夠知足需求
  • 它有助於可視化數據。如前所述,在高維度中可視化數據是很是困難的,所以將咱們的空間縮小到2D或3D可讓咱們更清晰地繪製和觀察數據

是時候深刻了解本文的關鍵 - 各類降維技術!咱們將使用一個實踐問題:Big Mart Sales III中的數據集點擊這裏下載數據提取碼爲:fmk0 。

3.經常使用的降維技術

降維能夠經過兩種不一樣的方式完成:

  • 僅保留原始數據集中最相關的變量(此技術稱爲特徵選擇)
  • 經過查找較小的一組新變量,每一個變量都是輸入變量的組合,包含與輸入變量基本相同的信息(此技術稱爲降維)

咱們如今將介紹各類降維技術以及如何在Python中實現它們。

3.1缺失值比率

假設你有一個數據集。你的第一步是什麼?在構建模型以前,你應該會但願先探索數據。在研究數據時,你會發現數據集中存在一些缺失值。怎麼辦?你將嘗試找出這些缺失值的緣由,而後將輸入它們或徹底刪除具備缺失值的變量(使用適當的方法)。

若是咱們有太多的缺失值(好比說超過50%)怎麼辦?咱們應該輸入這些缺失值仍是直接刪除變量?我寧願放棄變量,由於它沒有太多的信息。然而,這不是一成不變的。咱們能夠設置一個閾值,若是任何變量中缺失值的百分比大於該閾值,咱們將刪除該變量。

讓咱們在Python中實現這種方法。

導入所須要的庫

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

首先,讓咱們加載數據:

讀取數據

train=pd.read_csv("Train_UWu5bXk.csv")

注意:應在讀取數據時添加文件的路徑。

如今,咱們將檢查每一個變量中缺失值的百分比。咱們可使用.isnull().sum()來計算它。

檢查每一個變量中缺失值的百分比

train.isnull().sum()/len(train)*100

正如你在上表中所看到的,並無太多的缺失值(實際上只有2個變量具備缺失值)。咱們可使用適當的方法來輸入變量,或者咱們能夠設置閾值,好比20%,並刪除具備超過20%缺失值的變量。讓咱們看看如何在Python中完成此操做:

保存變量中缺失的值

a = train.isnull().sum()/len(train)*100

將列名保存在變量中

variables = train.columns
variable = [ ]
for i in range(0,12):
if a[i]<=20: #將閾值設置爲20%
variable.append(variables[i])

所以,要使用的變量存儲在「variables」中,它只包含哪些缺失值小於20%的特徵

3.2低方差過濾器

假設咱們的數據集中的一個變量,其中全部觀察值都是相同的,例如1。若是咱們要使用此變量,你認爲它能夠改進咱們將要創建的模型麼?答案固然是否認的,由於這個變量的方差爲零。

所以,咱們須要計算給出的每一個變量的方差。而後刪除與咱們的數據集中其餘變量相比方差比較小的變量。如上所述,這樣作的緣由是方差較小的變量不會影響目標變量。

讓咱們首先使用已知ItemWeight觀察值的中值來填充temWeight列中的缺失值。對於OutletSize列,咱們將使用已知OutletSize值的模式來填充缺失值:

train['Item_Weight'].fillna(train['Item_Weight'].median(), inplace=True)
train['Outlet_Size'].fillna(train['Outlet_Size'].mode()[0], inplace=True)

讓咱們檢查一下是否全部的缺失值都已經被填滿了:

train.isnull().sum()/len(train)*100

嘿瞧!咱們都已經準備好了。如今讓咱們計算全部數值變量的方差。

train.var()

如上面的輸出所示,與其餘變量相比,Item_Visibility的方差很是小。咱們能夠安全地刪除此列。這就是咱們應用低方差過濾器的方法。讓咱們在Python中實現這個:

numeric = train[['Item_Weight', 'Item_Visibility', 'Item_MRP', 'Outlet_Establishment_Year']]
var = numeric.var()
numeric = numeric.columns
variable = [ ]
for i in range(0,len(var)):
if var[i]>=10: #將閾值設置爲10%
variable.append(numeric[i+1])

上面的代碼爲咱們提供了方差大於10的變量列表。

3.3高度相關過濾器

兩個變量之間的高度相關意味着它們具備類似的趨勢,而且可能攜帶相似的信息。這能夠大大下降某些模型的性能(例如線性迴歸和邏輯迴歸模型)。咱們能夠計算出本質上是數值的獨立數值變量之間的相關性。若是相關係數超過某個閾值,咱們能夠刪除其中一個變量(丟棄一個變量是很是主觀的,而且應該始終記住該變量)。

做爲通常準則,咱們應該保留那些與目標變量顯示出良好或高相關性的變量。

讓咱們在Python中執行相關計算。咱們將首先刪除因變量(ItemOutletSales)並將剩餘的變量保存在新的DataFrame(df)中。

df=train.drop('Item_Outlet_Sales', 1)
df.corr()

太棒了,咱們的數據集中沒有任何具備高相關性的變量。一般,若是一對變量之間的相關性大於0.5-0.6,咱們真的應該認真的考慮丟棄其中的一個變量。

3.4 隨機森林

隨機森林是最普遍使用的特徵選擇算法之一。它附帶內置的重要功能,所以你無需單獨編程。這有助於咱們選擇較小的特徵子集。

咱們須要經過應用一個熱編碼將數據轉換爲數字形式,由於隨機森林(Scikit-Learn實現)僅採用數字輸入。讓咱們也刪除ID變量(Item_IdentifierOutlet_Identifier),由於這些只是惟一的數字,目前對咱們來講並不重要。

from sklearn.ensemble import RandomForestRegressor
df=df.drop(['Item_Identifier', 'Outlet_Identifier'], axis=1)
model = RandomForestRegressor(random_state=1, max_depth=10)
df=pd.get_dummies(df)
model.fit(df,train.Item_Outlet_Sales)

擬合模型後,繪製特徵重要性圖:

features = df.columns
importances = model.feature_importances_
indices = np.argsort(importances)[-9:] # top 10 features
plt.title('Feature Importances')
plt.barh(range(len(indices)), importances[indices], color='b', align='center')
plt.yticks(range(len(indices)), [features[i] for i in indices])
plt.xlabel('Relative Importance')
plt.show()

基於上圖,咱們能夠手動選擇最頂層的特徵來減小數據集中的維度。值得注意的是,咱們可使用sklearn的SelectFromModel來實現這一點。它根據權重的重要性來選擇特徵。

from sklearn.feature_selection import SelectFromModel
feature = SelectFromModel(model)
Fit = feature.fit_transform(df, train.Item_Outlet_Sales)

3.5 反向特徵消除

按照如下步驟來理解和使用「反向特徵消除」技術:

  • 咱們首先獲取數據集中存在的全部的n個變量,而後使用它們訓練模型
  • 而後咱們計算模型的性能
  • 如今,咱們在消除每一個變量(n次)後計算模型的性能,即咱們每次都丟棄一個變量並在剩餘的n-1個變量上訓練模型
  • 咱們肯定移除變量後對模型性能影響最小(或沒有)變化的變量,而後刪除該變量
  • 重複此過程,直到不能刪除任何變量

在構建線性迴歸或邏輯迴歸模型時,可使用此方法。咱們來看看它的Python實現:

from sklearn.linear_model import LinearRegression
from sklearn.feature_selection import RFE
from sklearn import datasets
lreg = LinearRegression()
rfe = RFE(lreg, 10)
rfe = rfe.fit_transform(df, train.Item_Outlet_Sales)

咱們須要指定算法和要選擇的特徵數量,並返回從反向特徵消除中得到的變量列表。咱們還可使用「 rfe.ranking」命令檢查變量的排名。

3.6 正向特徵選擇

這與咱們在上面看到的反向特徵消除的過程相反。咱們是嘗試找到改善模型性能的最佳特徵,而不是消除特徵。該技術的工做原理以下:

  • 咱們從一個特徵開始。本質上,咱們分別使用每一個特徵訓練模型n次
  • 選擇性能最佳的變量做爲起始變量
  • 而後咱們重複這個過程並每次只添加一個變量。保留產生最高性能增加的變量
  • 咱們重複這個過程,直到模型的性能沒有顯著的改進

讓咱們用Python實現它:

from sklearn.feature_selection import f_regression
ffs = f_regression(df,train.Item_Outlet_Sales )

這將返回一個數組,其中包含變量的F值和與每一個F值對應的p值。爲了咱們的目的,咱們將選擇F值大於10的變量:

variable = [ ]
for i in range(0,len(df.columns)-1):
if ffs0 >=10:
variable.append(df.columns[i])

這爲咱們提供了基於正向特徵選擇算法的最多變量。

注意反向特徵消除和正向特徵選擇都是很是耗時且計算成本高的。它們實際上僅用於具備少許輸入變量的數據集。

到目前爲止咱們看到的技術一般在咱們的數據集中沒有太多變量時使用。這些或多或少的特徵選擇技術,在接下來的部分中,咱們將使用Fashion MNIST數據集,該數據集包含屬於不一樣類型服裝的圖像,例如T恤,褲子,包等。數據集可點擊此處下載,提取碼爲:a708。

該數據集共有70,000張圖像,其中60,000張在訓練集中,其他10,000張是測試圖像。在本文的範圍中,咱們將僅處理訓練圖像。訓練集文件採用zip格式。解壓縮zip文件後,你將得到一個.csv文件和一個包含這60,000張圖像的訓練集文件夾。每一個圖像的相應標籤能夠在'train.csv'文件中找到。

3.7 因子分析

假設咱們有兩個變量:收入和教育。這些變量可能具備高度相關性,由於具備較高教育水平的人每每具備顯着較高的收入,反之亦然。

在因子分析技術中,變量按其相關性進行分組,即特定組內的全部變量之間具備高度相關性,但每每與其餘組的變量之間相關性較低。在這裏,每一個組都被稱爲一個因子。與原始數據維度相比,這些因子的數量不多。可是,這些因子每每很難觀察到。

讓咱們先讀入訓練集文件夾中包含的全部圖像:

import pandas as pd
import numpy as np
from glob import glob
import cv2
images = [cv2.imread(file) for file in glob('train/*.png')]

注意:你必須使用train文件夾的路徑替換glob函數內的路徑。

如今咱們將這些圖像轉換爲 numpy數組格式,以便咱們能夠執行數學運算並繪製圖像。

images = np.array(images)
images.shape

(60000,28,28,3)

如上所示,它是一個三維數組。咱們必須將它轉換爲一維的,由於全部即將出現的技術只須要一維輸入。爲此,咱們須要展平圖像:

image = []
for i in range(0,60000):
img = images[i].flatten()
image.append(img)
image = np.array(image)

如今讓咱們建立一個DataFrame,其中包含每一個圖像中每一個像素的像素值,以及它們對應的標籤(對於標籤,咱們將使用train.csv文件)。

train = pd.read_csv("train.csv") # 給出你的train.csv文件的完整路徑
feat_cols = [ 'pixel'+str(i) for i in range(image.shape[1]) ]
df = pd.DataFrame(image,columns=feat_cols)
df['label'] = train['label']

如今咱們將使用因子分析來分解數據集:

from sklearn.decomposition import FactorAnalysis
FA = FactorAnalysis(n_components = 3).fit_transform(df[feat_cols].values)

這裏,n_components將決定轉換數據中的因子數量。轉換數據後,是時候可視化結果了:

%matplotlib inline
import matplotlib.pyplot as plt
plt.figure(figsize=(12,8))
plt.title('Factor Analysis Components')
plt.scatter(FA[:,0], FA[:,1])
plt.scatter(FA[:,1], FA[:,2])
plt.scatter(FA[:,2],FA[:,0])

看起來很棒,不是嗎?咱們能夠在上圖中看到全部不一樣的因素。這裏,x軸和y軸表示分解因子的值。正如我前面提到的,很難單獨觀察這些因素,但咱們已經可以成功地減小數據的維度。

3.8主成分分析(PCA)

PCA是一種技術,能夠幫助咱們從現有的大量變量中提取一組新的變量。這些新提取的變量稱爲主成分。爲了便於你快速學習PCA降維,如下是你在進一步處理以前應該瞭解的關於PCA的一些要點:

  • 主成分是原始變量的線性組合
  • 提取主成分的方法是,第一主成分解釋數據集中的最大方差
  • 第二主成分試圖解釋數據集中的剩餘方差,並與第一主成分不相關
  • 第三主成分試圖解釋前兩個主成分沒法解釋的方差等,以此類推

在繼續以前,咱們將從咱們的數據集中隨機繪製一些圖像:

rndperm = np.random.permutation(df.shape[0])
plt.gray()
fig = plt.figure(figsize=(20,10))
for i in range(0,15):
ax = fig.add_subplot(3,5,i+1)
ax.matshow(df.loc[rndperm[i],feat_cols].values.reshape((28,28*3)).astype(float))

讓咱們使用Python實現PCA降維並轉換數據集:

from sklearn.decomposition import PCA
pca = PCA(n_components=4)
pca_result = pca.fit_transform(df[feat_cols].values)

在這種狀況下,n_components將決定轉換數據中的主要成分的數量。讓咱們看一下使用這4個成分解釋了多少差別。咱們將使用explainvarianceratio_來計算相同的內容。

plt.plot(range(4), pca.explained_variance_ratio_)
plt.plot(range(4), np.cumsum(pca.explained_variance_ratio_))
plt.title("Component-wise and Cumulative Explained Variance")

在上圖中,藍線表示按成分解釋的方差,而橙線表示累積解釋的方差。咱們只用四個組件就能夠解釋數據集中大約60%的方差變化。如今讓咱們嘗試可視化每一個分解的成分:

import seaborn as sns
plt.style.use('fivethirtyeight')
fig, axarr = plt.subplots(2, 2, figsize=(12, 8))
sns.heatmap(pca.components_[0, :].reshape(28, 84), ax=axarr0, cmap='gray_r')
sns.heatmap(pca.components_[1, :].reshape(28, 84), ax=axarr0, cmap='gray_r')
sns.heatmap(pca.components_[2, :].reshape(28, 84), ax=axarr1, cmap='gray_r')
sns.heatmap(pca.components_[3, :].reshape(28, 84), ax=axarr1, cmap='gray_r')
axarr0.set_title(
"{0:.2f}% Explained Variance".format(pca.explained_variance_ratio_[0]*100),
fontsize=12
)
axarr0.set_title(
"{0:.2f}% Explained Variance".format(pca.explained_variance_ratio_[1]*100),
fontsize=12
)
axarr1.set_title(
"{0:.2f}% Explained Variance".format(pca.explained_variance_ratio_[2]*100),
fontsize=12
)
axarr1.set_title(
"{0:.2f}% Explained Variance".format(pca.explained_variance_ratio_[3]*100),
fontsize=12
)
axarr0.set_aspect('equal')
axarr0.set_aspect('equal')
axarr1.set_aspect('equal')
axarr1.set_aspect('equal')

plt.suptitle('4-Component PCA')

咱們添加到PCA技術中的每一個額外維度獲取模型中的方差愈來愈少。第一個部分是最重要的成分,其次是第二個成分,而後是第三個成分,依此類推。

咱們還可使用奇異值分解 (SVD)將咱們的原始數據集分解爲其成分,從而減小維數。

SVD將原始變量分解爲三個組成矩陣。它主要用於從數據集中刪除冗餘的特徵。它使用特徵值和特徵向量的概念來肯定這三個矩陣。因爲本文的範圍,咱們不會深刻研究它的理論,但讓咱們堅持咱們的計劃,即減小數據集中的維度。

讓咱們實現SVD並分解咱們的原始變量:

from sklearn.decomposition import TruncatedSVD 
svd = TruncatedSVD(n_components=3, random_state=42).fit_transform(df[feat_cols].values)

讓咱們經過繪製前兩個主成分來可視化變換後的變量:

plt.figure(figsize=(12,8))
plt.title('SVD Components')
plt.scatter(svd[:,0], svd[:,1])
plt.scatter(svd[:,1], svd[:,2])
plt.scatter(svd[:,2],svd[:,0])

上面的散點圖很是清晰地向咱們展現了分解的成分。如前所述,這些組件之間沒有太多相關性。

3.9獨立成分分析

獨立成分分析(ICA)是基於信息理論的,也是最普遍使用的降維技術之一。PCA和ICA之間的主要區別在於PCA尋找不相關的因素,而ICA尋找獨立因素。

若是兩個變量不相關,則意味着它們之間沒有線性關係。若是它們是獨立的,則意味着它們不依賴於任何其餘變量。例如,一我的的年齡與該人吃什麼或他/她看多少電視無關。

該算法假設給定變量是一些未知潛在變量的線性混合。它還假設這些潛在變量是相互獨立的,即它們不依賴於其餘變量,所以它們被稱爲觀察數據的獨立成分。

讓咱們直觀地比較一下PCA和ICA,以便更好地瞭解它們的不一樣之處:

這裏,圖像(a)表示PCA結果,而圖像(b)表示相同數據集上的ICA結果。

PCA的方程是x = W x。

  • x是觀察結果
  • W是混合矩陣
  • χ是來源或獨立成分

如今咱們必須找到一個非混合矩陣,使成分儘量的獨立。測量成分獨立性的最經常使用方法是非高斯性:

  • 根據中心極限定理,獨立成分之和的分佈傾向於正態分佈(高斯分佈)。

  • 所以,咱們能夠尋找最大化獨立成分的每一個份量的峯度的變換。峯度是分佈的第三階段。
  • 最大化峯度將使分佈非高斯分佈,所以得到獨立成分。

上述分佈是非高斯分佈,這又使得各成分互相獨立。讓咱們嘗試在Python中實現ICA:

from sklearn.decomposition import FastICA 
ICA = FastICA(n_components=3, random_state=12) 
X=ICA.fit_transform(df[feat_cols].values)

這裏,n_components將決定轉換數據中的成分數量。咱們使用ICA將數據轉換爲3個成分。讓咱們看看它是如何改變數據的:

plt.figure(figsize=(12,8))
plt.title('ICA Components')
plt.scatter(X[:,0], X[:,1])
plt.scatter(X[:,1], X[:,2])
plt.scatter(X[:,2], X[:,0])

數據已經被分紅不一樣的獨立成分,在上圖中能夠很是清楚地看到。X軸和Y軸表示分解的獨立成分的值。

如今咱們將看到一些使用投影技術來減小數據維度的方法。

3.10基於投影的方法

首先,咱們須要瞭解投影是什麼。假設咱們有兩個向量,矢量a和矢量b,以下所示:

咱們想求a在b上的投影。那麼設a和b之間的角度爲∅。投影(a1)看起來像:

a1是與b平行的向量所以,咱們可使用如下等式獲得向量a在向量b上的投影:

  • a1 = a到b的投影
  • b = b單位矢量的方向

經過將一個矢量投影到另外一個矢量上,能夠下降維度。

在投影技術中,能夠經過將其點投影到較低維空間來表示多維數據。如今咱們將討論不一樣的預測方法:

  • 投射到有趣的方向:
  • 有趣的方向取決於特定的問題,但通常來講,投影值是非高斯的方向被認爲是有趣的
  • 與ICA(獨立成分分析)相似,投影尋找最大化投影值的峯度的方向,做爲非高斯性的度量。
  • 投影集合管:

曾幾什麼時候,人們認爲地球是平的。不管你去哪裏,它都會保持平坦(讓咱們暫時忽視山脈)。可是,若是你繼續向一個方向走,那麼你最終會走向何方。若是地球是平坦的,那這就不會發生。地球只是看起來比較平坦,那是由於咱們看到的與地球相比是微不足道的。

地球看起來平坦的這些小部分是多方面的,若是咱們將全部這些方面組合在一塊兒,咱們就能夠得到地球的大尺度視圖,也就是原始數據。相似地,對於n維曲線,小的平面快是流形,而且這些流形的組合將給出咱們原始的n維曲線。讓咱們看看投影到流形上的步驟:

  • 咱們首先尋找一個接近數據的流形
  • 而後將數據投影到那個流形上
  • 最後爲了表示,咱們展開了流形
  • 有各類技術能夠得到流形,全部這些技術都包含三個步驟:
  • 從每一個數據點收集信息以構建具備一個以數據點做爲頂點的圖
  • 將上面生成的圖轉換爲適合嵌入步驟的輸入
  • 計算(nXn)本徵方程

讓咱們經過一個例子來理解流形投影技術。

若是一個流形連續可微縮到任意階,則稱爲平滑流形或可微分流形。ISOMAP是一種旨在恢復非線性流形的完整低維表示的算法。它假設流形是平滑的。

它還假設對於流形上的任何一對點,兩點之間的測地距離(曲面上兩點之間的最短距離)等於歐幾里德距離(直線上兩點之間的最短距離)。讓咱們首先形象化一對點之間的測地線和歐幾里德距離:

  • Dn1n2 = X1和X2之間的測地距離
  • dn1n2 = X1和X2之間的歐幾里德距離

ISOMAP假設這兩個距離相等。如今讓咱們看一下這種技術更詳細的解釋。如前所述,全部這些技術都採用三步法。咱們將詳細介紹這些步驟:

  • 鄰近圖:
  • 第一步是計算全部數據點對點之間的距離: dij =dχ(xi,xj)= || xi-xj || χ dχ(xi, xj) = xi和xj測地線距離 || xi-xj || = xi到xj的歐氏距離
  • 在計算距離以後,咱們肯定流形的相鄰數據點
  • 最後生成鄰域圖:G = G(V,ℰ),其中頂點集合V = {x1,x2,...,xn}是輸入數據點和邊緣集合ℰ= {eij}表示附近的點之間的距離
  • 計算圖形距離:
  • 如今咱們經過圖形距離計算流形中各點之間的測地距離
  • 圖形距離是圖G中全部點對點之間的最短路徑距離
  • 嵌入:
  • 一旦咱們獲得距離,咱們就造成了一個方形圖距離的對稱(nXn)矩陣
  • 如今咱們選擇嵌入向量來最小化測地距離和圖形距離之間的差距
  • 最後,圖形G經過(t Xn)矩陣嵌入Y中

讓咱們用Python實現它,這樣就更清楚的理解我在說什麼了。咱們將經過等距映射進行非線性降維。對於可視化,咱們將只採用數據集的一個子集,由於在整個數據集上運行它將須要花費大量時間。

from sklearn import manifold 
trans_data = manifold.Isomap(n_neighbors=5, n_components=3, n_jobs=-1).fit_transform(dffeat_cols.values)

使用的參數:

  • n_neighbors決定每一個點的鄰居數量
  • n_components決定流形的座標數
  • n_jobs = -1將使用全部可用的CPU核心

可視化轉換後的數據:

plt.figure(figsize=(12,8))
plt.title('Decomposition using ISOMAP')
plt.scatter(trans_data[:,0], trans_data[:,1])
plt.scatter(trans_data[:,1], trans_data[:,2])
plt.scatter(trans_data[:,2], trans_data[:,0])

你能夠在上面看到這些成分之間的相關性很是低。實際上,與咱們以前使用SVD得到的成分相比,它們的相關性更小!

3.11 t-分佈式隨機鄰域嵌入(t-SNE)

到目前爲止,咱們已經瞭解到PCA對於具備大量變量的數據集的降維和可視化是一個很好的選擇。可是,若是咱們可使用更高級的東西呢?若是咱們能夠輕鬆地以非線性方式搜索呢?t-SNE就是這樣一種技術。咱們可使用兩種方法來映射數據點:

  • 局部方法:它們將流形上的附近點映射到低維表示中的附近點。
  • 全局方法:他們試圖在全部尺度上保持幾何,即將流形上的附近點映射到低維表示中的附近點以及將遠處的點映射到遠點上。
  • t-SNE是可以同時保留數據的本地和全局結構的少數算法之一
  • 計算了高維空間和低維空間中點的機率類似度
  • 將數據點之間的高維歐氏距離被轉換爲表示類似性的條件機率:

xi和xj是數據點,|| xi-xj || 表示這些數據點之間的歐幾里德距離,σi是高維空間中數據點的方差

  • 對於對應於高維數據點xi和xj的低維數據點yi和yj,可使用如下公式計算類似的條件機率:

其中:|| yi-yj || 表示yi和yj之間的歐幾里德距離

  • 在計算兩個機率以後,它最小化了兩個機率之間的差別

如今咱們將用Python實現它,並將結果可視化:

from sklearn.manifold import TSNE 
tsne = TSNE(n_components=3, n_iter=300).fit_transform(dffeat_cols.values)

n_components將決定轉換數據中的成分數量。是時候查看可視化轉換後的數據:

plt.figure(figsize=(12,8))
plt.title('t-SNE components')
plt.scatter(tsne[:,0], tsne[:,1])
plt.scatter(tsne[:,1], tsne[:,2])
plt.scatter(tsne[:,2], tsne[:,0])

在這裏,你能夠清楚地看到使用強大的t-SNE技術轉換的不一樣成分。

3.12 UMAP

t-SNE在大型數據集上工做表現很好,但它也有它的侷限性,例如丟失大型的信息,計算時間慢,沒法有意義地表示很是大的數據集。統一流形近似和投影(UMAP)是一種降維技術,與t-SNE相比,能夠保留儘量多的本地數據結構和全局數據結構,而且運行時間更短。聽起來頗有趣,對吧。

UMAP的一些主要優點是:

  • 它能夠絕不費力地處理大型數據集和高維數據
  • 它結合了可視化的強大功能和減小數據維度的能力
  • 除了保留本地結構外,它還保留了數據的全局結構。UMAP將流形上的附近點映射到低維表示中的附近點,並對遠點進行相同的映射

該方法使用k-近鄰的概念,並使用隨機梯度降低來優化結果。它首先計算高維空間中的點之間的距離,將它們投影到低維空間,並計算該低維空間中的點之間的距離。而後,它使用隨機梯度降低來最小化這些距離之間的差別。

咱們如今將在Python中實現它:

import umap
umap_data = umap.UMAP(n_neighbors=5, min_dist=0.3, n_components=3).fit_transform(dffeat_cols.values)

  • n_neighbors肯定使用的相鄰點的數量
  • min_dist控制容許嵌入的緊密程度。值越大,嵌入點的分佈越均勻

讓咱們可視化一下這個變換:

plt.figure(figsize=(12,8))
plt.title('Decomposition using UMAP')
plt.scatter(umap_data[:,0], umap_data[:,1])
plt.scatter(umap_data[:,1], umap_data[:,2])
plt.scatter(umap_data[:,2], umap_data[:,0])

維度已經減小了,咱們能夠想象不一樣的變換成分。變換後的變量之間的相關性很是小。讓咱們比較UMAP和t-SNE的結果:

咱們能夠看到,與從t-SNE得到的成分之間的相關性相比,從UMAP得到的成分之間的相關性很是小。所以,UMAP傾向於提供更好的結果。

正如UMAP的GitHub代碼庫中所提到的,與t-SNE相比,它在保留數據全局結構方面的表現更好。這意味着它一般能夠提供更好的「全局」數據視圖以及保留本地鄰居關係。

深呼吸。咱們已經學習了至關多的降維技術。讓咱們簡要總結一下在那裏可使用它們。

4. 簡要總結何時使用什麼技術

在本節中,咱們將簡要總結咱們所涵蓋的每種降維技術的使用案例。瞭解在什麼地方可使用什麼樣的技術,由於它有助於節省時間,精力和計算能力。

  • 缺失值比率:若是數據集的缺失值太多,咱們使用此方法來減小變量的數量。咱們能夠刪除其中包含大量缺失值的變量
  • 低方差過濾器:咱們使用此方法來識別和刪除數據集中的常量變量。目標變量不會受到方差較小的變量的過分影響,所以能夠安全地刪除這些變量
  • 高相關過濾器:具備高相關性的一對變量增長了數據集中的多重共線性。所以,咱們可使用此技術來查找高度相關的功能並相應地刪除它們
  • 隨機森林:這是最經常使用的技術之一,它告訴咱們數據集中存在的每一個特徵的重要性。咱們能夠找到每一個特徵的重要性並保留最頂層的特徵,從而減小維度
  • 這兩個反向特徵消除正向特徵選擇技術須要大量的計算時間,所以通常在較小的數據集使用
  • 因子分析:該技術最適合咱們具備高度相關的變量集的狀況。它將變量基於它們的相關性劃分爲不一樣的組,並用因子表示每一個組
  • 主成分分析:這是處理線性數據最普遍使用的技術之一。它將數據劃分爲一組成分,試圖解釋儘量多的方差
  • 獨立成分分析:咱們可使用ICA將數據轉換爲獨立的成分,這些成分使用更少的成分來描述數據
  • ISOMAP:當數據強非線性時,咱們使用這種技術
  • t-SNE:當數據強非線性時,這種技術也能很好地工做。它對於可視化也很是有效
  • UMAP:這種技術適用於高維數據。與t-SNE相比,它運行的時間更短

結束語

這是一篇關於降維的全面文章,你能夠在任何地方用到它!在編寫過程當中我得到了不少的樂趣,並找到了一些我以前歷來沒用使用過的新方法(好比UMAP)。

處理成千上萬的特徵是任何數據科學家必備的技能。咱們天天生成的數據量是史無前例的,咱們須要找到不一樣的方法來肯定如何使用它。降維是一種很是有用的方法,對我來講,不管是在專業的應用中,仍是在機器學習的比賽中,它都產生了奇妙的效果。

The Ultimate Guide to 12 Dimensionality Reduction Techniques (with Python codes)

相關文章
相關標籤/搜索