機器學習項目實戰 交易數據異常檢測

現在有一批經過處理後的信用卡用戶交易數據,我們需要通過這些數據學習一個模型,可以用來預測新的一條交易數據是否涉嫌信用卡欺詐。 首先,當然先需要導入下必要的python庫
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

%matplotlib inline
先讀取下原始數據看看
data = pd.read_csv("creditcard.csv")
print(data.shape)
data.head() #打印前5行
(284807, 31)
Time V1 V2 V3 V4 V5 V6 V7 V8 V9 V21 V22 V23 V24 V25 V26 V27 V28 Amount Class
0 0.0 -1.359807 -0.072781 2.536347 1.378155 -0.338321 0.462388 0.239599 0.098698 0.363787 -0.018307 0.277838 -0.110474 0.066928 0.128539 -0.189115 0.133558 -0.021053 149.62 0
1 0.0 1.191857 0.266151 0.166480 0.448154 0.060018 -0.082361 -0.078803 0.085102 -0.255425 -0.225775 -0.638672 0.101288 -0.339846 0.167170 0.125895 -0.008983 0.014724 2.69 0
2 1.0 -1.358354 -1.340163 1.773209 0.379780 -0.503198 1.800499 0.791461 0.247676 -1.514654 0.247998 0.771679 0.909412 -0.689281 -0.327642 -0.139097 -0.055353 -0.059752 378.66 0
3 1.0 -0.966272 -0.185226 1.792993 -0.863291 -0.010309 1.247203 0.237609 0.377436 -1.387024 -0.108300 0.005274 -0.190321 -1.175575 0.647376 -0.221929 0.062723 0.061458 123.50 0
4 2.0 -1.158233 0.877737 1.548718 0.403034 -0.407193 0.095921 0.592941 -0.270533 0.817739 -0.009431 0.798278 -0.137458 0.141267 -0.206010 0.502292 0.219422 0.215153 69.99 0

5 rows × 31 columns

可以看到,總共有284807個樣本,每個樣本有31個特徵,其中V1到V28 這28個特徵,是已經經過處理加密後的乾淨數據,雖然不知道具體代表什麼意思,但是可以直接拿來用就可以了。剩下的幾個特徵,

Time表示交易時間

Amount 表示交易金額總量

Class 即輸出,表示此條交易行爲是否存在信用卡欺詐,0爲正常,1爲異常。
我們將Class爲0的稱爲負樣本,Class爲1的稱爲正樣本

## 特徵縮放 另外,我們看下,Amount這個特徵,和其他V1到V28特徵相比,數值範圍存在明顯的差距,所以,我們需要對Amount 進行特徵縮放
from sklearn.preprocessing import StandardScaler
# print(data['Amount'].reshape(-1,1))
data['normAmount'] = StandardScaler().fit_transform(data['Amount'].reshape(-1,1))
data = data.drop(['Time','Amount'],axis=1)  #刪除不用的列
data.head()
.dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V21 V22 V23 V24 V25 V26 V27 V28 Class normAmount
0 -1.359807 -0.072781 2.536347 1.378155 -0.338321 0.462388 0.239599 0.098698 0.363787 0.090794 -0.018307 0.277838 -0.110474 0.066928 0.128539 -0.189115 0.133558 -0.021053 0 0.244964
1 1.191857 0.266151 0.166480 0.448154 0.060018 -0.082361 -0.078803 0.085102 -0.255425 -0.166974 -0.225775 -0.638672 0.101288 -0.339846 0.167170 0.125895 -0.008983 0.014724 0 -0.342475
2 -1.358354 -1.340163 1.773209 0.379780 -0.503198 1.800499 0.791461 0.247676 -1.514654 0.207643 0.247998 0.771679 0.909412 -0.689281 -0.327642 -0.139097 -0.055353 -0.059752 0 1.160686
3 -0.966272 -0.185226 1.792993 -0.863291 -0.010309 1.247203 0.237609 0.377436 -1.387024 -0.054952 -0.108300 0.005274 -0.190321 -1.175575 0.647376 -0.221929 0.062723 0.061458 0 0.140534
4 -1.158233 0.877737 1.548718 0.403034 -0.407193 0.095921 0.592941 -0.270533 0.817739 0.753074 -0.009431 0.798278 -0.137458 0.141267 -0.206010 0.502292 0.219422 0.215153 0 -0.073403

5 rows × 30 columns

類不平衡問題

接下來,我們看下當前樣本中,負樣本和正樣本分別有多少個

count_class = pd.value_counts(data['Class'],sort=True).sort_index()
print(count_class)
0    284315
1       492
Name: Class, dtype: int64

我們發現,負樣本有284315個,而正樣本只有492個,存在嚴重的正負樣本比例不平衡,也就是類不平衡問題。下面具體來說下。

類不平衡是說在訓練分類器模型時,樣本集中的類別分佈不均勻,比如上面那個問題,284807個數據,理想情況下,應該是正負樣本數量近似相等;而像上面正樣本284315個,負樣本只有492個,這個就存在嚴重的類不平衡問題。

爲啥要避免這個問題呢?從訓練模型的角度來說,如果某類的樣本數量很少,那麼這個類別鎖提供的‘信息’就會很少,這樣的化,就會導致我們的模型訓練效果很差。

如何避免呢,常用的有兩種方式來使得不同類別樣本比例相對平衡
1. 下采樣:
對訓練集裏面樣本數量較多的類別(多數類)進行欠採樣,拋棄一些樣本來緩解類不平衡。
2. 過採樣:
對訓練集裏面樣本數量較少的類別(少數類)進行過採樣,合成新的樣本來緩解類不平衡。
這個時候會用到一個非常經典的過採樣算法SMOTE

我們先採用下采樣來處理下這個問題

首先,分離出特徵X 和 輸出變量y

#分離出特徵X 和 輸出變量y
X = data.iloc[:,data.columns != 'Class']
y = data.iloc[:,data.columns == 'Class']
# print(X.head())
# print(X.shape)
# print(y.head())
# print(y.shape)

所謂下采樣,就是從多數類中隨機選擇少量樣本再合併原有少數類樣本作爲新的訓練數據集。

對於這個問題,具體來說,就是既然只有492個正樣本,那我們就從作爲多數類的負樣本(284315個)中,隨機選取492個,然後和之前的492個正樣本重新組成一個新的訓練數據集

#正樣本個數
positive_sample_count = len(data[data.Class == 1])
print("正樣本個數爲:",positive_sample_count)

#正樣本所對應的索引爲
positive_sample_index = np.array(data[data.Class == 1].index)
print("正樣本在數據集中所對應的索引爲(打印前5個):",positive_sample_index[:5])

#負樣本所對應的索引
negative_sample_index = data[data.Class == 0].index
#numpy.random.choice(a, size=None, replace=True, p=None) 從給定的一維陣列生成一個隨機樣本
#replace 樣品是否有更換  True 表示每次都隨機生成, false表示只隨機生成一次
random_negative_sample_index = np.random.choice(negative_sample_index, positive_sample_count,replace = False)
random_negative_sample_index = np.array(random_negative_sample_index)
print("負樣本在數據集中所對應的索引爲(打印前5個):",random_negative_sample_index[:5])

under_sample_index = np.concatenate([positive_sample_index,random_negative_sample_index])
under_sample_data = data.iloc[under_sample_index,:]
X_under_sample = under_sample_data.iloc[:,under_sample_data.columns != 'Class']
y_under_sample = under_sample_data.iloc[:,under_sample_data.columns == 'Class']

print('下采樣後,新數據集中,正樣本所佔比例:',
      len(under_sample_data[under_sample_data.Class==1])/len(under_sample_data))
print('下采樣後,新數據集中,負樣本所佔比例:',
      len(under_sample_data[under_sample_data.Class==0])/len(under_sample_data))
print('下采樣後,新數據集的樣本個數爲:',len(under_sample_data))
正樣本個數爲: 492
正樣本在數據集中所對應的索引爲(打印前5個): [ 541  623 4920 6108 6329]
負樣本在數據集中所對應的索引爲(打印前5個): [ 38971   9434  75592 113830 203239]
下采樣後,新數據集中,正樣本所佔比例: 0.5
下采樣後,新數據集中,負樣本所佔比例: 0.5
下采樣後,新數據集的樣本個數爲: 984

訓練集測試集的劃分以及交叉驗證

接下來,我們要做的一件事,就是需要將當前數據集分爲訓練集測試集

訓練集用去訓練生成模型, 測試集則用於最終的模型測試
而在訓練集中,我們還需要進行一個叫做交叉驗證的操作,來進行調參以及模型選擇。

首先,需要強調下,交叉驗證,是針對於訓練集的,堅決不能動測試集!!!

所謂k折交叉驗證,就是將訓練集隨機分爲K份,然後,我們依次選擇其中的k-1份來進行訓練,剩下的1份用來進行測試,循環k次(每次組合的K-1份都不相同),然後取最後的平均精度,作爲當前訓練出的模型的精度。

10折交叉驗證

我們可以通過Sklearn 中的的 sklearn.cross_validation模塊下的train_test_split來隨機劃分訓練集和測試集。

調用方式爲:X_train,X_test, y_train, y_test =train_test_split(train_data,train_target,test_size=0.4, random_state=0)
參數說明:

train_data:要劃分的樣本特徵集

train_target:劃分的樣本輸出

test_size: 如果是小數的話,表示劃分的測試集所佔的樣本比例,整數的話,則爲測試集樣本個數

random_state: 隨機數種子,其實就是該組隨機數的編號,在需要重複試驗的時候,保證得到一組一樣的隨機數。比如你每次都填1,其他參數一樣的情況下你得到的隨機數組是一樣的。但填0或不填,每次都會不一樣。

from sklearn.cross_validation import train_test_split

#這個是將下采樣之前的初始樣本數據進行訓練集和測試集的劃分,
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.3, random_state=0)

X_train_under_sample, X_test_under_sample, y_train_under_sample, y_test_under_sample = train_test_split(X_under_sample,
                                                                                                        y_under_sample,
                                                                                                        test_size=0.3, 
                                                                                                        random_state=0)
print('訓練集樣本數:',len(X_train_under_sample)) 
print('測試集樣本數:',len(X_test_under_sample)) 
訓練集樣本數: 688
測試集樣本數: 296


C:\Anaconda3\lib\site-packages\sklearn\cross_validation.py:41: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
  "This module will be removed in 0.20.", DeprecationWarning)

下面,我們將通過交叉驗證,採用邏輯迴歸來訓練模型

關於交叉驗證,我們可以用sklearn.cross_validation模塊中的KFold方法來進行處理。調用方式爲:

class sklearn.cross_validation.KFold(n, n_folds=3, shuffle=False, random_state=None)

參數說明:

n:要分割的數據集個數

n_folds: 對應交叉驗證折數

shuffle:是否在劃分之前洗牌數據。

模型訓練與選擇

from sklearn.linear_model import LogisticRegression
from sklearn.cross_validation import KFold, cross_val_score
from sklearn.metrics import confusion_matrix,recall_score,classification_report 

def Kfold_for_TrainModel(X_train_data, y_train_data):
    fold = KFold(len(X_train_data),5,shuffle = False)

    # 正則化前面的C 參數
    c_params = [0.01, 0.1, 1, 10, 100]
    #這塊生成一個DataFrame 用來保存不同的C參數,對應的召回率是多少
    result_tables = pd.DataFrame(columns = ['C_parameter','Mean recall score'])
    result_tables['C_parameter'] = c_params
    j = 0
    for c_param in c_params:
        print('-------------------------------------------')
        print('C參數爲:',c_param)
        print('-------------------------------------------')
        print('')

        recall_list = []
        for iteration, indices in enumerate(fold,start=1):
            #採用l1正則化
            lr = LogisticRegression(C=c_param, penalty = 'l1')
            #indices[0] 保存的是這個k=5次訓練中的某一次的用來驗證的數據的索引
            #indices[1] 保存的是這個k=5次訓練中的某一次的用來測試的數據的索引
            lr.fit(X_train_data.iloc[indices[0],:], 
                   y_train_data.iloc[indices[0],:].values.ravel())#.ravel可以將輸出降到一維
            #用剩下的一份數據進行測試(即indices[1]中所保存的下標)
            y_undersample_pred = lr.predict(X_train_data.iloc[indices[1],:].values)

            recall = recall_score(y_train_data.iloc[indices[1],:].values,
                                  y_undersample_pred)
            recall_list.append(recall)
            print('Iteration ',iteration," 召回率爲:",recall)
        print('')
        print('平均召回率爲:', np.mean(recall_list))
        print('')
        result_tables.loc[j,'Mean recall score'] = np.mean(recall_list)
        j = j+1

#     print(result_tables['Mean recall score'])
    result_tables['Mean recall score'] = result_tables['Mean recall score'].astype('float64')
    best_c_param = result_tables.loc[result_tables['Mean recall score'].idxmax(), 'C_parameter']
    print('*********************************************************************************')
    print('最佳模型對應的C參數 = ', best_c_param)
    print('*********************************************************************************')
    return best_c_param  
best_c_param = Kfold_for_TrainModel(X_train_under_sample, y_train_under_sample)
-------------------------------------------
C參數爲: 0.01
-------------------------------------------

Iteration  1  召回率爲: 0.9315068493150684
Iteration  2  召回率爲: 0.9178082191780822
Iteration  3  召回率爲: 1.0
Iteration  4  召回率爲: 0.972972972972973
Iteration  5  召回率爲: 0.9545454545454546

平均召回率爲: 0.9553666992023157

-------------------------------------------
C參數爲: 0.1
-------------------------------------------

Iteration  1  召回率爲: 0.8356164383561644
Iteration  2  召回率爲: 0.863013698630137
Iteration  3  召回率爲: 0.9491525423728814
Iteration  4  召回率爲: 0.9459459459459459
Iteration  5  召回率爲: 0.9090909090909091

平均召回率爲: 0.9005639068792076

-------------------------------------------
C參數爲: 1
-------------------------------------------

Iteration  1  召回率爲: 0.8493150684931506
Iteration  2  召回率爲: 0.8904109589041096
Iteration  3  召回率爲: 0.9830508474576272
Iteration  4  召回率爲: 0.9459459459459459
Iteration  5  召回率爲: 0.9090909090909091

平均召回率爲: 0.9155627459783485

-------------------------------------------
C參數爲: 10
-------------------------------------------

Iteration  1  召回率爲: 0.863013698630137
Iteration  2  召回率爲: 0.863013698630137
Iteration  3  召回率爲: 0.9830508474576272
Iteration  4  召回率爲: 0.9459459459459459
Iteration  5  召回率爲: 0.8939393939393939

平均召回率爲: 0.9097927169206482

-------------------------------------------
C參數爲: 100
-------------------------------------------

Iteration  1  召回率爲: 0.8767123287671232
Iteration  2  召回率爲: 0.863013698630137
Iteration  3  召回率爲: 0.9661016949152542
Iteration  4  召回率爲: 0.9459459459459459
Iteration  5  召回率爲: 0.8939393939393939

平均召回率爲: 0.9091426124395708

*********************************************************************************
最佳模型對應的C參數 =  0.01
*********************************************************************************

當正則化參數C設置爲0.01時,所得模型的召回率最高。所以我們選擇f1正則,並且正則參數爲0.01這個模型來作爲最終模型。然後接下來,我們將會用最終所訓練出的模型,對最終的測試集進行預測。看看效果如何

性能度量

首先,需要說下分類問題中的性能度量相關的東西。那就是混淆矩陣,在混淆矩陣中,我們可以獲得很多性能度量相關有用的信息。

在機器學習中,混淆矩陣(confusion matrix)是一種評價分類模型好壞的形象化展示工具。其中,行代表的是實際類別,列代表的是預測的類別

下面來說下解釋下TP,FP,TN和FN

TP(True Positive):真正例,即將一個實際爲正例的樣本正確的判斷爲正例

FP(False Positive):假正例,即將一個實際爲負例的樣本錯誤的判斷爲正例

TN(True Negtive):真負例,即將一個實際爲負例的樣本正確的判斷爲負例

FN(False Negtive):假負例,即將一個實際爲正例的樣本錯誤的判斷爲負例
混淆矩陣

下面再介紹幾種常用的性能度量的指標

查準率(Precision):
預測爲正例的樣本中,實際爲正例所佔的比例,公式爲:

Precision=TPTP+FP

查全率(也叫做召回率)(Recall):
正確預測爲正例的樣本數佔所有正例的比率,公式爲:
Recall=TPTP+FN

準確率(Accuracy):
所有樣本中,預測正確的所佔的比例,公式爲:
Accuracy=TP+TNTP+FP+TN+FN

下面,我們來繪製下稀疏矩陣

import itertools
def plot_confusion_matrix(confusion_matrix, classes):
#     print(confusion_matrix)
    #plt.imshow 繪製熱圖
    plt.figure()
    plt.imshow(confusion_matrix, interpolation='nearest',cmap=plt.cm.Blues)
    plt.title('confusion matrix')
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=0)
    plt.yticks(tick_marks, classes)
    thresh = confusion_matrix.max() / 2.
    for i, j in itertools.product(range(confusion_matrix.shape[0]), range(confusion_matrix.shape[1])):
        plt.text(j, i, confusion_matrix[i, j],
                 horizontalalignment="center",
                 color="white" if confusion_matrix[i, j] > thresh else "black")

    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    plt.show()
    print('查準率爲:',confusion_matrix[1,1]/(confusion_matrix[1,1]+confusion_matrix[0,1]))
    print('召回率爲:',confusion_matrix[1,1]/(confusion_matrix[1,1]+confusion_matrix[1,0]))
    print('準確率爲:',(confusion_matrix[0,0]+confusion_matrix[1,1])/(confusion_matrix[0,0]+confusion_matrix[0,1]+confusion_matrix[1,1]+confusion_matrix[1,0]))
    print('*********************************************************************************')
lr = LogisticRegression(C = best_c_param, penalty = 'l1')
lr.fit(X_train_under_sample, y_train_under_sample.values.ravel())

#獲得測試集的測試結果
y_undersample_pred = lr.predict(X_test_under_sample.values)
#構建稀疏矩陣
conf_matrix = confusion_matrix(y_test_under_sample,y_undersample_pred)
# np.set_printoptions(precision=2)
class_names = [0,1]

plot_confusion_matrix(conf_matrix
                      , classes=class_names)

查準率爲: 0.9019607843137255
召回率爲: 0.9387755102040817
準確率爲: 0.918918918918919
*********************************************************************************

上面求得的度量指標都是針對於下采樣樣本中的測試集,而我們最後需要測試的是整個所有樣本數據中的測試集,所以,下面,我們用剛纔訓練出來的那個模型,去測試下下采樣前的測試集看看

#獲得測試集的測試結果
y_pred = lr.predict(X_test.values)
#構建稀疏矩陣
conf_matrix = confusion_matrix(y_test,y_pred)
# np.set_printoptions(precision=2)
class_names = [0,1]

plot_confusion_matrix(conf_matrix
                      , classes=class_names)

查準率爲: 0.012054600248182947
召回率爲: 0.9251700680272109
準確率爲: 0.8694217197429865
*********************************************************************************

雖然召回率和準確率都不錯,但是精確率太低了,也就是說,雖然把147個正樣本中的136個都已正確預測出,但是代價是,同時把10894個負例預測爲正例。真是寧可錯殺一千,也不放過一個啊·

我們想想,爲啥會出現這個問題?其實就是因爲我們選取的負樣本太少了,284315個負樣本中,我們只選取了492個來進行訓練模型,從而導致泛化能力太差。
這也就是下采樣的缺點 由於採樣的樣本要少於原樣本集合,因此會造成一些信息缺失,未被採樣的樣本往往帶有很重要的信息

過採樣,SMOTE算法

下面,我們採用過採樣,SMOTE算法進行數據的處理

SMOTE全稱是Synthetic Minority Oversampling Technique即合成少數類過採樣技術,具體思想是:對少數類樣本進行分析並根據少數類樣本人工合成新樣本添加到數據集中

算法流程如下:
1. 對於少數類中的每一個樣本x ,用歐式距離爲標準計算它到少數類樣本集Smin 中所有樣本的距離,得到其k近鄰
2. 確定採樣倍率N ,對於每一個少數類樣本x ,從其k近鄰中隨機選擇若干個樣本,假設選擇的近鄰爲下面,我們採用過採樣,SMOTE算法進行數據的處理

SMOTE全稱是Synthetic Minority Oversampling Technique即合成少數類過採樣技術,具體思想是:對少數類樣本進行分析並根據少數類樣本人工合成新樣本添加到數據集中

算法流程如下:
1. 對於少數類中的每一個樣本x ,用歐式距離爲標準計算它到少數類樣本集Smin 中所有樣本的距離,得到其k近鄰
2. 確定採樣倍率N ,對於每一個少數類樣本x ,從其k近鄰中隨機選擇若干個樣本,假設選擇的近鄰爲x^
3. 對於每一個隨機選出的近鄰x^ ,分別與原樣本按照如下的公式構建新的樣本

xnew=x+rand(0,1)(x^x)

SMOTE算法

下面,看下具體代碼

#pip install imblearn 需要先安裝imblearn包
from imblearn.over_sampling import SMOTE
from sklearn.ensemble import RandomForestClassifier
oversampler = SMOTE(random_state = 0)

X_over_samples, y_over_samples = oversampler.fit_sample(X_train, y_train.values.ravel())

查下經過過採樣,SMOTE算法後,正負樣本分別有多少個

len(y_over_samples[y_over_samples == 1]), len(y_over_samples[y_over_samples == 0])
(199019, 199019)

可以看到正負樣本已經很均衡了,好了,現在用新的樣本集重新進行模型的訓練與選擇

#這塊注意,之前定義的Kfold_for_TrainModel函數傳的參數類型是DataFrame,所有這塊需要轉換下
best_c_param = Kfold_for_TrainModel(pd.DataFrame(X_over_samples), 
                                    pd.DataFrame(y_over_samples))
-------------------------------------------
C參數爲: 0.01
-------------------------------------------

Iteration  1  召回率爲: 0.9285714285714286
Iteration  2  召回率爲: 0.912
Iteration  3  召回率爲: 0.9129489124936773
Iteration  4  召回率爲: 0.8972829022573392
Iteration  5  召回率爲: 0.8974462044795055

平均召回率爲: 0.9096498895603901

-------------------------------------------
C參數爲: 0.1
-------------------------------------------

Iteration  1  召回率爲: 0.9285714285714286
Iteration  2  召回率爲: 0.92
Iteration  3  召回率爲: 0.9145422357106727
Iteration  4  召回率爲: 0.8986521285816574
Iteration  5  召回率爲: 0.8987777456756315

平均召回率爲: 0.9121087077078782

-------------------------------------------
C參數爲: 1
-------------------------------------------

Iteration  1  召回率爲: 0.9285714285714286
Iteration  2  召回率爲: 0.92
Iteration  3  召回率爲: 0.9146686899342438
Iteration  4  召回率爲: 0.8987777456756315
Iteration  5  召回率爲: 0.8989536096071954

平均召回率爲: 0.9121942947576999

-------------------------------------------
C參數爲: 10
-------------------------------------------

Iteration  1  召回率爲: 0.9285714285714286
Iteration  2  召回率爲: 0.92
Iteration  3  召回率爲: 0.9146686899342438
Iteration  4  召回率爲: 0.8988028690944264
Iteration  5  召回率爲: 0.8991294735387592

平均召回率爲: 0.9122344922277715

-------------------------------------------
C參數爲: 100
-------------------------------------------

Iteration  1  召回率爲: 0.9285714285714286
Iteration  2  召回率爲: 0.92
Iteration  3  召回率爲: 0.9146686899342438
Iteration  4  召回率爲: 0.8991169118293617
Iteration  5  召回率爲: 0.8989661713165927

平均召回率爲: 0.9122646403303254

*********************************************************************************
最佳模型對應的C參數 =  100.0
*********************************************************************************

可以看到,當C參數爲100時,模型召回率最好,我們就用此模型,進行測試集數據的預測

lr = LogisticRegression(C = best_c_param, penalty = 'l1')
lr.fit(X_over_samples, y_over_samples)
# lr.fit(pd.DataFrame(X_over_samples),  pd.DataFrame(y_over_samples).values.ravel())
#獲得測試集的測試結果
y_pred = lr.predict(X_test.values)
#構建稀疏矩陣
conf_matrix = confusion_matrix(y_test,y_pred)
# np.set_printoptions(precision=2)
class_names = [0,1]

plot_confusion_matrix(conf_matrix
                      , classes=class_names)

查準率爲: 0.06040268456375839
召回率爲: 0.9183673469387755
準確率爲: 0.9752817667918964
*********************************************************************************

相對於上面的欠採樣,這次效果明顯好多了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章