乳がんデータセットにおける順列重要度

Machine LearningMachine LearningBeginner
今すぐ練習

This tutorial is from open-source community. Access the source code

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、sklearn.inspectionpermutation_importance 関数を使って、ウィスコンシン乳がんデータセットで順列重要度をどのように使用するかを示します。ランダムフォレスト分類器を使ってデータを分類し、テストセットでの精度を計算します。また、階層的クラスタリングを使って特徴量の多重共線性をどのように処理するかも示します。

VMのヒント

VMの起動が完了したら、左上隅をクリックして ノートブック タブに切り替えて、Jupyter Notebookを使って練習しましょう。

時々、Jupyter Notebookが読み込み終わるまで数秒待つ必要がある場合があります。Jupyter Notebookの制限により、操作の検証を自動化することはできません。

学習中に問題に遭遇した場合は、Labbyにお尋ねください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills ml/sklearn -.-> lab-49244{{"乳がんデータセットにおける順列重要度"}} end

ランダムフォレスト分類器を学習する

まず、ウィスコンシン乳がんデータセットを読み込み、学習用とテスト用のセットに分割します。その後、学習用セットでランダムフォレスト分類器を学習し、テスト用セットでの精度を評価します。

data = load_breast_cancer()
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

clf = RandomForestClassifier(n_estimators=100, random_state=42)
clf.fit(X_train, y_train)
print("Accuracy on test data: {:.2f}".format(clf.score(X_test, y_test)))

特徴量の重要度をプロットする

ツリーベースの特徴量の重要度と順列重要度をプロットします。順列重要度のプロットでは、特徴量を入れ替えると精度が最大 0.012 低下することが示されており、これは特徴量がすべて重要でないことを示唆しています。これは、上で計算した高いテスト精度と矛盾しています。つまり、何らかの特徴量が重要であるはずです。順列重要度は、学習中にモデルが各特徴量にどれだけ依存しているかを示すために学習用セットで計算されます。

result = permutation_importance(clf, X_train, y_train, n_repeats=10, random_state=42)
perm_sorted_idx = result.importances_mean.argsort()

tree_importance_sorted_idx = np.argsort(clf.feature_importances_)
tree_indices = np.arange(0, len(clf.feature_importances_)) + 0.5

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 8))
ax1.barh(tree_indices, clf.feature_importances_[tree_importance_sorted_idx], height=0.7)
ax1.set_yticks(tree_indices)
ax1.set_yticklabels(data.feature_names[tree_importance_sorted_idx])
ax1.set_ylim((0, len(clf.feature_importances_)))
ax2.boxplot(
    result.importances[perm_sorted_idx].T,
    vert=False,
    labels=data.feature_names[perm_sorted_idx],
)
fig.tight_layout()
plt.show()

多重共線性を持つ特徴量を処理する

特徴量が共線的な場合、ある特徴量を入れ替えるとモデルの性能にほとんど影響がないことがあります。なぜなら、相関する特徴量から同じ情報を得ることができるからです。多重共線性を持つ特徴量を処理する方法の1つは、スピアマンの順位相関係数に基づいて階層的クラスタリングを行い、閾値を選び、各クラスタから1つの特徴量のみを残すことです。まず、相関する特徴量のヒートマップをプロットします。

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 8))
corr = spearmanr(X).correlation

## Ensure the correlation matrix is symmetric
corr = (corr + corr.T) / 2
np.fill_diagonal(corr, 1)

## We convert the correlation matrix to a distance matrix before performing
## hierarchical clustering using Ward's linkage.
distance_matrix = 1 - np.abs(corr)
dist_linkage = hierarchy.ward(squareform(distance_matrix))
dendro = hierarchy.dendrogram(
    dist_linkage, labels=data.feature_names.tolist(), ax=ax1, leaf_rotation=90
)
dendro_idx = np.arange(0, len(dendro["ivl"]))

ax2.imshow(corr[dendro["leaves"], :][:, dendro["leaves"]])
ax2.set_xticks(dendro_idx)
ax2.set_yticks(dendro_idx)
ax2.set_xticklabels(dendro["ivl"], rotation="vertical")
ax2.set_yticklabels(dendro["ivl"])
fig.tight_layout()
plt.show()

クラスタに特徴量をグループ化するための閾値を選ぶ

デンドログラムを目視で確認することで、手動で閾値を選び、特徴量をクラスタにグループ化し、各クラスタから1つの特徴量を選んで残します。そして、データセットからそれらの特徴量を選択し、新しいランダムフォレストを学習します。完全なデータセットで学習したランダムフォレストと比較すると、新しいランダムフォレストのテスト精度はあまり変化しませんでした。

cluster_ids = hierarchy.fcluster(dist_linkage, 1, criterion="distance")
cluster_id_to_feature_ids = defaultdict(list)
for idx, cluster_id in enumerate(cluster_ids):
    cluster_id_to_feature_ids[cluster_id].append(idx)
selected_features = [v[0] for v in cluster_id_to_feature_ids.values()]

X_train_sel = X_train[:, selected_features]
X_test_sel = X_test[:, selected_features]

clf_sel = RandomForestClassifier(n_estimators=100, random_state=42)
clf_sel.fit(X_train_sel, y_train)
print(
    "Accuracy on test data with features removed: {:.2f}".format(
        clf_sel.score(X_test_sel, y_test)
    )
)

まとめ

この実験では、ランダムフォレスト分類器を使って、ウィスコンシン乳がんデータセットにおける特徴量の重要度を計算するために順列重要度をどのように使用するかを示しました。また、階層的クラスタリングを使って多重共線性を持つ特徴量をどのように処理するかを示しました。