0. 前言
前面对鸢尾花数据集进行了降维并且可视化了其数据分布。因为本来的目的是为了可视化,所以选择将4维特征降至2维,也就是将PCA()的参数n_components设置为2。那如果想知道n_components该如何取值,什么取值是最好的,该如何做呢?下面将对此问题进行说明。
1. n_components
还是以鸢尾花数据集为例,想象画一条曲线,该曲线横坐标是降维后保留的特征的数目,纵坐标是降维后新特征矩阵获取的可解释性方差的贡献率。那么就可以确定n_components的最佳取值了。
- PCA()中的n_components使用默认值,再通过.explained_variance_ratio_返回每个特征的信息占比
pca = PCA().fit(X) # 默认n_components为特征数目4
pca_info = pca.explained_variance_ratio_
print("每个特征在原始数据信息占比:\n", pca_info)
"""结果"""
"""
# 每个特征在原始数据信息占比:
[0.92461872 0.05306648 0.01710261 0.00521218]
"""
- 不断累积特征,算信息占比;即前一个特征信息占比,前两个特征信息占比…
pca_info_sum = np.cumsum(pca_info)
print("前i个特征总共在原始数据信息占比:\n", pca_info_sum)
"""结果"""
"""
前i个特征总共在原始数据信息占比:
[0.92461872 0.97768521 0.99478782 1. ]
"""
2. 可视化
可以通过上面的数据来绘制曲线,就可以通过图像直观感受n_components的合理取值
"""可解释性方差贡献率曲线"""
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 1. 加载数据集
iris = load_iris()
X = iris.data
y = iris.target
# 2. 调用PCA
pca = PCA().fit(X) # 默认n_components为特征数目4
pca_info = pca.explained_variance_ratio_
# print("每个特征在原始数据信息占比:\n", pca_info)
pca_info_sum = np.cumsum(pca_info)
# print("前i个特征总共在原始数据信息占比:\n", pca_info_sum)
plt.plot([1, 2, 3, 4], pca_info_sum) # [1, 2, 3, 4]表示选1个特征、2个特征...
plt.xticks([1, 2, 3, 4]) # 限制坐标长度
plt.xlabel('The number of features after dimension')
plt.ylabel('The sum of explained_variance_ratio_')
plt.show()
可视化结果:
根据结果可以看到,选取特征数目的增加,获取原始数据的信息也会随之增加。上面的数据集选取2个或3个特征获取的原始数据的信息都还不错,即n_components可以取2也可以取3。
鸢尾花数据集是4维特征,所以图像比较容易观察,若数据特征很多维,选取转折点处的特征数目作为n_components的取值。
3. 最大似然估计自选n_components取值
除了可以认为设置n_components的值以及使用默认值之外,还可以设置其参数为"mle",即让PCA用最大似然估计自己选择超参数。
"""最大似然估计自选超参数"""
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import numpy as np
# 1. 加载数据集
iris = load_iris()
X = iris.data
y = iris.target
# 2. 调用PCA
pca = PCA(n_components='mle') # 自选
pca = pca.fit(X)
pca_new = pca.transform(X)
print(pca_new)
部分输出结果:
[[-2.68412563 0.31939725 -0.02791483]
[-2.71414169 -0.17700123 -0.21046427]
[-2.88899057 -0.14494943 0.01790026]
[-2.74534286 -0.31829898 0.03155937]
[-2.72871654 0.32675451 0.09007924]
[-2.28085963 0.74133045 0.16867766]
[-2.82053775 -0.08946138 0.25789216]
可以看到选取了三列,即其最大似然估计判断选取3个特征是最佳的取值。因为选3个原始信息的获取量可以达到很好的效果(99%+信息量):
print(pca.explained_variance_ratio_.sum())
# 0.9947878161267246
4. 信息占比n_components
n_components的取值还可以是0-1之间的浮点数,这就表示希望保留的信息量的比例。
比如,设置n_components=0.95就表示希望保留95%的信息量,那么PCA就会自动选使得信息量>=95%的特征数量。但在设置n_components为浮点数的同时,需设置svd_solver=‘full’
"""浮点数"""
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
# 1. 加载数据集
iris = load_iris()
X = iris.data
y = iris.target
# 2. 调用PCA
pca = PCA(n_components=0.95, svd_solver='full') # 浮点数
pca = pca.fit(X)
pca_new = pca.transform(X)
print(pca_new.shape)
print(pca.explained_variance_ratio_.sum())
输出结果:
(150, 2)
0.9776852063187949
(150, 2)可以看出,选了是2个特征,且信息量占比可以达到97%+,满足>=95%.
在不想通过画图方式确定n_components取值,且明确想保留的信息占比时,就可以用这种方式。