以前にこんな記事を書きました
ここでは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
大変見やすくなったと思います。これを使って精度の詳細を分析すると分類系の精度の関数を使わずとも詳細が分かると思います。