scikit-learn

Python用の機械学習ライブラリ。分類、回帰、クラスタリング、次元削減等の幅広いアルゴリズムを提供。シンプルで一貫したAPI、優れたドキュメント、教育用途にも最適。従来の機械学習手法の標準実装。

Python機械学習データサイエンス分類回帰クラスタリング

GitHub概要

scikit-learn/scikit-learn

scikit-learn: machine learning in Python

スター59,842
ウォッチ2,876
フォーク25,123
作成日:2010年8月17日
言語:Python
ライセンス:BSD 3-Clause License

トピックス

scikit-learnmachine-learningpythondata-scienceclassificationregressionclusteringstatistics

スター履歴

scikit-learn/scikit-learn Star History
データ取得日時: Invalid Date

フレームワーク

scikit-learn

概要

scikit-learnは、Pythonの代表的な機械学習ライブラリです。

詳細

scikit-learn(サイキットラーン)は2007年に開発が始まったPythonのオープンソース機械学習ライブラリで、データマイニングとデータ分析のためのシンプルで効率的なツールを提供します。分類、回帰、クラスタリング、次元削減などの古典的機械学習アルゴリズムを豊富に実装し、一貫性のある使いやすいAPIを特徴としています。NumPy、SciPy、matplotlib との統合により、Pythonデータサイエンスエコシステムの中核を担っています。教育から実務まで幅広く使用され、機械学習の入門者から専門家まで多くの開発者に愛用されています。前処理、特徴選択、モデル選択、評価などの機械学習パイプライン全体をサポートし、プロトタイピングから小〜中規模のプロダクションシステムまで対応可能です。豊富なドキュメントとサンプルコード、活発なコミュニティサポートにより、機械学習学習の標準的な選択肢となっています。

メリット・デメリット

メリット

  • 一貫したAPI: すべてのアルゴリズムで統一されたインターフェース
  • 豊富なアルゴリズム: 分類・回帰・クラスタリング・次元削減の包括的実装
  • 優秀なドキュメント: 詳細な説明とサンプルコードが充実
  • 安定性: 長期間の開発により高い信頼性とバグの少なさ
  • 学習しやすさ: 機械学習の入門に最適な設計
  • パイプライン機能: 前処理からモデル評価まで一貫した処理
  • 活発なコミュニティ: 大規模なユーザーベースと継続的な開発

デメリット

  • ディープラーニング非対応: ニューラルネットワークの実装が限定的
  • スケーラビリティ: 大規模データセットでのパフォーマンス制限
  • GPU非対応: GPU アクセラレーションが標準サポートされていない
  • オンライン学習: リアルタイム学習機能が限定的
  • フレキシビリティ: カスタムアルゴリズムの実装が困難
  • メモリ使用量: 大容量データでメモリ効率が課題となる場合がある

主要リンク

書き方の例

Hello World

import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report

# scikit-learnのバージョン確認
import sklearn
print(f"scikit-learn version: {sklearn.__version__}")

# サンプルデータの作成
from sklearn.datasets import make_classification
X, y = make_classification(
    n_samples=1000, 
    n_features=20, 
    n_informative=15, 
    n_redundant=5, 
    random_state=42
)

# データの分割
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# モデルの作成と学習
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)

# 予測と評価
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)

print(f"精度: {accuracy:.4f}")
print("\n詳細レポート:")
print(classification_report(y_test, y_pred))

データ前処理

import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler, LabelEncoder, OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline

# サンプルデータの作成
data = {
    'age': [25, 30, 35, np.nan, 45],
    'income': [50000, 60000, np.nan, 80000, 90000],
    'education': ['高校', '大学', '大学院', '高校', '大学'],
    'city': ['東京', '大阪', '東京', '名古屋', '大阪']
}
df = pd.DataFrame(data)
print("元データ:")
print(df)

# 数値列と カテゴリ列の分離
numeric_features = ['age', 'income']
categorical_features = ['education', 'city']

# 数値データの前処理パイプライン
numeric_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='median')),
    ('scaler', StandardScaler())
])

# カテゴリデータの前処理パイプライン
categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant', fill_value='unknown')),
    ('onehot', OneHotEncoder(handle_unknown='ignore'))
])

# 前処理パイプラインの結合
preprocessor = ColumnTransformer(
    transformers=[
        ('num', numeric_transformer, numeric_features),
        ('cat', categorical_transformer, categorical_features)
    ]
)

# 前処理の実行
X_processed = preprocessor.fit_transform(df)
print(f"\n前処理後のデータ形状: {X_processed.shape}")
print(f"特徴量名: {preprocessor.get_feature_names_out()}")

分類タスク

from sklearn.datasets import load_iris, load_breast_cancer
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
import matplotlib.pyplot as plt

# データセットの読み込み
data = load_breast_cancer()
X, y = data.data, data.target

# データの分割
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# 複数のモデルで比較
models = {
    'Logistic Regression': LogisticRegression(random_state=42),
    'SVM': SVC(random_state=42, probability=True),
    'Random Forest': RandomForestClassifier(n_estimators=100, random_state=42),
    'Gradient Boosting': GradientBoostingClassifier(random_state=42)
}

results = {}

for name, model in models.items():
    # 学習
    model.fit(X_train, y_train)
    
    # 予測
    y_pred = model.predict(X_test)
    
    # 評価指標の計算
    accuracy = accuracy_score(y_test, y_pred)
    precision = precision_score(y_test, y_pred)
    recall = recall_score(y_test, y_pred)
    f1 = f1_score(y_test, y_pred)
    
    # クロスバリデーション
    cv_scores = cross_val_score(model, X_train, y_train, cv=5)
    
    results[name] = {
        'Accuracy': accuracy,
        'Precision': precision,
        'Recall': recall,
        'F1-Score': f1,
        'CV Mean': cv_scores.mean(),
        'CV Std': cv_scores.std()
    }

# 結果の表示
results_df = pd.DataFrame(results).T
print("モデル比較結果:")
print(results_df.round(4))

回帰タスク

from sklearn.datasets import make_regression, load_boston
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt

# 回帰用サンプルデータの作成
X, y = make_regression(
    n_samples=500, 
    n_features=10, 
    n_informative=5, 
    noise=0.1, 
    random_state=42
)

# データの分割
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# 特徴量の標準化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# 回帰モデルの定義
models = {
    'Linear Regression': LinearRegression(),
    'Ridge': Ridge(alpha=1.0),
    'Lasso': Lasso(alpha=1.0),
    'Random Forest': RandomForestRegressor(n_estimators=100, random_state=42)
}

results = {}

for name, model in models.items():
    # 線形モデルには標準化されたデータを使用
    if name in ['Linear Regression', 'Ridge', 'Lasso']:
        model.fit(X_train_scaled, y_train)
        y_pred = model.predict(X_test_scaled)
    else:
        model.fit(X_train, y_train)
        y_pred = model.predict(X_test)
    
    # 評価指標の計算
    mse = mean_squared_error(y_test, y_pred)
    rmse = np.sqrt(mse)
    mae = mean_absolute_error(y_test, y_pred)
    r2 = r2_score(y_test, y_pred)
    
    results[name] = {
        'MSE': mse,
        'RMSE': rmse,
        'MAE': mae,
        'R2 Score': r2
    }

# 結果の表示
results_df = pd.DataFrame(results).T
print("回帰モデル比較結果:")
print(results_df.round(4))

クラスタリング

from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans, DBSCAN, AgglomerativeClustering
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score, adjusted_rand_score
import matplotlib.pyplot as plt

# クラスタリング用データの生成
X, y_true = make_blobs(
    n_samples=300, 
    centers=4, 
    cluster_std=0.60, 
    random_state=0
)

# データの標準化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# クラスタリングアルゴリズムの適用
clustering_algorithms = {
    'K-Means': KMeans(n_clusters=4, random_state=42),
    'DBSCAN': DBSCAN(eps=0.3, min_samples=5),
    'Agglomerative': AgglomerativeClustering(n_clusters=4)
}

results = {}

plt.figure(figsize=(15, 5))

for i, (name, algorithm) in enumerate(clustering_algorithms.items()):
    # クラスタリングの実行
    cluster_labels = algorithm.fit_predict(X_scaled)
    
    # シルエットスコアの計算
    if len(set(cluster_labels)) > 1:  # クラスター数が1より大きい場合のみ
        silhouette_avg = silhouette_score(X_scaled, cluster_labels)
        ari = adjusted_rand_score(y_true, cluster_labels)
    else:
        silhouette_avg = -1
        ari = -1
    
    results[name] = {
        'Silhouette Score': silhouette_avg,
        'Adjusted Rand Index': ari,
        'Number of Clusters': len(set(cluster_labels))
    }
    
    # 可視化
    plt.subplot(1, 3, i + 1)
    plt.scatter(X[:, 0], X[:, 1], c=cluster_labels, cmap='viridis', alpha=0.6)
    plt.title(f'{name}\nSilhouette: {silhouette_avg:.3f}')
    plt.xlabel('特徴量 1')
    plt.ylabel('特徴量 2')

plt.tight_layout()
plt.show()

# 結果の表示
results_df = pd.DataFrame(results).T
print("クラスタリング結果:")
print(results_df.round(4))

パイプラインとグリッドサーチ

from sklearn.datasets import load_digits
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report

# データセットの読み込み
digits = load_digits()
X, y = digits.data, digits.target

# データの分割
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# SVMパイプライン
svm_pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('classifier', SVC())
])

# ランダムフォレストパイプライン
rf_pipeline = Pipeline([
    ('classifier', RandomForestClassifier())
])

# グリッドサーチのパラメータ
svm_params = {
    'classifier__C': [0.1, 1, 10],
    'classifier__gamma': ['scale', 'auto'],
    'classifier__kernel': ['rbf', 'linear']
}

rf_params = {
    'classifier__n_estimators': [50, 100, 200],
    'classifier__max_depth': [10, 20, None],
    'classifier__min_samples_split': [2, 5, 10]
}

# グリッドサーチの実行
print("SVM グリッドサーチ中...")
svm_grid = GridSearchCV(
    svm_pipeline, 
    svm_params, 
    cv=5, 
    scoring='accuracy',
    n_jobs=-1
)
svm_grid.fit(X_train, y_train)

print("ランダムフォレスト グリッドサーチ中...")
rf_grid = GridSearchCV(
    rf_pipeline, 
    rf_params, 
    cv=5, 
    scoring='accuracy',
    n_jobs=-1
)
rf_grid.fit(X_train, y_train)

# 結果の比較
models = {
    'SVM': svm_grid,
    'Random Forest': rf_grid
}

for name, model in models.items():
    y_pred = model.predict(X_test)
    print(f"\n{name} 結果:")
    print(f"最適パラメータ: {model.best_params_}")
    print(f"クロスバリデーションスコア: {model.best_score_:.4f}")
    print(f"テストスコア: {model.score(X_test, y_test):.4f}")

モデルの保存と読み込み

import joblib
import pickle
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

# データの準備
X, y = make_classification(n_samples=1000, n_features=20, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# パイプラインの作成と学習
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('classifier', RandomForestClassifier(n_estimators=100, random_state=42))
])

pipeline.fit(X_train, y_train)
original_score = pipeline.score(X_test, y_test)
print(f"元のモデル精度: {original_score:.4f}")

# 1. joblibを使用した保存・読み込み(推奨)
joblib.dump(pipeline, 'model_pipeline.joblib')
loaded_pipeline_joblib = joblib.load('model_pipeline.joblib')
joblib_score = loaded_pipeline_joblib.score(X_test, y_test)
print(f"joblib読み込み後精度: {joblib_score:.4f}")

# 2. pickleを使用した保存・読み込み
with open('model_pipeline.pkl', 'wb') as f:
    pickle.dump(pipeline, f)

with open('model_pipeline.pkl', 'rb') as f:
    loaded_pipeline_pickle = pickle.load(f)

pickle_score = loaded_pipeline_pickle.score(X_test, y_test)
print(f"pickle読み込み後精度: {pickle_score:.4f}")

# 3. モデルのメタデータ保存
model_info = {
    'model_type': 'RandomForestClassifier',
    'parameters': pipeline.named_steps['classifier'].get_params(),
    'feature_names': [f'feature_{i}' for i in range(X.shape[1])],
    'classes': pipeline.classes_,
    'accuracy': original_score
}

# メタデータの保存
joblib.dump(model_info, 'model_metadata.joblib')
loaded_metadata = joblib.load('model_metadata.joblib')

print("\nモデルメタデータ:")
for key, value in loaded_metadata.items():
    print(f"{key}: {value}")

# 新しいデータでの予測
import numpy as np
new_data = np.random.randn(5, 20)
predictions = loaded_pipeline_joblib.predict(new_data)
probabilities = loaded_pipeline_joblib.predict_proba(new_data)

print(f"\n新しいデータの予測: {predictions}")
print(f"予測確率: {probabilities}")