shapley-calculator 0.1.4
A library to calculate Shapley values for feature importance in machine learning models.
Requires Python: >=3.6

# Shapley Calculator

A library to calculate Shapley values for feature importance in machine learning models.

## Installation

```bash
pip install shapley_calculator

## Example of usage

Here is an example of how to use `shapley_calculator` to calculate Shapley values:

```python
import numpy as np
import pandas as pd
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestRegressor
from shapley_calculator.shapley import ShapleyValueCalculator
from tqdm import tqdm  # for progress display
import matplotlib.pyplot as plt  # for visualization

# Load California Housing dataset
print("Loading California Housing dataset...")
housing = fetch_california_housing()
X = housing.data
y = housing.target
feature_names = housing.feature_names

# Create DataFrame for data display
print("\nFirst 5 rows of the original dataset:")
df = pd.DataFrame(X, columns=feature_names)
df['Price'] = y
print(df.head().to_string())
print("\nFeature descriptions:")
for name, description in zip(feature_names, housing.feature_names):
    print(f"{name:10}: {description}")
print(f"Target     : House price in $100,000s")

# Take a subsample of data to speed up the example
n_samples = 1000  # reduce dataset size
np.random.seed(42)  # fix seed
indices = np.random.choice(len(X), n_samples, replace=False)
X = X[indices]
y = y[indices]

print("\nPreprocessing data...")
# Scale features
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# Split data into training and test sets
X_train, X_test, y_train, y_test = train_test_split(
    X_scaled, y, test_size=0.2, random_state=42
)

print("Training Random Forest model...")
# Train random forest model
model = RandomForestRegressor(n_estimators=50, random_state=42)  # reduce number of trees
model.fit(X_train, y_train)

print("Calculating Shapley values...")
# Take only part of the test set for Shapley value calculation
n_test_samples = 100  # number of examples for analysis
X_test_sample = X_test[:n_test_samples]
y_test_sample = y_test[:n_test_samples]

# Create Shapley calculator
calculator = ShapleyValueCalculator(model, X_test_sample, y_test_sample, 
                                  num_samples=100, random_state=42)

# Calculate Shapley values
shapley_values = calculator.get_shapley_values(normalize=True)

# Create DataFrame with results
results = pd.DataFrame({
    'Feature': feature_names,
    'Shapley Value': shapley_values
})

# Sort features by importance
results_sorted = results.sort_values('Shapley Value', ascending=False)

print("\nCalifornia Housing Dataset Analysis")
print("\nShapley Values (normalized, sorted by importance):")
print(results_sorted)

# Create and display visualization for overall Shapley values
print("\nGenerating Shapley values visualization...")
calculator.plot_shapley_values(
    feature_names=feature_names,
    title='Overall Feature Importance (Average Shapley Values)'
)
plt.show()

print("\nAnalyzing specific example...")
# Analyze specific example
sample_idx = 0
sample_shapley = calculator.get_shapley_values(sample_idx=sample_idx, normalize=True)

print("\nExample Analysis")
print("Sample features and their contributions:")
for name, value, shapley in zip(feature_names, X_test_sample[sample_idx], sample_shapley):
    actual_value = scaler.inverse_transform([X_test_sample[sample_idx]])[0][feature_names.index(name)]
    print(f"{name:10}: {actual_value:8.2f} (Shapley: {shapley:8.4f})")

# Create and display visualization for specific example
print("\nGenerating Shapley values visualization for the specific example...")
calculator.plot_shapley_values(
    feature_names=feature_names,
    sample_idx=sample_idx,
    title=f'Feature Importance for Example #{sample_idx}'
)
plt.show()

# Model quality assessment
train_score = model.score(X_train, y_train)
test_score = model.score(X_test, y_test)

print(f"\nModel Performance:")
print(f"R2 score (train): {train_score:.3f}")
print(f"R2 score (test): {test_score:.3f}")