异常检测实战笔记

  本文是《智能风控原理、算法与工程实践》第6章学习笔记。

  异常检测,又称为离群点检测,是找出行为与预期行为差异较大的对象的检测过程。异常检测在风控领域的应用有样本清洗、个体欺诈检测模型、PreA预筛选模型和冷启动模型等。

离群点和噪声

  通常认为,样本集由真实数据和噪声组成。离群点既可能是由真实数据产生,也有可能是由噪声带来的。噪声被定义为被测量变量的随机误差和方差。离群点的定义为数据集中偏离整体数据集趋势的那些对象。

  噪声被普遍认为是正常数据和异常数据的边界。通常情况下,异常点的离群程度是大于噪声的,但实际用中两者并不容易区分。 在真实场景中,欺诈样本占比极少,无法进行有监督训练。即使通过SMOTE算法采样或者半监督学习进行扩充,由于欺诈手段在不停变化,通过历史欺诈样本学习得到的模型在应对新的欺诈手段时很难起到识别作用,因此存在问题。

  欺诈检测可以分为个体欺诈检测和团体欺诈检测。个体欺诈检测由于占比极小、与整体显著不同,与离群点性质相同,可以通过异常检测技术来识别;团体欺诈检测的中心思想是团伙发现,通常使用基于图的社区发现算法识别。在金融领域,聚集就意味着风险。

z-score检验

  z-score也叫标准分数,是一个数与其所在数组的平均数的差除以标准差的值。它所计算的是对于给定分数,其距离当前群体的平均数多少个标准差。常用来描述样本偏离正态分布的程度。

  z-score检验需要假设样本满足正态分布,然而大部分实际场景的数据都不满足正态分布的假设条件,因此实际应用效果一般。

KNN异常检测

  KNN算法专注于全局异常检测,所以无法检测到局部异常。

  首先,对于数据集中的每条记录,必须找到k个最近的邻居。然后使用这K个邻居计算异常分数。

有三种方法

  在实际方法中后两种的应用度较高。然而,分数的绝对值在很大程度上取决于数据集本身、维度数和规范化。

  参数k的选择当然对结果很重要。如果选择过低,记录的密度估计可能不可靠。(即过拟合)另一方面,如果它太大,密度估计可能太粗略。K值的选择通常在10-50这个范围内。所以在分类方法中,选择一个合适的K值,可以用交叉验证法。

  但是,事实上基于KNN的算法都是不适用于欺诈检测的,因为他们本身就对噪声比较敏感。

LOF异常检测

  局部异常因子(Local Outlier Factor)是一种基于密度的异常检测算法。 LOF算法将每一个样本到其k近邻样本的距离量化为一种密度的概念,称为局部可达密度。首先需要确定近邻样本个数k,然后计算LOF分数。这个分数是由局部可达密度计算得到的。

  下面介绍一个用LOF算法进行数据清洗,去除离群样本从而提高模型的案例。

from pyod.models.lof import LOF

#训练异常检测模型,然后输出训练集样本的异常分
clf=LOF(n_neighbors=20,algorithm='auto',leaf_size=30,metric='minkowski',p=2,metric_params=None,contamination=0.1,n_jobs=1)
clf.fit(x)

#异常分
out_pred = clf.predict_proba(x,method ='linear')[:,1]
train['out_pred'] = out_pred

#异常分在0.9百分位以下的样本删掉
key=train['out_pred'].quantile(0.9)

x = train[train.out_pred< key][feature_lst]
y = train[train.out_pred < key]['bad_ind']

val_x =  val[feature_lst]
val_y = val['bad_ind']

lr_model = LogisticRegression(C=0.1,class_weight='balanced')
lr_model.fit(x,y)
y_pred = lr_model.predict_proba(x)[:,1]
fpr_lr_train,tpr_lr_train,_ = roc_curve(y,y_pred)
train_ks = abs(fpr_lr_train - tpr_lr_train).max()
print('train_ks : ',train_ks)

y_pred = lr_model.predict_proba(val_x)[:,1]
fpr_lr,tpr_lr,_ = roc_curve(val_y,y_pred)
val_ks = abs(fpr_lr - tpr_lr).max()
print('val_ks : ',val_ks)
from matplotlib import pyplot as plt
plt.plot(fpr_lr_train,tpr_lr_train,label = 'train LR')
plt.plot(fpr_lr,tpr_lr,label = 'evl LR')
plt.plot([0,1],[0,1],'k--')
plt.xlabel('False positive rate')
plt.ylabel('True positive rate')
plt.title('ROC Curve')
plt.legend(loc = 'best')
plt.show()

  模型效果有所提升,并且过拟合的倾向也稍微减轻。因此在建模前先使用LOF算法将样本中的离群点过滤掉。

IF异常检测法

  孤立森林(Isolation Forest),是一种基于空间随机划分思想的集成算法,由多棵二叉树并行得到,再将结果进行加权平均。在IF的每棵孤立树中,特征及特征值的选择完全是从数据中随机选取的。   用一个简单的例子来说明 Isolation Forest 的基本想法。沿着两个坐标轴进行随机切分,尝试把下图中的点A'和点B'分别切分出来。先随机选择一个特征维度,在这个特征的最大值和最小值之间随机选择一个值,按照跟特征值的大小关系将数据进行左右切分。然后,在左右两组数据中,重复上述步骤,再随机的按某个特征维度的取值把数据进行细分,直到无法细分,即:只剩下一个数据点,或者剩下的数据全部相同。跟先前的例子类似,直观上,点B'跟其他数据点比较疏离,可能只需要很少的几次操作就可以将它细分出来;点A'需要的切分次数可能会更多一些。

异常检测实战笔记

  孤立森林的核心概念,就是数据点在二叉树中所处的深度反应了该条数据的“疏离”程度。

  下面介绍用IF异常检测算法制作一张PreA评分卡。

  PreA模型是指在申请评分卡之前,设置一张根据免费数据进行粗筛选的评分卡。需要模型可以拒绝很少量的客群,并且其中大部分都是负样本。这样可以节省掉被拒绝用户查询外部数据的成本。下面使用异常分数作为PreA模型的评分,使用0.7分作为正负样本的分割阈值。

from pyod.models.iforest import IForest
clf = IForest(behaviour='new', bootstrap=False, contamination=0.1, max_features=1.0,
                max_samples='auto', n_estimators=500, n_jobs=-1, random_state=None,verbose=0)
clf.fit(x)
out_pred = clf.predict_proba(x,method ='linear')[:,1]
train['out_pred'] = out_pred
trian['for_pred']=np.where(train.out_pred>0.1,'负样本占比','正样本占比')
dic=dict(train.groupby(train.for_pred).bad_ind.agg(np.sum)/train.bad_ind.groupby(train.for_pred).count())
pd.DataFrame(dic,index=[0])

  结果是被拒绝的用户中负样本占比高达12.5%,远大于原始数据。因此可以先使用部分数据训练无监督异常检测模型,将明显的离群用户过滤掉,以减少查询外部数据的开销。

  在不能部署监督学习的场景时,比如冷启动阶段,可以尝试使用异常检测的方法部署模型。   再使用IF制作无监督版申请评分卡。

from pyod.models.iforest import IForest
clf = IForest(behaviour='new', bootstrap=False, contamination=0.1, max_features=1.0,
                max_samples='auto', n_estimators=500, n_jobs=-1, random_state=None,verbose=0)
clf.fit(x)
y_pred = clf.predict_proba(x,method ='linear')[:,1]
fpr_lr_train,tpr_lr_train,_ = roc_curve(y,y_pred)
train_ks = abs(fpr_lr_train - tpr_lr_train).max()
print('train_ks : ',train_ks)

y_pred = clf.predict_proba(val_x,method ='linear')[:,1]
fpr_lr,tpr_lr,_ = roc_curve(val_y,y_pred)
val_ks = abs(fpr_lr - tpr_lr).max()
print('val_ks : ',val_ks)
from matplotlib import pyplot as plt
plt.plot(fpr_lr_train,tpr_lr_train,label = 'train LR')
plt.plot(fpr_lr,tpr_lr,label = 'evl LR')
plt.plot([0,1],[0,1],'k--')
plt.xlabel('False positive rate')
plt.ylabel('True positive rate')
plt.title('ROC Curve')
plt.legend(loc = 'best')
plt.show()
异常检测实战笔记

  可以看到,KS和ROC曲线表现不如监督训练的评分卡,但是对于无监督学习来说效果是非常不错的。因此在项目冷启动的过程中,可以根据经验挑选一些有区分度的特征,使用异常检测模型进行无监督训练,得到集欺诈检测与信用评级功能与一体的冷启动模型。

  无监督模型的建模难点不在于模型,而在于特征的选取。由于没有标签,特征的构造无法通过数据分析手段进行,因此通常需要结合领域知识进行精准的特征构造。

【作者】:Labryant

【原创公众号】:风控猎人

【简介】:某创业公司策略分析师,积极上进,努力提升。乾坤未定,你我都是黑马。

【转载说明】:转载请说明出处,谢谢合作!~

展开阅读全文

页面更新:2024-06-05

标签:异常   正态分布   平均数   噪声   样本   算法   密度   局部   实战   分数   邻居   模型   特征   距离   笔记   方法   数据   科技

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top