我正在尝试使用sklearn的PCA函数进行降维,具体来说是
from sklearn.decomposition import PCAdef mypca(X,comp): pca = PCA(n_components=comp)pca.fit(X)PCA(copy=True, n_components=comp, whiten=False)Xpca = pca.fit_transform(X)return Xpcafor n_comp in range(10,1000,20): Xpca = mypca(X,n_comp) # X是一个二维数组 print Xpca
我在循环中调用mypca函数,使用不同的comp值。我这样做是为了找到解决我所面临的问题的最佳comp值。但是mypca函数总是返回相同的值,即Xpca,无论comp的值如何。
它返回的值对于我从循环中发送的第一个comp值是正确的,即每次发送的Xpca值在我的例子中对于comp = 10是正确的。
为了找到最佳的comp值,我应该怎么做?
回答:
看起来您正在尝试传递不同数量的组件,并每次重新拟合。PCA的一个很棒的特点是实际上不需要这样做。您可以拟合完整的组件数量(甚至可以是数据集中维度的数量),然后简单地丢弃您不想要的组件(即那些方差较小的组件)。这相当于用更少的组件重新拟合整个模型。节省了大量计算。
如何操作:
# x = 输入数据,尺寸(<点数>, <维度>)# 拟合完整模型max_components = x.shape[1] # 与输入维度相同数量的组件pca = PCA(n_components=max_components)pca.fit(x)# 转换数据(包含所有组件)y_all = pca.transform(x)# 仅保留前k个组件(具有最大方差)k = 2y = y_all[:, 0:k]
关于如何选择组件数量,这取决于您想要做什么。选择组件数量k
的一种标准方法是查看每个k
选择的解释方差分数(R^2
)。如果您的数据分布在一个低维线性子空间附近,那么当您绘制R^2
与k
的曲线时,曲线将呈现“肘部”形状。肘部将位于子空间的维度处。查看这条曲线是好习惯,因为它有助于理解数据。即使没有清晰的肘部,通常会选择一个R^2
的阈值,例如保留95%的方差。
如何操作(这应该在具有max_components
组件的模型上进行):
# 计算每个组件数量选择的解释方差分数r2 = pca.explained_variance_.cumsum() / x.var(0).sum()
您可能想要继续的另一种方法是将PCA转换后的数据输入到下游算法(例如分类器/回归),然后根据性能选择您的组件数量(例如使用交叉验证)。
附注:可能只是格式问题,但您的mypca()
中的代码块应该缩进,否则它不会被解释为函数的一部分。