目录

项目背景

目标

方案一:下采样的方法训练模型

获取数据

数据预处理

检查是否有缺失值:

查看数据类型:

查看数据分布

方案二:smote(过采样)处理数据不平衡数据

获取数据

数据预处理

检查是否有缺失值:

查看数据类型:

不平衡数据处理

方法一:直接使用smote

方法二:利用SMOTE+undersampling解决数据不平衡

分割数据集:

方法1的数据集

方法2的数据集

模型训练

准备好算法API

交叉验证的函数

模型调优

网格搜索模型调优

计算各个指标:

集成算法

保存模型:


项目背景

一批交易数据,数据总量28万,其中正常交易数据量占比99.83%,欺诈交易数据量仅占比0.17%。

目标

训练出一个模型,能判断出交易数据是正常数据还是欺诈数据

方案一:下采样的方法训练模型

获取数据

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import time
import warnings
warnings.filterwarnings('ignore')# 加载数据文件
df = pd.read_csv("creditcard.csv")# 查看数据内容
df.head()

上图可以看到,数据除了Amount外,都经过了标准化处理

数据预处理

检查是否有缺失值:

# 检查是否有空置
df.isnull().sum()

没有缺失值的情况

查看数据类型:

# 查看数据类型
df.dtypes

查看数据分布

# 查看Class分布
labels = ['Not Fraud', 'Fraud'] # 标签
size = df['Class'].value_counts() # 统计class的类别数量
colors = ['lightgreen', 'orange'] # 颜色
explode = [0, 0.1] # 饼图突出
plt.figure(figsize=(9,9)) # 画布大小
plt.pie(size, colors=colors, explode=explode, labels=labels, shadow=True, autopct='%.2f%%') # 饼图参数设置
plt.axis('off') # 关闭坐标轴
plt.title("Data Distribution") # 标题
plt.legend() # 显示标签
plt.show() # 显示

这里可以看到欺诈数据占比非常小,如果使用下采样的方法训练模型,有非常大的概率出现过拟合的现象,导致模型泛化能力差,这时候第一个方案可以停下。

方案二:smote(过采样)处理数据不平衡数据

如果不处理不平衡数据,用这些数据来训练,模型往往只会学到分辨样本多的类别,而少数类别因为学习的数据量过少,无法准确预测。

获取数据

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import time
import warnings
warnings.filterwarnings('ignore')# 加载数据文件
df = pd.read_csv("creditcard.csv")# 查看数据内容
df.head()

上图可以看到,数据除了Amount外,都经过了标准化处理

数据预处理

对Amount进行标准化处理

from sklearn.preprocessing import StandardScalerdf['scaled_amount'] = StandardScaler().fit_transform(df['Amount'].values.reshape(-1,1)) # 金额归一化
df['scaled_time'] = StandardScaler().fit_transform(df['Time'].values.reshape(-1,1)) # 时间归一化df.drop(['Amount', 'Time'], axis=1, inplace=True) # 删除原始的数据列

检查是否有缺失值:

# 检查是否有空置
df.isnull().sum()

没有缺失值的情况

查看数据类型:

# 查看数据类型
df.dtypes

不平衡数据处理

这里我们提出一个想法,不管是对数据进行过采样还是欠采样,都是去平衡两类数据,那么我们可以尝试在用单纯的smote的同时,再创建一组数据集,对少数样本过采样,多数样本下采样,分别训练,查看效果。

方法一:直接使用smote

from imblearn.over_sampling import SMOTEX_new_1, y_new_1 = SMOTE().fit_resample(X, y)# 新的类分布
y_new_1.value_counts()

方法二:利用SMOTE+undersampling解决数据不平衡

from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import RandomUnderSampler
from imblearn.pipeline import Pipeline # 管道,把要用的工具封装在一起# over
over = SMOTE(sampling_strategy=0.1)# under
under = RandomUnderSampler(sampling_strategy=0.5)# pipeline
steps = [('o', over),('u', under)]pipeline = Pipeline(steps=steps)X_new_2, y_new_2 = pipeline.fit_resample(X, y)# 新的类分布
y_new_2.value_counts()

分割数据集:

方法1的数据集

from sklearn.model_selection import train_test_splitX_new_1_train, X_new_1_test, y_new_1_train, y_new_1_test = train_test_split(X_new_1, y_new_1)# 数据集
X_new_1_train = X_new_1_train.values
X_new_1_test = X_new_1_test.values# 标签
y_new_1_train = y_new_1_train.values
y_new_1_test = y_new_1_test.values

方法2的数据集

X_new_2_train, X_new_2_test, y_new_2_train, y_new_2_test = train_test_split(X_new_2, y_new_2)# 数据集
X_new_2_train = X_new_2_train.values
X_new_2_test = X_new_2_test.values# 标签
y_new_2_train = y_new_2_train.values
y_new_2_test = y_new_2_test.values

模型训练

因为我们处理的是一个二分类问题,这里选择的二分类中表现较好的逻辑回归,还有强大的SVM,以及各种集成算法来训练模型。利用交叉验证和网格搜索,从中选择出最优的模型和最优的参数,

准备好算法API

# 简单分类器实现
from sklearn.linear_model import LogisticRegression # 逻辑回归
from sklearn.linear_model import SGDClassifier      # 随机梯度from sklearn.svm import SVC                         # 支撑向量机from sklearn.ensemble import RandomForestClassifier # 随机森林
from sklearn.model_selection import cross_val_score # 交叉验证计算accuracy
from sklearn.model_selection import GridSearchCV    # 网格搜索,获取最优参数
from sklearn.model_selection import StratifiedKFold # 交叉验证
from collections import Counter
# 评估指标
from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score, roc_auc_score, accuracy_score, classification_reportfrom sklearn.ensemble import BaggingClassifier, GradientBoostingClassifier # 集成学习
from xgboost import XGBClassifier                   # 极限梯度提升树classifiers = {'LogisticRegression':LogisticRegression(), # 逻辑回归# "SVC":SVC(),                               # 支撑向量机'RFC':RandomForestClassifier(),            # 随机森林'Bagging':BaggingClassifier(),             # 集成学习bagging'SGD':SGDClassifier(),                     # 随机梯度'GBC':GradientBoostingClassifier(),        # 集成学习Gradient'xgb':XGBClassifier()                      # 极限梯度提升树
}

交叉验证的函数

def accuracy_score(X_train, y_train):for key, classifier in classifiers.items(): # 遍历每一个分类器,分别训练、计算得分classifier.fit(X_train, y_train)training_score = cross_val_score(classifier, X_train, y_train, cv=5) # 5折交叉验证print("Classifier Name : ", classifier.__class__.__name__,"  Training Score :", round(training_score.mean(), 2)*100,'%')

结果1

# 1.1 SMOTE
accuracy_score(X_new_1_train, y_new_1_train)

这里SVM算法也会消耗大量的时间,这里我把它pass掉了

结果2

# 1.2 SMOTE + under sampling
accuracy_score(X_new_2_train, y_new_2_train)

这里两种方法的结果都还不错,继续往下调优,然后我们可以看到的是,一些集成算法出现过拟合的现象,所以我们调优方向可以往降低模型复杂度这边走

模型调优

网格搜索模型调优

# 网格搜索:获取最优超参数
# 1 LR
def LR_gs(X_train, y_train):# LRLR_param = {'penalty':['l1', 'l2'],'C':[0.001, 0.01, 0.1, 1, 10]}LR_gs = GridSearchCV(LogisticRegression(),param_grid=LR_param, n_jobs=-1, scoring='accuracy')LR_gs.fit(X_train, y_train)LR_estimators = LR_gs.best_estimator_ # 最优参数return LR_estimators# 2 RFC
def RFC_gs(X_train, y_train):RFC_param = {'n_estimators':[100, 150, 200], # 多少棵树'criterion':['gini', 'entropy'], # 衡量标准'max_depth':list(range(2,5,1)), # 树的深度}RFC_gs = GridSearchCV(RandomForestClassifier(), param_grid=RFC_param, n_jobs=-1, scoring='accuracy')RFC_gs.fit(X_train, y_train)RFC_estimators = RFC_gs.best_estimator_return RFC_estimators# 3 Bag
def BAG_gs(X_train, y_train):BAG_param = {'n_estimators':[10, 15, 20]}BAG_gs = GridSearchCV(BaggingClassifier(), param_grid=BAG_param, n_jobs=-1, scoring='accuracy')BAG_gs.fit(X_train, y_train)BAG_estimators = BAG_gs.best_estimator_return BAG_estimators# 4 SGD
def SGD_gs(X_train, y_train):SGD_param = {'penalty':['l2','l1'],'max_iter':[1000, 1500, 2000]}SGD_gs = GridSearchCV(SGDClassifier(), param_grid=SGD_param, n_jobs=-1, scoring='accuracy')SGD_gs.fit(X_train, y_train)SGD_estimators = SGD_gs.best_estimator_return SGD_estimators# 5 xgb
def XGB_gs(X_train, y_train):XGB_param = {'n_estimators':[60,80,100,200],'max_depth':[3,4,5,6],'learning_rate':[0.1,0.2,0.3,0.4]}XGB_gs = GridSearchCV(XGBClassifier(), param_grid=XGB_param, n_jobs=-1, scoring='accuracy')XGB_gs.fit(X_train, y_train)XGB_estimators = XGB_gs.best_estimator_return XGB_estimators​​

调用上面的函数:

# 采用新的数据集:X_new_1_train, y_new_1_train# 模型交叉验证、训练,获取最优超参数LR_best_estimator = LR_gs(X_new_1_train, y_new_1_train)# KNN_best_estimator = KNN_gs(X_new_1_train, y_new_1_train)# SVC_best_estimator = SVC_gs(X_new_1_train, y_new_1_train)# DT_best_estimator = DT_gs(X_new_1_train, y_new_1_train)RFC_best_estimator = RFC_gs(X_new_1_train, y_new_1_train)BAG_best_estimator = BAG_gs(X_new_1_train, y_new_1_train)SGD_best_estimator = SGD_gs(X_new_1_train, y_new_1_train)XGB_best_estimator = XGB_gs(X_new_1_train, y_new_1_train)

注:这一步在我电脑计算了三个多小时

# 采用新的数据集:X_new_2_train, y_new_2_train# 模型交叉验证、训练,获取最优超参数LR_best_estimator = LR_gs(X_new_2_train, y_new_2_train)# KNN_best_estimator = KNN_gs(X_new_2_train, y_new_2_train)# SVC_best_estimator = SVC_gs(X_new_2_train, y_new_2_train)# DT_best_estimator = DT_gs(X_new_2_train, y_new_2_train)RFC_best_estimator = RFC_gs(X_new_2_train, y_new_2_train)BAG_best_estimator = BAG_gs(X_new_2_train, y_new_2_train)SGD_best_estimator = SGD_gs(X_new_2_train, y_new_2_train)XGB_best_estimator = XGB_gs(X_new_2_train, y_new_2_train)

等以上步骤都计算完成,我们就得到了网格搜索找出的最优超参数,利用得到的最优超参数,去计算准确率,精准率,召回率,f1_score,auc面积。

计算各个指标:

(这个模型我们主要是为了检测异常数据,也就是找到少数类,所以我们更看重数据查的全不全,也就是召回率和AUC指标)

# 预测新的数据集:X_new_test, y_new_test
from sklearn.metrics import precision_recall_fscore_support
from sklearn.metrics import accuracy_scoreresult_df = pd.DataFrame(columns=['Accuracy', 'F1-score', 'Recall', 'Precision', 'AUC_ROC'],index=['LR','RFC','Bagging','SGD','XGB'])def caculate(models, X_test, y_test):# 计算各种参数的值accuracy_results = []F1_score_results = []Recall_results = []Precision_results = []AUC_ROC_results = []for model in models:y_pred = model.predict(X_test)accuracy = accuracy_score(y_test, y_pred) # 计算准确度precision, recall, f1_score, _ = precision_recall_fscore_support(y_test, y_pred) # 计算:精确度,召回率,f1_scoreAUC_ROC = roc_auc_score(y_test, y_pred) # 计算ROC, AUC# 保存计算值accuracy_results.append(accuracy)F1_score_results.append(f1_score)Recall_results.append(recall)AUC_ROC_results.append(AUC_ROC)Precision_results.append(precision)return accuracy_results, F1_score_results, Recall_results, AUC_ROC_results, Precision_results

带入数据1

# 将所有最优超参数的模型放在一起
best_models = [LR_best_estimator, RFC_best_estimator,BAG_best_estimator, SGD_best_estimator, XGB_best_estimator]# 调用函数计算各项指标值
accuracy_results, F1_score_results, Recall_results, AUC_ROC_results, Precision_results = caculate(best_models, X_new_1_test, y_new_1_test)# 将各项值放入到DataFrame中
result_df['Accuracy'] = accuracy_results
result_df['F1-score'] = F1_score_results
result_df['Recall'] = Recall_results
result_df['Precision'] = Precision_results
result_df['AUC_ROC'] = AUC_ROC_resultsresult_df # 显示计算结果

可视化:

# 可视化 AUC的评分
g = sns.barplot('AUC_ROC', result_df.index, data=result_df, palette='hsv', orient='h')

带入第二组数据:

result_df_2 = pd.DataFrame(columns=['Accuracy', 'F1-score', 'Recall', 'Precision', 'AUC_ROC'],index=['LR','RFC','Bagging','SGD','XGB'])# 将所有最优超参数的模型放在一起
best_models = [LR_best_estimator, RFC_best_estimator,BAG_best_estimator, SGD_best_estimator, XGB_best_estimator]# 调用函数计算各项指标值
accuracy_results, F1_score_results, Recall_results, AUC_ROC_results, Precision_results = caculate(best_models, X_new_2_test, y_new_2_test)# 将各项值放入到DataFrame中
result_df_2['Accuracy'] = accuracy_results
result_df_2['F1-score'] = F1_score_results
result_df_2['Recall'] = Recall_results
result_df_2['Precision'] = Precision_results
result_df_2['AUC_ROC'] = AUC_ROC_resultsresult_df_2

可视化:

# 可视化 AUC的评分
g = sns.barplot('AUC_ROC', result_df_2.index, data=result_df_2, palette='hsv', orient='h')

看到auc面积这里,第二组数据的结果会略微高于第一组数据,这时候我们后续可以只使用第二组数据。

到这里我们可以看到,Bagging和XGBoost都有较好的表现效果,我们选出这两个算法,对它们进行一个集成,集成为一个算法,看看能不能得到更优的效果。

集成算法

# 集成学习# 根据以上AUC的结果,选择: LR 和 SVC 和 XGB 当做基模型# KNN_test = pd.Series(KNN_best_estimator.predict(X_new_1_test), name = 'KNN')Bagging_test = pd.Series(BAG_best_estimator.predict(X_new_1_test),name = 'Bagging')XGB_test = pd.Series(XGB_best_estimator.predict(X_new_1_test), name='XGB')# 把以上3个模型的预测结果集成起来
ensemble_results = pd.concat([Bagging_test, XGB_test], axis=1)ensemble_results

集成,训练:

# 将上述3个模型集成起来,当做一个模型
from sklearn.ensemble import VotingClassifiervoting_clf = VotingClassifier(estimators=[('BAG', BAG_best_estimator), ('XGB', XGB_best_estimator)], n_jobs=-1)# 训练
voting_clf.fit(X_new_1_train, y_new_1_train)# 预测
y_final_pred = voting_clf.predict(X_new_1_test)# 评估结果 : 最终集成学习预测的结果明显高于之前各个模型单独预测的结果print(classification_report(y_new_1_test, y_final_pred))

可以看到我们最终集成的模型预测的结果明显高于单独预测的结果,然后我们把这个超级模型保存起来:

保存模型:

import picklepickle.dump(voting_clf,open('./bag_xgb.dat','wb'))

后续也可以绘制一下ROC曲线,这里我觉得没必要了。over!

需要源码的话可以点个赞私信我

机器学习预测实战 -- 信用卡交易欺诈数据监测(含方案和代码思路)相关推荐

  1. 信用卡交易欺诈数据检测

    背景 目标  案例流程 方案一:下采样 方案二:采用SMOTE 技术来处理数据不平衡问题,SMOTE (Synthetic Minority Over-sampling Technique),即:合成 ...

  2. Python时间序列模型推理预测实战:时序推理数据预处理(特征生成、lstm输入结构组织)、模型加载、模型预测结果保存、条件判断模型循环运行

    Python时间序列模型推理预测实战:时序推理数据预处理(特征生成.lstm输入结构组织).模型加载.模型预测结果保存.条件判断模型循环运行 目录

  3. 机器学习项目实战----信用卡欺诈检测

    一.任务基础 数据集包含由欧洲人于2013年9月使用信用卡进行交易的数据.此数据集显示两天内发生的交易,其中284807笔交易中有492笔被盗刷.数据集非常不平衡,正例(被盗刷)占所有交易的0.172 ...

  4. 机器学习项目实战----信用卡欺诈检测(一)

    一.任务基础 数据集包含由欧洲人于2013年9月使用信用卡进行交易的数据.此数据集显示两天内发生的交易,其中284807笔交易中有492笔被盗刷.数据集非常不平衡,正例(被盗刷)占所有交易的0.172 ...

  5. 【数据分析与挖掘】基于LightGBM,XGBoost,逻辑回归的分类预测实战:英雄联盟数据(有数据集和代码)

    机器学习-LightGBM 一.LightGBM的介绍与应用 1.1 LightGBM的介绍 1.2 LightGBM的应用 二.数据集来源 三.基于英雄联盟数据集的LightGBM分类实战 Step ...

  6. 机器学习项目实战----信用卡欺诈检测(二)

    六.混淆矩阵: 混淆矩阵是由一个坐标系组成的,有x轴以及y轴,在x轴里面有0和1,在y轴里面有0和1.x轴表达的是预测的值,y轴表达的是真实的值.可以对比真实值与预测值之间的差异,可以计算当前模型衡量 ...

  7. 大数据预测实战-随机森林预测实战(一)-数据预处理

    数据读取 气温预测的任务目标就是使用一份天气相关数据来预测某一天的最高温度,属于回归任务,首先观察一下数据集∶ # 数据读取 import pandas as pdfeatures = pd.read ...

  8. 二手车价格预测实战(一)——数据探索

    目录 1.理解赛题: 背景 基础知识 2.数据探索 数据概况 探索性数据分析 缺失值可视化 查看变量分布 查看预测值价格的分布 查看变量间的关系 分析日期与价格关系 3.总结 1.理解赛题: 赛题:零 ...

  9. 大数据预测实战-随机森林预测实战(三)-数据量对结果影响分析

    下面对比一下特征数量对结果的影响,之前两次比较没有加入新的天气特征,这次把降水.风速.积雪 3 项特征加入数据集中,看看效果怎样∶ # 准备加入新的特征 from sklearn.ensemble i ...

最新文章

  1. 2020年第十五届全国大学生智能汽车竞赛浙江赛区比赛成绩分析
  2. [置顶] Linux协议栈代码阅读笔记(一)
  3. android多功能计算器 源码,Android计算器源码
  4. IE开发人员工具之实用功能讲解
  5. python restful服务部署_用python为mysql实现restful接口
  6. KDD 2019 | 使用神经网络为A*搜索算法赋能:以个性化路径推荐为例
  7. [下载]青岛交通旅游地图[download]
  8. c#反编译生成DLL过程
  9. 惊艳!ftrack和UE4,强强联合!
  10. 天池大赛 xgboost/lightgbm + python36 + win10_64 环境配置
  11. React 使用阿里巴巴矢量图标库管理Icon图标的Icon-antd用法
  12. 无法启动此应用因为计算机丢失,开机无法启动此程序因为计算机中丢失怎么回事...
  13. nvcc: command not found
  14. 一旦确诊青光眼无法彻底根治,需进行终身防治
  15. 前端培训,丁鹿学堂和达内浅析
  16. 易福门传感器PN3593
  17. openedx搭建(汉化版)
  18. Web项目错误记录java.sql.SQLException: Incorrect integer value: ‘aa‘ for column ‘password‘
  19. Andorid Skia
  20. 【书影观后感 十】理解原则从《我的历程》看到的

热门文章

  1. c语言的九九乘法口诀,【转】C语言::输出九九乘法口诀表
  2. 2020-8-26 剑指offer编程小哥令狐 075211
  3. LTE_DRX不连续接收(1)
  4. 八、 数据库的数据查询
  5. php语法与C的差别
  6. 2019年清华大学软件学院预推免机试试题
  7. Java中double类型比较大小
  8. 最近发现一个文字素材网站
  9. vSAN 6.6双活新特性 和 vSAN双活用户的演讲视频
  10. php怎么做多行文本域,php多行文本