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

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,我們下面主要也會講解基於這個類的使用的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
"""
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,首先生成隨機數據並可視化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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()
  三維數據的分佈圖如下:

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

1
2
3
4
5
6
from sklearn.decomposition import PCA

pca = PCA(n_components=3)
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)
  輸出結果如下:

1
2
3
[0.98318212 0.00850037 0.00831751]

[3.78521638 0.03272613 0.03202212]
  可以看出投影后三個特徵維度的方差比例大約爲98.3% 0.8% 0.8% 。投影后第一個特徵佔了絕大多數的主成分比例。

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

1
2
3
4
5
6
from sklearn.decomposition import PCA

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

  輸出結果如下:

1
2
3
[0.98318212 0.00850037]

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

  爲了由直觀的認識,我們看看此時轉化後的數據分佈,代碼如下:

1
2
3
X_new = pca.transform(X)
plt.scatter(X_new[:, 0], X_new[:, 1],marker='o')
plt.show()
  (報錯待學習)

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

1
2
3
4
5
pca = PCA(n_components=0.95)
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)
print(pca.n_components_)
  上面我們指定了主成分至少佔95% ,輸出如下:

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

1
2
3
4
5
pca = PCA(n_components = 0.99)
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)
print(pca.n_components_)
  此時輸出的結果:

1
2
3
[0.98318212 0.00850037]
[3.78521638 0.03272613]
2
  這個結果也很好理解,因爲我們第一個主成分佔了98.3%的方差比例,第二個主成分佔了0.8%的方差比例,兩者一起可以滿足我們的閾值。

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

1
2
3
4
5
pca = PCA(n_components = 'mle')
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)
print(pca.n_components_)
  輸出結果如下:

1
2
3
[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,選取三個特徵查看數據分佈情況
  選取三個特徵的原因是人對三維空間比較有概念

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

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,選取兩個特徵查看數據分佈情況
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

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降維,降到二維
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

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數據可以理解爲一種結構化的表格數據

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

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,而一次只處理幾個樣本。還可以被視爲“玩具示例”。

代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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能夠找到使數據線性可分的數據投影

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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()
  結果展示:

知識擴展:python 中的 __doc__是什麼意思?
  (對於代碼功能的註釋,通過__doc__ 可以輸出)

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

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

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

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

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

舉個例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

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

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