MNIST 多項ロジスティック回帰

Beginner

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

はじめに

この実験では、MNIST データセットからの手書き数字を分類するためにロジスティック回帰アルゴリズムをどのように使用するかを学びます。MNIST 数字分類タスクのサブセットに対して L1 ペナルティを付けた多項ロジスティック回帰を適合させるために、SAGA アルゴリズムを使用します。

VM のヒント

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

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

学習中に問題に遭遇した場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。そうすれば、迅速に問題を解決します。

ライブラリのインポート

この実験に必要なライブラリをインポートして始めましょう。scikit-learn ライブラリを使ってデータセットを取得し、モデルを学習させ、モデルの性能を評価します。

import time
import matplotlib.pyplot as plt
import numpy as np

from sklearn.datasets import fetch_openml
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.utils import check_random_state

MNIST データセットの読み込み

scikit-learn のfetch_openml関数を使って MNIST データセットを読み込みます。また、train_samplesの数を 5000 に設定することで、データのサブセットを選択します。

## Turn down for faster convergence
t0 = time.time()
train_samples = 5000

## Load data from https://www.openml.org/d/554
X, y = fetch_openml(
    "mnist_784", version=1, return_X_y=True, as_frame=False, parser="pandas"
)

前処理

データをシャッフルし、データセットを訓練用とテスト用に分割し、StandardScalerを使ってデータをスケーリングすることで、データの前処理を行います。

random_state = check_random_state(0)
permutation = random_state.permutation(X.shape[0])
X = X[permutation]
y = y[permutation]
X = X.reshape((X.shape[0], -1))

X_train, X_test, y_train, y_test = train_test_split(
    X, y, train_size=train_samples, test_size=10000
)

scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

モデルの学習

L1 ペナルティ付きのロジスティック回帰と SAGA アルゴリズムを使ってモデルを学習します。Cの値を訓練サンプル数で割った 50.0 に設定します。

## Turn up tolerance for faster convergence
clf = LogisticRegression(C=50.0 / train_samples, penalty="l1", solver="saga", tol=0.1)
clf.fit(X_train, y_train)

モデルの評価

モデルの性能を、疎密度と正解率を計算することで評価します。

sparsity = np.mean(clf.coef_ == 0) * 100
score = clf.score(X_test, y_test)

print("Sparsity with L1 penalty: %.2f%%" % sparsity)
print("Test score with L1 penalty: %.4f" % score)

モデルの可視化

各クラスの分類ベクトルをプロットすることで、モデルを可視化します。

coef = clf.coef_.copy()
plt.figure(figsize=(10, 5))
scale = np.abs(coef).max()
for i in range(10):
    l1_plot = plt.subplot(2, 5, i + 1)
    l1_plot.imshow(
        coef[i].reshape(28, 28),
        interpolation="nearest",
        cmap=plt.cm.RdBu,
        vmin=-scale,
        vmax=scale,
    )
    l1_plot.set_xticks(())
    l1_plot.set_yticks(())
    l1_plot.set_xlabel("Class %i" % i)
plt.suptitle("Classification vector for...")

run_time = time.time() - t0
print("Example run in %.3f s" % run_time)
plt.show()

まとめ

この実験では、MNIST データセットからの手書き数字を分類するためにロジスティック回帰をどのように使用するかを学びました。また、ロジスティック回帰に対する L1 ペナルティ付きの SAGA アルゴリズムをどのように使用するかも学びました。疎な重みベクトルを持つことで 0.8 を超える正解率を達成し、モデルをより解釈可能にしました。ただし、このデータセットでは、L2 ペナルティ付きの線形モデルや非線形の多層パーセプトロンモデルが達成できる精度よりも、この精度はかなり低いことにも留意しました。