問題描述:判斷用戶是否竊漏電html
問題解決:二分類問題python
缺失值:拉格朗日插值法進行填充api
使用的特徵:電量趨勢降低指標、線損指標、警告類指標網絡
這裏使用的數據來<python數據分析與實戰第六章>session
數據:dom
代碼實現:函數
一、加載數據測試
import pandas as pd from random import shuffle datafile = path + 'chapter6/model.xls' data = pd.read_excel(datafile)
二、劃分訓練集和測試集this
#data = data.as_matrix() 舊版本的pandas是這麼使用的,將dataframe轉換爲矩陣 data = data.iloc[:,:].values #新版本這麼使用 shuffle(data) p = 0.8 #設置訓練數據比例 train = data[:int(len(data)*p),:] test = data[int(len(data)*p):,:]
三、使用keras定義模型lua
from keras.models import Sequential #導入神經網絡初始化函數 from keras.layers.core import Dense, Activation #導入神經網絡層函數、激活函數 netfile = path + 'chapter6/net.model' #構建的神經網絡模型存儲路徑 net = Sequential() #創建神經網絡 net.add(Dense(3, 10)) #添加輸入層(3節點)到隱藏層(10節點)的鏈接 net.add(Activation('relu')) #隱藏層使用relu激活函數 net.add(Dense(10, 1)) #添加隱藏層(10節點)到輸出層(1節點)的鏈接 net.add(Activation('sigmoid')) #輸出層使用sigmoid激活函數 net.compile(loss = 'binary_crossentropy', optimizer = 'adam', class_mode = "binary") #編譯模型,使用adam方法求解 net.fit(train[:,:3], train[:,3], nb_epoch=100, batch_size=1) #訓練模型,循環100次 net.save_weights(netfile) #保存模型
因爲keras版本致使的錯誤:
常見錯誤(均是由於keras版本改動)
Dense
can accept only 1 positional arguments ('units',), but you passed the following positional arguments: [23, 34]nb_epoch
argument in fit
has been renamed epochs
解決方法:
修改代碼中的「nb_epoch」爲「epochs」便可
修改後的代碼:
from keras.models import Sequential #導入神經網絡初始化函數 from keras.layers.core import Dense, Activation #導入神經網絡層函數、激活函數 netfile = path + 'chapter6/net.model' #構建的神經網絡模型存儲路徑 net = Sequential() #創建神經網絡 net.add(Dense(input_dim=3, units=10)) #添加輸入層(3節點)到隱藏層(10節點)的鏈接 net.add(Activation('relu')) #隱藏層使用relu激活函數 net.add(Dense(input_dim=10, units=1)) #添加隱藏層(10節點)到輸出層(1節點)的鏈接 net.add(Activation('sigmoid')) #輸出層使用sigmoid激活函數 net.compile(loss = 'binary_crossentropy', optimizer = 'adam') #編譯模型,使用adam方法求解 net.fit(train[:,:3], train[:,3], epochs=100, batch_size=1) #訓練模型,循環100次 net.save_weights(netfile) #保存模型
部分結果:
Epoch 97/100 232/232 [==============================] - 1s 3ms/step - loss: 0.3171 Epoch 98/100 232/232 [==============================] - 1s 3ms/step - loss: 0.3196 Epoch 99/100 232/232 [==============================] - 1s 3ms/step - loss: 0.3194 Epoch 100/100 232/232 [==============================] - 1s 3ms/step - loss: 0.3144
咱們也能夠訓練時加入更多的評價指標:(二分類指標)
具體的評價指標的使用可參考文檔:
https://keras.io/api/metrics/classification_metrics/#precision-class
import tensorflow as tf import numpy as np #精確率評價指標 from keras.models import Sequential #導入神經網絡初始化函數 from keras.layers.core import Dense, Activation #導入神經網絡層函數、激活函數 netfile = path + 'chapter6/net.model' #構建的神經網絡模型存儲路徑 net = Sequential() #創建神經網絡 net.add(Dense(input_dim=3, units=10)) #添加輸入層(3節點)到隱藏層(10節點)的鏈接 net.add(Activation('relu')) #隱藏層使用relu激活函數 net.add(Dense(input_dim=10, units=1)) #添加隱藏層(10節點)到輸出層(1節點)的鏈接 net.add(Activation('sigmoid')) #輸出層使用sigmoid激活函數 net.compile(loss = 'binary_crossentropy', optimizer = 'adam', metrics=['accuracy', tf.keras.metrics.Precision(), tf.keras.metrics.Recall()]) #編譯模型,使用adam方法求解 net.fit(train[:,:3], train[:,3], epochs=100, batch_size=1) #訓練模型,循環1000次 net.save_weights(netfile) #保存模型
部分結果:
Epoch 97/100 232/232 [==============================] - 1s 4ms/step - loss: 0.1729 - accuracy: 0.9526 - precision: 0.8902 - recall: 0.8770 Epoch 98/100 232/232 [==============================] - 1s 4ms/step - loss: 0.1740 - accuracy: 0.9526 - precision: 0.8908 - recall: 0.8774 Epoch 99/100 232/232 [==============================] - 1s 4ms/step - loss: 0.1693 - accuracy: 0.9569 - precision: 0.8910 - recall: 0.8780 Epoch 100/100 232/232 [==============================] - 1s 4ms/step - loss: 0.1750 - accuracy: 0.9526 - precision: 0.8915 - recall: 0.8783
對模型進行驗證:
scores = net.evaluate(test[:,:3], test[:,3], verbose=0) for i in range(1,len(net.metrics_names)): print("%s: %.2f%%" % (net.metrics_names[i], scores[i]*100)) # 打印出驗證集準確率
accuracy: 88.14%
precision: 89.14%
recall: 87.85%
使用模型進行預測:這裏注意有兩個api,一個獲得的是機率值,另外一個獲得的是類別:
使用predict()獲得的是機率值:這裏將其用round進行四捨五入後進行展開。
predict_result = tf.round(net.predict(test[:,:3]).reshape(len(test))) with tf.Session() as sess: print(predict_result.eval())
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 0. 0. 1. 0. 0. 1. 1. 1. 1. 0. 0. 1. 1. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 1. 0. 0. 0.]
使用predict_classes()獲得的是類別:
predict_result2 = net.predict_classes(test[:,:3]).reshape(len(test))
predict_result2
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0], dtype=int32)
打印一下真實的標籤:
y_true = np.array(test[:,3])
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
四、評價指標的計算方式以及混淆矩陣
咱們能夠直接經過sklearn api來計算評價指標:
from sklearn.metrics import classification_report target_names = ['no','yes'] print(classification_report(test[:,3],predict_result2,target_names=target_names))
結果:
precision recall f1-score support no 0.98 0.88 0.93 50 yes 0.57 0.89 0.70 9 accuracy 0.88 59 macro avg 0.77 0.88 0.81 59 weighted avg 0.92 0.88 0.89 59
或者咱們能夠經過混淆矩陣本身來計算:首先是得到混淆矩陣
from sklearn.metrics import confusion_matrix cnf_matrix = confusion_matrix(test[:,3], predict_result2) print(cnf_matrix)
#行、列的索引就是標籤id,這裏有兩類,用0,1,表示
[[44 6] [ 1 8]]
混淆矩陣中的四個值分別表明TP、FP、TN、PN
根據混淆矩陣,咱們能夠計算二分類評價指標:(標籤爲1的是正樣本,所以TP是[1][1])
TP=cnf_matrix[1][1] #預測爲正的真實標籤爲正 FP=cnf_matrix[0][1] #預測爲正的真實標籤爲負 FN=cnf_matrix[1][0] #預測爲負的真實標籤爲正 TN=cnf_matrix[0][0] #預測爲負的真實標籤爲負 accuracy=(TP+TN)/(TP+FP+FN+TN) precision=TP/(TP+FP) recall=TP/(TP+FN) f1score=2 * precision * recall/(precision + recall) print(accuracy,precision,recall,f1score)
0.8813559322033898 0.5714285714285714 0.8888888888888888 0.6956521739130435
這也上面api計算的yes的評價指標的值一致。
五、繪製混淆矩陣
import matplotlib.pyplot as plt %matplotlib inline def cm_plot(y, yp, labels_name): from sklearn.metrics import confusion_matrix #導入混淆矩陣函數 cm = confusion_matrix(y, yp) #混淆矩陣 plt.matshow(cm, cmap=plt.cm.Greens) #畫混淆矩陣圖,配色風格使用cm.Greens,更多風格請參考官網。 plt.colorbar() #顏色標籤 num_local = np.array(range(len(labels_name))) plt.xticks(num_local, labels_name) # 將標籤印在x軸座標上 plt.yticks(num_local, labels_name) # 將標籤印在y軸座標上 for x in range(len(cm)): #數據標籤 for y in range(len(cm)): plt.annotate(cm[x,y], xy=(x, y), horizontalalignment='center', verticalalignment='center') plt.ylabel('True label') #座標軸標籤 plt.xlabel('Predicted label') #座標軸標籤 return plt cm_plot(test[:,3],predict_result2,['no', 'yes']).show()
六、二分類其餘評價指標(這兩個我從新在colab上運行的,所以數據和上面不同)
ROC曲線:
橫座標:假正率(False positive rate, FPR),預測爲正但實際爲負的樣本佔全部負例樣本的比例;
FPR = FP / ( FP +TN)
縱座標:真正率(True positive rate, TPR),這個其實就是召回率,預測爲正且實際爲正的樣本佔全部正例樣本的比例。
TPR = TP / ( TP+ FN)
AUC:就是roc曲線和橫座標圍城的面積。
如何繪製?
對於二值分類問題,實例的值每每是連續值,經過設定一個閾值,將實例分類到正類或者負類(好比大於閾值劃分爲正類)。上述中咱們直接利用四捨五入來區分正類和負類。所以,能夠變化閾值,根據不一樣的閾值進行分類,根據分類結果計算獲得ROC空間中相應的點,鏈接這些點就造成ROC curve。ROC curve通過(0,0) (1,1),實際上(0,0)和(1,1)連線造成的ROC curve實際上表明的是一個隨機分類器。通常狀況下,這個曲線都應該處於(0,0)和(1,1)連線的上方,
代碼實現:
from sklearn.metrics import roc_curve, auc # 爲每一個類別計算ROC曲線和AUC predict_res=net.predict(test[:,:3]).reshape(len(test)) fpr,tpr,threholds=roc_curve(test[:,3],predict_res,pos_label=1) roc_auc=auc(fpr,tpr) plt.plot(fpr,tpr,linewidth=2, label='ROC curve (area = %0.2f)' % roc_auc) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('Receiver operating characteristic example') plt.legend(loc="lower right") plt.show()
繪製Precision-Recall曲線:
from sklearn.metrics import precision_recall_curve from sklearn.metrics import average_precision_score precision,recall,_ = precision_recall_curve(test[:,3],predict_res,pos_label=1) average_precision = average_precision_score(test[:,3],predict_res,pos_label=1) plt.plot(recall, precision,label='Precision-recall curve of class (area = {1:0.2f})'.format(i, average_precision)) plt.xlabel('Recall', fontsize=16) plt.ylabel('Precision',fontsize=16) plt.title('Extension of Precision-Recall curve to 2-class',fontsize=16) plt.legend(loc="upper right")#legend 是用於設置圖例的函數 plt.show()
關於二分類評價指標網上已經有不少講解的很清楚的了,就不仔細講了,仍是注重實際的代碼。原本是應該對比不一樣的模型的,結果搞成了講解二分類指標了。。。
參考:
《python數據分析與挖掘實戰》
https://www.cnblogs.com/liweiwei1419/p/9870034.html
https://blog.csdn.net/weixin_39541558/article/details/82708832