Python scikit-learnでクラス分類推定度を確認する

個人開発したアプリの宣伝
目的地が設定できる手帳のような使い心地のTODOアプリを公開しています。
Todo with Location

Todo with Location

  • Yoshiko Ichikawa
  • Productivity
  • Free

スポンサードリンク

scikit-learnの各分類モデルにはdecision_functionpredict_probaといった分類確信度のスコアを取得できるメソッドがあります。

各分類モデルで学習データをfit後、各メソッドに予測を行うデータセットを与えることで確信度を確認することができます。


2クラス分類での例

fitまで済ましておきます。

from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import make_circles
import numpy as np
from sklearn.model_selection import train_test_split

X, y = make_circles(noise=0.25, factor=0.5, random_state=1)
y_named = np.array(["blue", "red"])[y]
X_train, X_test, y_train_named, y_test_named, y_train, y_test = train_test_split(X, y_named, y, random_state=0)
gbrt = GradientBoostingClassifier(random_state=0)
gbrt.fit(X_train, y_train_named)


decision_function

decision_functionはレンジなしの信頼度を表す。

print("Decision function:\n{}".format(gbrt.decision_function(X_test)[:6]))


正であれば"red"、負であれば"blue"の度合いを表す。値が大きいほどそのクラスに対する確信度が高い。

Decision function:
[ 4.13592629 -1.7016989  -3.95106099 -3.62599351  4.28986668  3.66166106]


predict_proba

predict_probaはそのクラスに分類される確率を表す。

print("Predicted probabilities:\n{}".format(gbrt.predict_proba(X_test[:6])))

左が"blue",右が"red"である確率を表す。足すと1となる。

Predicted probabilities:
[[0.01573626 0.98426374]
 [0.84575649 0.15424351]
 [0.98112869 0.01887131]
 [0.97406775 0.02593225]
 [0.01352142 0.98647858]
 [0.02504637 0.97495363]]


多クラス分類での例

fitまで済ましておく。

from sklearn.datasets import load_iris

iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=42)

gbrt = GradientBoostingClassifier(learning_rate=0.01, random_state=0)
gbrt.fit(X_train, y_train)


decision_function
print("Decision function:\n{}".format(gbrt.decision_function(X_test)[:6,:]))

各列は個々のクラスに対応する「確信度スコア」を表す。値が大きいほどそのクラスである可能性が高い

Decision function:
[[-0.52931069  1.46560359 -0.50448467]
 [ 1.51154215 -0.49561142 -0.50310736]
 [-0.52379401 -0.4676268   1.51953786]
 [-0.52931069  1.46560359 -0.50448467]
 [-0.53107259  1.28190451  0.21510024]
 [ 1.51154215 -0.49561142 -0.50310736]]

実際にpredictすると結果との対応がわかる。

print("Predictions:\n{}".format(gbrt.predict(X_test)))


Predictions:
[1 0 2 1 1 0 1 2 1 1 2 0 0 0 0 1 2 1 1 2 0 2 0 2 2 2 2 2 0 0 0 0 1 0 0 2 1 0]


predict_proba
print("Predicted probabilities:\n{}".format(gbrt.predict_proba(X_test)[:6]))

こちらも各列の和が1となる。上記のpredictの結果と対応していることがわかる。

Predicted probabilities:
[[0.10664722 0.7840248  0.10932798]
 [0.78880668 0.10599243 0.10520089]
 [0.10231173 0.10822274 0.78946553]
 [0.10664722 0.7840248  0.10932798]
 [0.10825347 0.66344934 0.22829719]
 [0.78880668 0.10599243 0.10520089]]


分類クラスが文字列時の確認

irisデータセットの分類でtarget_names ['setosa' 'versicolor' 'virginica']のクラスを結果として返す場合、

from sklearn.linear_model import LogisticRegression

named_target = iris.target_names[y_train]
logreg = LogisticRegression()
logreg.fit(X_train, named_target)
print("unique classes in training data: {}".format(logreg.classes_))
print("predictions: {}".format(logreg.predict(X_test)[:10]))
argmax_dec_func = np.argmax(logreg.decision_function(X_test), axis=1)
print("argmax of decision function: {}".format(argmax_dec_func[:10]))
print("argmax combined with classes_: {}".format(logreg.classes_[argmax_dec_func][:10]))

上記のようにlogreg.classes_[np.argmax(logreg.decision_function(X_test), axis=1)]として最大度合のnumpyインデックスとclasses_の引き当てを行い確認することができる。

unique classes in training data: ['setosa' 'versicolor' 'virginica']
predictions: ['versicolor' 'setosa' 'virginica' 'versicolor' 'versicolor' 'setosa'
 'versicolor' 'virginica' 'versicolor' 'versicolor']
argmax of decision function: [1 0 2 1 1 0 1 2 1 1]
argmax combined with classes_: ['versicolor' 'setosa' 'virginica' 'versicolor' 'versicolor' 'setosa'
 'versicolor' 'virginica' 'versicolor' 'versicolor']