首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何比较PCA和NMF的预测能力

如何比较PCA和NMF的预测能力
EN

Stack Overflow用户
提问于 2018-01-08 10:46:19
回答 1查看 6.8K关注 0票数 15

我想比较一种算法的输出与不同的预处理数据: NMF和PCA。为了得到一个可比较的结果,而不是为每个PCA和NMF选择相同数量的分量,我想选择的数量解释了95%的保留方差。

我想知道是否有可能识别NMF的每个组成部分中所保留的方差。

例如,使用PCA,这将由:retainedVariance(i) = eigenvalue(i) / sum(eigenvalue)给出。

有什么想法吗?

EN

回答 1

Stack Overflow用户

发布于 2018-03-11 07:48:35

TL;DR

您应该遍历不同的n_components,并在每次迭代时估计已解码的Xexplained_variance_score。这将显示您需要多少个组件来解释95%的差异。

现在我来解释一下原因。

PCA与NMF的关系

与其他许多无监督学习算法一样,NMF和PCA的目标是做两件事:

  • 输入X编码成压缩表示形式H
  • H解码回X',而X'应该尽可能接近X

他们以一种类似的方式做这件事:

  • 解码在PCA和NMF中类似:它们输出X' = dot(H, W),其中W是一个学习的矩阵参数。
  • 编码是不同的。在主成分分析中,它也是线性的:H = dot(X, V),其中V也是一个学习参数。在NMF中,H = argmin(loss(X, H, W)) (仅针对H ),其中lossXdot(H, W)之间的均方误差,外加一些额外的惩罚。采用坐标下降的方法进行极小化,结果在X中可能是非线性的。
  • 培训也不同。PCA按顺序学习:第一分量不受约束地最小化最小均方误差,每个下一k第四分量在与前一分量正交的前提下使残差最小。NMF将与编码时相同的loss(X, H, W)最小化,但现在对于HW都是如此。

如何测量降维性能

如果要测量编码/解码算法的性能,可以按照通常的步骤执行:

  1. 在encoder+decoder上培训X_train
  2. 要度量样本中的性能,请使用首选的度量(例如MAE、RMSE或解释的方差)将X_train'=decode(encode(X_train))X_train进行比较。
  3. 要度量算法的样本外性能(泛化能力),请使用未见的X_test执行步骤2。

让我们用PCANMF试试吧!

代码语言:javascript
复制
from sklearn import decomposition, datasets, model_selection, preprocessing, metrics
# use the well-known Iris dataset
X, _ = datasets.load_iris(return_X_y=True)
# split the dataset, to measure overfitting
X_train, X_test = model_selection.train_test_split(X, test_size=0.5, random_state=1)
# I scale the data in order to give equal importance to all its dimensions
# NMF does not allow negative input, so I don't center the data
scaler = preprocessing.StandardScaler(with_mean=False).fit(X_train)
X_train_sc = scaler.transform(X_train)
X_test_sc = scaler.transform(X_test)
# train the both decomposers
pca = decomposition.PCA(n_components=2).fit(X_train_sc)
nmf = decomposition.NMF(n_components=2).fit(X_train_sc)
print(sum(pca.explained_variance_ratio_))

它将打印您解释的0.9536930834362043方差比--这是PCA的默认度量,使用它的特征值进行估计。我们可以用一种更直接的方式来测量它--通过对实际和“预测”的值应用一个度量:

代码语言:javascript
复制
def get_score(model, data, scorer=metrics.explained_variance_score):
    """ Estimate performance of the model on the data """
    prediction = model.inverse_transform(model.transform(data))
    return scorer(data, prediction)

print('train set performance')
print(get_score(pca, X_train_sc))
print(get_score(nmf, X_train_sc))

print('test set performance')
print(get_score(pca, X_test_sc))
print(get_score(nmf, X_test_sc))

这给

代码语言:javascript
复制
train set performance
0.9536930834362043 # same as before!
0.937291711378812 
test set performance
0.9597828443047842
0.9590555069007827

您可以看到,在训练集上,PCA的性能优于NMF,但在测试集上,它们的性能几乎相同。这种情况发生,因为NMF应用了大量的regularization

  • HW (学习参数)必须是非负的。
  • H应尽可能小(L1和L2处罚)
  • W应尽可能小(L1和L2处罚)

这些正则化使得NMF对训练数据的拟合效果更差,但也可能提高其泛化能力,这在我们的情况下是可能的。

如何选择组件的数量

PCA中,它很简单,因为它的组件h_1, h_2, ... h_k是按顺序学习的。如果添加新组件h_(k+1),则第一个k不会更改。因此,您可以估计每个组件的性能,并且这些估计将不依赖于组件的数量。这使得主成分分析只需对数据进行一次拟合就可以输出explained_variance_ratio_数组。

NMF更复杂,因为它的所有组件都是同时训练的,而每个组件都依赖于所有其他组件。因此,如果添加k+1th组件,第一个k组件将发生变化,并且无法将每个特定组件与其解释的方差(或任何其他度量)匹配。

但是,您所能做的是为每个组件安装一个新的NMF实例,并比较所解释的总方差:

代码语言:javascript
复制
ks = [1,2,3,4]
perfs_train = []
perfs_test = []
for k in ks:
    nmf = decomposition.NMF(n_components=k).fit(X_train_sc)
    perfs_train.append(get_score(nmf, X_train_sc))
    perfs_test.append(get_score(nmf, X_test_sc))
print(perfs_train)
print(perfs_test)

这会给

代码语言:javascript
复制
[0.3236945680665101, 0.937291711378812, 0.995459457205891, 0.9974027602663655]
[0.26186701106012833, 0.9590555069007827, 0.9941424954209546, 0.9968456603914185]

因此,需要三个组件(从火车组的性能判断)或两个组件(通过测试集)来解释至少95%的方差。请注意,这种情况是不寻常的,是由小规模的培训和测试数据造成的:通常测试集的性能会略有下降,但在我的例子中,性能实际上略有提高。

票数 31
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48148689

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档