Python機器學習筆記:使用scikit-learn工具進行PCA降維


  之前總結過關於PCA的知識:深入學習主成分分析(PCA)算法原理。這里打算再寫一篇筆記,總結一下如何使用scikit-learn工具來進行PCA降維。

  在數據處理中,經常會遇到特征維度比樣本數量多得多的情況,如果拿到實際工程中去跑,效果不一定好。一是因為冗余的特征會帶來一些噪音,影響計算的結果;二是因為無關的特征會加大計算量,耗費時間和資源。所以我們通常會對數據重新變換一下,再跑模型。數據變換的目的不僅僅是降維,還可以消除特征之間的相關性,並發現一些潛在的特征變量。

  降維算法由很多,比如PCA ,ICA,SOM,MDS, ISOMAP,LLE等,在此不一一列舉。PCA是一種無監督降維算法,它是最常用的降維算法之一,可以很好的解決因變量太多而復雜性,計算量增大的弊端。

一,PCA 的目的

  PCA算法是一種在盡可能減少信息損失的前提下,找到某種方式降低數據的維度的方法。PCA通常用於高維數據集的探索與可視化,還可以用於數據壓縮,數據預處理。

  通常來說,我們期望得到的結果,是把原始數據的特征空間(n個d維樣本)投影到一個小一點的子空間里去,並盡可能表達的很好(就是損失信息最少)。常見的應用在於模式識別中,我們可以通過減少特征空間的維度,抽取子空間的數據來最好的表達我們的數據,從而減少參數估計的誤差。注意,主成分分析通常會得到協方差矩陣和相關矩陣。這些矩陣可以通過原始數據計算出來。協方差矩陣包含平方和向量積的和。相關矩陣與協方差矩陣類似,但是第一個變量,也就是第一列,是標准化后的數據。如果變量之間的方差很大,或者變量的量綱不統一,我們必須先標准化再進行主成分分析。

二,PCA算法思路

1,去掉數據的類別特征(label),將去掉后的 d 維數據作為樣本

2,計算 d 維的均值向量(即所有數據的每一維向量的均值)

3,計算所有數據的散布矩陣(或者協方差矩陣)

4,計算特征值(e1 , e2 , e3 , .... ed)以及相應的特征向量(lambda1,lambda2,...lambda d)

5,按照特征值的大小對特征向量降序排序,選擇前 k 個最大的特征向量,組成 d*k 維的矩陣W(其中每一列代表一個特征向量)

6,運行 d*K 的特征向量矩陣W將樣本數據變換成新的子空間。

 

  • 注意1:雖然PCA有降維的效果,也許對避免過擬合有作用,但是最好不要用PCA去作用於過擬合。
  • 注意2:在訓練集中找出PCA的主成分,(可以看做為映射mapping),然后應用到測試集和交叉驗證集中,而不是對所有數據集使用PCA然后再划分訓練集,測試集和交叉驗證集。

三,PCA算法流程

 下面我們看看具體的算法流程:

輸入:n維樣本集,要降維到的維數 n'。

輸出:降維后的樣本集D'

 

1) 對有所的樣本進行中心化:

2) 計算樣本的協方差矩陣

3) 對矩陣進行特征值分解

4) 取出最大的 n' 個特征值對應的特征向量 ,將所有的特征向量標准化后,組成特征向量矩陣W。

5) 對樣本集中的每一個樣本 ,轉化為新的樣本 

6) 得到輸出的樣本集 

 有時候,我們不指定降維后的  n'  的值,而是換種方式,指定一個降維到的主成分比重閾值 t 。這個閾值 t 在 (0 , 1]之間。加入我們的 n個特征值為,則  n'  可以通過下式得到:

 

四,PCA算法優缺點總結

  PCA算法作為一個非監督學習的降維方法,它只需要特征值分解,就可以對數據進行壓縮,去噪。因此在實際場景應用很廣泛。為了克服PCA的一些缺點,出現了很多PCA的變種,比如未解決非線性降維的KPCA,還有解決內存限制的增量PCA方法Incremental PCA ,以及解決稀疏數據降維的PCA方法Sparse PCA 等等。

4.1  PCA算法優點

1,僅僅需要以方差衡量信息量,不受數據集以外的因素影響

2,各主成分之間正交,可消除原始數據成分間的相互影響的因素

3,計算方法簡單,主要運算時特征值分解,易於實現

4.2  PCA算法缺點

1,主成分各個特征維度的含義具有一定的模糊性,不如原始樣本特征的解釋性強

2,方差小的非主成分也可能含有對樣本差異的重要信息,因降維丟棄可能對后續數據處理有影響。

 

scikit-learn PCA類介紹

    在scikit-learn中,與PCA相關的類都在sklearn.decomposition包中。最常用的PCA類就是sklearn.decomposition.PCA,我們下面主要也會講解基於這個類的使用的方法。

"""
The :mod:`sklearn.decomposition` module includes matrix decomposition
algorithms, including among others PCA, NMF or ICA. Most of the algorithms of
this module can be regarded as dimensionality reduction techniques.
"""
 
from .nmf import NMF, non_negative_factorization
from .pca import PCA, RandomizedPCA
from .incremental_pca import IncrementalPCA
from .kernel_pca import KernelPCA
from .sparse_pca import SparsePCA, MiniBatchSparsePCA
from .truncated_svd import TruncatedSVD
from .fastica_ import FastICA, fastica
from .dict_learning import (dict_learning, dict_learning_online, sparse_encode,
                            DictionaryLearning, MiniBatchDictionaryLearning,
                            SparseCoder)
from .factor_analysis import FactorAnalysis
from ..utils.extmath import randomized_svd
from .online_lda import LatentDirichletAllocation
 
__all__ = ['DictionaryLearning',
           'FastICA',
           'IncrementalPCA',
           'KernelPCA',
           'MiniBatchDictionaryLearning',
           'MiniBatchSparsePCA',
           'NMF',
           'PCA',
           'RandomizedPCA',
           'SparseCoder',
           'SparsePCA',
           'dict_learning',
           'dict_learning_online',
           'fastica',
           'non_negative_factorization',
           'randomized_svd',
           'sparse_encode',
           'FactorAnalysis',
           'TruncatedSVD',
           'LatentDirichletAllocation']

  

    除了PCA類以外,最常用的PCA相關類還有KernelPCA類,它主要用於非線性數據的降維,需要用到核技巧。因此在使用的時候需要選擇合適的核函數並對核函數的參數進行調參。

    另外一個常用的PCA相關類是IncrementalPCA類,它主要是為了解決單機內存限制的。有時候我們的樣本量可能是上百萬+,維度可能也是上千,直接去擬合數據可能會讓內存爆掉, 此時我們可以用IncrementalPCA類來解決這個問題。IncrementalPCA先將數據分成多個batch,然后對每個batch依次遞增調用partial_fit函數,這樣一步步的得到最終的樣本最優降維。

    此外還有SparsePCA和MiniBatchSparsePCA。他們和上面講到的PCA類的區別主要是使用了L1的正則化,這樣可以將很多非主要成分的影響度降為0,這樣在PCA降維的時候我們僅僅需要對那些相對比較主要的成分進行PCA降維,避免了一些噪聲之類的因素對我們PCA降維的影響。SparsePCA和MiniBatchSparsePCA之間的區別則是MiniBatchSparsePCA通過使用一部分樣本特征和給定的迭代次數來進行PCA降維,以解決在大樣本時特征分解過慢的問題,當然,代價就是PCA降維的精確度可能會降低。使用SparsePCA和MiniBatchSparsePCA需要對L1正則化參數進行調參。

一,sklearn.decomposition.PCA 參數介紹

  下面我們主要基於sklearn.decomposition.PCA來講解如何使用scikit-learn進行PCA降維。PCA類基本不需要調參,一般來說,我們只需要指定我們需要降維到的維度,或者我們希望降維后的主成分的方差和占原始維度所有特征方差和的比例閾值就可以了。

    現在我們對sklearn.decomposition.PCA的主要參數做一個介紹:

    1)n_components:這個參數可以幫我們指定希望PCA降維后的特征維度數目。最常用的做法是直接指定降維到的維度數目,此時n_components是一個大於等於1的整數。當然,我們也可以指定主成分的方差和所占的最小比例閾值,讓PCA類自己去根據樣本特征方差來決定降維到的維度數,此時n_components是一個(0,1]之間的數。當然,我們還可以將參數設置為"mle", 此時PCA類會用MLE算法根據特征的方差分布情況自己去選擇一定數量的主成分特征來降維。我們也可以用默認值,即不輸入n_components,此時n_components=min(樣本數,特征數)。

    2)whiten :判斷是否進行白化。所謂白化,就是對降維后的數據的每個特征進行歸一化,讓方差都為1.對於PCA降維本身來說,一般不需要白化。如果你PCA降維后有后續的數據處理動作,可以考慮白化。默認值是False,即不進行白化。

    3)svd_solver:即指定奇異值分解SVD的方法,由於特征分解是奇異值分解SVD的一個特例,一般的PCA庫都是基於SVD實現的。有4個可以選擇的值:{‘auto’, ‘full’, ‘arpack’, ‘randomized’}。randomized一般適用於數據量大,數據維度多同時主成分數目比例又較低的PCA降維,它使用了一些加快SVD的隨機算法。 full則是傳統意義上的SVD,使用了scipy庫對應的實現。arpack和randomized的適用場景類似,區別是randomized使用的是scikit-learn自己的SVD實現,而arpack直接使用了scipy庫的sparse SVD實現。默認是auto,即PCA類會自己去在前面講到的三種算法里面去權衡,選擇一個合適的SVD算法來降維。一般來說,使用默認值就夠了。

    除了這些輸入參數外,有兩個PCA類的成員值得關注。第一個是explained_variance_,它代表降維后的各主成分的方差值。方差值越大,則說明越是重要的主成分。第二個是explained_variance_ratio_,它代表降維后的各主成分的方差值占總方差值的比例,這個比例越大,則越是重要的主成分。,

二,PCA對象的屬性

    components_ :返回具有最大方差的成分。

    explained_variance_ratio_ :返回所保留的 n 個成分各自的方差百分比

    n_components_:返回所保留的成分個數 n

    mean_ :

    noise_variance_ :

三,PCA對象的方法

    1) fit(X, y=None)  fit() 可以說是scikit-learn中通用的方法,每個需要訓練的算法都會有fit()方法,他其實就是算法中的“訓練”這一步驟。因為PCA是無監督學習算法,此處y自然等於None。fit(X),表示用數據 X 來訓練PCA模型。函數返回值:調用fit方法的對象本身。比如pca.fit(X),表示用X對pca這個對象進行訓練。

    2)fit_transform(X)  用X來訓練PCA模型,同時返回降維后的數據, NewX = pca.fit_transform(X)。NewX就是降維后的數據。

    3)inverse_transform()  將降維后的數據轉換成原始數據,X = pca.inverse_transform(NewX)

    4)tranform(X) 將數據X轉換成降維后的數據。當模型訓練好后,對於新輸入的數據,都可以用transform 方法來降維。

    此外,還有get_covariance(),get_precision(),get_params(deep = True),score(X, y =True) 等方法。

四,PCA實例1

   下面我們用一個實例來學習一下scikit-learn中的PCA類使用。

 1,首先生成隨機數據並可視化

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# make_nlobs方法常被用來生成聚類算法的測試數據
# make_blobs會根據用戶指定的特征數量,中心點數量,范圍等來生成幾類數據
from sklearn.datasets.samples_generator import make_blobs
# X為樣本特征,Y為樣本簇類型 共10000個樣本,每個樣本3個特征,共4個簇
# n_samples表示產生多少個數據  n_features表示數據是幾維,
# centers表示中心點 cluster_std表示分布的標准差
X, y = make_blobs(n_samples=10000, n_features=3, centers=[[3, 3, 3], [0, 0, 0], [1, 1, 1],
                [2, 2, 2]], cluster_std=[0.2, 0.1, 0.2, 0.2], random_state=9)
fig = plt.figure()
ax = Axes3D(fig, rect=[0, 0, 1, 1], elev=30, azim=20)
plt.scatter(X[:, 0], X[:, 1], X[:, 2], marker='o')
plt.show()

  三維數據的分布圖如下:

我們先只對數據進行投影,看看投影后的三個維度的方差分布,代碼如下:

from sklearn.decomposition import PCA

pca = PCA(n_components=3)
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)

  輸出結果如下:

[0.98318212 0.00850037 0.00831751]

[3.78521638 0.03272613 0.03202212]

  可以看出投影后三個特征維度的方差比例大約為98.3%  0.8%  0.8% 。投影后第一個特征占了絕大多數的主成分比例。

  現在我們來進行降維,從三維降到二維,代碼如下:

from sklearn.decomposition import PCA

pca = PCA(n_components=2)
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)

  

  輸出結果如下:

[0.98318212 0.00850037]

[3.78521638 0.03272613]

  這個結果其實可以預料,因為上面三個投影后的特征維度的方差分別為:[3.78521638 0.03272613 0.03202212] ,投影到二維后選擇的肯定是錢兩個特征,而拋棄第三個特征。

  為了由直觀的認識,我們看看此時轉化后的數據分布,代碼如下:

X_new = pca.transform(X)
plt.scatter(X_new[:, 0], X_new[:, 1],marker='o')
plt.show()

  (報錯待學習)

 

  現在我們 看看不直接指定降維的維度,而指定降維后的主成分方差和比例。

pca = PCA(n_components=0.95)
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)
print(pca.n_components_)

  上面我們指定了主成分至少占95% ,輸出如下:

[0.98318212]
[3.78521638]
1

  可見只有第一個投影特征被保留,這也很好理解,我們的第一個主成分占投影特征的方差比例高達98%。只選擇這一個特征維度便可以滿足95%的閾值。我們現在選擇閾值99%看看,代碼如下:

pca = PCA(n_components = 0.99)
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)
print(pca.n_components_)

  此時輸出的結果:

[0.98318212 0.00850037]
[3.78521638 0.03272613]
2

  這個結果也很好理解,因為我們第一個主成分占了98.3%的方差比例,第二個主成分占了0.8%的方差比例,兩者一起可以滿足我們的閾值。

    最后我們看看讓MLE算法自己選擇降維維度的效果,代碼如下:

pca = PCA(n_components = 'mle')
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)
print(pca.n_components_)

  輸出結果如下:

[0.98318212]
[3.78521638]
1

  可見由於我們的數據的第一個投影特征的方差占比高達98.3%,MLE算法只保留了我們的第一個特征。

五,IRIS數據集實踐IPCA(Incremental  PCA)

   IRIS數據集是常見的分類試驗數據集,也成為鳶尾花數據集,是一類多重變量分析的數據集。數據集包含150個數據集,分為三類,沒類50個數據,每個數據包含4個特征。可以通過花萼長度,花萼寬度,花瓣長度,花瓣寬度(sepal length,sepal width ,petal length ,petal width )4個特征預測鳶尾花卉屬於(Setosa,Versicolour,Virginica)三個種類中的哪一類。

1,選取三個特征查看數據分布情況

  選取三個特征的原因是人對三維空間比較有概念

#_*_coding:utf-8_*_
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn import datasets


data = datasets.load_iris()
X =data['data']
y =data['target']
ax = Axes3D(plt.figure())
for c, i, target_name in zip('rgb', [0, 1, 2], data.target_names):
    ax.scatter(X[y==i, 0], X[y==i, 2], c=c, label=target_name)

ax.set_xlabel(data.feature_names[0])
ax.set_xlabel(data.feature_names[1])
ax.set_xlabel(data.feature_names[2])
ax.set_title('Iris')
plt.legend()
plt.show()

  在X[y==i ,0], X[y==i, 1], X[y==i,2]中,通過0,1,2選擇了三個特征

   可以看出:紅色的Setosa離得遠。

2,選取兩個特征查看數據分布情況

#_*_coding:utf-8_*_
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn import datasets


data = datasets.load_iris()
X =data['data']
y =data['target']
ax = Axes3D(plt.figure())
for c, i, target_name in zip('rgb', [0, 1, 2], data.target_names):
    ax.scatter(X[y==i, 0], X[y==i, 1], c=c, label=target_name)

ax.set_xlabel(data.feature_names[0])
ax.set_xlabel(data.feature_names[1])
ax.set_title('Iris')
plt.legend()
plt.show()

  結果如下:

  可見:利用特征子集,紅色的setosa仍然是線性可分的。

3,利用PCA降維,降到二維

#_*_coding:utf-8_*_
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn import datasets
from sklearn.decomposition import PCA

data = datasets.load_iris()
X =data['data']
y =data['target']
pca = PCA(n_components=2)
X_p = pca.fit(X).transform(X)
ax = plt.figure()
for c, i, target_name in zip('rgb', [0, 1, 2], data.target_names):
    plt.scatter(X_p[y==i, 0], X_p[y==i, 1], c=c, label=target_name)

plt.xlabel('Dimension1')
plt.ylabel('Dimension2')
plt.title('Iris')
plt.legend()
plt.show()

   結果如圖:

4,利用pandas庫查看數據分析

   pandas數據可以理解為一種結構化的表格數據

#_*_coding:utf-8_*_
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn import datasets
from sklearn.decomposition import PCA
import pandas as pd
import seaborn

data = datasets.load_iris()
X =data['data']
y =data['target']
a = pd.DataFrame(X, columns=data.feature_names)
# 隨機打印一下看看數據
print(a.sample(5))
# 箱圖,看數據范圍
seaborn.boxplot(data= a)
plt.plot(a)
plt.legend(data.feature_names)
plt.show()

  箱型圖:

 

  折線圖:

5,Incremental PCA 

   當要分解的數據集太大而無法放入內存時,增量主成分分析(IPCA)通常用作主成分分析(PCA)的替代。IPCA主要是為了解決單機內存限制的,有時候我們的樣本量可能是上百萬+,維度可能也是上千,直接去擬合數據可能會讓內存爆掉,此時我們可以使用Incremental PCA類來解決這個問題。

  IPCA 是將數據分成多個batch,然后對每個batch依次遞增調用partial_fit函數,這樣一步步的得到最終的樣本最優降維。

  此處示例用作視覺檢查,IPCA能夠找到類似的數據投影到PCA,而一次只處理幾個樣本。還可以被視為“玩具示例”。

代碼:

import numpy as np
import matplotlib.pyplot as plt

from sklearn.datasets import load_iris
from sklearn.decomposition import PCA , IncrementalPCA

iris = load_iris()
X = iris.data
y = iris.target

n_components = 2
ipca = IncrementalPCA(n_components=n_components, batch_size=10)
X_ipca = ipca.fit_transform(X)

pca = PCA(n_components=n_components)
X_pca = pca.fit_transform(X)

colors = ['navy', 'turquoise', 'darkorange']

for X_trainsformed, title in [(X_ipca, "Incremental PCA"), (X_pca, "PCA")]:
    plt.figure(figsize=(8, 8))
    for color, i ,target_name in zip(colors, [0,1,2], iris.target_names):
        plt.scatter(X_trainsformed[y == i, 0], X_trainsformed[y ==i, 1],
                    color=color, lw=2, label=target_name)

    if "Incremental" in title:
        err = np.abs(np.abs(X_pca) - np.abs(X_ipca)).mean()
        plt.title(title + 'of iris dataset\nMean absolute unsigned error%.6f'%err)
    else:
        plt.title(title + 'of iris dataset')
    plt.legend(loc='best', shadow=False, scatterpoints=1)
    plt.axis([-4, 4, -1.5, 1.5])

plt.show()

  

結果:

 

6,Kernel PCA

   下面示例可以顯示Kernel PCA能夠找到使數據線性可分的數據投影

import numpy as np
import matplotlib.pyplot as plt

from sklearn.decomposition import PCA, KernelPCA
from sklearn.datasets import make_circles
np.random.seed(0)

X, y = make_circles(n_samples=400, factor=0.3, noise=0.05)

kpca = KernelPCA(kernel='rbf', fit_inverse_transform=True, gamma=10)
X_kpca = kpca.fit_transform(X)
X_back = kpca.inverse_transform(X_kpca)
pca = PCA()
X_pca = pca.fit_transform(X)

# Plot results

plt.figure()
plt.subplot(2, 2, 1, aspect='equal')
plt.title("Original space")
reds = y == 0
blues = y == 1

plt.scatter(X[reds, 0], X[reds, 1], c="red",
            s=20, edgecolor='k')
plt.scatter(X[blues, 0], X[blues, 1], c="blue",
            s=20, edgecolor='k')
plt.xlabel("$x_1$")
plt.ylabel("$x_2$")

X1, X2 = np.meshgrid(np.linspace(-1.5, 1.5, 50), np.linspace(-1.5, 1.5, 50))
X_grid = np.array([np.ravel(X1), np.ravel(X2)]).T
# projection on the first principal component (in the phi space)
Z_grid = kpca.transform(X_grid)[:, 0].reshape(X1.shape)
plt.contour(X1, X2, Z_grid, colors='grey', linewidths=1, origin='lower')

plt.subplot(2, 2, 2, aspect='equal')
plt.scatter(X_pca[reds, 0], X_pca[reds, 1], c="red",
            s=20, edgecolor='k')
plt.scatter(X_pca[blues, 0], X_pca[blues, 1], c="blue",
            s=20, edgecolor='k')
plt.title("Projection by PCA")
plt.xlabel("1st principal component")
plt.ylabel("2nd component")

plt.subplot(2, 2, 3, aspect='equal')
plt.scatter(X_kpca[reds, 0], X_kpca[reds, 1], c="red",
            s=20, edgecolor='k')
plt.scatter(X_kpca[blues, 0], X_kpca[blues, 1], c="blue",
            s=20, edgecolor='k')
plt.title("Projection by KPCA")
plt.xlabel(r"1st principal component in space induced by $\phi$")
plt.ylabel("2nd component")

plt.subplot(2, 2, 4, aspect='equal')
plt.scatter(X_back[reds, 0], X_back[reds, 1], c="red",
            s=20, edgecolor='k')
plt.scatter(X_back[blues, 0], X_back[blues, 1], c="blue",
            s=20, edgecolor='k')
plt.title("Original space after inverse transform")
plt.xlabel("$x_1$")
plt.ylabel("$x_2$")

plt.subplots_adjust(0.02, 0.10, 0.98, 0.94, 0.04, 0.35)

plt.show()

  結果展示:

 

六,流水線操作:PCA降維和邏輯回歸預測

  下面使用PCA進行無監督降維操作,而回歸預測使用邏輯回歸算法。

  注意:這個我們使用GridSearchCV來設置PCA的維度。

代碼:

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

from sklearn import datasets
from sklearn.decomposition import PCA
from sklearn.linear_model import SGDClassifier
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV

# define a pipeline to search for the best combination of PCA  truncation
logistic = SGDClassifier(loss='log', penalty='l2', early_stopping=True,
                         max_iter=10000, tol=1e-5, random_state=0)

pca = PCA()
pipe = Pipeline(steps=[('pca', pca), ('logistic', logistic)])

digits = datasets.load_digits()
X_digits = digits.data
y_digits = digits.target

#Parameters of pipelines can be set using '_' separated parameter names
param_grid = {
    'pca__n_components': [5, 20, 30, 40, 50, 64],
    'logistic__alpha': np.logspace(-4, 4, 5)
}

search = GridSearchCV(pipe, param_grid, iid=False, cv=5, return_train_score=False)
search.fit(X_digits, y_digits)
print("Best parameter (CV score=%0.3f):"%search.best_score_)
print(search.best_params_)

#plot the pca spectrum
pca.fit(X_digits)

fig, (ax0, ax1) = plt.subplots(nrows=2, sharex=True, figsize=(6, 6))
ax0.plot(pca.explained_variance_ratio_, linewidth=2)
ax0.set_ylabel("PCA explained variance")

ax0.axvline(search.best_estimator_.named_steps['pca'].n_components,
            linestyle=':', label='n_components chosen')
ax0.legend(prop=dict(size=12))

# for each number of components, find the best classifier results
results = pd.DataFrame(search.cv_results_)
components_col = 'param_pca__n_components'
best_clfs = results.groupby(components_col).apply(
    lambda g: g.nlargest(1, 'mean_test_score')
)
best_clfs.plot(x= components_col, y='mean_test_score', yerr='std_test_score',
               legend=False, ax=ax1)
ax1.set_ylabel("Classification accuracy (val)")
ax1.set_xlabel('n_components')

plt.tight_layout()
plt.show()

  

結果展示:

 

知識擴展:python 中的 __doc__是什么意思?

  (對於代碼功能的注釋,通過__doc__ 可以輸出)

  每個對象都會有一個__doc__屬性,用於描述該對象的作用。在一個模塊被import時,其文件中的某些特征的字符串會被python解釋器保存在相應對象的__doc__屬性中。

  比如,一個模塊有模塊的__doc__,一個class或者function也有其對應的__doc__屬性。在python中,一個模塊其實就是一個 .py 文件。在文件中特殊的地方書寫的字符串就是所謂的docstrings。就是將被放在__doc__的內容。這個“特殊的地方 “  包括:

1, 一個文件任何一條可執行的代碼之前   # 模塊的__doc__

2, 一個類,在類定於語句后,任何可執行代碼前   # 類的 __doc__

3,一個函數,在函數定於語句后,任何可執行代碼前   # 函數的__doc__

舉個例子:

# use  __doc__ 屬性
class MyClass:
    'string.'

    def printSay(self):
        'print say welcome to you.'
        print('say welcome to you.')


print(MyClass.__doc__)
print(MyClass.printSay.__doc__)

# 輸出結果
string.
print say welcome to you.

  

 

參考文獻:https://www.cnblogs.com/charlotte77/p/5625984.html

 https://www.cnblogs.com/pinard/p/6239403.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM