目录

一、任务目标解读

信用卡欺诈检测

任务流程:

主要解决问题:

二、项目挑战与解决方案制定

1、导入我们的工具包

2、数据读取

3、数据标签分布

三、数据标准化处理

四、下采样数据集制作

五、交叉验证

六、数据集切分

七、模型评估方法与召回率

八、正则化惩罚项

演示交叉验证

九、训练逻辑回归模型

十、混淆矩阵评估分析

交叉验证与不同参数结果

混淆矩阵(模板)

十一、测试集遇到的问题

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

十二、阈值对结果的影响

十三、SMOTE样本生成策略

十四、过采样效果

1、导包

2、读数据,找到特征和标签

3、对数据集进行切分

4、样本生成

5、训练集样本数量

6、混淆矩阵

项目总结


一、任务目标解读

信用卡欺诈检测

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

任务流程:

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

主要解决问题:

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

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

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

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

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

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

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

二、项目挑战与解决方案制定

1、导入我们的工具包

import pandas as pd  #数据处理和数据分析
import matplotlib.pyplot as plt  #可视化展示
import numpy as np   #矩阵计算
import warnings
warnings.filterwarnings('ignore')
%matplotlib inline  #可以在Notebook中直接画图

2、数据读取

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

 

关注:数据类型、数据问题

3、数据标签分布

count_classes = pd.value_counts(data['Class'], sort = True).sort_index()
count_classes.plot(kind = 'bar')
plt.title("Fraud class histogram")
plt.xlabel("Class")
plt.ylabel("Frequency")

  • 希望0和1一样多(过采样:oversample)-》造假数据,可能导致模型结果下降
  • 0 和1一样少(下采样:undersample)-》数据没有充分利用,效果下降。

三、数据标准化处理

参考:

sklearn的API:sklearn.preprocessing.StandardScaler — scikit-learn 1.0.2 documentation

from sklearn.preprocessing import StandardScalerdata['normAmount'] = StandardScaler().fit_transform(data['Amount'].values.reshape(-1, 1))
data = data.drop(['Time','Amount'],axis=1)
data.head()

 对所有数据都要进行标准化。 

四、下采样数据集制作

选500个。

X = data.iloc[:, data.columns != 'Class']
y = data.iloc[:, data.columns == 'Class']# 得到所有异常样本的索引
number_records_fraud = len(data[data.Class == 1])
fraud_indices = np.array(data[data.Class == 1].index)# 得到所有正常样本的索引
normal_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[:, under_sample_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))

五、交叉验证

train:训练集。建立模型

val:验证集。验证模型好坏

test:测试集

cross_validation

六、数据集切分

随机切分

from sklearn.model_selection import train_test_split# 整个数据集进行划分
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size = 0.3, random_state = 0)print("原始训练集包含样本数量: ", len(X_train))
print("原始测试集包含样本数量: ", len(X_test))
print("原始样本总数: ", len(X_train)+len(X_test))# 下采样数据集进行划分
X_train_undersample, X_test_undersample, y_train_undersample, y_test_undersample = train_test_split(X_undersample,y_undersample,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))

七、模型评估方法与召回率

召回率recall:分母:关注的人

分子:检测到的

Recall = TP/(TP+FN)

八、正则化惩罚项

演示交叉验证

#Recall = TP/(TP+FN)
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import KFold, cross_val_score
from sklearn.metrics import confusion_matrix,recall_score,classification_report
from sklearn.model_selection import cross_val_predict

正则化惩罚项:

损失函数:

九、训练逻辑回归模型

def printing_Kfold_scores(x_train_data,y_train_data):fold = KFold(5,shuffle=False) # 定义不同力度的正则化惩罚力度c_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# k-fold 表示K折的交叉验证,这里会得到两个索引集合: 训练集 = indices[0], 验证集 = indices[1]j = 0#循环遍历不同的参数for c_param in c_param_range:print('-------------------------------------------')print('正则化惩罚力度: ', c_param)print('-------------------------------------------')print('')recall_accs = []#一步步分解来执行交叉验证  iteration:第几次验证  indices:索引标签for iteration, indices in enumerate(fold.split(x_train_data)): # 指定算法模型,并且给定参数lr = LogisticRegression(C = c_param, penalty = 'l1',solver='liblinear')# 训练模型,注意索引不要给错了,训练的时候一定传入的是训练集,所以X和Y的索引都是0lr.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('')#找到最好的参数,哪一个Recall高,自然就是最好的了。best_c = results_table.loc[results_table['Mean recall score'].astype('float32').idxmax()]['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.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')
import itertools
lr = LogisticRegression(C = best_c, penalty = 'l1')
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(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 = 0.01, penalty = 'l1',solver='liblinear')
# 训练模型,还是用下采样的数据集
lr.fit(X_train_undersample,y_train_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样本生成策略

1、针对少数样本做

2、计算少数样本中,到其他样本的距离d

3、按距离从小到大排序d12,d13,d14

4、选择倍率k=2(选择最近的k个)

5、选k个样本d12,d13

x1'=x1+random(0,1)·d12

x1''=x1+random(0,1)·d13

安装工具包imblearn:pip3 install imblearn

十四、过采样效果

1、导包

import pandas as pd
from imblearn.over_sampling import SMOTE
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split

2、读数据,找到特征和标签

credit_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']

3、对数据集进行切分

features_train, features_test, labels_train, labels_test = train_test_split(features, labels, test_size=0.3, random_state=0)

4、样本生成

基于SMOTE算法来进行样本生成,这样正例和负例样本数量就是一致的了,得到了比例均衡的样本。

oversampler=SMOTE(random_state=0)
os_features,os_labels=oversampler.fit_sample(features_train,labels_train)

5、训练集样本数量

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)

6、混淆矩阵

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,准确率,F1,Roc曲线(AUC)等,也可以根据实际问题自己指定评估指标。

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

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

(7)得到的结果一定要和实际任务结合在一起,有时候虽然得到的结果指标还不错,但是实际应用却成了问题,所以测试环节也是必不可少的。

唐宇迪学习笔记10:项目实战-交易数据异常检测相关推荐

  1. 唐宇迪学习笔记18:案例——SVM调参实例

    目录 一.SVM案例:线性支持向量机 SVM:支持向量机 支持向量基本原理 例子 Support Vector Machines: 最小化 雷区 训练一个基本的SVM 对比实验 二.软间隔C值对结果的 ...

  2. 唐宇迪学习笔记4:Python可视化库——Seaborn

    目录 一.整体布局风格设置 五种主题风格 1.darkgrid 2.whitegrid 3.dark 4.white 5.ticks 二.风格细节设置 1.指定画图距离轴线的位置 2.指定轴的隐藏与否 ...

  3. 唐宇迪学习笔记1:Python环境安装、Pytho科学计算库——Numpy

    目录 一.AI数据分析入门 ​1.案例来源 2.Python环境配置(Python3) Python的安装 Python库安装工具 Jupyter Notebook 二.Python科学计算库--Nu ...

  4. 唐宇迪学习笔记3:Python数据可视化库——Matplotlib

    目录 一.Matplotlib概述 最基本的图 线条格式 线条颜色 颜色与格式结合 二.子图与标注 绘制多个线 指定线条的宽度 自定义参数 子图 给图上加上注释 三.风格设置 ​四.条形图 五.条形图 ...

  5. 唐宇迪学习笔记20:聚类算法——DBSCAN

    目录 一.DBSCAN聚类算法 (Density-Based Spatial Clustering of Applications with Noise) 二.DBSCAN工作流程 工作流程 参数选择 ...

  6. 唐宇迪Pytorch笔记(附课程资料)

    目录 pytorch_tutorial 介绍 软件架构 安装教程 所需python包 使用说明 配套资料 { title = {pytorch深度学习实战}, author = {唐宇迪}, url ...

  7. 唐宇迪强化学习笔记之项目实战(flabby bird)

    强化学习: 学习系统没有像很多其它形式的机器学习方法一样被告知应该做出什么行为,必须在尝试了之后才能发现哪些行为会导致奖励的最大化,当前的行为可能不仅仅会影响即时奖励,还会影响下一步的奖励以及后续的所 ...

  8. Java学习笔记_16 项目实战之天天酷跑(三):缓冲加载游戏界面

    前文,我们完成了开始游戏界面的搭建.本文将实现缓冲加载界面的搭建.并搭建与前面俩界面间的桥梁. 实现输入正确用户名密码后,进入开始游戏界面,点击开始游戏按钮后,进入缓冲加载界面的功能. 界面示意图: ...

  9. Java学习笔记_17 项目实战之天天酷跑(四):游戏主界面

    接上文,本文将实现游戏主界面,功能如下: 移动的背景图片.动态的玩家.玩家的移动功能. 五种障碍物持续出现.玩家和障碍物的碰撞. 暂停.继续功能. 首先,看一下整体效果: 动图实在太大,几秒钟的 Gi ...

最新文章

  1. 太卷了!人大附中「内卷」到了美国?华裔家长抗议中国学生持F1签证抢占美国IMO名额...
  2. linux命令后面常见的/dev/null 和 21 的含义
  3. 理解Promise (4)
  4. matlab遗传算法无人机问题,基于改进遗传算法的无人机路径规划
  5. [实践篇] Softmax Regression
  6. Bug之Yii继承类的
  7. javascript深拷贝和浅拷贝
  8. python人工智能原理及其应用_人工智能原理与实践:基于Python语言和TensorFlow
  9. C++ 多继承中的多义性
  10. 【Java】注解 @Value 你真的会用么
  11. ubuntn安装qt5.12.10
  12. 动易模板制作示例(三)
  13. 年仅30岁!腾讯游戏程序员毛星云意外身故。。。
  14. java 流水账号生成器_Java之流水号生成器(示例代码)
  15. 百度文库等禁止页面弹出(禁用javascript)
  16. 电路分析第二章 二端口网络
  17. Android 软件安装方法介绍
  18. 福昕 关闭互联PDF
  19. Metasploit技术(一)——Metasploit简介与基础
  20. 一文读懂,CPU、精简指令集、复杂指令集该如何理解?

热门文章

  1. 大数据学习之路(电脑配置)
  2. 20180511-Allegro16.6 NC Drill和Optimize drill head travel的关系
  3. 维修记录,移动升级千兆宽带过程中的坑
  4. 李想骂街之后 理想IPO真能渡劫?
  5. CDMA版iPhone 4广东通话乐成 批量烧号不可行
  6. 全球及中国高岭土市场运行规模与投资发展建议报告2022版
  7. 基于 yolov5n6 和tkinker实现的检测模型的可视化界面
  8. 5种快速查找容器文件系统中文件的方法
  9. 电路基本原理那些事儿番外篇 电压
  10. 硬盘主要参数详解(上)