信用卡欺诈检测

基于信用卡交易记录数据建立分类模型来预测哪些交易记录是异常的哪些是正常的。

任务流程:

  • 加载数据,观察问题
  • 针对问题给出解决方案
  • 数据集切分
  • 评估方法对比
  • 逻辑回归模型
  • 建模结果分析
  • 方案效果对比

主要解决问题:

(1)在此项目中,我们首选对数据进行了观察,发现了其中样本不均衡的问题,其实我们做任务工作之前都一定要先进行数据检查,看看数据有什么问题,针对这些问题来选择解决方案。

(2)这里我们提出了两种方法,下采样和过采样,两条路线来进行对比实验,任何实际问题来了之后,我们都不会一条路走到黑的,没有对比就没有伤害,通常都会得到一个基础模型,然后对各种方法进行对比,找到最合适的,所以在任务开始之前,一定得多动脑筋多一手准备,得到的结果才有可选择的余地。

(3)在建模之前,需要对数据进行各种预处理的操作,比如数据标准化,缺失值填充等,这些都是必要操作,由于数据本身已经给定了特征,此处我们还没有提到特征工程这个概念,后续实战中我们会逐步引入,其实数据预处理的工作是整个任务中最为最重也是最苦的一个阶段,数据处理的好不好对结果的影响是最大的。

(4)先选好评估方法,再进行建模。建模的目的就是为了得到结果,但是我们不可能一次就得到最好的结果,肯定要尝试很多次,所以一定得有一个合适的评估方法,可以用这些通用的,比如Recall,准确率等,也可以根据实际问题自己指定评估指标。

(5)选择合适的算法,这里我们使用的是逻辑回归,也详细分析了其中的细节,这是因为我们刚刚讲解完逻辑回归的原理就拿它来练手了,之后我们还会讲解其他算法,并不一定非要用逻辑回归来完成这个任务,其他算法可能效果会更好。但是有一点我希望大家能够理解就是在机器学习中并不是越复杂的算法越实用,恰恰相反,越简单的算法反而应用的越广泛。逻辑回归就是其中一个典型的代表了,简单实用,所以任何分类问题都可以把逻辑回归当做一个待比较的基础模型了。

(6)模型的调参也是很重要的,之前我们通过实验也发现了不同的参数可能会对结果产生较大的影响,这一步也是必须的,后续实战内容我们还会来强调调参的细节,这里就简单概述一下了。对于参数我建立大家在使用工具包的时候先看看其API文档,知道每一个参数的意义,再来实验选择合适的参数值。

(7)得到的结果一定要和实际任务结合在一起,有时候虽然得到的结果指标还不错,但是实际应用却成了问题,所以测试环节也是必不可少的。到此,这个项目就给大家介绍到这里了,在实践中学习才能成长的更快,建议大家一定使用提供的Notebook代码文件来自己完成一遍上述操作。

导入工具包:

import pandas as pdimport matplotlib.pyplot as pltimport numpy as np%matplotlib inline

数据读取

data = pd.read_csv("creditcard.csv")

首先拿到数据查看数据的标签分布,这里看看异常数据和正常数据各自的数量:
c

ount_classes = pd.value_counts(data['Class'], sort = True).sort_index()#这里会把Class这一列样本的类别作为index,value为每个类型样本的数量count_classes.plot(kind = 'bar')plt.title("Fraud class histogram")plt.xlabel("Class")plt.ylabel("Frequency")

数据标准化处理

from sklearn.preprocessing import StandardScalerdata['normAmount'] = StandardScaler().fit_transform(data['Amount'].values.reshape(-1,1))#不仅计算训练数据的均值和方差,还会基于计算出来的均值和方差来转换训练数据,从而把数据转换成标准的正太分布#那么reshape(1,-1)呢?也就是直接变成了一行了。#那这个-1在这里要怎么理解呢?#跟进numpy库官网的介绍,这里的-1被理解为unspecified value,意思是未指定为给定的。如果我只需要特定的行数,列数多少#无所谓,我只需要指定行数,那么列数直接用-1代替就行了,计算机帮我们算赢有多少列,反之亦然。#所以-1在这里应该可以理解为一个正整数通配符,它代替任何整数。data = data.drop(['Time', 'Amount'], axis = 1)#去掉标准化之前的数据

这里看到异常数据很少,但是正常数据巨多,这里为了在训练的时候以免因为全部采到正常数据因为正常和异常数据所带来的比例上的误差而对结果造成印象,我们采取下采样,使得异常数据和正常数据的个数一样。

X = data.iloc[:,data.columns != 'Class']#获得特征变量的所有数据y = data.iloc[:,data.columns == 'Class']#获得因变量也就是分类数据那一列作为ynumber_records_fraud = len(data[data.Class == 1])fraud_indices = data[data.Class == 1].index#得到所有异常样本索引以及数量方便之后对正常样本进行采样,因为需要:1:1normal_indices = data[data.Class == 0].index#在正常样本中随机采样出指定个数的样本,并取索引random_normal_indices = np.random.choice(normal_indices, number_records_fraud, replace = False)random_normal_indices = np.array(random_normal_indices)#有了正常和异常样本后把他们的索引都拿到手under_sample_indices = np.concatenate([fraud_indices, random_normal_indices])#根据索引得到下采样所有的样本点under_sample_data = data.iloc[under_sample_indices,:])X_undersample = under_sample_data.iloc[:,under_sample_data.columns != 'Class']y_undersample = under_sample_data.iloc[:,undersample_data.columns == 'Class']#下采样 样本比例print("正常样本所占整体比例:", len(under_sample_data[under_sample_data.Class == 0])/len(under_sample_data))print("异常样本所占整体比例: ", len(under_sample_data[under_sample_data.Class == 1])/len(under_sample_data))
print("下采样策略总体样本数量: ", len(under_sample_data))

数据集划分

from sklearn.model_selection import train_test_split#对整个数据集进行划分 这里是73开,训练集70%测试集30%一般是28开,但是不会比73更高,注意要设置random_sstate保证随机取样的数据是一样的否则后面验证比较会有一个多的偶然因素X_train, X_test, y_train, y_test = train_test_split(X,y,test_size = 0.3,random_state = 0)print("")
print("下采样训练集包含样本数量: ", len(X_train_undersample))
print("下采样测试集包含样本数量: ", len(X_test_undersample))
print("下采样样本总数: ", len(X_train_undersample)+len(X_test_undersample))

OK数据基本处理完毕了,开始建立逻辑回归模型

#Recall = TP/(TP+FN)召回率计算公式TP(True Positive):将正类预测为正类(的数目),真实为0,预测也为0;FN(False Negative):将正类预测为负类(的数目),真实为0,预测为1;FP(False Positive):将负类预测为正类(的数目), 真实为1,预测为0;TN(True Negative):将负类预测为负类(的数目),真实为1,预测也为1。前边T\F是分类正确或者错误,后面的P\N是结果被分成是正例或负例精确率(precision):TP/(TP+FP)
召回率(recall):TP/(TP+FN)在所有异常样本中我们正确取出的异常样本所占比例from sklearn.linear_model import LogisticRegressionfrom sklearn.model_selection import KFold, cross_val_scorefrom sklearn.metrics import confusion_matrix, recall_score,classification_reportfrom sklearn.model_selection import cross_val_predictdef printing_Kfold_scores(x_train_data, y_train_data):fold = KFold(5,shuffle = False)#将训练集进行五段切分进行交叉验证,这里不进行洗牌参数为Falsec_param_range = [0.01, 0.1, 1, 10, 100]#定义不同力度的正则化惩罚力度results_table = pd.DataFrame(index = range(len(c_param_range),2), columns  = ['C_parameter','Mean recall score'])results_table['C_parameter'] = c_param_range#展示结果用的表格j = 0#k-fold 表示K折的交叉验证,这里会得到两个索引集合:训练集 = indices[0], 验证集 = indices[1]for c_param in c_param_range:print('----------------------------------')print('正则化惩罚力度: ' , c_param)print('----------------------------------')print('')recall_accs = []#一步步分解来执行交叉验证for iteration, indices in enumerate(fold.split(x_train_data):lr = LogisticRegression(C=c_param, penalty = 'l1',solver='liblinear')#指定算法模型,并且给定参数lr.fit(x_train_data.iloc[indices[0],:], y_train_data.iloc[indices[0],:].values.ravel())#建立好模型后,预测模型结果,这里用的是验证集,索引为1y_pred_undersample = lr.predict(x_train_data.iloc[indices[1],:].values)#有了预测结果之后就可以来进行评估了,这里recall_score需要传入预测值和真实值。recall_acc = recall_score(y_train_data.iloc[indices[1],:].values, y_pred_undersample)#一会还要算平均,所以把每一步的结果都先保存起来。recall_accs.append(recall_acc)print('Iteration ', iteration, ': 召回率 =', recall_acc)#当执行完所有的交叉验证后,计算平均结果results_table.loc[j,'Mean recall score'] = np.mean(recall_accs)j += 1print('')print('平均召回率 ', np.mean(recall_accs))print('')best_c = results_table.loc[results_table['Mean recall score'].astype('float32').idmax()]['C_parameter']#打印最好的结果print('*********************************************************************************')print('效果最好的模型所选参数 = ', best_c)print('*********************************************************************************')return best_c#交叉验证与不同参数结果best_c = printing_Kfold_scores(X_train_undersample, y_train_undersample)

def plot_confusion_matrix(cm,classes, title = 'Confusion matrix',cmap = plt.cm.Blues):plt.title(title)tick_marks = np.arange(len(classes))plt.xticks(tick_marks, classes, rotation=0)plt.yticks(tick_marks, classes)plt.imshow(cm, interpolation='nearest', cmap=cmap)plt.colorbar()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')import itertoolslr = LogisticRegression(C = best_c, penalty = 'l1', solver = 'liblinear')lr.fit(X_train_undersample,y_train_undersample.values.ravel())y_pred_undersample = lr.predict(X_test_undersample.values)#计算所需值cnf_matrix = confusion_matrix(y_test_undersample, y_pred_undersample)np.set_printoptions(precision = 2)print("召回率:", cnf_matrix[1,1]/(cnf_matrix[1,0] + cnf_matrix[1,1]))#绘制class_names = [0,1]plt.figure()plot_confusion_matrix(cnf_matrix,classes = class_names,title = 'Confusion matrix')plt.show()

#下采样方案在原始数据中的结果

lr = LogisticRegression(C = best_c, penalty = 'l1', solver = 'liblinear')lr.fit(X_train_undersample, y_train_undersample.values.ravel())y_pred = lr.predict(X_test.values)#计算所需值cnf_matrix = confusion_matrix(y_test,y_pred)np.set_printoptions(precison = 2)print("召回率:", cnf_matrix[1,1]/ (cnf_matrix[1,0] + cnf_matrix[1,1]))#绘制class_names = [0,1]plt.figure()plot_confusion_matrix(cnf_matrix,classes = class_names, title = 'Confusion matrix')plt.show()

#原始数据值借建模结果

best_c = printing_Kfold_scores(X_train,y_train)lr = LogisticRegression(C = best_c, penalty = 'l1',solver='liblinear')
lr.fit(X_train,y_train.values.ravel())
y_pred_undersample = lr.predict(X_test.values)# Compute confusion matrix
cnf_matrix = confusion_matrix(y_test,y_pred_undersample)
np.set_printoptions(precision=2)print("Recall metric in the testing dataset: ", cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1]))# Plot non-normalized confusion matrix
class_names = [0,1]
plt.figure()
plot_confusion_matrix(cnf_matrix, classes=class_names, title='Confusion matrix')
plt.show()

#阈值对结果的影响#用之前最好的参数来进行建模lr = LogisticRegression(C = 0.01, penalty = 'l1', solver = 'liblinear')#训练模型,还是用下采样的数据集lr.fit(X_train_undersample, y_trian_undersample.values.ravel())#得到预测结果的概率值y_pred_undersample_proba = lr.predict_proba(X_test_undersample.values)#指定不同的阈值thresholds = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9]plt.figure(figsize = (10,10))j = 1# 用混淆矩阵来进行展示
for i in thresholds:y_test_predictions_high_recall = y_pred_undersample_proba[:,1] > iplt.subplot(3,3,j)j += 1cnf_matrix = confusion_matrix(y_test_undersample,y_test_predictions_high_recall)np.set_printoptions(precision=2)print("给定阈值为:",i,"时测试集召回率: ", cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1]))class_names = [0,1]plot_confusion_matrix(cnf_matrix, classes=class_names, title='Threshold >= %s'%i)

SMOTE过采样方案

这里下采样的结果召回率太糟糕了,所以使用过采样的方案

import pandas as pdfrom imblearn.over_sampling import SMOTEfrom sklearn.metrics import confusion_matrixfrom sklearn.model_selection import train_test_splitcredit_cards = pd.read_csv('creditcard.csv')columns = credit_cards.columns#在特征中去除掉标签features_columns = columns.delete(len(columns)-1)features = credit_cards[features_columns]labels = credit_cards['Class']features_train, features_test, label_train, label_test = train_test_split(features,lables,test_size = 0.3,random_state =0)#基于SMOTE算法进行样本生成,这样正例和负例样本数量就是一致的了oversampler  =SMOTE(random_state = 0)os_features, os_labels = oversampler.fit_sample(features_train, labels_train)#训练集样本数量len(os_labels[os_labels = 1])os_features = pd.DataFrame(os_features)os_labels = pd.DataFrame(os_labels)best_c = printing_Kfold_scores(os_features, os_labels)lr = LogisticRegression(C = best_c, penalty = 'l1', solver = 'liblinear')lr.fit(os_features, os_labels.values.ravel())y_pred = lr.predict(features_test.values)#计算混淆矩阵cnf_matrix = confusion_matrix(labels_test, y_pred)np.set_printoptions(precision = 2)print("召回率:", cnf_matrix[1,1] / (cnf_matrix[1,0] + cnf_matrix[1,1]))#绘制class_names = [0,1]plt.figure()plot_confusion_matrix(cnf_matrix,classes = class_names, title = 'Confusion matrix')plt.show()

项目总结

(1)在此项目中,我们首选对数据进行了观察,发现了其中样本不均衡的问题,其实我们做任务工作之前都一定要先进行数据检查,看看数据有什么问题,针对这些问题来选择解决方案。

(2)这里我们提出了两种方法,下采样和过采样,两条路线来进行对比实验,任何实际问题来了之后,我们都不会一条路走到黑的,没有对比就没有伤害,通常都会得到一个基础模型,然后对各种方法进行对比,找到最合适的,所以在任务开始之前,一定得多动脑筋多一手准备,得到的结果才有可选择的余地。

(3)在建模之前,需要对数据进行各种预处理的操作,比如数据标准化,缺失值填充等,这些都是必要操作,由于数据本身已经给定了特征,此处我们还没有提到特征工程这个概念,后续实战中我们会逐步引入,其实数据预处理的工作是整个任务中最为最重也是最苦的一个阶段,数据处理的好不好对结果的影响是最大的。

(4)先选好评估方法,再进行建模。建模的目的就是为了得到结果,但是我们不可能一次就得到最好的结果,肯定要尝试很多次,所以一定得有一个合适的评估方法,可以用这些通用的,比如Recall,准确率等,也可以根据实际问题自己指定评估指标。

(5)选择合适的算法,这里我们使用的是逻辑回归,也详细分析了其中的细节,这是因为我们刚刚讲解完逻辑回归的原理就拿它来练手了,之后我们还会讲解其他算法,并不一定非要用逻辑回归来完成这个任务,其他算法可能效果会更好。但是有一点我希望大家能够理解就是在机器学习中并不是越复杂的算法越实用,恰恰相反,越简单的算法反而应用的越广泛。逻辑回归就是其中一个典型的代表了,简单实用,所以任何分类问题都可以把逻辑回归当做一个待比较的基础模型了。

(6)模型的调参也是很重要的,之前我们通过实验也发现了不同的参数可能会对结果产生较大的影响,这一步也是必须的,后续实战内容我们还会来强调调参的细节,这里就简单概述一下了。对于参数我建立大家在使用工具包的时候先看看其API文档,知道每一个参数的意义,再来实验选择合适的参数值。

(7)得到的结果一定要和实际任务结合在一起,有时候虽然得到的结果指标还不错,但是实际应用却成了问题,所以测试环节也是必不可少的。到此,这个项目就给大家介绍到这里了,在实践中学习才能成长的更快,建议大家一定使用提供的Notebook代码文件来自己完成一遍上述操作。

机器学习-逻辑回归-信用卡检测任务相关推荐

  1. [转载] 吴恩达机器学习逻辑回归练习题:逻辑回归及规则化(python实现)

    参考链接: 了解逻辑回归 Python实现 练习题背景:网易云课堂->吴恩达机器学习课程->逻辑回归练习题 对于练习题的详细内容,和课程中推荐的octave编程实现,请见:吴恩达机器学习逻 ...

  2. 机器学习——逻辑回归

    机器学习--逻辑回归 一.逻辑回归 logistic回归又称logistic回归分析,常用于数据挖掘,疾病自动诊断,经济预测等领域.它是一种广义的线性回归分析模型,因此与多重线性回归分析有很多相同之处 ...

  3. 机器学习 逻辑回归算法应用案例

    机器学习 逻辑回归算法应用案例 时间:2020.09.12 出处:https://www.kesci.com/home/project/5bfe39b3954d6e0010681cd1 注明:初学逻辑 ...

  4. 泰坦尼克(机器学习逻辑回归)

    泰坦尼克(机器学习逻辑回归) 原文链接 数据预处理 import pandas as pd train=pd.read_csv('C:/Users/Admin/Downloads/train.csv' ...

  5. EduCoder 机器学习 逻辑回归

    逻辑回归是属于机器学习里面的监督学习,它是以回归的思想来解决分类问题的一种非常经典的二分类分类器.由于其训练后的参数有较强的可解释性,在诸多领域中,逻辑回归通常用作 baseline 模型,以方便后期 ...

  6. 机器学习 --- 逻辑回归

    逻辑回归是属于机器学习里面的监督学习,它是以回归的思想来解决分类问题的一种非常经典的二分类分类器.由于其训练后的参数有较强的可解释性,在诸多领域中,逻辑回归通常用作 baseline 模型,以方便后期 ...

  7. 机器学习算法平台alink_机器学习-逻辑回归算法

    1-逻辑回归算法原理推导 逻辑回归算法其实是一个分类算法,是非常经典,优秀的算法.一般我们不知道用哪个分类算法的时候,首先用逻辑回归算法试一试:它不仅可以实现二分类算法,还可以解决多分类问题 逻辑回归 ...

  8. Coursera 机器学习 -- 逻辑回归 笔记 【第二周】

    Logistic Regression Model(逻辑回归模型) Cost Function 如下所示,本章讲述了如何拟合cost参数θ: hypothesis函数在图中复习一下,在图中我们的假设函 ...

  9. 西电-机器学习-逻辑回归

    逻辑回归 本次作业的目的是建立一个逻辑回归模型,用于预测一个学生是否应该被大学录取. 简单起见,大学通过两次考试的成绩来确定一个学生是否应该录取.你有以前数届考生的成绩,可以做为训练集学习逻辑回归模型 ...

最新文章

  1. linux 模拟生成 CAN 设备
  2. R语言abs函数计算数值数据对象的绝对值实战
  3. zynq学习06 zynq的PL中加入的AXI_GPIO IP核来控制GPIO操作
  4. linux安装redis服务,配置PHP扩展
  5. visual studio 2005,visual studio 2008调出即时窗口
  6. java语言编程基础_java语言编程基础
  7. spring cloud + spring boot + springmvc+mybatis分布式微服务云架构
  8. 台大李宏毅Machine Learning 2017Fall学习笔记 (10)Tips for Deep Learning
  9. 二分插入排序(折半插入排序)--排序算法(六)
  10. abaqus模拟单向压缩实验
  11. 【C语言练习】分离英语句子中的单词并统计每个单词出现次数后排序输出
  12. 拍照时光圈与景深控制
  13. HDOJ--1162--Eddy's picture
  14. c语言日期计算器程序代码,用C语言写一个日期计算器
  15. OpenCV中LBPH人脸识别器识别人脸实战(附Python源码)
  16. 解决MacBook浏览器打开北京工作居住证系统问题
  17. 达梦数据库统计模式下所有表记录数
  18. k8spod使用gpu
  19. redis之lua脚本: 原子性 调试 嵌入高级语言
  20. Spring Boot—13、发送电子邮件

热门文章

  1. Tomcat部署项目的方法
  2. Node-SASS安装 scss
  3. idea 光标变粗 无法输入
  4. sqlserver中的分页sql语句,不同于mysql中的limit,相当于top+top
  5. 把分类信息,在表格中展现出来,通过合并单元格来实现信息之间的层级关系...
  6. 转SFTP 和FTPS的区别是什么?
  7. WCF(一) ---- 简单调用
  8. 删除所有的.svn 文件
  9. (转)Java初始化顺序
  10. 接口测试--测试工具apipost脚本大全