Przejdź do głównej zawartości

feature_importance

czym jest feature importance? ⭐

  • Feature importance to miara znaczenia poszczególnych cech w modelu uczenia maszynowego.
  • Pokazuje, które cechy mają największy wpływ na przewidywania modelu.
  • Pomaga w zrozumieniu modelu i selekcji najważniejszych cech.
  • Może być używane do feature selection i interpretacji modelu.
  • Różne algorytmy obliczają feature importance w różny sposób.

metody obliczania feature importance ⭐

1. Tree-based methods

  • Random Forest: Średnia redukcja nieczystości (impurity) dla każdej cechy.
  • Decision Trees: Redukcja Gini index lub entropy.
  • Gradient Boosting: Podobnie jak Random Forest.

2. Permutation importance

  • Mierzy spadek wydajności po losowym przetasowaniu wartości cechy.
  • Działa z każdym modelem (nie tylko tree-based).
  • Bardziej niezawodne niż wbudowane feature importance.

3. SHAP values

  • Shapley Additive Explanations - zaawansowana metoda interpretacji.
  • Pokazuje wkład każdej cechy do konkretnej predykcji.
  • Bardzo dokładne, ale wolniejsze w obliczeniach.

przykładowy kod (feature importance)

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.inspection import permutation_importance
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
import seaborn as sns

# Generowanie danych
np.random.seed(42)
n_samples = 1000

# Generowanie cech z różną ważnością
feature1 = np.random.normal(0, 1, n_samples) # Bardzo ważna
feature2 = np.random.normal(0, 1, n_samples) # Ważna
feature3 = np.random.normal(0, 1, n_samples) # Średnio ważna
feature4 = np.random.normal(0, 1, n_samples) # Mało ważna
feature5 = np.random.normal(0, 1, n_samples) # Nieistotna

# Target zależny od cech z różną siłą
y = (2 * feature1 + 1.5 * feature2 + 0.5 * feature3 +
0.1 * feature4 + 0 * feature5 + np.random.normal(0, 0.5, n_samples)) > 0

# Tworzenie DataFrame
data = pd.DataFrame({
'feature1': feature1,
'feature2': feature2,
'feature3': feature3,
'feature4': feature4,
'feature5': feature5,
'target': y
})

print("Rozkład klas:")
print(data['target'].value_counts(normalize=True))

# Podział danych
X = data.drop('target', axis=1)
y = data['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)

# Skalowanie dla modeli liniowych
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

1. feature importance w Random Forest

# Trenowanie Random Forest
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)
rf_model.fit(X_train, y_train)

# Wbudowane feature importance
rf_importance = rf_model.feature_importances_
feature_names = X.columns

# Tworzenie DataFrame z importance
importance_df = pd.DataFrame({
'feature': feature_names,
'importance': rf_importance
}).sort_values('importance', ascending=False)

print("Feature Importance - Random Forest:")
print(importance_df)

# Wizualizacja
plt.figure(figsize=(12, 4))

plt.subplot(1, 3, 1)
plt.bar(range(len(rf_importance)), rf_importance)
plt.title('Feature Importance - Random Forest')
plt.xlabel('Feature Index')
plt.ylabel('Importance')
plt.xticks(range(len(feature_names)), feature_names, rotation=45)

# Wykres słupkowy z nazwami cech
plt.subplot(1, 3, 2)
colors = plt.cm.viridis(np.linspace(0, 1, len(importance_df)))
plt.barh(importance_df['feature'], importance_df['importance'], color=colors)
plt.title('Feature Importance - Random Forest')
plt.xlabel('Importance')
plt.gca().invert_yaxis()

2. permutation importance

# Permutation importance dla Random Forest
perm_importance = permutation_importance(
rf_model, X_test, y_test,
n_repeats=10,
random_state=42,
n_jobs=-1
)

perm_importance_df = pd.DataFrame({
'feature': feature_names,
'importance': perm_importance.importances_mean,
'std': perm_importance.importances_std
}).sort_values('importance', ascending=False)

print("\nPermutation Importance - Random Forest:")
print(perm_importance_df)

# Wizualizacja permutation importance
plt.subplot(1, 3, 3)
colors = plt.cm.plasma(np.linspace(0, 1, len(perm_importance_df)))
plt.barh(perm_importance_df['feature'], perm_importance_df['importance'],
color=colors, xerr=perm_importance_df['std'])
plt.title('Permutation Importance - Random Forest')
plt.xlabel('Importance')
plt.gca().invert_yaxis()

plt.tight_layout()
plt.show()

3. porównanie różnych modeli

# Różne modele
models = {
'Random Forest': RandomForestClassifier(n_estimators=100, random_state=42),
'Gradient Boosting': GradientBoostingClassifier(n_estimators=100, random_state=42),
'Logistic Regression': LogisticRegression(random_state=42)
}

# Słownik na wyniki
importance_results = {}

for name, model in models.items():
print(f"\nTrenowanie {name}...")

# Trenowanie
if name == 'Logistic Regression':
model.fit(X_train_scaled, y_train)
# Dla regresji logistycznej używamy wartości bezwzględnych współczynników
importance = np.abs(model.coef_[0])
else:
model.fit(X_train, y_train)
importance = model.feature_importances_

importance_results[name] = {
'model': model,
'importance': importance,
'feature_names': feature_names
}

print(f"Feature importance dla {name}:")
for i, (feature, imp) in enumerate(zip(feature_names, importance)):
print(f" {feature}: {imp:.4f}")

# Wizualizacja porównania
plt.figure(figsize=(15, 5))

for i, (name, result) in enumerate(importance_results.items()):
plt.subplot(1, 3, i+1)

# Sortowanie według importance
sorted_indices = np.argsort(result['importance'])[::-1]
sorted_features = [result['feature_names'][j] for j in sorted_indices]
sorted_importance = [result['importance'][j] for j in sorted_indices]

colors = plt.cm.Set3(np.linspace(0, 1, len(sorted_features)))
plt.barh(sorted_features, sorted_importance, color=colors)
plt.title(f'Feature Importance - {name}')
plt.xlabel('Importance')
plt.gca().invert_yaxis()

plt.tight_layout()
plt.show()

4. feature selection na podstawie importance

# Feature selection na podstawie importance
def select_features_by_importance(importance_scores, feature_names, threshold=0.01):
"""Wybór cech na podstawie importance"""
selected_features = []
selected_importance = []

for feature, importance in zip(feature_names, importance_scores):
if importance > threshold:
selected_features.append(feature)
selected_importance.append(importance)

return selected_features, selected_importance

# Przykład dla Random Forest
rf_importance = importance_results['Random Forest']['importance']
selected_features, selected_importance = select_features_by_importance(
rf_importance, feature_names, threshold=0.05
)

print(f"\nWybrane cechy (threshold > 0.05): {selected_features}")

# Porównanie wydajności z wszystkimi cechami vs wybrane cechy
from sklearn.metrics import accuracy_score

# Model z wszystkimi cechami
rf_full = RandomForestClassifier(n_estimators=100, random_state=42)
rf_full.fit(X_train, y_train)
y_pred_full = rf_full.predict(X_test)
accuracy_full = accuracy_score(y_test, y_pred_full)

# Model z wybranymi cechami
X_train_selected = X_train[selected_features]
X_test_selected = X_test[selected_features]

rf_selected = RandomForestClassifier(n_estimators=100, random_state=42)
rf_selected.fit(X_train_selected, y_train)
y_pred_selected = rf_selected.predict(X_test_selected)
accuracy_selected = accuracy_score(y_test, y_pred_selected)

print(f"Accuracy z wszystkimi cechami: {accuracy_full:.3f}")
print(f"Accuracy z wybranymi cechami: {accuracy_selected:.3f}")
print(f"Liczba cech: {X_train.shape[1]} -> {len(selected_features)}")

5. analiza korelacji z targetem

# Analiza korelacji między cechami a targetem
correlations = []
for feature in feature_names:
correlation = np.corrcoef(X_train[feature], y_train)[0, 1]
correlations.append(abs(correlation))

correlation_df = pd.DataFrame({
'feature': feature_names,
'correlation': correlations
}).sort_values('correlation', ascending=False)

print("\nKorelacja z targetem (wartości bezwzględne):")
print(correlation_df)

# Wizualizacja korelacji
plt.figure(figsize=(12, 4))

plt.subplot(1, 3, 1)
plt.bar(range(len(correlations)), correlations)
plt.title('Korelacja z targetem')
plt.xlabel('Feature Index')
plt.ylabel('|Correlation|')
plt.xticks(range(len(feature_names)), feature_names, rotation=45)

# Porównanie importance z korelacją
plt.subplot(1, 3, 2)
plt.scatter(correlations, rf_importance, alpha=0.7)
for i, feature in enumerate(feature_names):
plt.annotate(feature, (correlations[i], rf_importance[i]),
xytext=(5, 5), textcoords='offset points', fontsize=8)
plt.xlabel('|Correlation with target|')
plt.ylabel('Feature Importance (RF)')
plt.title('Importance vs Correlation')

# Heatmapa korelacji między cechami
plt.subplot(1, 3, 3)
correlation_matrix = X_train.corr()
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('Correlation Matrix')

plt.tight_layout()
plt.show()

6. SHAP values (podstawowe)

# Instalacja SHAP (jeśli nie jest zainstalowane)
# !pip install shap

try:
import shap

# Tworzenie explainer dla Random Forest
explainer = shap.TreeExplainer(rf_model)

# Obliczanie SHAP values dla zbioru testowego
shap_values = explainer.shap_values(X_test)

# Średnie SHAP values
mean_shap_values = np.abs(shap_values).mean(0)

shap_df = pd.DataFrame({
'feature': feature_names,
'shap_importance': mean_shap_values
}).sort_values('shap_importance', ascending=False)

print("\nSHAP Feature Importance:")
print(shap_df)

# Wizualizacja SHAP
plt.figure(figsize=(10, 6))
plt.barh(shap_df['feature'], shap_df['shap_importance'])
plt.title('SHAP Feature Importance')
plt.xlabel('Mean |SHAP value|')
plt.gca().invert_yaxis()
plt.show()

except ImportError:
print("SHAP nie jest zainstalowane. Zainstaluj: pip install shap")

praktyczne ćwiczenia

  1. Porównaj metody - przetestuj różne metody obliczania feature importance.

  2. Feature selection - użyj feature importance do selekcji cech.

  3. Threshold tuning - znajdź optymalny próg dla feature selection.

  4. Cross-validation - użyj CV do oceny stabilności feature importance.

  5. Real data - zastosuj na rzeczywistych zbiorach danych.

dobre praktyki

  • Walidacja: Używaj cross-validation do oceny stabilności.
  • Interpretacja: Uważaj na korelacje między cechami.
  • Threshold: Dostosuj próg do problemu biznesowego.
  • Multiple methods: Używaj różnych metod do weryfikacji.

polecane źródła