0
0

classification_report優秀すぎる件

Posted at

以前にこんな記事を書きました

ここではclassification_reportというScikit-Learnにある分類の於ける各指標をクラスごとに計算してくれるものを利用して書いたのですが、私がQiitaを始めて2回目に書いた深さ優先探索や幅優先探索のアルゴリズムを使って辞書データを自動解析する関数を使えばかなり自由度の高い分析ができるんじゃないかと思いました。

では実際にプログラムを組んでみます。
使用するのはアヤメのデータになります。

from sklearn.linear_model import LogisticRegression as LR
from sklearn.metrics import classification_report
import pandas as pd

df = pd.read_csv("iris.csv")

y = df["category"]
x = df.drop("category", axis=1)
for col in x.columns:
    x[col] = (x[col] - x[col].mean()) / x[col].std()

model = LR()
model.fit(x, y)
y_pred = model.predict(x)
print(classification_report(y, y_pred))
              precision    recall  f1-score   support

           0       1.00      1.00      1.00        50
           1       0.98      0.94      0.96        50
           2       0.94      0.98      0.96        50

    accuracy                           0.97       150
   macro avg       0.97      0.97      0.97       150
weighted avg       0.97      0.97      0.97       150

これだけ見ると数字の桁数が小数点以下2桁で精密さにかけるのではないかと思いますが、辞書機能を使って見ると

rep = classification_report(y, y_pred, output_dict=True)
print(rep)
{'0': {'precision': 1.0, 'recall': 1.0, 'f1-score': 1.0, 'support': 50}, '1': {'precision': 0.9791666666666666, 'recall': 0.94, 'f1-score': 0.9591836734693877, 'support': 50}, '2': {'precision': 0.9423076923076923, 'recall': 0.98, 'f1-score': 0.9607843137254902, 'support': 50}, 'accuracy': 0.9733333333333334, 'macro avg': {'precision': 0.9738247863247862, 'recall': 0.9733333333333333, 'f1-score': 0.9733226623982927, 'support': 150}, 'weighted avg': {'precision': 0.9738247863247864, 'recall': 0.9733333333333334, 'f1-score': 0.9733226623982927, 'support': 150}}

ではこの辞書データに対して深さ優先探索を使ってデータを使いやすくします。

def depth(jsn, var=""):
    if isinstance(jsn, dict):
        for row in jsn:
            depth(jsn[row], var=var+"[\""+row+"\"]")
    elif isinstance(jsn, list) and jsn != []:
        for i in range(len(jsn)):
            depth(jsn[i], var=var+"["+str(i)+"]")
    else:
        print(var+"="+str(jsn))
        pass

これに対して先ほどの辞書データを使いますと

depth(rep, var="rep")
rep["0"]["precision"]=1.0
rep["0"]["recall"]=1.0
rep["0"]["f1-score"]=1.0
rep["0"]["support"]=50
rep["1"]["precision"]=0.9791666666666666
rep["1"]["recall"]=0.94
rep["1"]["f1-score"]=0.9591836734693877
rep["1"]["support"]=50
rep["2"]["precision"]=0.9423076923076923
rep["2"]["recall"]=0.98
rep["2"]["f1-score"]=0.9607843137254902
rep["2"]["support"]=50
rep["accuracy"]=0.9733333333333334
rep["macro avg"]["precision"]=0.9738247863247862
rep["macro avg"]["recall"]=0.9733333333333333
rep["macro avg"]["f1-score"]=0.9733226623982927
rep["macro avg"]["support"]=150
rep["weighted avg"]["precision"]=0.9738247863247864
rep["weighted avg"]["recall"]=0.9733333333333334
rep["weighted avg"]["f1-score"]=0.9733226623982927
rep["weighted avg"]["support"]=150

大変見やすくなったと思います。これを使って精度の詳細を分析すると分類系の精度の関数を使わずとも詳細が分かると思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0