python数据异常检测_(三十)项目实战|交易数据异常检测(五)-python数据分析与机器学习实战(学习笔记)...

文章原创,最近更新:2018-06-8

1.SMOTE样本生成策略

课程资料:这里所涉及到的练习资料creditcard.csv相关的链接以及密码如下:

链接: https://pan.baidu.com/s/1APgU4cTAaM9zb8_xAIc41Q 密码: xgg7

对于下采样操作而言,模型回归的评估以及参数的选择.那么这个就是下采样应该怎么样去做这个事情.不光有下采样的操作,还有过采样的操作.那么接下来讲的就是过采样的操作,是关于SMOTE的算法.

(1)对于少数类中每一个样本x,以欧氏距离为标准计算它到少数类样本集中所有样本的距离,得到其k近邻.

(2)根据样本不平衡比例设置一个采样比例以确定采样倍率N,对于每一个少数类样本,从其k近邻中随机选择若干个样本,假设选择的近邻为xn.

(3)对于每一个随机选出的近邻xn,分别与原样本按照如下的公式构建新的样本.

ad394fecedbf?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weixin

ad394fecedbf?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weixin

在过采样的时候要有数据的生成,现在有0和1两类的样本.0类样本很多,1类样本很少,现在希望1类的样本也很多进行生成的操作.

假设1类的样本有100个,想生成500个,那我们能不能做这个事呢?肯定是可以的.首先介绍一个算法,这个算法是在数据挖掘以及统计当中非常常用的,这个算法就叫SMOTE,给大家解释一下,流程是怎么完成这样的事的.

(1)对于少数类中每一个样本x,以欧氏距离为标准计算它到少数类样本集中所有样本的距离,得到其k近邻.

先将少数类的样本先拿出来,以欧氏距离为标准计算它到少数类样本集中所有样本的距离,得到其k近邻.具体案例如下:

ad394fecedbf?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weixin

假设有个三角形,比较稀缺的类别,写个for循环,这个for循环遍历每个三角形的样本,第一次遍历的样本是xi,计算xi样本到其他样本的距离.

ad394fecedbf?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weixin

比如d1,d2,d3,...dn.计算好之后,分别将d1,d2,d3,...dn进行排序的操作,那么将一个样本变成5个样本,就把排序好的样本每5个就切一刀分组,如果将一个样本变成10个样本,那么就将排序好的样本每10个就切一刀分组.具体案例如下:

ad394fecedbf?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weixin

假设是排序好的样本每5个就切一刀分组,那么接下来就按公式操作:

ad394fecedbf?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weixin

这个公式的x是表示刚才切下来的xi样本,xnew是新生成的样本.是不是有5个距离,其中如下的截图就是算出来的欧氏距离

ad394fecedbf?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weixin

比如d1乘以一个随机数,比如这个随机数是0.76,就会得到一个新值,再将新值加到原始的数据上,那么就会得到一个新的数据.接下来用d1,d2,d3,d4,d5按照以上的方法都得到新的值.这个就叫SMOTE算法.接下来就是按照SMOTE算法来进行一个数据生成的操作.

首先导入python相关的库以及模块.

import pandas as pd

from imblearn.over_sampling import SMOTE

from sklearn.ensemble import RandomForestClassifier

from sklearn.metrics import confusion_matrix

from sklearn.model_selection import train_test_split

因为imblearn.over_sampling 这个库第一次使用,需要进行按照.

在,输入:pip install imblearn,即可以安装完毕.

over_sampling指的是过采样的操作.

因为以下代码,之前都有提到过,因此就不一一再次述说了.

credit_cards=pd.read_csv('creditcard.csv')

columns=credit_cards.columns

# The labels are in the last column ('Class'). Simply remove it to obtain features columns

features_columns=columns.delete(len(columns)-1)

features=credit_cards[features_columns]

labels=credit_cards['Class']

features_train, features_test, labels_train, labels_test = train_test_split(features,

labels,

test_size=0.2,

random_state=0)

我们来看看重点的代码,具体如下:

oversampler=SMOTE(random_state=0)

os_features,os_labels=oversampler.fit_sample(features_train,labels_train)

oversampler=SMOTE(random_state=0),用SMOTE进行数据生成,首先实例化一个对象,叫oversampler,SMOTE可以不使用参数,但是要使每次生成的数据都是一样的,可以random_state=0.

os_features,os_labels=oversampler.fit_sample(features_train,labels_train),用oversampler.fit_sample()将原始数据传进来,刚才有对原始数据进行切分,有切分成测试集以及训练集.需要想一个问题,切分完之后,需要哪哪一部分进行生成呢?肯定是拿训练集进行生成并建立一个模型.测试集是千万不可以动的.

fit_sample(features_train,labels_train)传进来的是训练集的x以及训练集的y,训练完之后,就会自动做一个平衡,就会知道0有多少个,1有多少个?

ad394fecedbf?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weixin

len(os_labels[os_labels==1])

这里是计算lable1的有多少个?共有227454个.lable0的也有20多万个,因此样本就均衡了.可以通过过采样的方式,查看recall有多少?

os_features = pd.DataFrame(os_features)

os_labels = pd.DataFrame(os_labels)

best_c = printing_Kfold_scores(os_features,os_labels)

输出结果如下:

-------------------------------------------

C parameter: 0.01

-------------------------------------------

Iteration 1 : recall score = 0.890322580645

Iteration 2 : recall score = 0.894736842105

Iteration 3 : recall score = 0.968861347792

Iteration 4 : recall score = 0.957595541926

Iteration 5 : recall score = 0.958430881173

Mean recall score 0.933989438728

-------------------------------------------

C parameter: 0.1

-------------------------------------------

Iteration 1 : recall score = 0.890322580645

Iteration 2 : recall score = 0.894736842105

Iteration 3 : recall score = 0.970410534469

Iteration 4 : recall score = 0.959980655302

Iteration 5 : recall score = 0.960178498807

Mean recall score 0.935125822266

-------------------------------------------

C parameter: 1

-------------------------------------------

Iteration 1 : recall score = 0.890322580645

Iteration 2 : recall score = 0.894736842105

Iteration 3 : recall score = 0.970454796946

Iteration 4 : recall score = 0.96014552489

Iteration 5 : recall score = 0.960596168431

Mean recall score 0.935251182603

-------------------------------------------

C parameter: 10

-------------------------------------------

Iteration 1 : recall score = 0.890322580645

Iteration 2 : recall score = 0.894736842105

Iteration 3 : recall score = 0.97065397809

Iteration 4 : recall score = 0.960343368396

Iteration 5 : recall score = 0.960530220596

Mean recall score 0.935317397966

-------------------------------------------

C parameter: 100

-------------------------------------------

Iteration 1 : recall score = 0.890322580645

Iteration 2 : recall score = 0.894736842105

Iteration 3 : recall score = 0.970543321899

Iteration 4 : recall score = 0.960211472725

Iteration 5 : recall score = 0.960903924995

Mean recall score 0.935343628474

*********************************************************************************

Best model to choose from cross validation is with C parameter = 100.0

*********************************************************************************

通过以上的结果可以知道recall值平均算下来大概是0.935.

我们在看一下混淆矩阵.

lr = LogisticRegression(C = best_c, penalty = 'l1')

lr.fit(os_features,os_labels.values.ravel())

y_pred = lr.predict(features_test.values)

# Compute confusion matrix

cnf_matrix = confusion_matrix(labels_test,y_pred)

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()

输出结果如下:

Recall metric in the testing dataset: 0.90099009901

ad394fecedbf?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weixin

通过输出结果我们可以知道,测试集共有5万多个样本,recall值是等于90%.之前的recall值是约等于91%(这个数值是大概,有点忘记了).这个结果比之前的结果稍微低了一些,而现在的误杀值有517个.之前的误杀值有8000多个,是500多个的十几倍.通过过采样得到的误差是偏低一些的.

使用过采样recall值可能偏低一些,但是模型的优点是精度偏高.这就是与下采样的区别.

总结:

对于样本不均衡数据,要利用越多的数据越好,能利用一种生成方式,就不妨利用这种生成方式.下采样误杀率很高,这是模型本身自带的一个问题,因为0和1一样少,会存在潜在的意识是原始数据0和1的数据一样少,导致误杀率偏高.过采样的结果偏好一些,虽然recall偏低了一点,但是整体的效果还是不错的.

流程总结:

首先要观察数据,当前数据是否分布均衡,不均衡的情况下就要想一些方法.

(这节课的数据是比较纯净的,就不需要做其他一些预处理的操作,直接原封不动的拿出来就可以了.很多情况下,不见得可以直接拿到特征数据,

后面讲到特征工程的时候,会拿到比较难的数据,怎么去建立特征以及怎么样去寻求一些帮助呢?)

让数据进行标准化,让数据的浮动比较小一些,然后再进行数据的选择以及参数的选择.通过交叉验证的方式.

混淆矩阵以及模型的评估标准

通过阈值与预测值进行比较,然后得到最终的一个预测结果.不同的阈值会使结果发生很大的变化.

SMOTE算法.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值