SVM_信用卡欺詐

概述

初衷是因爲引用卡欺詐問題相對與其他機器學習問題略有不同,因爲二分類數據量差距過大,導致以往的評價方法對其不適用,如下圖的284807 筆交易中只有492筆是欺詐行爲,如果用以爲的準確率評價幾乎都在99%以上,但是這並不能說明模型好,因爲即使漏掉1個欺詐交易都是損失很大的,所以這篇裏引入了召回率和精確率,進行綜合評價,詳細步驟如下:

  • 對數據源中不比較的字段進行刪減,對數值型數據進行規範化,因爲沒有測試集數據,所以進行數據劃分。
  • 數據建模使用的是LinearSVR,因爲LinearSVC 對線性分類做了優化,對於數據量大的線性可分問題,使用 LinearSVC 的效率要高於 SVC。這裏我們是假設特徵是線性可分的(線性可分就可以理解成用一條線能把兩個類別分開),當然也可以使用邏輯迴歸、決策樹、或者是把核函數設置爲rbf(高斯核函數)進行嘗試。

實現過程

SVM介紹

model = svm.SVC(kernel=‘rbf’, C=1.0, gamma=‘auto’) 

kernel代表核函數的選擇,它有四種選擇,只不過默認是 rbf,即高斯核函數。linear:線性核函數poly:多項式核函數rbf:高斯核函數(默認)sigmoid:sigmoid 核函數這四種函數代表不同的映射方式。

此外引用一位知乎題主的回答,我覺得比較實用:
作者:Jason Gu
鏈接:https://www.zhihu.com/question/21883548/answer/19693213

  1. Linear核:主要用於線性可分的情形。參數少,速度快,對於一般數據,分類效果已經很理想了。
  2. RBF核:主要用於線性不可分的情形。參數多,分類結果非常依賴於參數。有很多人是通過訓練數據的交叉驗證來尋找合適的參數,不過這個過程比較耗時。我個人的體會是:使用libsvm,默認參數,RBF核比Linear核效果稍差。通過進行大量參數的嘗試,一般能找到比linear核更好的效果。至於到底該採用哪種核,要根據具體問題,有的數據是線性可分的,有的不可分,需要多嘗試不同核不同參數。如果特徵的提取的好,包含的信息量足夠大,很多問題都是線性可分的。當然,如果有足夠的時間去尋找RBF核參數,應該能達到更好的效果。

此外,sigmoid一般用於處理神經網絡,pold雖然可以處理非線性問題,但是訓練時間比較長。

數據源下載

數據源
鏈接:https://pan.baidu.com/s/14F8WuX0ZJntdB_r1EC08HA 提取碼:58gp

說明:Class=0 爲正常(非欺詐),Class=1 代表欺詐。

代碼實現

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn import svm
from sklearn.metrics import confusion_matrix, precision_recall_curve
import warnings
import itertools
warnings.filterwarnings('ignore')

# 混淆矩陣可視化
def plot_confusion_matrix(cm, classes, normalize = False, title = 'Confusion matrix"', cmap = plt.cm.Blues) :
    plt.figure()
    plt.imshow(cm, interpolation = 'nearest', cmap = cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation = 0)
    plt.yticks(tick_marks, classes)
 
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])) :
        plt.text(j, i, cm[i, j],
                 horizontalalignment = 'center',
                 color = 'white' if cm[i, j] > thresh else 'black')
 
    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    plt.show()

# 顯示模型評估結果
def show_metrics():
    tp = cm[1,1]
    fn = cm[1,0]
    fp = cm[0,1]
    tn = cm[0,0]
    print('精確率: {:.3f}'.format(tp/(tp+fp)))
    print('召回率: {:.3f}'.format(tp/(tp+fn)))
    print('F1值: {:.3f}'.format(2*(((tp/(tp+fp))*(tp/(tp+fn)))/((tp/(tp+fp))+(tp/(tp+fn))))))

# 繪製精確率-召回率曲線
def plot_precision_recall():
    plt.step(recall, precision, color = 'b', alpha = 0.2, where = 'post')
    plt.fill_between(recall, precision, step ='post', alpha = 0.2, color = 'b')
    plt.plot(recall, precision, linewidth=2)
    plt.xlim([0.0,1])
    plt.ylim([0.0,1.05])
    plt.xlabel('召回率')
    plt.ylabel('精確率')
    plt.title('精確率-召回率 曲線')
    plt.show();
     
data = pd.read_csv('./creditcard.csv')
data['Amount_Norm'] = StandardScaler().fit_transform(data['Amount'].values.reshape(-1,1))
y = np.array(data.Class.tolist())
data = data.drop(['Time','Amount','Class'],axis=1)
X = np.array(data.as_matrix())#DataFrame的形式,這個時候要記得轉換成數組
train_x, test_x, train_y, test_y = train_test_split (X, y, test_size = 0.1, random_state = 33)
#創建SVM模型
model = svm.LinearSVC()
model.fit(train_x,train_y)
prediction=model.predict(test_x)
cm = confusion_matrix(test_y, prediction)
show_metrics()
# 設置plt正確顯示中文
plt.rcParams['font.sans-serif'] = ['SimHei']
# 繪製類別分佈

class_names = [0,1]
# 顯示混淆矩陣
plot_confusion_matrix(cm, classes = class_names, title = '邏輯迴歸 混淆矩陣')

score_y = model.decision_function(test_x)
precision, recall, thresholds = precision_recall_curve(test_y, score_y)
plot_precision_recall()

結果:
精確率: 0.843
召回率: 0.717
F1值: 0.775
在這裏插入圖片描述
在這裏插入圖片描述

代碼解釋

  1. 可以把混淆矩陣理解成對測試集做預測後給的一個反饋,有4種可能:
    tp:判斷是,結果對;
    tn:判斷是,結果錯
    fn:判斷不是,結果錯;
    fp:判斷不是,結果對
  2. 精確率: P = TP/ (TP+FP),你可以理解成預測欺詐的準確率,預測成功的所有情況中,欺詐的情況佔多大的比例
  3. 召回率 R = TP/ (TP+FN),也稱爲查全率。就是所有的欺詐情況中,你查出來的佔多少
  4. plot_precision_recall用於測試精確率和召回率的一個動態關係,可以看到兩者成反比,一般召回率越高,精確率越低,比如你認爲所有的交易都是欺詐交易,那麼召回率可以達到100%,但是準確率就會很低。

總結

信用卡欺詐問題總體來說是一個二分類問題,其特點在於類別數據比差距過大,評價指標不能僅使用metrics.accuracy_score(prediction,test_y))。建模實現分類的方法有很多,以及各個模型下還有參數調整情況,可以嘗試使用弱分類器組成Adaboost、還有將隨機森林與GridSearchCV結合找出最優解,可以下次寫一下實現方法,邏輯迴歸也是一個比較實用的方法但是經測試訓練時間較快,但是效果略差於SVM。

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