常見的機器學習算法(十一)PCA

(一) 直接調用sklearn的API:

from sklearn.decomposition import PCA              #PCA特徵降維#
train_reduced = PCA.fit_transform(train)
test_reduced = PCA.transform(test)

完整代碼:

from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt

digits = load_digits()
x = digits.data#特徵
y = digits.target#標籤

pca = PCA()
pca.fit(x)

plt.figure()
plt.plot(pca.explained_variance_, 'k', linewidth=2)
plt.xlabel('n_components', fontsize=16)
plt.ylabel('explained_variance_', fontsize=16)
plt.show()

pca.explained_variance_ 是協方差矩陣D的對角線元素,如下圖所示:

(二)不調用API

1.應用背景

主成分分析(Principal Components Analysis),簡稱PCA,是一種數據降維技術,用於數據預處理。一般我們獲取的原始數據維度都很高,比如1000個特徵,在這1000個特徵中可能包含了很多無用的信息或者噪聲,真正有用的特徵才100個,那麼我們可以運用PCA算法將1000個特徵降到100個特徵。這樣不僅可以去除無用的噪聲,還能減少很大的計算量。
在PCA中,數據從原來的座標系轉化到新的座標系中。當然這裏新的座標系也不是隨便設定的,而是應該根據數據本身的特徵來設計。通常第一個新座標軸選擇的是原始數據方差最大的方向,第二個座標軸是與第一個座標軸正交且具有最大方差的方向。這句話的意思就是,第二個選取的方向應該和第一個方向具有很弱的相關性。


總結:

降維可以緩解維度災難問題
降維可以在壓縮數據的同時讓信息損失最小化
理解幾百個維度的數據結構很困難,兩三個維度的數據通過可視化更容易理解

2.設計思路

PCA主成分分析算法,是一種線性降維,將高維座標系映射到低維座標系中。
如何選擇低維座標系呢?就是求協方差的特徵值和特徵向量過協方差矩陣的特徵值和特徵向量,特徵向量代表座標系,特徵值代表映射到新座標的長度
然後做數據轉換。

3.步驟:

  1. 去除平均值
  2. 計算協方差矩陣
  3. 計算協方差矩陣的特徵值和特徵向量
  4. 特徵值從大到小排序
  5. 保留最上面k個特徵向量
  6. 將數據轉換到k個向量構件的新空間中
  7. n維矩陣*k維特徵向量=k維矩陣

4.完整代碼

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

#計算均值,要求輸入數據爲numpy的矩陣格式,行表示樣本數,列表示特徵
def meanX(dataX):
    return np.mean(dataX,axis=0)#axis=0表示按照列來求均值,如果輸入list,則axis=1

"""
參數:
    - XMat:傳入的是一個numpy的矩陣格式,行表示樣本數,列表示特徵    
    - k:表示取前k個特徵值對應的特徵向量
返回值:
    - finalData:參數一指的是返回的低維矩陣,對應於輸入參數二
    - reconData:參數二對應的是移動座標軸後的矩陣
"""
def pca(XMat, k):
    average = meanX(XMat)
    m, n = np.shape(XMat)
    avgs = np.tile(average, (m, 1))
    data_adjust = XMat - avgs
    covX = np.cov(data_adjust.T)   #計算協方差矩陣
    featValue, featVec=  np.linalg.eig(covX)  #求解協方差矩陣的特徵值和特徵向量
    index = np.argsort(-featValue) #按照featValue進行從大到小排序
    if k > n:
        print ("k must lower than feature number")
        return
    else:
        #注意特徵向量時列向量,而numpy的二維矩陣(數組)a[m][n]中,a[1]表示第1行值
        selectVec = np.matrix(featVec.T[index[:k]]) #所以這裏需要進行轉置
        finalData = data_adjust * selectVec.T
        reconData = (finalData * selectVec) + average
    return finalData, reconData
#輸入文件的每行數據都以\t隔開
def loaddata(datafile):
    return np.array(pd.read_csv(datafile,sep="\t",header=None)).astype(np.float)
#因爲我將維數k指定爲2,所以可以使用下面的函數將其繪製出來
def plotBestFit(data1, data2):
    dataArr1 = np.array(data1)
    dataArr2 = np.array(data2)

    m = np.shape(dataArr1)[0]
    axis_x1 = []
    axis_y1 = []
    axis_x2 = []
    axis_y2 = []
    for i in range(m):
        axis_x1.append(dataArr1[i,0])
        axis_y1.append(dataArr1[i,1])
        axis_x2.append(dataArr2[i,0])
        axis_y2.append(dataArr2[i,1])
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(axis_x1, axis_y1, s=50, c='red', marker='s')
    ax.scatter(axis_x2, axis_y2, s=50, c='blue')
    plt.xlabel('x1');
    plt.ylabel('x2');
    plt.savefig("outfile.png")
    plt.show()

def main():
    datafile = "data.txt"
    XMat = loaddata(datafile)
    k = 2
    return pca(XMat, k)


if __name__ == "__main__":
    finalData, reconMat = main()
    plotBestFit(finalData, reconMat)#藍色部分爲重構後的原始數據,紅色則是提取後的二維特徵

注:

數據:data.txt文件,注意:使用的是相對路徑,把數據放到你的.py代碼同一級目錄下,並列關係

5.1	3.5	1.4	0.2
4.9	3.0	1.4	0.2
4.7	3.2	1.3	0.2
4.6	3.1	1.5	0.2
5.0	3.6	1.4	0.2
5.4	3.9	1.7	0.4
4.6	3.4	1.4	0.3
5.0	3.4	1.5	0.2
4.4	2.9	1.4	0.2
4.9	3.1	1.5	0.1
5.4	3.7	1.5	0.2
4.8	3.4	1.6	0.2
4.8	3.0	1.4	0.1
4.3	3.0	1.1	0.1
5.8	4.0	1.2	0.2
5.7	4.4	1.5	0.4
5.4	3.9	1.3	0.4
5.1	3.5	1.4	0.3
5.7	3.8	1.7	0.3
5.1	3.8	1.5	0.3
5.4	3.4	1.7	0.2
5.1	3.7	1.5	0.4
4.6	3.6	1.0	0.2
5.1	3.3	1.7	0.5
4.8	3.4	1.9	0.2
5.0	3.0	1.6	0.2
5.0	3.4	1.6	0.4
5.2	3.5	1.5	0.2
5.2	3.4	1.4	0.2
4.7	3.2	1.6	0.2
4.8	3.1	1.6	0.2
5.4	3.4	1.5	0.4
5.2	4.1	1.5	0.1
5.5	4.2	1.4	0.2
4.9	3.1	1.5	0.1
5.0	3.2	1.2	0.2
5.5	3.5	1.3	0.2
4.9	3.1	1.5	0.1
4.4	3.0	1.3	0.2
5.1	3.4	1.5	0.2
5.0	3.5	1.3	0.3
4.5	2.3	1.3	0.3
4.4	3.2	1.3	0.2
5.0	3.5	1.6	0.6
5.1	3.8	1.9	0.4
4.8	3.0	1.4	0.3
5.1	3.8	1.6	0.2
4.6	3.2	1.4	0.2
5.3	3.7	1.5	0.2
5.0	3.3	1.4	0.2
7.0	3.2	4.7	1.4
6.4	3.2	4.5	1.5
6.9	3.1	4.9	1.5
5.5	2.3	4.0	1.3
6.5	2.8	4.6	1.5
5.7	2.8	4.5	1.3
6.3	3.3	4.7	1.6
4.9	2.4	3.3	1.0
6.6	2.9	4.6	1.3
5.2	2.7	3.9	1.4
5.0	2.0	3.5	1.0
5.9	3.0	4.2	1.5
6.0	2.2	4.0	1.0
6.1	2.9	4.7	1.4
5.6	2.9	3.6	1.3
6.7	3.1	4.4	1.4
5.6	3.0	4.5	1.5
5.8	2.7	4.1	1.0
6.2	2.2	4.5	1.5
5.6	2.5	3.9	1.1
5.9	3.2	4.8	1.8
6.1	2.8	4.0	1.3
6.3	2.5	4.9	1.5
6.1	2.8	4.7	1.2
6.4	2.9	4.3	1.3
6.6	3.0	4.4	1.4
6.8	2.8	4.8	1.4
6.7	3.0	5.0	1.7
6.0	2.9	4.5	1.5
5.7	2.6	3.5	1.0
5.5	2.4	3.8	1.1
5.5	2.4	3.7	1.0
5.8	2.7	3.9	1.2
6.0	2.7	5.1	1.6
5.4	3.0	4.5	1.5
6.0	3.4	4.5	1.6
6.7	3.1	4.7	1.5
6.3	2.3	4.4	1.3
5.6	3.0	4.1	1.3
5.5	2.5	4.0	1.3
5.5	2.6	4.4	1.2
6.1	3.0	4.6	1.4
5.8	2.6	4.0	1.2
5.0	2.3	3.3	1.0
5.6	2.7	4.2	1.3
5.7	3.0	4.2	1.2
5.7	2.9	4.2	1.3
6.2	2.9	4.3	1.3
5.1	2.5	3.0	1.1
5.7	2.8	4.1	1.3
6.3	3.3	6.0	2.5
5.8	2.7	5.1	1.9
7.1	3.0	5.9	2.1
6.3	2.9	5.6	1.8
6.5	3.0	5.8	2.2
7.6	3.0	6.6	2.1
4.9	2.5	4.5	1.7
7.3	2.9	6.3	1.8
6.7	2.5	5.8	1.8
7.2	3.6	6.1	2.5
6.5	3.2	5.1	2.0
6.4	2.7	5.3	1.9
6.8	3.0	5.5	2.1
5.7	2.5	5.0	2.0
5.8	2.8	5.1	2.4
6.4	3.2	5.3	2.3
6.5	3.0	5.5	1.8
7.7	3.8	6.7	2.2
7.7	2.6	6.9	2.3
6.0	2.2	5.0	1.5
6.9	3.2	5.7	2.3
5.6	2.8	4.9	2.0
7.7	2.8	6.7	2.0
6.3	2.7	4.9	1.8
6.7	3.3	5.7	2.1
7.2	3.2	6.0	1.8
6.2	2.8	4.8	1.8
6.1	3.0	4.9	1.8
6.4	2.8	5.6	2.1
7.2	3.0	5.8	1.6
7.4	2.8	6.1	1.9
7.9	3.8	6.4	2.0
6.4	2.8	5.6	2.2
6.3	2.8	5.1	1.5
6.1	2.6	5.6	1.4
7.7	3.0	6.1	2.3
6.3	3.4	5.6	2.4
6.4	3.1	5.5	1.8
6.0	3.0	4.8	1.8
6.9	3.1	5.4	2.1
6.7	3.1	5.6	2.4
6.9	3.1	5.1	2.3
5.8	2.7	5.1	1.9
6.8	3.2	5.9	2.3
6.7	3.3	5.7	2.5
6.7	3.0	5.2	2.3
6.3	2.5	5.0	1.9
6.5	3.0	5.2	2.0
6.2	3.4	5.4	2.3
5.9	3.0	5.1	1.8

 

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