web-dev-qa-db-ja.com

PCAとNMFの予測力を比較する方法

アルゴリズムの出力を、前処理されたさまざまなデータ(NMFとPCA)と比較したいと思います。どういうわけか比較可能な結果を​​得るために、各PCAとNMFにちょうど同じ数のコンポーネントを選択する代わりに、たとえば、保持された分散の95%を説明する量を選びたいと思います。

NMFの各コンポーネントに保持されている差異を特定することが可能かどうか疑問に思っていました。

たとえば、PCAを使用すると、これは次のようになります。retainedVariance(i) = eigenvalue(i) / sum(eigenvalue)

何か案は?

13
Phil D

TL; DR

異なる_n_components_をループして、各反復でデコードされたXの_explained_variance_score_を推定する必要があります。これは、95%の差異を説明するために必要なコンポーネントの数を示します。

その理由を説明します。

PCAとNMFの関係

NMFとPCAは、他の多くの教師なし学習アルゴリズムと同様に、次の2つのことを行うことを目的としています。

  • encode入力Xを圧縮表現に入力H;
  • decodeH _X'_に戻ります。これは、Xにできる限り近い値にする必要があります。

彼らはどういうわけか似た方法でそれを行います:

  • デコードはPCAとNMFで似ています。これらはX' = dot(H, W)を出力します。ここで、Wは学習された行列パラメーターです。
  • エンコーディングは異なります。 PCAでは、これも線形です:H = dot(X, V)。ここで、Vも学習されたパラメーターです。 NMFでは、H = argmin(loss(X, H, W))Hのみに関して)、ここでlossXdot(H, W)の間の平均二乗誤差です。さらに、いくつかの追加のペナルティ。最小化は座標降下によって実行され、結果はXで非線形になる可能性があります。
  • トレーニングも違います。 PCAは順次学習します。最初のコンポーネントは制約なしでMSEを最小化し、次のkthコンポーネントはそれぞれ、前のコンポーネントと直交することを条件として、残りのMSEを最小化します。 NMFは、エンコード時と同じloss(X, H, W)を最小化しますが、HWの両方が最小化されます。

次元削減のパフォーマンスを測定する方法

エンコード/デコードアルゴリズムのパフォーマンスを測定する場合は、通常の手順に従います。

  1. _X_train_でエンコーダーとデコーダーをトレーニングする
  2. サンプル内のパフォーマンスを測定するには、優先メトリック(例:MAE、RMSE、または説明された分散)を使用してX_train'=decode(encode(X_train))と_X_train_を比較します
  3. アルゴリズムのサンプル外のパフォーマンス(一般化能力)を測定するには、目に見えない_X_test_を使用してステップ2を実行します。

PCANMFで試してみましょう!

_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つのコンポーネント(テストセットによる)が必要です。このケースは異常であり、トレーニングとテストデータのサイズが小さいことが原因であることに注意してください。通常、テストセットではパフォーマンスが少し低下しますが、私の場合は実際には少し改善されています。

17
David Dale