アルゴリズムの出力を、前処理されたさまざまなデータ(NMFとPCA)と比較したいと思います。どういうわけか比較可能な結果を得るために、各PCAとNMFにちょうど同じ数のコンポーネントを選択する代わりに、たとえば、保持された分散の95%を説明する量を選びたいと思います。
NMFの各コンポーネントに保持されている差異を特定することが可能かどうか疑問に思っていました。
たとえば、PCAを使用すると、これは次のようになります。retainedVariance(i) = eigenvalue(i) / sum(eigenvalue)
何か案は?
異なる_n_components
_をループして、各反復でデコードされたX
の_explained_variance_score
_を推定する必要があります。これは、95%の差異を説明するために必要なコンポーネントの数を示します。
その理由を説明します。
NMFとPCAは、他の多くの教師なし学習アルゴリズムと同様に、次の2つのことを行うことを目的としています。
X
を圧縮表現に入力H
;H
_X'
_に戻ります。これは、X
にできる限り近い値にする必要があります。彼らはどういうわけか似た方法でそれを行います:
X' = dot(H, W)
を出力します。ここで、W
は学習された行列パラメーターです。H = dot(X, V)
。ここで、V
も学習されたパラメーターです。 NMFでは、H = argmin(loss(X, H, W))
(H
のみに関して)、ここでloss
はX
とdot(H, W)
の間の平均二乗誤差です。さらに、いくつかの追加のペナルティ。最小化は座標降下によって実行され、結果はX
で非線形になる可能性があります。k
thコンポーネントはそれぞれ、前のコンポーネントと直交することを条件として、残りのMSEを最小化します。 NMFは、エンコード時と同じloss(X, H, W)
を最小化しますが、H
とW
の両方が最小化されます。エンコード/デコードアルゴリズムのパフォーマンスを測定する場合は、通常の手順に従います。
X_train
_でエンコーダーとデコーダーをトレーニングするX_train'=decode(encode(X_train))
と_X_train
_を比較しますX_test
_を使用してステップ2を実行します。PCA
とNMF
で試してみましょう!
_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のデフォルトメトリックの説明された分散比を出力します。より直接的な方法で測定することができます-実際の「予測された」値にメトリックを適用することにより:
_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))
_
与える
_train set performance
0.9536930834362043 # same as before!
0.937291711378812
test set performance
0.9597828443047842
0.9590555069007827
_
トレーニングセットではPCAはNMFよりもパフォーマンスが優れていますが、テストセットではパフォーマンスはほぼ同じです。これは、NMFが多くのregularizationを適用するために発生します。
H
およびW
(学習されたパラメーター)は負でない必要がありますH
はできるだけ小さくする必要があります(L1およびL2ペナルティ)W
はできるだけ小さくする必要があります(L1およびL2ペナルティ)これらの正則化により、NMFがトレーニングデータに適合しなくなる可能性がありますが、私たちの場合に発生した一般化機能が向上する可能性があります。
[〜#〜] pca [〜#〜]では、そのコンポーネント_h_1, h_2, ... h_k
_が順次学習されるため、簡単です。新しいコンポーネントh_(k+1)
を追加しても、最初のk
は変更されません。したがって、各コンポーネントのパフォーマンスを推定でき、これらの推定はコンポーネントの数に依存しません。これにより、PCAは、データへの単一の適合後にのみ_explained_variance_ratio_
_配列を出力できます。
[〜#〜] nmf [〜#〜]は、そのすべてのコンポーネントが同時にトレーニングされ、それぞれが残りすべてに依存するため、より複雑です。したがって、_k+1
_ thコンポーネントを追加すると、最初のk
コンポーネントが変更され、各特定のコンポーネントをその説明された分散(またはその他のメトリック)と一致させることができなくなります。
しかし、できることは、コンポーネントの数ごとにNMF
の新しいインスタンスを適合させ、説明された分散の合計を比較することです。
_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)
_
与えるだろう
_[0.3236945680665101, 0.937291711378812, 0.995459457205891, 0.9974027602663655]
[0.26186701106012833, 0.9590555069007827, 0.9941424954209546, 0.9968456603914185]
_
したがって、分散の少なくとも95%を説明するには、3つのコンポーネント(トレインセットのパフォーマンスによる判断)または2つのコンポーネント(テストセットによる)が必要です。このケースは異常であり、トレーニングとテストデータのサイズが小さいことが原因であることに注意してください。通常、テストセットではパフォーマンスが少し低下しますが、私の場合は実際には少し改善されています。