Importância por Permutação em Dados de Câncer de Mama

Beginner

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

Introdução

Este laboratório demonstra como usar a importância de permutação no conjunto de dados de câncer de mama de Wisconsin usando a função permutation_importance de sklearn.inspection. O Classificador Floresta Aleatória é usado para classificar os dados e calcular sua precisão em um conjunto de teste. Também mostraremos como lidar com a multicolinearidade nas características usando agrupamento hierárquico.

Dicas da Máquina Virtual

Após o início da VM, clique no canto superior esquerdo para mudar para a aba Notebook para acessar o Jupyter Notebook para praticar.

Às vezes, pode ser necessário aguardar alguns segundos para que o Jupyter Notebook termine de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

Se você enfrentar problemas durante o aprendizado, sinta-se à vontade para perguntar ao Labby. Forneça feedback após a sessão e resolveremos o problema rapidamente para você.

Treinar um Classificador Floresta Aleatória

Primeiro, carregamos o conjunto de dados de câncer de mama de Wisconsin e o dividimos em conjuntos de treinamento e teste. Em seguida, treinamos um Classificador Floresta Aleatória no conjunto de treinamento e avaliamos sua precisão no conjunto de teste.

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("Precisão nos dados de teste: {:.2f}".format(clf.score(X_test, y_test)))

Plotar a Importância das Características

Plotamos a importância das características baseadas em árvores e a importância por permutação. O gráfico de importância por permutação mostra que a permutação de uma característica reduz a precisão no máximo em 0,012, o que sugeria que nenhuma das características é importante. Isso contradiz a alta precisão de teste calculada acima: alguma característica deve ser importante. A importância por permutação é calculada no conjunto de treinamento para mostrar em que medida o modelo depende de cada característica durante o treinamento.

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()

Lidar com Características Multicolinear

Quando as características são colineares, a permutação de uma característica terá pouco efeito no desempenho do modelo, pois pode obter a mesma informação de uma característica correlacionada. Uma forma de lidar com características multicolinear é realizar agrupamento hierárquico nas correlações de posto de Spearman, escolher um limiar e manter uma única característica de cada cluster. Primeiro, plotamos um mapa de calor das características correlacionadas.

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

## Garantir que a matriz de correlação seja simétrica
corr = (corr + corr.T) / 2
np.fill_diagonal(corr, 1)

## Convertemos a matriz de correlação em uma matriz de distância antes de realizar
## o agrupamento hierárquico usando o linkage de Ward.
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()

Escolher um Limiar para Agrupar Características em Clusters

Visualmente, escolhemos manualmente um limiar no dendrograma para agrupar as nossas características em clusters e selecionar uma característica de cada cluster para manter, selecionando essas características do nosso conjunto de dados e treinando uma nova floresta aleatória. A precisão de teste da nova floresta aleatória não mudou muito em comparação com a floresta aleatória treinada no conjunto de dados completo.

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(
    "Precisão nos dados de teste com características removidas: {:.2f}".format(
        clf_sel.score(X_test_sel, y_test)
    )
)

Resumo

Este laboratório demonstrou como usar a importância por permutação para calcular a importância das características no conjunto de dados de câncer de mama de Wisconsin usando um Classificador de Floresta Aleatória. Mostramos como lidar com características multicolinear usando agrupamento hierárquico.