🙆

LogisticRegressionの重みを可視化してみる

に公開

今回はLogisticRegressionの回帰係数を可視化して各特徴量の分類に対する寄与度を可視化してみました。

検証内容

今回はscikit-learn上で利用できるirisデータを使います。irisは多クラス(3クラス)データであり特徴量は4つあります。LogisticRegressionを学習させ、その回帰係数を可視化してみます。

早速実装する

環境構築

まずは必要なライブラリをインストールします。

uv init iris_logistic_regression -p 3.12
cd iris_logistic_regression
uv add scikit-learn pandas matplotlib numpy

コードの実装

今回実装したコードは以下になります。

iris_logistic_regression.py
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score


iris = load_iris()
X, y = iris.data, iris.target

X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7)

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

lr = LogisticRegression()
lr.fit(scaled_X_train, y_train)

prob = lr.predict(scaled_X_test)
accuracy = accuracy_score(prob, y_test)
print(accuracy)

coef = lr.coef_
features = iris.feature_names
class_names = [f"class {i}" for i in range(3)]


data = {class_name: coef[i, :] for i, class_name in enumerate(class_names)}
df = pd.DataFrame(
    data,
    columns=class_names,
    index=features,
)
df.plot.barh()
plt.grid()
plt.show()

まずはirisデータを読み込みます。今回は学習データを全体の70%利用し、各特徴量はStandardScalerによって標準化します。

iris = load_iris()
X, y = iris.data, iris.target

X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7)

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

モデルはsklearn.linear_model.LogisticRegressionを利用します。精度指標はaccuracyを採用します。

lr = LogisticRegression()
lr.fit(scaled_X_train, y_train)
accuracy = accuracy_score(prob, y_test)
print(accuracy)

次に回帰係数を取り出してグラフにする部分の実装になります。今回は3つのクラスがあるためlr.coef_は(3, 4)の形状をしています(3はクラス数、4は特徴量の数)。なので、各クラスごとに係数をDataFrameに格納して、そこからバープロットを作成します。なお、プロットの作成は以下のページを参考にしました。

https://www.scaler.com/topics/matplotlib/plotting-multiple-bar-chart/

coef = lr.coef_
features = iris.feature_names
class_names = [f"class {i}" for i in range(3)]


data = {class_name: coef[i, :] for i, class_name in enumerate(class_names)}
df = pd.DataFrame(
    data,
    columns=class_names,
    index=features,
)
df.plot.barh()
plt.grid()
plt.show()

コードの実行

早速コードを実行してみます。まず精度ですが95%程度になっています(シンプルなタスクなのでスコアもカスタマイズなしで高いですね)。

uv run iris_logistic_regression.py

# 結果
0.9555555555555556

実行すると以下のようなグラフが生成されます(シードは固定していないので毎回少しずつ変わります)。結果の見方としては、4つの特徴量がクラスごとの推論にどれくらい影響しているかを回帰係数を利用することで判断しています。例えばpetal width(cm)については、クラス0とクラス1では大きくなるほどそのクラスと判定されにくく、逆にクラス2では判定に大きく正の相関が見受けられます。他のクラスについても同様な見方ができますし、係数の絶対値が大きければ大きいほど影響力が大きいです。その観点から言うと、sepalよりpetalの方が結果に対する影響力は多い傾向がありそう、と言うのが見受けられます。

まとめ

今回はLogisticRegressionの回帰係数を可視化することで、分類に対してどのような影響力があるか可視化してみました。このように係数を可視化すると言うのは初学者の時はやってましたが、時間が立ってから改めて作ると、グラフ作る方法とか結構忘れているところがあったりで、改めて勉強することの大事さを感じました。皆さんもぜひモデルを開発した時はそのモデルの判断基準などを可視化してみて下さい。

Discussion