1、前述python
怎麼樣對訓練出來的模型進行評估是有必定指標的,本文就相關指標作一個總結。git
2、具體dom
一、混淆矩陣函數
混淆矩陣如圖:post
第一個參數true,false是指預測的正確性。測試
第二個參數true,postitives是指預測的結果。fetch
相關公式:spa
檢測正列的效果:3d
檢測負列的效果:rest
公式解釋:
fp_rate:
tp_rate:
recall:(召回率)
值越大越好
presssion:(準確率)
TP:原本是正例,經過模型預測出來是正列
TP+FP:經過模型預測出來的全部正列數(其中包括原本是負例,但預測出來是正列)
值越大越好
F1_Score:
準確率和召回率是負相關的。如圖所示:
通俗解釋:
實際上很是簡單,精確率是針對咱們預測結果而言的,它表示的是預測爲正的樣本中有多少是真正的正樣本。那麼預測爲正就有兩種可能了,一種就是把正類預測爲正類(TP),另外一種就是把負類預測爲正類(FP),也就是
而召回率是針對咱們原來的樣本而言的,它表示的是樣本中的正例有多少被預測正確了。那也有兩種可能,一種是把原來的正類預測成正類(TP),另外一種就是把原來的正類預測爲負類(FN)。
其實就是分母不一樣,一個分母是預測爲正的樣本數,另外一個是原來樣本中全部的正樣本數。
二、ROC曲線
過程:對第一個樣例,預測對,閾值是0.9,因此曲線向上走,以此類推。
對第三個樣例,預測錯,閾值是0.7 ,因此曲線向右走,以此類推。
幾種狀況:
因此得出結論,曲線在對角線以上,則準確率好。
三、AUC面積
M是樣本中正例數
N是樣本中負例數
其中累加解釋是把預測出來的全部機率結果按照分值升序排序,而後取正例所對應的索引號進行累加
經過AUC面積預測出來的能夠知道好到底有多好,壞到底有多壞。由於正例的索引比較大,則AUC面積越大。
總結:
四、交叉驗證
爲在實際的訓練中,訓練的結果對於訓練集的擬合程度一般仍是挺好的(初試條件敏感),可是對於訓練集以外的數據的擬合程度一般就不那麼使人滿意了。所以咱們一般並不會把全部的數據集都拿來訓練,而是分出一部分來(這一部分不參加訓練)對訓練集生成的參數進行測試,相對客觀的判斷這些參數對訓練集以外的數據的符合程度。這種思想就稱爲交叉驗證。
通常3折或者5折交叉驗證就足夠了。
3、代碼
#!/usr/bin/python # -*- coding: UTF-8 -*- # 文件名: mnist_k_cross_validate.py from sklearn.datasets import fetch_mldata import matplotlib import matplotlib.pyplot as plt import numpy as np from sklearn.linear_model import SGDClassifier from sklearn.model_selection import StratifiedKFold from sklearn.base import clone from sklearn.model_selection import cross_val_score from sklearn.base import BaseEstimator #評估指標 from sklearn.model_selection import cross_val_predict from sklearn.metrics import confusion_matrix from sklearn.metrics import precision_score from sklearn.metrics import recall_score from sklearn.metrics import f1_score from sklearn.metrics import precision_recall_curve from sklearn.metrics import roc_curve from sklearn.metrics import roc_auc_score from sklearn.ensemble import RandomForestClassifier # Alternative method to load MNIST, if mldata.org is down from scipy.io import loadmat #利用Matlib加載本地數據 mnist_raw = loadmat("mnist-original.mat") mnist = { "data": mnist_raw["data"].T, "target": mnist_raw["label"][0], "COL_NAMES": ["label", "data"], "DESCR": "mldata.org dataset: mnist_k_cross_validate-original", } print("Success!") # mnist_k_cross_validate = fetch_mldata('MNIST_original', data_home='test_data_home') print(mnist) X, y = mnist['data'], mnist['target'] # X 是70000行 784個特徵 y是70000行 784個像素點 print(X.shape, y.shape) # some_digit = X[36000] print(some_digit) some_digit_image = some_digit.reshape(28, 28)#調整矩陣 28*28=784 784個像素點調整成28*28的矩陣 圖片是一個28*28像素的圖片 每個像素點是一個rgb的值 print(some_digit_image) # plt.imshow(some_digit_image, cmap=matplotlib.cm.binary, interpolation='nearest') plt.axis('off') plt.show() # X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[:60000]#6/7做爲訓練,1/7做爲測試 shuffle_index = np.random.permutation(60000)#返回一組隨機的數據 shuffle 打亂60000中每行的值 即每一個編號的值不是原先的對應的值 X_train, y_train = X_train[shuffle_index], y_train[shuffle_index] # Shuffle以後的取值 # # y_train_5 = (y_train == 5)# 是5就標記爲True,不是5就標記爲false y_test_5 = (y_test == 5) print(y_test_5) #這裏能夠直接寫成LogGression sgd_clf = SGDClassifier(loss='log', random_state=42)# log 表明邏輯迴歸 random_state或者random_seed 隨機種子 寫死之後生成的隨機數就是同樣的 sgd_clf.fit(X_train, y_train_5)#構建模型 print(sgd_clf.predict([some_digit]))# 測試模型 最終爲5 # # ### K折交叉驗證 ##總共會運行3次 skfolds = StratifiedKFold(n_splits=3, random_state=42)# 交叉驗證 3折 跑三次 在訓練集中的開始1/3 中測試,中間1/3 ,最後1/3作驗證 for train_index, test_index in skfolds.split(X_train, y_train_5): #能夠把sgd_clf = SGDClassifier(loss='log', random_state=42)這一行放入進來,傳不一樣的超參數 這裏就不用克隆了 clone_clf = clone(sgd_clf)# clone一個上一個同樣的模型 讓它不變了 每次初始隨機參數w0,w1,w2都同樣,因此設定隨機種子是同樣 X_train_folds = X_train[train_index]#對應的是訓練集中訓練的X 沒有陰影的 y_train_folds = y_train_5[train_index]# 對應的是訓練集中的訓練y 沒有陰影的 X_test_folds = X_train[test_index]#對應的是訓練集中的測試的X 陰影部分的 y_test_folds = y_train_5[test_index]#對應的是訓練集中的測試的Y 陰影部分的 clone_clf.fit(X_train_folds, y_train_folds)#構建模型 y_pred = clone_clf.predict(X_test_folds)#驗證 print(y_pred) n_correct = sum(y_pred == y_test_folds)# 如若預測對了加和 由於true=1 false=0 print(n_correct / len(y_pred))#獲得預測對的精度 #用判斷正確的數/總共預測的 獲得一個精度 # #PS:這裏能夠把上面的模型生成直接放在交叉驗證裏面傳一些超參數好比阿爾法,看最後的準確率則知道什麼超參數最好。 #這是Sk_learn裏面的實現的函數cv是幾折,score評估什麼指標這裏是準確率,結果相似上面一大推代碼 print(cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring='accuracy')) #這是Sk_learn裏面的實現的函數cv是幾折,score評估什麼指標這裏是準確率 class Never5Classifier(BaseEstimator):#給定一個分類器,永遠不會分紅5這個類別 由於正負列樣本不均勻,因此得出的結果是90%,因此只拿精度是不許確的。 def fit(self, X, y=None): pass def predict(self, X): return np.zeros((len(X), 1), dtype=bool) never_5_clf = Never5Classifier() print(cross_val_score(never_5_clf, X_train, y_train_5, cv=3, scoring='accuracy'))#給每個結果一個結果 # # # # ##混淆矩陣 能夠準確地知道哪個類別判斷的不許 y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3)#給每個結果預測一個機率 print(confusion_matrix(y_train_5, y_train_pred)) # # y_train_perfect_prediction = y_train_5 print(confusion_matrix(y_train_5, y_train_5)) #準確率,召回率,F1Score print(precision_score(y_train_5, y_train_pred)) print(recall_score(y_train_5, y_train_pred)) print(sum(y_train_pred)) print(f1_score(y_train_5, y_train_pred)) sgd_clf.fit(X_train, y_train_5) y_scores = sgd_clf.decision_function([some_digit]) print(y_scores) threshold = 0 # Z的大小 wT*x的結果 y_some_digit_pred = (y_scores > threshold) print(y_some_digit_pred) threshold = 200000 y_some_digit_pred = (y_scores > threshold) print(y_some_digit_pred) y_scores = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3, method='decision_function') print(y_scores)#直接得出Score precisions, recalls, thresholds = precision_recall_curve(y_train_5, y_scores) print(precisions, recalls, thresholds) def plot_precision_recall_vs_threshold(precisions, recalls, thresholds): plt.plot(thresholds, precisions[:-1], 'b--', label='Precision') plt.plot(thresholds, recalls[:-1], 'r--', label='Recall') plt.xlabel("Threshold") plt.legend(loc='upper left') plt.ylim([0, 1]) # plot_precision_recall_vs_threshold(precisions, recalls, thresholds) # plt.savefig('./temp_precision_recall') y_train_pred_90 = (y_scores > 70000) print(precision_score(y_train_5, y_train_pred_90)) print(recall_score(y_train_5, y_train_pred_90)) fpr, tpr, thresholds = roc_curve(y_train_5, y_scores) def plot_roc_curve(fpr, tpr, label=None): plt.plot(fpr, tpr, linewidth=2, label=label) plt.plot([0, 1], [0, 1], 'k--') plt.axis([0, 1, 0, 1]) plt.xlabel('False Positive Rate') plt.ylabel('True positive Rate') plot_roc_curve(fpr, tpr) plt.show() # plt.savefig('img_roc_sgd') print(roc_auc_score(y_train_5, y_scores)) forest_clf = RandomForestClassifier(random_state=42) y_probas_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3, method='predict_proba') y_scores_forest = y_probas_forest[:, 1] fpr_forest, tpr_forest, thresholds_forest = roc_curve(y_train_5, y_scores_forest) plt.plot(fpr, tpr, 'b:', label='SGD') plt.plot(fpr_forest, tpr_forest, label='Random Forest') plt.legend(loc='lower right') plt.show() # plt.savefig('./img_roc_forest') print(roc_auc_score(y_train_5, y_scores_forest)) # #