信用貸款反欺詐模型

一舆乔、項目介紹

數(shù)據(jù)集來自于某銀行信用卡交易數(shù)據(jù)磨德,顯示兩天內(nèi)發(fā)生的交易幾率缘回,284,807筆交易中發(fā)生了492筆盜刷。

二、項目目的

通過信用卡的歷史交易數(shù)據(jù)切诀,利用機(jī)器學(xué)習(xí)算法構(gòu)建信用卡反欺詐預(yù)測模型揩环,提前發(fā)現(xiàn)客戶信用卡被盜刷事件,并且要求模型準(zhǔn)確度在95%以上最大化召回率幅虑。

三、項目過程

1. 建模準(zhǔn)備

  • 模型選擇:
    該項目主要解決持卡人是否會發(fā)生信用卡被盜刷事件顾犹,屬于二分類問題倒庵,可以通過二分類算法找到具體解決辦法,例如可以選用邏輯回歸模型構(gòu)建模型(Logistic Regression)
  • 數(shù)據(jù)處理:
    數(shù)據(jù)表中炫刷,V1,V2,...V28以及amount列屬于特征字段擎宝,其中v1-v28已做脫敏處理,但amount數(shù)據(jù)規(guī)格與其他特征差別較大浑玛,需進(jìn)行特征縮放绍申;

    交易數(shù)據(jù)有284,807條,其中492筆發(fā)生盜刷事件顾彰,數(shù)據(jù)集不平衡需要需要進(jìn)行欠采樣處理极阅。

    1.1 特征縮放:歸一化處理
    • 將Amount的值轉(zhuǎn)化為-1,1之間
from sklearn.preprocessing import StandardScaler
data['normAmount'] = StandardScaler().fit_transform(data['Amount'].values.reshape(-1,1))
data = data.drop(['Time','Amount'],axis=1)
標(biāo)準(zhǔn)化Amount列

1.2 欠采樣處理:
這里我們先進(jìn)行隨機(jī)欠采樣方法,將0樣本的數(shù)量縮小到1樣本相同數(shù)量

# 求類別為1的數(shù)據(jù)的個數(shù)
number_records_fraud = len(data[data.Class == 1])
# 類別為1的索引集合
fraud_indices = np.array(data[data.Class == 1].index)
# 類別為0的索引集合
normal_indices = np.array(data[data.Class == 0].index)

# 在類別為0中涨享,取與類別1相同數(shù)目的隨機(jī)數(shù)
random_normal_indices = np.random.choice(normal_indices,size=number_records_fraud,replace = False)  # 得到的是索引
# 合并1樣本和新的0樣本索引
under_sample_indices =  np.concatenate([fraud_indices,random_normal_indices])
# 取新索引數(shù)據(jù)集
under_sample_data = data.iloc[under_sample_indices]
新數(shù)據(jù)集樣本

如何平衡樣本

  • 不平衡樣本會影響模型的評估效果筋搏,嚴(yán)重的會帶來過擬合或欠擬合現(xiàn)象。所以我們需要讓正負(fù)樣本在模型訓(xùn)練中擁有相同的數(shù)量厕隧。在這里奔脐,數(shù)據(jù)集中樣本較多的一類成為“大眾類”,樣本較少的一類稱為“小眾類”
  • 處理方法:
    1. 下采樣(Undersamping,欠采樣):
    以小眾類的樣本數(shù)為標(biāo)準(zhǔn)吁讨,在大眾類樣本中取得與小眾類的樣本數(shù)相同數(shù)量髓迎。

弊端:下采樣是選擇部分大眾類,下采樣會由于丟失信息而導(dǎo)致欠擬合建丧,往往還會丟失重要信息排龄。
改進(jìn)方法1:EasyEnsemble將多數(shù)類樣本隨機(jī)劃分成n個子集,每個子集的數(shù)量等于小眾類樣本的數(shù)量茶鹃,這相當(dāng)于欠采樣涣雕。接著將每個子集與小眾類樣本結(jié)合起來分別訓(xùn)練一個模型,最后將n個模型集成闭翩,這樣雖然每個子集的樣本少于總體樣本挣郭,但集成后總信息量并不減少。
改進(jìn)方法2:BalanceCascade則是采用了有監(jiān)督結(jié)合Boosting的方式(Boosting方法是一種用來提高弱分類算法準(zhǔn)確度的方法,這種方法通過構(gòu)造一個預(yù)測函數(shù)系列,然后以一定的方式將他們組合成一個預(yù)測函數(shù))疗韵。在第n輪訓(xùn)練中兑障,將從大眾類樣本中抽樣得來的子集與小眾類樣本結(jié)合起來訓(xùn)練一個基學(xué)習(xí)器H,訓(xùn)練完后大眾類中能被H正確分類的樣本會被剔除。在接下來的第n+1輪中流译,從被剔除后的大眾類樣本中產(chǎn)生子集用于與小眾類樣本結(jié)合起來訓(xùn)練逞怨,最后將不同的基學(xué)習(xí)器H集成起來。

2. 上采樣(Oversampling,過采樣):
以大眾類為標(biāo)準(zhǔn)福澡,生成一些小眾類樣本叠赦,使大、小眾類樣本數(shù)相同革砸。

弊端:上采樣是復(fù)制多份小眾類除秀,后面結(jié)果的小眾類中會出現(xiàn)一些重復(fù)樣本,這可能會導(dǎo)致過擬合現(xiàn)象算利。
改進(jìn)方法:通過抽樣方法在小眾類樣本中加入白噪聲(比如高斯噪聲)變成新樣本一定程度上可以緩解這個問題册踩。如年齡,原年齡=新年齡+random(0,1)

上采樣代表算法:SMOTE 算法
SMOTE是通過對小眾樣本進(jìn)行插值來獲取新樣本的效拭。比如對于每個小眾類樣本a暂吉,從 a最鄰近的樣本中選取 樣本b,然后在對 ab 中隨機(jī)選擇一點(diǎn)作為新樣本缎患。

2.創(chuàng)建模型

2.1 數(shù)據(jù)拆分:訓(xùn)練集慕的、測試集
2.2 交叉驗證
2.3 模型評估方法
2.4 正則化懲罰項
2.5 構(gòu)建模型

  • 2.5.1 使用交叉驗證,尋找最佳正則化懲罰項
  • 2.5.2 使用下采樣數(shù)據(jù)進(jìn)行訓(xùn)練较锡,下采樣數(shù)據(jù)進(jìn)行測試
  • 2.5.3 使用下采樣數(shù)據(jù)進(jìn)行訓(xùn)練业稼,原始數(shù)據(jù)進(jìn)行測試
  • 2.5.4 不同閾值對結(jié)果的影響
  • 2.5.5 比較:使用原始數(shù)據(jù)進(jìn)行訓(xùn)練與測試
2.1 數(shù)據(jù)拆分

利用sklearn的train_test_split將數(shù)據(jù)源切分為訓(xùn)練集和測試集。

  • 訓(xùn)練集:用于訓(xùn)練模型的數(shù)據(jù)集
  • 測試集:用于對模型結(jié)果進(jìn)行測試的數(shù)據(jù)集
# 導(dǎo)入切分?jǐn)?shù)據(jù)模塊(訓(xùn)練集和測試集)
from sklearn.model_selection import train_test_split
# 切分原始數(shù)據(jù)集
x_train,x_test,y_train,y_test = train_test_split(x_data, y_data, test_size = 0.3, random_state = 0)
# 切分下采樣數(shù)據(jù)集
x_train_undersample, x_test_undersample, y_train_undersample ,y_test_undersample = train_test_split(x_data_undersample ,y_data_undersample, test_size = 0.3, random_state = 0)
# random_state 為隨機(jī)數(shù)種子
原始數(shù)據(jù)訓(xùn)練集數(shù)目: 199364
原始數(shù)據(jù)測試集數(shù)目: 85443
原始數(shù)據(jù)總數(shù)目: 284807
下采樣訓(xùn)練集數(shù)目: 688
下采樣測試集數(shù)目: 296
下采樣總數(shù)目: 984
2.2 交叉驗證

交叉驗證是在機(jī)器學(xué)習(xí)建立模型和驗證模型參數(shù)時常用的辦法蚂蕴,就是重復(fù)的使用數(shù)據(jù)低散,把得到的樣本數(shù)據(jù)進(jìn)行切分,組合為不同的訓(xùn)練集和測試集骡楼,用訓(xùn)練集來訓(xùn)練模型熔号,用測試集來評估模型預(yù)測的好壞。在此基礎(chǔ)上可以得到多組不同的訓(xùn)練集和測試集鸟整,某次訓(xùn)練集中的某樣本在下次可能成為測試集中的樣本引镊,即所謂"交叉"。

  • 常見形式:
    1. Holdout 驗證:
    常識來說篮条,Holdout 驗證并非一種交叉驗證弟头,因為數(shù)據(jù)并沒有交叉使用。 隨機(jī)從最初的樣本中選出部分涉茧,形成交叉驗證數(shù)據(jù)赴恨,而剩余的就當(dāng)做訓(xùn)練數(shù)據(jù)。 一般來說伴栓,少于原本樣本三分之一的數(shù)據(jù)被選做驗證數(shù)據(jù)伦连。
    2. K-fold cross-validation:
    K折交叉驗證雨饺,初始采樣分割成K個子樣本,一個單獨(dú)的子樣本被保留作為驗證模型的數(shù)據(jù)惑淳,其他K-1個樣本用來訓(xùn)練额港。交叉驗證重復(fù)K次,每個子樣本驗證一次歧焦,平均K次的結(jié)果或者使用其它結(jié)合方式移斩,最終得到一個單一估測。這個方法的優(yōu)勢在于绢馍,同時重復(fù)運(yùn)用隨機(jī)產(chǎn)生的子樣本進(jìn)行訓(xùn)練和驗證叹哭,每次的結(jié)果驗證一次,10折交叉驗證是最常用的
    3. 留一驗證:
    正如名稱所建議痕貌, 留一驗證(LOOCV)意指只使用原本樣本中的一項來當(dāng)做驗證資料, 而剩余的則留下來當(dāng)做訓(xùn)練資料糠排。 這個步驟一直持續(xù)到每個樣本都被當(dāng)做一次驗證資料舵稠。 事實上,這等同于和K-fold 交叉驗證是一樣的入宦,其中K為原本樣本個數(shù)哺徊。 在某些情況下是存在有效率的演算法,如使用kernel regression 和Tikhonov regularization乾闰。
  • 當(dāng)數(shù)據(jù)量較少時落追,我們就可以使用K折交叉驗證,來訓(xùn)練優(yōu)化選擇模型涯肩;而當(dāng)數(shù)據(jù)量較多時轿钠,將數(shù)據(jù)分成三份(訓(xùn)練集、驗證集病苗、測試集)疗垛,訓(xùn)練集用來訓(xùn)練模型,驗證集用來進(jìn)行驗證判斷模型好壞硫朦,測試集用來進(jìn)行最后檢測贷腕。


    k折交叉驗證
2.3 模型評估方法

混淆矩陣:

  • 混淆矩陣的每一列代表了預(yù)測類別,每一列的總數(shù)表示預(yù)測為該類別的數(shù)據(jù)的數(shù)目咬展;每一行代表了數(shù)據(jù)的真實歸屬類別泽裳,每一行的數(shù)據(jù)總數(shù)表示該類別的數(shù)據(jù)實例的數(shù)目,每一列中的數(shù)值表示真實數(shù)據(jù)被預(yù)測為該類的數(shù)目破婆。

    精確率:
  • 預(yù)測為正的結(jié)果中涮总,實際為正的占比,精確率代表了模型預(yù)測的正確程度荠割。
  • pre = TP / (FP + TP)
    召回率:
  • 實際為正中妹卿,預(yù)測也為正的占比旺矾,召回率代表了實際為正的用戶被預(yù)測出來的概率程度。
  • recall = TP / (FN + TP)
    F1-score
  • F1 = 2(精確率*召回率)/(精確率+召回率)
  • 驗證一個模型的好壞是根據(jù)其精確率和召回率指標(biāo)的高低夺克,但他們是兩個互相矛盾的指標(biāo)箕宙,高精確率就意味著低召回率,而F1值是綜合上述兩個指標(biāo)的評估指標(biāo)铺纽,用于綜合反映整體的指標(biāo)柬帕。
2.4 正則化懲罰項

正則化是結(jié)構(gòu)風(fēng)險最小化策略的實現(xiàn),是在經(jīng)驗風(fēng)險上加上一個正則化項或懲罰項狡门。正則化項一般是負(fù)責(zé)模型復(fù)雜度的單調(diào)遞增函數(shù)陷寝,模型越復(fù)雜,正則化值就越大其馏。正則化的作用是選擇經(jīng)驗風(fēng)險與模型復(fù)雜度同時較小的模型凤跑。正則化符合奧卡姆剃刀原理,在所有可能選擇的模型中叛复,能夠很好地解釋數(shù)據(jù)并且十分簡單的才是最好的模型仔引。


  • L1正則化中可以對|w|求累加和,但是只直接計算絕對值求累加和的話褐奥,[1.0.0,0,0]和[0.25,0.25,0.25,0.25,0.25]的結(jié)果是相同的咖耘,無法做出區(qū)分。
  • L2正則化懲罰力度更大撬码,對權(quán)重參數(shù)求平方和儿倒,目的是讓大的更大,相對懲罰更多呜笑。入系數(shù)夫否,表示正則化懲罰力度。à值越大蹈垢,表示懲罰力度越大慷吊,對模型影響越大。如果入值較小曹抬,意味著懲罰力度較小溉瓶,不會對結(jié)果產(chǎn)生太大影響。

L1與L2的選擇:

  • 如果數(shù)據(jù)集中有很多特征谤民,而這些特征中并不是每一個都對結(jié)果有重要影響堰酿,那么就應(yīng)該選擇L1正則化的模型。
  • 但如果數(shù)據(jù)集中特征本來就不多张足,而且每一個都有很重要的作用触创,那么就應(yīng)該選擇L2正則化的模型。
2.5 模型構(gòu)建

(1)K折驗證法为牍,選擇最佳正則化懲罰項:

def printing_Kfold_scores(x_train_data,y_train_data):
    # 得到一個可迭代對象哼绑,遍歷5次岩馍,每次出來一個2值列表,存放每次的訓(xùn)練集和測試集(分成5塊抖韩,返回的時索引值)
    fold = KFold(5,shuffle=False) 
    # 不同正則化懲罰力度參數(shù)值
    c_param_range = [0.01,0.1,1,10,100]
    
    # 創(chuàng)建不同正則化懲罰力度表
    result_table = pd.DataFrame(index = range(len(c_param_range)), columns = ['C_parameter','Mean recall score'])
    result_table['C_parameter'] = c_param_range
    
    j = 0
    
    # 每次傳入一個懲罰力度蛀恩,進(jìn)行交叉驗證,輸出平均得分到懲罰力度表
    for c_param in c_param_range:
        print("- - "*20)
        print("第{}個參數(shù)值:".format(j),c_param)
        print("- - "*20)
        
        # 創(chuàng)建列表茂浮,接受每次交叉驗證效果得分
        recall_accs = []
        
        # 根據(jù)每次交叉驗證耍休,創(chuàng)建模型(即訓(xùn)練不同的訓(xùn)練集)
        for iteration, indices in enumerate(fold.split(x_train_data)):  # enumerate,返回序號和數(shù)據(jù)集
            # 創(chuàng)建邏輯回歸模型升略,傳入訓(xùn)練集
            lr = LogisticRegression(C = c_param, penalty = "l1",solver='liblinear')
            lr.fit(x_train_data.iloc[indices[0]], y_train_data.iloc[indices[0]].values)  #indices[0]是交叉驗證的訓(xùn)練集索引,這里是取對應(yīng)訓(xùn)練集數(shù)據(jù)
            
            # 進(jìn)行預(yù)測由缆,傳入驗證集
            y_predict_undersample = lr.predict(x_train_data.iloc[indices[1]].values) #indices[1]是交叉驗證的測試集索引
            
            # 返回每次模型的recall_score得分
            recall_acc = recall_score(y_train_data.iloc[indices[1]].values, y_predict_undersample)  #傳入測試集已知結(jié)果矩欠、預(yù)測結(jié)果
            # 將每次交叉驗證模型得分加入recall_accs列表
            recall_accs.append(recall_acc)
            print("第 {} 次遍歷,recall得分為:{}".format(iteration,recall_acc))
        
        # 將每次交叉驗證模型得分的平均分加入到不同正則化懲罰力度結(jié)果表中
        print("")
        avg_score = np.mean(recall_accs)
        print('該懲罰力度平均得分: ', avg_score)
        print(" - - - - 進(jìn)懲罰力度得分表- - - - -")
        result_table.iloc[j,1] = avg_score
        print(result_table)
        print('')
        j += 1
    
    # best_c 為不同懲罰力度效果表中幌羞,效果最好的懲罰力度
    result_table['Mean recall score'] = result_table['Mean recall score'].astype("float64") #修改列的類型寸谜,因為被強(qiáng)制改為了object類型
    best_c = result_table.iloc[result_table['Mean recall score'].idxmax()]['C_parameter']

    # 建模結(jié)束
    print("模型訓(xùn)練結(jié)束","* " * 30)
    print("效果最好的正則化懲罰力度為:",best_c)
    print("* " * 30)
    
    return best_c

運(yùn)行結(jié)果:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
第0個正則化參數(shù): 0.01
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
第 0 次遍歷,recall得分為:0.9846153846153847
第 1 次遍歷属桦,recall得分為:0.9846153846153847
第 2 次遍歷程帕,recall得分為:0.9367088607594937
第 3 次遍歷,recall得分為:0.9841269841269841
第 4 次遍歷地啰,recall得分為:0.9436619718309859

該懲罰力度平均得分:  0.9667457171896465
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
第1個正則化參數(shù): 0.1
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
第 0 次遍歷,recall得分為:0.9230769230769231
第 1 次遍歷讲逛,recall得分為:0.9230769230769231
第 2 次遍歷亏吝,recall得分為:0.8354430379746836
第 3 次遍歷,recall得分為:0.9365079365079365
第 4 次遍歷盏混,recall得分為:0.9154929577464789

該懲罰力度平均得分:  0.906719555676589
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
第2個正則化參數(shù): 1
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
第 0 次遍歷蔚鸥,recall得分為:0.9384615384615385
第 1 次遍歷,recall得分為:0.8769230769230769
第 2 次遍歷许赃,recall得分為:0.8607594936708861
第 3 次遍歷止喷,recall得分為:0.9365079365079365
第 4 次遍歷,recall得分為:0.9436619718309859

該懲罰力度平均得分:  0.9112628034788848
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
第3個正則化參數(shù): 10
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
第 0 次遍歷混聊,recall得分為:0.9538461538461539
第 1 次遍歷弹谁,recall得分為:0.8923076923076924
第 2 次遍歷,recall得分為:0.8481012658227848
第 3 次遍歷句喜,recall得分為:0.9365079365079365
第 4 次遍歷预愤,recall得分為:0.9436619718309859

該懲罰力度平均得分:  0.9148850040631107
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
第4個正則化參數(shù): 100
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
第 0 次遍歷,recall得分為:0.9538461538461539
第 1 次遍歷咳胃,recall得分為:0.8923076923076924
第 2 次遍歷植康,recall得分為:0.8354430379746836
第 3 次遍歷,recall得分為:0.9365079365079365
第 4 次遍歷展懈,recall得分為:0.9436619718309859

該懲罰力度平均得分:  0.9123533584934904
模型訓(xùn)練結(jié)束
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
效果最好的正則化懲罰力度為: 0.01
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  • 根據(jù)以上運(yùn)行結(jié)果销睁,選擇的正則化懲罰項為0.01

(2)使用下采樣數(shù)據(jù)進(jìn)行訓(xùn)練供璧,下采樣數(shù)據(jù)進(jìn)行測試
傳遞正則化懲罰項0.01,使用L1正則化方法冻记,同時繪制出混淆矩陣睡毒,計算模型評估指標(biāo)。

lr = LogisticRegression(C = best_c, penalty = "l1",solver='liblinear')
# 訓(xùn)練模型——傳遞下采樣后的訓(xùn)練集
lr.fit(x_train_undersample, y_train_undersample.values)
# 預(yù)測
y_pred_undersample = lr.predict(x_test_undersample)
# 繪制混淆矩陣  傳入?yún)?shù)為(真實值檩赢、預(yù)測值)
cnf_matrix = confusion_matrix(y_test_undersample,y_pred_undersample)
# 混淆矩陣圖形
print("混淆矩陣:\n",cnf_matrix,"\n")
# 設(shè)置浮點(diǎn)數(shù)為小數(shù)點(diǎn)后兩位
np.set_printoptions(precision=2)
# 輸出標(biāo)簽<1>召回率值(被召回的數(shù)目/數(shù)目總和)
print("標(biāo)簽<1>的召回率為:", str(round(cnf_matrix[1,1] / (cnf_matrix[1,1] + cnf_matrix[1,0]),4)*100) + '%')
print("標(biāo)簽<1>的精確率為:", str(round(cnf_matrix[1,1] / (cnf_matrix[1,1] + cnf_matrix[0,1]),4)*100) + '%')
# plot繪制
class_names = [0, 1]  # 分類:0吕嘀,1類別
plt.figure()
plot_confusion_matrix(cnf_matrix, classes=class_names, title = 'Confusion matrix')  #利用plot定義函數(shù)繪制
plt.show()

輸出結(jié)果:



召回率為93.28%,精確率為93.92%

(3)預(yù)測原始數(shù)據(jù)
使用以上訓(xùn)練出的結(jié)果贞瞒,對原始數(shù)據(jù)(未下采樣處理)進(jìn)行預(yù)測

lr = LogisticRegression(C = best_c, penalty = "l1",solver='liblinear')
# 訓(xùn)練模型——依然使用下采樣后的數(shù)據(jù)進(jìn)行訓(xùn)練
lr.fit(x_train_undersample, y_train_undersample.values)

# 預(yù)測模型——使用全體數(shù)據(jù)預(yù)測
y_pred = lr.predict(x_test)

# 創(chuàng)建混淆矩陣
cnf_matrix = confusion_matrix(y_test,y_pred)
print("標(biāo)簽<1>的召回率為:", str(round(cnf_matrix[1,1] / (cnf_matrix[1,1] + cnf_matrix[1,0]),4)*100) + '%')
print("標(biāo)簽<1>的精確率為:", str(round(cnf_matrix[1,1] / (cnf_matrix[1,1] + cnf_matrix[0,1]),4)*100) + '%')

結(jié)果

召回率93.2%偶房,精確率1.84%,該模型存在較大的誤差率军浆,準(zhǔn)確度很低
(4)不同閾值對結(jié)果的影響
在邏輯回歸中棕洋,lr.predict_proba返回的時分類概率,我們可以調(diào)整閾值(默認(rèn)為0.5乒融,即大于0.5為對應(yīng)的分類)掰盘,得到不同的精確率和召回率

# 得到預(yù)測分類概率
y_pred_undersample_proba = lr.predict_proba(x_test_undersample)
# 閾值列表
thresholds = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
plt.figure(figsize=(12,12))

j = 1
for i in thresholds:
    # 
    y_test_predictions_high_recall = y_pred_undersample_proba[:,1] > i
    
    # 創(chuàng)建相應(yīng)子圖
    plt.subplot(3,3,j)
    j += 1
    
    # 創(chuàng)建混淆矩陣   (預(yù)測數(shù)據(jù)的真實值,預(yù)測值)
    cnf_matrix = confusion_matrix(y_test_undersample,y_test_predictions_high_recall)  
    np.set_printoptions(precision=2)
    print("當(dāng)閾值設(shè)置為 {} 時:".format(i))
    print(" ")
    # 正確率
    precession = cnf_matrix[1,1] / (cnf_matrix[1,1] + cnf_matrix[1,0])
    # 召回率
    recall = cnf_matrix[1,1] / (cnf_matrix[1,1] + cnf_matrix[0,1])
    # F1值 2*(正確率*召回率)/(正確率+召回率)
    f1 = 2*(precession*recall)/(precession+recall)
    
    print("標(biāo)簽<1>的召回率為:", str(round(cnf_matrix[1,1] / (cnf_matrix[1,1] + cnf_matrix[1,0]),4)*100) + '%')
    print("標(biāo)簽<1>的精確率為:", str(round(cnf_matrix[1,1] / (cnf_matrix[1,1] + cnf_matrix[0,1]),4)*100) + '%')
    print("* * * * * *F1值為:",str(round(f1,4) * 100) + '%')
    print("- " * 40)

    # 繪制plot混淆矩陣圖
    class_names = [0,1]
    plot_confusion_matrix(cnf_matrix, classes=class_names, title='Threshold >= %s'%i) 

結(jié)果:

當(dāng)閾值設(shè)置為 0.1 時:
標(biāo)簽<1>的召回率為: 100.0%
標(biāo)簽<1>的精確率為: 50.339999999999996%
* * * * * *F1值為: 66.97%
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
當(dāng)閾值設(shè)置為 0.2 時:
標(biāo)簽<1>的召回率為: 100.0%
標(biāo)簽<1>的精確率為: 50.339999999999996%
* * * * * *F1值為: 66.97%
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
當(dāng)閾值設(shè)置為 0.3 時:
標(biāo)簽<1>的召回率為: 100.0%
標(biāo)簽<1>的精確率為: 50.339999999999996%
* * * * * *F1值為: 66.97%
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
當(dāng)閾值設(shè)置為 0.4 時:
標(biāo)簽<1>的召回率為: 99.33%
標(biāo)簽<1>的精確率為: 60.660000000000004%
* * * * * *F1值為: 75.32%
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
當(dāng)閾值設(shè)置為 0.5 時:
標(biāo)簽<1>的召回率為: 93.28999999999999%
標(biāo)簽<1>的精確率為: 93.92%
* * * * * *F1值為: 93.60000000000001%
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
當(dāng)閾值設(shè)置為 0.6 時:
標(biāo)簽<1>的召回率為: 85.22999999999999%
標(biāo)簽<1>的精確率為: 99.22%
* * * * * *F1值為: 91.7%
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
當(dāng)閾值設(shè)置為 0.7 時:
標(biāo)簽<1>的召回率為: 84.56%
標(biāo)簽<1>的精確率為: 100.0%
* * * * * *F1值為: 91.64%
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
當(dāng)閾值設(shè)置為 0.8 時:
標(biāo)簽<1>的召回率為: 73.83%
標(biāo)簽<1>的精確率為: 100.0%
* * * * * *F1值為: 84.94%
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
當(dāng)閾值設(shè)置為 0.9 時:
標(biāo)簽<1>的召回率為: 51.68000000000001%
標(biāo)簽<1>的精確率為: 100.0%
* * * * * *F1值為: 68.14%
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
混淆矩陣
  • 當(dāng)閾值選擇0.6時赞季,精確率為99.22%大于95%愧捕,召回率為85.22%為最高,滿足條件

(5)比較:使用原始數(shù)據(jù)訓(xùn)練模型及預(yù)測
這里我們使用原始數(shù)據(jù)對模型進(jìn)行訓(xùn)練申钩,對比使用下采樣的預(yù)測結(jié)果

best_c = printing_Kfold_scores(x_train,y_train)
  • 得到最佳懲罰項為10
    預(yù)測全體數(shù)據(jù):
lr = LogisticRegression(C = best_c, penalty = "l1",solver='liblinear')
# 訓(xùn)練模型——使用原始數(shù)據(jù)進(jìn)行訓(xùn)練
lr.fit(x_train, y_train.values)

# 預(yù)測模型——使用全體數(shù)據(jù)預(yù)測
y_pred = lr.predict(x_test)

# 創(chuàng)建混淆矩陣
cnf_matrix = confusion_matrix(y_test,y_pred)
print("標(biāo)簽<1>的召回率為:", str(round(cnf_matrix[1,1] / (cnf_matrix[1,1] + cnf_matrix[1,0]),4)*100) + '%')
print("標(biāo)簽<1>的精確率為:", str(round(cnf_matrix[1,1] / (cnf_matrix[1,1] + cnf_matrix[0,1]),4)*100) + '%')

# plot
class_names = [0, 1]  # 分類:0次绘,1類別
plt.figure()
plot_confusion_matrix(cnf_matrix, classes=class_names, title = 'Confusion matrix')  #利用plot定義函數(shù)繪制
plt.show()
結(jié)果

召回率為61.9%,精確率為88.35,%,評估指標(biāo)均不如下采樣訓(xùn)練結(jié)果撒遣,因此對于不平衡數(shù)據(jù)需要進(jìn)行平衡處理邮偎。

四、總結(jié)

  • 通過K折交叉驗證方法义黎,計算得到最佳正則化懲罰項為0.01禾进。
  • 在創(chuàng)建模型過程中,使用下采樣方法廉涕,根據(jù)需求將閾值調(diào)整到0.6時泻云,得到的召回率為85.22%,精確率為99.22%狐蜕,F(xiàn)1值為91.7%壶愤,為符合初衷要求的最優(yōu)模型。
  • 通過對比馏鹤,使用原始數(shù)據(jù)進(jìn)行訓(xùn)練模型征椒,召回率僅為61.9%,精確率為88.35%湃累,存在較大的誤差率以及召回程度很低勃救,因此使用對于不平衡的數(shù)據(jù)碍讨,我們需要進(jìn)行下采樣或過采樣處理。
  • 后續(xù)可以根據(jù)不同的業(yè)務(wù)需求蒙秒,調(diào)整閾值得到不同的召回率和精確率勃黍。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市晕讲,隨后出現(xiàn)的幾起案子覆获,更是在濱河造成了極大的恐慌,老刑警劉巖瓢省,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弄息,死亡現(xiàn)場離奇詭異,居然都是意外死亡勤婚,警方通過查閱死者的電腦和手機(jī)摹量,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來馒胆,“玉大人缨称,你說我怎么就攤上這事∽S兀” “怎么了睦尽?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長型雳。 經(jīng)常有香客問我骂删,道長,這世上最難降的妖魔是什么四啰? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮粗恢,結(jié)果婚禮上柑晒,老公的妹妹穿的比我還像新娘。我一直安慰自己眷射,他們只是感情好匙赞,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著妖碉,像睡著了一般涌庭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上欧宜,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天坐榆,我揣著相機(jī)與錄音,去河邊找鬼冗茸。 笑死席镀,一個胖子當(dāng)著我的面吹牛匹中,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播豪诲,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼顶捷,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了屎篱?” 一聲冷哼從身側(cè)響起服赎,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎交播,沒想到半個月后重虑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡堪侯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年嚎尤,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伍宦。...
    茶點(diǎn)故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡芽死,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出次洼,到底是詐尸還是另有隱情关贵,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布卖毁,位于F島的核電站揖曾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏亥啦。R本人自食惡果不足惜炭剪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望翔脱。 院中可真熱鬧奴拦,春花似錦、人聲如沸届吁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疚沐。三九已至暂氯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間亮蛔,已是汗流浹背痴施。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人晾剖。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓锉矢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親齿尽。 傳聞我的和親對象是個殘疾皇子沽损,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評論 2 359