だから、私はsci-kitを使っていくつかのデータを分類します。データを分類する13の異なるクラス値/カテゴリがあります。これで、相互検証を使用して、混同マトリックスを印刷できました。ただし、TPとFPなどはクラスラベルなしでのみ表示されるため、どのクラスが何であるかはわかりません。以下にコードと出力を示します。
def classify_data(df, feature_cols, file):
nbr_folds = 5
RANDOM_STATE = 0
attributes = df.loc[:, feature_cols] # Also known as x
class_label = df['task'] # Class label, also known as y.
file.write("\nFeatures used: ")
for feature in feature_cols:
file.write(feature + ",")
print("Features used", feature_cols)
sampler = RandomOverSampler(random_state=RANDOM_STATE)
print("RandomForest")
file.write("\nRandomForest")
rfc = RandomForestClassifier(max_depth=2, random_state=RANDOM_STATE)
pipeline = make_pipeline(sampler, rfc)
class_label_predicted = cross_val_predict(pipeline, attributes, class_label, cv=nbr_folds)
conf_mat = confusion_matrix(class_label, class_label_predicted)
print(conf_mat)
accuracy = accuracy_score(class_label, class_label_predicted)
print("Rows classified: " + str(len(class_label_predicted)))
print("Accuracy: {0:.3f}%\n".format(accuracy * 100))
file.write("\nClassifier settings:" + str(pipeline) + "\n")
file.write("\nRows classified: " + str(len(class_label_predicted)))
file.write("\nAccuracy: {0:.3f}%\n".format(accuracy * 100))
file.writelines('\t'.join(str(j) for j in i) + '\n' for i in conf_mat)
#Output
Rows classified: 23504
Accuracy: 17.925%
0 372 46 88 5 73 0 536 44 317 0 200 127
0 501 29 85 0 136 0 655 9 154 0 172 67
0 97 141 78 1 56 0 336 37 429 0 435 198
0 135 74 416 5 37 0 507 19 323 0 128 164
0 247 72 145 12 64 0 424 21 296 0 304 223
0 190 41 36 0 178 0 984 29 196 0 111 43
0 218 13 71 7 52 0 917 139 177 0 111 103
0 215 30 84 3 71 0 1175 11 55 0 102 62
0 257 55 156 1 13 0 322 184 463 0 197 160
0 188 36 104 2 34 0 313 99 827 0 69 136
0 281 80 111 22 16 0 494 19 261 0 313 211
0 207 66 87 18 58 0 489 23 157 0 464 239
0 113 114 44 6 51 0 389 30 408 0 338 315
ご覧のとおり、どの列が何であるかを実際に知ることはできません。また、印刷も「不整合」であるため、理解するのが困難です。
ラベルも印刷する方法はありますか?
doc から、混同マトリックスの行と列のラベルを印刷するオプションはないようです。ただし、引数labels=...
を使用してラベルの順序を指定できます
例:
from sklearn.metrics import confusion_matrix
y_true = ['yes','yes','yes','no','no','no']
y_pred = ['yes','no','no','no','no','no']
print(confusion_matrix(y_true, y_pred))
# Output:
# [[3 0]
# [2 1]]
print(confusion_matrix(y_true, y_pred, labels=['yes', 'no']))
# Output:
# [[1 2]
# [0 3]]
混同行列をラベル付きで印刷する場合は、pandas
を試して、index
のcolumns
およびDataFrame
を設定できます。
import pandas as pd
cmtx = pd.DataFrame(
confusion_matrix(y_true, y_pred, labels=['yes', 'no']),
index=['true:yes', 'true:no'],
columns=['pred:yes', 'pred:no']
)
print(cmtx)
# Output:
# pred:yes pred:no
# true:yes 1 2
# true:no 0 3
または
unique_label = np.unique([y_true, y_pred])
cmtx = pd.DataFrame(
confusion_matrix(y_true, y_pred, labels=unique_label),
index=['true:{:}'.format(x) for x in unique_label],
columns=['pred:{:}'.format(x) for x in unique_label]
)
print(cmtx)
# Output:
# pred:no pred:yes
# true:no 3 0
# true:yes 2 1
混同行列の行と列にラベルを付ける方法が、sklearnがクラスをコーディングした方法と正確に一致するようにすることが重要です。ラベルの実際の順序は、分類子の.classes_属性を使用して明らかにできます。以下のコードを使用して、混同マトリックスデータフレームを準備できます。
labels = rfc.classes_
conf_df = pd.DataFrame(confusion_matrix(class_label, class_label_predicted, columns=labels, index=labels))
conf_df.index.name = 'True labels'
2つ目の注意点は、分類器がラベルを適切に予測していないことです。正しく予測されたラベルの数は、混同行列の主対角線上に表示されます。行列全体にゼロ以外の値があり、一部のクラスはまったく予測されていません。列はすべてゼロです。デフォルトのパラメーターで分類器を実行し、それらを最適化することをお勧めします。
混同行列は単なるnumpy行列であるため、列情報は含まれていません。できることは、マトリックスをデータフレームに変換してから、このデータフレームを印刷することです。
import pandas as pd
import numpy as np
def cm2df(cm, labels):
df = pd.DataFrame()
# rows
for i, row_label in enumerate(labels):
rowdata={}
# columns
for j, col_label in enumerate(labels):
rowdata[col_label]=cm[i,j]
df = df.append(pd.DataFrame.from_dict({row_label:rowdata}, orient='index'))
return df[labels]
cm = np.arange(9).reshape((3, 3))
df = cm2df(cm, ["a", "b", "c"])
print(df)
コードスニペットは https://Gist.github.com/nickynicolson/202fe765c99af49acb20ea9f77b6255e からのものです
出力:
a b c
a 0 1 2
b 3 4 5
c 6 7 8
データには13の異なるクラスがあるようです。そのため、混同マトリックスには13の行と列があります。さらに、クラスにはなんらラベルが付けられておらず、私が見ることができるものからの整数だけです。
これが当てはまらず、トレーニングデータに実際のラベルがある場合、一意のラベルのリストをconfusion_matrixに渡すことができます。
conf_mat = confusion_matrix(class_label, class_label_predicted, df['task'].unique())