做網(wǎng)站主流軟件是php嗎什么是淘寶seo
文章目錄
- 引言
- 數(shù)據(jù)集
- 分析
- 1. 讀入數(shù)據(jù)并快速瀏覽
- 2.計算欺詐交易占數(shù)據(jù)集中交易總數(shù)的百分比
- 3. 類別不平衡對模型的影響
- 3.1 總體思路
- (1)數(shù)據(jù)的劃分
- (2)訓(xùn)練模型
- (3)測試模型
- (4)解決不平衡問題
- 3.2 為什么要解決不平衡問題
- 4. 處理不平衡數(shù)據(jù)集
- 5. 訓(xùn)練和評估模型
- 5.1 回到原始數(shù)據(jù),制定規(guī)則
- 5.1.1 代碼
- 5.1.2 結(jié)果分析
- 混淆矩陣
- 分類報告
- 結(jié)論
- 5.2 邏輯回歸模型(未使用SMOTE)和邏輯回歸模型(使用SMOTE)
- 代碼及結(jié)果
- 混淆矩陣
- 分類報告
- 6. 進一步
- 7. 隨機森林模型
- 8. 模型應(yīng)用
- 誤報處理
- 漏報處理
引言
數(shù)據(jù)分析在銀行中的應(yīng)用有如下:
投資風(fēng)險分析
客戶終身價值預(yù)測
客戶細分
客戶流失率預(yù)測
個性化營銷
客戶情緒分析
虛擬助理和聊天機器人
……
這里是一個常見的數(shù)據(jù)分析用例
欺詐檢測是為識別和防止欺詐活動以及財務(wù)損失而采取的一種主動措施
一般的做法有:
- 統(tǒng)計學(xué):統(tǒng)計參數(shù)計算、回歸、概率分布、數(shù)據(jù)匹配;
- 人工智能:數(shù)據(jù)挖掘、機器學(xué)習(xí)、深度學(xué)習(xí)
機器學(xué)習(xí)是欺詐檢測的重要支柱,其工具包提供了兩種方法:
- 監(jiān)督方法:K-近鄰、邏輯回歸、支持向量機、決策樹、隨機森林、時間序列分析、神經(jīng)網(wǎng)絡(luò)等。
- 無監(jiān)督方法:聚類分析、鏈接分析、自組織地圖、主成分分析、異常識別等。
目前沒有通用的機器學(xué)習(xí)算法用于欺詐檢測。相反,對于現(xiàn)實世界的數(shù)據(jù)科學(xué)用例,通常會選擇幾種方法,通過測試比較,選擇最佳的。
數(shù)據(jù)集
Credit Card Fraud Detection | Kaggle數(shù)據(jù)集:
https://www.kaggle.com/mlg-ulb/creditcardfraud
該數(shù)據(jù)集是Kaggle信用卡欺詐檢測數(shù)據(jù)集的一個修改樣本,持卡人擁有信用卡的交易情況
下載以后保存在Jupyter notebook默認目錄下
分析
1. 讀入數(shù)據(jù)并快速瀏覽
import pandas as pdcreditcard_data = pd.read_csv('creditcard.csv', index_col=0)
print(creditcard_data.info())
print('\n')
pd.options.display.max_columns = len(creditcard_data)
print(creditcard_data.head(3))
結(jié)果如下:
<class 'pandas.core.frame.DataFrame'>
Index: 284807 entries, 0.0 to 172792.0
Data columns (total 30 columns):# Column Non-Null Count Dtype
--- ------ -------------- ----- 0 V1 284807 non-null float641 V2 284807 non-null float642 V3 284807 non-null float643 V4 284807 non-null float644 V5 284807 non-null float645 V6 284807 non-null float646 V7 284807 non-null float647 V8 284807 non-null float648 V9 284807 non-null float649 V10 284807 non-null float6410 V11 284807 non-null float6411 V12 284807 non-null float6412 V13 284807 non-null float6413 V14 284807 non-null float6414 V15 284807 non-null float6415 V16 284807 non-null float6416 V17 284807 non-null float6417 V18 284807 non-null float6418 V19 284807 non-null float6419 V20 284807 non-null float6420 V21 284807 non-null float6421 V22 284807 non-null float6422 V23 284807 non-null float6423 V24 284807 non-null float6424 V25 284807 non-null float6425 V26 284807 non-null float6426 V27 284807 non-null float6427 V28 284807 non-null float6428 Amount 284807 non-null float6429 Class 284807 non-null int64
dtypes: float64(29), int64(1)
memory usage: 67.4 MB
NoneV1 V2 V3 V4 V5 V6 V7 \
Time
0.0 -1.359807 -0.072781 2.536347 1.378155 -0.338321 0.462388 0.239599
0.0 1.191857 0.266151 0.166480 0.448154 0.060018 -0.082361 -0.078803
1.0 -1.358354 -1.340163 1.773209 0.379780 -0.503198 1.800499 0.791461 V8 V9 V10 V11 V12 V13 V14 \
Time
0.0 0.098698 0.363787 0.090794 -0.551600 -0.617801 -0.991390 -0.311169
0.0 0.085102 -0.255425 -0.166974 1.612727 1.065235 0.489095 -0.143772
1.0 0.247676 -1.514654 0.207643 0.624501 0.066084 0.717293 -0.165946 V15 V16 V17 V18 V19 V20 V21 \
Time
0.0 1.468177 -0.470401 0.207971 0.025791 0.403993 0.251412 -0.018307
0.0 0.635558 0.463917 -0.114805 -0.183361 -0.145783 -0.069083 -0.225775
1.0 2.345865 -2.890083 1.109969 -0.121359 -2.261857 0.524980 0.247998 V22 V23 V24 V25 V26 V27 V28 \
Time
0.0 0.277838 -0.110474 0.066928 0.128539 -0.189115 0.133558 -0.021053
0.0 -0.638672 0.101288 -0.339846 0.167170 0.125895 -0.008983 0.014724
1.0 0.771679 0.909412 -0.689281 -0.327642 -0.139097 -0.055353 -0.059752 Amount Class
Time
0.0 149.62 0
0.0 2.69 0
1.0 378.66 0
這個數(shù)據(jù)集共有284807條記錄。
數(shù)據(jù)集包含30個列,其中29個列是float64類型(浮點數(shù)),1個列是int64類型(整數(shù))。
每一列的數(shù)據(jù)都是非空的(沒有缺失值)。
通過creditcard_data.head(3),我們查看數(shù)據(jù)集的前3行:
Time:表示交易時間。
V1 到 V28:這些是經(jīng)過PCA(主成分分析)轉(zhuǎn)換后的特征
Amount:表示交易金額。
Class:目標(biāo)變量,表示交易是否為欺詐(1表示欺詐,0表示正常)。
數(shù)據(jù)集非常大且沒有缺失值,適合進行機器學(xué)習(xí)模型的訓(xùn)練。
通過初步的瀏覽,我們對數(shù)據(jù)有了一個基本的了解,可以進一步進行數(shù)據(jù)分析和建模工作。
2.計算欺詐交易占數(shù)據(jù)集中交易總數(shù)的百分比
# 計算欺詐交易數(shù)量
fraud_count = creditcard_data[creditcard_data['Class'] == 1].shape[0]
# 計算總交易數(shù)量
total_count = creditcard_data.shape[0]
# 計算百分比
fraud_percentage = (fraud_count / total_count) * 100
# 打印結(jié)果
print(f'欺詐交易占總交易數(shù)的百分比: {fraud_percentage:.2f}%')
結(jié)果如下:
使用條件篩選creditcard_data[creditcard_data[‘Class’] == 1]獲取所有標(biāo)記為欺詐交易的數(shù)據(jù),然后使用shape[0]計算行數(shù)(即欺詐交易的數(shù)量)。
欺詐案件總歸占少數(shù),隱藏在真實的交易中。
創(chuàng)建一個圖表,將欺詐與非欺詐的數(shù)據(jù)點可視化
import matplotlib.pyplot as plt
import numpy as np# prep_data(df)從數(shù)據(jù)集中提取特征和標(biāo)簽
def prep_data(df):X = df.iloc[:, 1:28] #選擇第1列到第28列的數(shù)據(jù)作為特征X = np.array(X).astype(float) #將數(shù)據(jù)框轉(zhuǎn)換為numpy數(shù)組,并將數(shù)據(jù)類型轉(zhuǎn)換為float(浮點數(shù))y = df.iloc[:, 29] #選擇第29列的數(shù)據(jù)作為標(biāo)簽(目標(biāo)變量)(1表示欺詐,0表示正常)y = np.array(y).astype(float) #標(biāo)簽轉(zhuǎn)換為numpy數(shù)組return X, ydef plot_data(X, y):plt.scatter(X[y==0, 0], X[y==0, 1], label='Class #0', alpha=0.5, linewidth=0.15)plt.scatter(X[y==1, 0], X[y==1, 1], label='Class #1', alpha=0.5, linewidth=0.15, c='r')plt.legend()return plt.show()X, y = prep_data(creditcard_data)plot_data(X, y)
結(jié)果如下:
欺詐性交易的比例非常低,類別不平衡
3. 類別不平衡對模型的影響
3.1 總體思路
數(shù)據(jù)集是信用卡交易記錄,我們想通過這個數(shù)據(jù)找出哪些交易是欺詐行為,哪些是正常的交易。
我們希望建立一個聰明的模型,幫助我們準(zhǔn)確地識別哪些交易是欺詐行為。
可以分為幾個簡單的步驟:
(1)數(shù)據(jù)的劃分
首先,我們把數(shù)據(jù)分成兩部分:一部分用于訓(xùn)練模型,另一部分用于測試模型。打個比方,用歷年真題來學(xué)習(xí),用今年的考試題來測試學(xué)習(xí)效果。
(2)訓(xùn)練模型
這里我們打算使用“邏輯回歸”的數(shù)學(xué)方法來訓(xùn)練我們的模型。讓這個模型會學(xué)到哪些交易看起來像是欺詐,哪些交易看起來是正常的。
(3)測試模型
訓(xùn)練好模型后,用測試數(shù)據(jù)來檢查模型的表現(xiàn)。我們會得到一個結(jié)果表,顯示模型預(yù)測的和實際的結(jié)果對比。比如,模型認為某些交易是欺詐,但實際上它們不是;或者模型認為某些交易是正常的,但實際上它們是欺詐。
(4)解決不平衡問題
我們的數(shù)據(jù)里,正常交易很多,欺詐交易很少。為了讓模型更好地識別欺詐交易,我們使用了一種叫做SMOTE的方法。這個方法會“制造”一些假的欺詐交易,讓數(shù)據(jù)看起來更平衡,就像我們在班級里增加一些假人,讓男女比例更均勻。
也就是說用 SMOTE 來重新平衡數(shù)據(jù),它不只是創(chuàng)建觀察值的精確副本,而是使用欺詐交易的最近鄰居的特征來創(chuàng)建新的、合成的樣本,這些樣本與少數(shù)人類別中的現(xiàn)有觀察值相當(dāng)相似
3.2 為什么要解決不平衡問題
在訓(xùn)練模型時,希望模型能更好地學(xué)習(xí)到如何識別每一類數(shù)據(jù)。
如果數(shù)據(jù)非常不平衡,比如正常交易很多,欺詐交易很少,模型會傾向于只學(xué)習(xí)正常交易,而忽略了欺詐交易。
打個比方,假設(shè)你在班級里玩一個游戲,老師給你看10張卡片,其中9張是蘋果,1張是橙子。然后老師讓你猜下一張卡片是什么。你很可能會猜是蘋果,因為蘋果的卡片太多了。如果這個時候老師給你多一些橙子的卡片,比如讓你看到5張?zhí)O果和5張橙子,那么你在猜下一張卡片時,就會更認真地考慮兩種可能性。
對于模型來說也是這樣,如果我們的數(shù)據(jù)里正常交易很多,欺詐交易很少,模型在訓(xùn)練過程中會主要學(xué)習(xí)到正常交易的特征,而不會很好地學(xué)習(xí)到欺詐交易的特征。
結(jié)果就是模型會更傾向于預(yù)測所有的交易都是正常的,
解決方法——讓數(shù)據(jù)平衡:
為了讓模型更好地學(xué)習(xí)到兩類交易的特征,我們可以使用一些技術(shù)手段,比如SMOTE。這種方法會“制造”一些假的欺詐交易,讓數(shù)據(jù)看起來更平衡。
這樣模型在訓(xùn)練過程中會看到更多的欺詐交易,更好地理解每一類數(shù)據(jù)的特征,從而更準(zhǔn)確地識別出欺詐交易
這樣,在預(yù)測時就會更準(zhǔn)確地判斷哪些交易是正常的,哪些是欺詐的。
就像你在玩卡片游戲時,看到的蘋果和橙子數(shù)量差不多,你在猜下一張卡片時就會更準(zhǔn)確一樣。
4. 處理不平衡數(shù)據(jù)集
讓我們把SMOTE應(yīng)用于該信用卡數(shù)據(jù),提供了更多的少數(shù)類別的觀察結(jié)果
SMOTE首先識別數(shù)據(jù)集中屬于少數(shù)類的樣本。
對于每個少數(shù)類樣本,SMOTE會在其最近鄰樣本中隨機選擇一個樣本。
在這兩個樣本之間隨機插值,生成一個新的合成樣本。
通過上述步驟生成足夠多的合成樣本,使得少數(shù)類樣本數(shù)量與多數(shù)類樣本數(shù)量接近或相等。
from imblearn.over_sampling import SMOTE# 實例化SMOTE對象
method = SMOTE()# 對數(shù)據(jù)進行過采樣
X_resampled, y_resampled = method.fit_resample(X, y)# 可視化過采樣后的數(shù)據(jù)
plot_data(X_resampled, y_resampled)# 打印過采樣前后的記錄數(shù)量
print(f'原始數(shù)據(jù)集記錄數(shù)量: {X.shape[0]}')
print(f'過采樣后數(shù)據(jù)集記錄數(shù)量: {X_resampled.shape[0]}')# 打印過采樣前后的類別分布
print(f'原始數(shù)據(jù)集類別分布:\n{pd.Series(y).value_counts()}')
print(f'過采樣后數(shù)據(jù)集類別分布:\n{pd.Series(y_resampled).value_counts()}')
結(jié)果如下:
原始數(shù)據(jù)集有284807條記錄,其中284315條是正常交易(類別0),492條是欺詐交易(類別1)。
過采樣后數(shù)據(jù)集有568630條記錄,其中正常交易仍然是284315條,但欺詐交易增加到了284315條,使得類別更加平衡。
為了更好地看到這種方法的結(jié)果,這里將其與原始數(shù)據(jù)進行比較:
def compare_plot(X, y, X_resampled, y_resampled, method):f, (ax1, ax2) = plt.subplots(1, 2)c0 = ax1.scatter(X[y==0, 0], X[y==0, 1], label='Class #0',alpha=0.5)c1 = ax1.scatter(X[y==1, 0], X[y==1, 1], label='Class #1',alpha=0.5, c='r')ax1.set_title('Original set')ax2.scatter(X_resampled[y_resampled==0, 0], X_resampled[y_resampled==0, 1], label='Class #0', alpha=.5)ax2.scatter(X_resampled[y_resampled==1, 0], X_resampled[y_resampled==1, 1], label='Class #1', alpha=.5,c='r')ax2.set_title(method)plt.figlegend((c0, c1), ('Class #0', 'Class #1'), loc='lower center', ncol=2, labelspacing=0.)plt.tight_layout(pad=3)return plt.show()print(f'Original set:\n'f'{pd.Series(y).value_counts()}\n\n'f'SMOTE:\n'f'{pd.Series(y_resampled).value_counts()}\n')compare_plot(X, y, X_resampled, y_resampled, method='SMOTE')
結(jié)果如下:
原始數(shù)據(jù)集類別分布:
0.0 284315
1.0 492
Name: count, dtype: int64
過采樣后數(shù)據(jù)集類別分布:
0.0 284315
1.0 284315
Name: count, dtype: int64
SMOTE方法平衡了數(shù)據(jù),少數(shù)群體現(xiàn)在與多數(shù)群體的規(guī)模相等
5. 訓(xùn)練和評估模型
在平衡了數(shù)據(jù)集之后,下一步訓(xùn)練和評估機器學(xué)習(xí)模型,以確保模型能夠更準(zhǔn)確地識別少數(shù)類(這里是欺詐交易)
這里用兩種方法作對比:制定規(guī)則來識別欺詐交易,用機器學(xué)習(xí)模型來識別欺詐交易
5.1 回到原始數(shù)據(jù),制定規(guī)則
基于原始數(shù)據(jù),制定一些規(guī)則來識別欺詐行為,
基于對數(shù)據(jù)的觀察和分析,定義一些特定的閾值來檢測異常交易
例如,可以根據(jù)特征的平均值和標(biāo)準(zhǔn)差來設(shè)置閾值。
計算特征均值:
使用creditcard_data.groupby(‘Class’).mean().round(3)[[‘V1’, ‘V3’]]來計算特征V1和V3在不同類別(正常交易和欺詐交易)中的平均值。
print(creditcard_data.groupby('Class').mean().round(3)[['V1', 'V3']])
結(jié)果為:
從輸出可以看到,正常交易(Class 0)和欺詐交易(Class 1)在特征V1和V3上的平均值有顯著差異。
對于正常交易(Class 0),特征V1和V3的平均值分別是0.008和0.012。
對于欺詐交易(Class 1),特征V1和V3的平均值分別是-4.772和-7.033。
這表明,欺詐交易的這兩個特征值明顯低于正常交易。
例如,可以制定一個規(guī)則:
如果交易的V1值小于-3并且V3值小于-5,則認為該交易是欺詐行為。
這是因為在欺詐交易中,V1和V3的平均值都顯著低于正常交易。
為了評估這種方法的性能,我們將把標(biāo)記的欺詐案例與實際案例進行比較
5.1.1 代碼
定義規(guī)則:如果交易的V1值小于-3并且V3值小于-5,則認為該交易是欺詐行為。
使用該規(guī)則標(biāo)記數(shù)據(jù)集中每一條交易是否為欺詐。
import pandas as pd# 讀取數(shù)據(jù)集
creditcard_data = pd.read_csv('creditcard.csv', index_col=0)# 計算特征均值
mean_values = creditcard_data.groupby('Class').mean().round(3)[['V1', 'V3']]
print(mean_values)# 制定規(guī)則:V1 < -3 和 V3 < -5
def rule_based_detection(row):if row['V1'] < -3 and row['V3'] < -5:return 1 # 標(biāo)記為欺詐else:return 0 # 標(biāo)記為正常# 應(yīng)用規(guī)則
creditcard_data['Predicted_Class'] = creditcard_data.apply(rule_based_detection, axis=1)# 計算混淆矩陣和分類報告
from sklearn.metrics import confusion_matrix, classification_reporty_true = creditcard_data['Class']
y_pred = creditcard_data['Predicted_Class']print("Confusion Matrix:")
print(confusion_matrix(y_true, y_pred))
print("\nClassification Report:")
print(classification_report(y_true, y_pred))
運行結(jié)果為
5.1.2 結(jié)果分析
計算混淆矩陣和分類報告
計算實際標(biāo)簽(Class)和預(yù)測標(biāo)簽(Predicted_Class)之間的混淆矩陣和分類報告,評估規(guī)則的性能。
混淆矩陣
Confusion Matrix:
[[283089 1226]
[ 322 170]]
283089個正常交易被正確分類為正常交易(真陰性)。
1226個正常交易被錯誤分類為欺詐交易(假陽性)。
322個欺詐交易被錯誤分類為正常交易(假陰性)。
170個欺詐交易被正確分類為欺詐交易(真陽性)。
分類報告
Precision(精確率):
類0(正常交易):精確率是1.00,表示所有被預(yù)測為正常交易的樣本中,實際是正常交易的比例是100%。
換句話說,模型對正常交易的預(yù)測非常準(zhǔn)確,沒有將正常交易誤判為欺詐交易。
類1(欺詐交易):精確率是0.12,表示所有被預(yù)測為欺詐交易的樣本中,實際是欺詐交易的比例是12%。
這意味著在所有被標(biāo)記為欺詐交易的樣本中,只有12%是真正的欺詐交易,正常交易很大可能被誤識別為欺詐交易。
Recall(召回率):
類0(正常交易):召回率是1.00,表示所有實際為正常交易的樣本中,正確被預(yù)測為正常交易的比例是100%。
模型能夠識別出所有的正常交易,沒有漏掉任何正常交易。
類1(欺詐交易):召回率是0.35,表示所有實際為欺詐交易的樣本中,正確被預(yù)測為欺詐交易的比例是35%。
在所有實際的欺詐交易中,只有35%被模型正確識別為欺詐交易,其余65%被誤識別為正常交易。也就是說,很多欺詐交易會被誤識別為正常交易。
打個比方:
假設(shè)有100個樣本,模型預(yù)測有20個是欺詐交易(類1),但實際上只有2個是欺詐交易,其余18個是正常交易。模型預(yù)測80個是正常交易(類0),其中實際有78個是正常交易,其余2個是欺詐交易。
精確率(類1):
預(yù)測為欺詐的20個樣本中,只有2個是實際欺詐,所以精確率 = 2/20 = 0.10。
召回率(類1):
實際為欺詐的4個樣本中,只有2個被正確識別,所以召回率 = 2/4 = 0.50。
F1-score:
類0(正常交易):F1-score是1.00,是精確率和召回率的調(diào)和平均數(shù)。
類1(欺詐交易):F1-score是0.18,表示模型對欺詐交易的分類效果較差。
F1-score 同時考慮了精確率和召回率兩個方面,是精確率(Precision)和召回率(Recall)的調(diào)和平均數(shù),用來衡量模型在分類任務(wù)中的性能。F1-score 適用于不平衡數(shù)據(jù)集。
F1-score = 2 × Precision × Recall Precision + Recall \text{F1-score} = 2 \times \frac{\text{Precision} \times \text{Recall}}{\text{Precision} + \text{Recall}} F1-score=2×Precision+RecallPrecision×Recall?
類0(正常交易):
精確率(Precision) 和 召回率(Recall) 都是1.00。 因此,F1-score 也是1.00。
這表明模型對正常交易的分類效果非常好,能夠準(zhǔn)確且全面地識別正常交易,沒有誤分類和漏分類的情況。
類1(欺詐交易):
精確率(Precision) 是0.12,表示所有被預(yù)測為欺詐交易的樣本中,實際是欺詐交易的比例。
召回率(Recall) 是0.35,表示所有實際為欺詐交易的樣本中,正確被預(yù)測為欺詐交易的比例。
F1-score 為 0.18
F1-score = 2 × 0.12 × 0.35 0.12 + 0.35 = 2 × 0.042 0.47 ≈ 0.18 \text{F1-score} = 2 \times \frac{0.12 \times 0.35}{0.12 + 0.35} = 2 \times \frac{0.042}{0.47} \approx 0.18 F1-score=2×0.12+0.350.12×0.35?=2×0.470.042?≈0.18
表示模型對欺詐交易的分類效果較差。誤報率較高(精確率低),漏報率也較高(召回率低)
Accuracy(準(zhǔn)確率), 正確分類的樣本數(shù)占總樣本數(shù)的比例
Accuracy = TP + TN TP + TN + FP + FN \text{Accuracy} = \frac{\text{TP} + \text{TN}}{\text{TP} + \text{TN} + \text{FP} + \text{FN}} Accuracy=TP+TN+FP+FNTP+TN?
混淆矩陣:
TN(True Negative):283089 - 正常交易被正確分類為正常交易
FP(False Positive):1226 - 正常交易被錯誤分類為欺詐交易
FN(False Negative):322 - 欺詐交易被錯誤分類為正常交易
TP(True Positive):170 - 欺詐交易被正確分類為欺詐交易
模型在所有樣本中有99%的樣本被正確分類,很高的準(zhǔn)確率,但在不平衡數(shù)據(jù)集中,準(zhǔn)確率并不能全面反映模型的性能,特別是對少數(shù)類(如欺詐交易)的識別能力。
支持度(Support)分類的樣本數(shù)量,正常交易遠多于欺詐交易,數(shù)據(jù)集極度不平衡
類0(正常交易)的樣本數(shù)是284315。
類1(欺詐交易)的樣本數(shù)是492。
高準(zhǔn)確率主要是由于模型對正常交易的高識別率(幾乎所有正常交易都被正確分類)
然而,模型對欺詐交易的識別效果較差,這可以從較低的類1(欺詐交易)的精確率、召回率和F1-score中看出。
Macro avg,宏平均,不同類別的指標(biāo)的簡單平均值。
精確率、召回率和F1-score分別是0.56、0.67和0.59。
簡單平均,它反映了每個類別的指標(biāo)對等的重要性。對于不平衡的數(shù)據(jù)集,少數(shù)類(如欺詐交易)的表現(xiàn)對這個值有較大影響
Weighted avg,加權(quán)平均,考慮了類別的樣本數(shù)量,占主導(dǎo)地位的多數(shù)類(如正常交易)的指標(biāo)。因此,即使欺詐交易的表現(xiàn)較差,由于正常交易占多數(shù),整體的加權(quán)平均值仍然很高。
精確率、召回率和F1-score分別是1.00、0.99和1.00
結(jié)論
基于原始數(shù)據(jù),制定一些規(guī)則來識別欺詐行為,檢測效果不佳。
5.2 邏輯回歸模型(未使用SMOTE)和邏輯回歸模型(使用SMOTE)
代碼及結(jié)果
import numpy as np
import pandas as pd
from imblearn.over_sampling import SMOTE
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix
from imblearn.pipeline import Pipeline# 讀取數(shù)據(jù)集
creditcard_data = pd.read_csv('creditcard.csv', index_col=0)
print(f"Original dataset size: {creditcard_data.shape[0]}")# 平衡數(shù)據(jù)集
X, y = creditcard_data.iloc[:, 1:28], creditcard_data.iloc[:, 29]
smote = SMOTE()
X_resampled, y_resampled = smote.fit_resample(X, y)
print(f"Resampled dataset size: {X_resampled.shape[0]}")# 劃分訓(xùn)練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
print(f"Training set size: {X_train.shape[0]}")
print(f"Test set size: {X_test.shape[0]}")# 訓(xùn)練邏輯回歸模型并評估
lr = LogisticRegression()
lr.fit(X_train, y_train)
predictions = lr.predict(X_test)
print("Logistic Regression (without SMOTE):")
print(pd.crosstab(y_test, predictions, rownames=['Actual Fraud'], colnames=['Flagged Fraud']))
print(confusion_matrix(y_test, predictions))
print(classification_report(y_test, predictions))# 結(jié)合SMOTE和邏輯回歸
pipeline = Pipeline([('SMOTE', smote), ('Logistic Regression', lr)])
pipeline.fit(X_train, y_train)
predictions = pipeline.predict(X_test)
print("Logistic Regression with SMOTE:")
print(pd.crosstab(y_test, predictions, rownames=['Actual Fraud'], colnames=['Flagged Fraud']))
print(confusion_matrix(y_test, predictions))
print(classification_report(y_test, predictions))
結(jié)果如下:
數(shù)據(jù)集劃分:
原始數(shù)據(jù)集被劃分為訓(xùn)練集和測試集,其中 X_train 和 y_train 用于訓(xùn)練模型,X_test 和 y_test 用于評估模型。
train_test_split(X, y, test_size=0.3, random_state=0) 將 70% 的數(shù)據(jù)用作訓(xùn)練集,30% 的數(shù)據(jù)用作測試集。
模型訓(xùn)練和評估:
訓(xùn)練邏輯回歸模型時,使用的是 X_train 和 y_train。
在測試集上進行預(yù)測,并生成混淆矩陣和分類報告時,使用的是 X_test 和 y_test。
測試集中,正常交易的樣本數(shù)為 85296,欺詐交易的樣本數(shù)為 147。
分類報告反映的是模型在測試集上的性能評估結(jié)果
混淆矩陣
Logistic Regression(未使用SMOTE)
Logistic Regression (without SMOTE):
Flagged Fraud 0 1
Actual Fraud
0 85284 12
1 58 89
[[85284 12][ 58 89]]
85284:正常交易正確分類(真負例)
12:正常交易誤分類為欺詐交易(假陽性)
58:欺詐交易誤分類為正常交易(假陰性)
89:欺詐交易正確分類(真陽性)
Logistic Regression with SMOTE(使用SMOTE)
Logistic Regression with SMOTE:
Flagged Fraud 0 1
Actual Fraud
0 83101 2195
1 12 135
[[83101 2195][ 12 135]]
83101:正常交易正確分類(真負例)
2195:正常交易誤分類為欺詐交易(假陽性)
12:欺詐交易誤分類為正常交易(假陰性)
135:欺詐交易正確分類(真陽性)
分類報告
Logistic Regression(未使用SMOTE)
precision recall f1-score support0 1.00 1.00 1.00 852961 0.88 0.61 0.72 147accuracy 1.00 85443macro avg 0.94 0.80 0.86 85443
weighted avg 1.00 1.00 1.00 85443
正常交易(類0):精確率、召回率和F1-score都為1.00。
欺詐交易(類1):精確率為0.88,召回率為0.61,F1-score為0.72,模型在識別欺詐交易時漏報較多,但誤報較少。
Logistic Regression(使用SMOTE)
precision recall f1-score support0 1.00 0.97 0.99 852961 0.06 0.92 0.11 147accuracy 0.97 85443macro avg 0.53 0.95 0.55 85443
weighted avg 1.00 0.97 0.99 85443
正常交易(類0):精確率仍然為1.00,但召回率下降到0.97,F1-score為0.99。
欺詐交易(類1):精確率下降到0.06,但召回率顯著提高到0.92,F1-score為0.11。能識別大部分欺詐交易,但誤報較多。
未使用SMOTE:模型對正常交易的識別效果非常好,但召回率較低,對欺詐交易的識別較差。
使用SMOTE:模型對欺詐交易的識別效果顯著提高,召回率達到0.92,但精確率大幅下降,誤報增多。
6. 進一步
可以看到,邏輯回歸模型在處理欺詐檢測問題上,比簡單的閾值設(shè)定規(guī)則(例如V1 < -3 和 V3 < -5)能更好地識別欺詐交易。
為了提高邏輯回歸模型的準(zhǔn)確性,可以調(diào)整一些算法參數(shù)(如正則化參數(shù)),也可以考慮使用k-fold交叉驗證而不是簡單地將數(shù)據(jù)集分成訓(xùn)練集和測試集,交叉驗證通過多次分割和訓(xùn)練數(shù)據(jù)集,減少了因數(shù)據(jù)分割隨機性帶來的誤差,可以更好地評估模型的性能并選擇最佳的模型參數(shù),提高模型的穩(wěn)定性和泛化能力。
也可以嘗試不同的SMOTE參數(shù),找到平衡精確率和召回率的最佳參數(shù),如 sampling_strategy 和 k_neighbors,以找到最佳的參數(shù)組合,當(dāng)欺詐記錄在數(shù)據(jù)集中非常分散時,SMOTE可能會引入偏見,因為生成的合成樣本可能不代表實際的欺詐模式,所以使用SMOTE會引入偏見問題。
還可以嘗試一些其他的機器學(xué)習(xí)算法(如如隨機森林、XGBoost),找到平衡精確率和召回率的最佳方案,從而在實際應(yīng)用中更有效地識別欺詐交易
7. 隨機森林模型
混淆矩陣和分類報告,顯示該模型在正常交易數(shù)量遠遠多于欺詐交易的情況下,欺詐檢測表現(xiàn)是比較理想的
import pandas as pd
import numpy as np
from imblearn.over_sampling import SMOTE
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score, roc_curve
from imblearn.pipeline import Pipeline
import matplotlib.pyplot as plt
import joblib# 數(shù)據(jù)預(yù)處理函數(shù)
def prep_data(df):X = df.iloc[:, 1:28]y = df.iloc[:, 29]return np.array(X).astype(float), np.array(y).astype(float)# 讀取數(shù)據(jù)集
creditcard_data = pd.read_csv('creditcard.csv', index_col=0)# 數(shù)據(jù)預(yù)處理
X, y = prep_data(creditcard_data)# 劃分訓(xùn)練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)# 創(chuàng)建并訓(xùn)練隨機森林模型的管道
pipeline = Pipeline([('scaler', StandardScaler()),('smote', SMOTE()),('randomforestclassifier', RandomForestClassifier(random_state=42))
])# 訓(xùn)練模型
pipeline.fit(X_train, y_train)# 預(yù)測測試集
y_pred = pipeline.predict(X_test)# 打印混淆矩陣和分類報告
print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred))
print("\nClassification Report:")
print(classification_report(y_test, y_pred))# 保存模型
joblib.dump(pipeline, 'random_forest_fraud_model.pkl')
print("Model saved as random_forest_fraud_model.pkl")
結(jié)果如下
8. 模型應(yīng)用
關(guān)于模型的應(yīng)用,需要結(jié)合實際情況優(yōu)化方案,粗略的思路,例如:
目前看起來有了一個好用的模型,以后有新的交易數(shù)據(jù)進來,先把這些數(shù)據(jù)按照之前訓(xùn)練集的標(biāo)準(zhǔn)整理好,數(shù)據(jù)格式和特征都和訓(xùn)練時一致,加載模型,把整理好的數(shù)據(jù)交給模型,讓它來判斷哪些交易是正常的,哪些可能是欺詐的。
模型會給出一個判斷結(jié)果,比如:
1 表示欺詐交易
0 表示正常交易
以下是未經(jīng)運行的示例
誤報處理
對于模型標(biāo)記為欺詐的交易(但可能是正常交易),引入人工審核,比如,設(shè)立團隊對這些交易進行復(fù)查,處理被誤報的正常交易
漏報處理
對于模型沒有標(biāo)記為欺詐的交易(但實際上可能是欺詐交易),需要降低漏報率
例如,提高模型閾值
讓模型輸出每筆交易是欺詐的概率,根據(jù)業(yè)務(wù)需求調(diào)整判斷標(biāo)準(zhǔn)(閾值),比如當(dāng)概率大于0.5時標(biāo)記為欺詐。
再如,組合多個模型提高判斷的準(zhǔn)確性
使用多個不同的模型,并取大家的綜合結(jié)果
也可以進一步更新和優(yōu)化訓(xùn)練模型