一、整体概览

反欺诈往往看做是二分类问题,但是仔细想想是多分类问题,因为每种不同类型的欺诈都当做是一种单独的类型。欺诈除了多样并且不断变化,欺诈检测还面临一下问题:

1). 由于大部分情况数据是没有标签的,各种成熟的监督学习是没有办法应用

2). 区分噪音和异常点时难度比较大,甚至需要一点点经验

3). 当多种不同的欺诈结合在一起时,区分欺诈类型比较难,因为不了解每一种欺诈定义

4). 即使有真的欺诈数据,即在有标签的情况下用监督学习,也存在很大的不确定性。用这种历史数据学出的模型只能检测当时存在以及比较相似的欺诈,而对于不同的诈骗和从未见过的诈骗,模型预测效果一般比较差。

因此,在实际情况中,一般不直接用任何监督学习,或者说不能至少单独依靠一个监督学习模型来奢求检测到所有的欺诈。没有历史标签和对诈骗的理解,无法做出对诈骗细分的模型。一般常见的做法是使用无监督模型,且需要不同专家根据经验来验证预测,提供反馈,便于及时调整模型。

拿到含有欺诈的数据之后,一般做法有通过关联矩阵分析以及多维尺度变换。

二、无监督学习

当一个场景需要做预判的时候,有没有标签,往往能做的主要有迁移学习、专家模型、无监督算法。

迁移学习

源域样本和目标域样本分布有比较大的区别,目标域样本量不够的话,通过算法缩小边缘分布之间和条件分布之间的差异。

  • 基于特征的迁移
  • 基于模型的迁移
  • 基于实例的迁移

不足之处:需要拥有与当前目标场景相关的源域数据

专家模型

主要是根据主观经验进行评判,而不是根据统计分析或者模型算法来进行客观的计算。常规操作过程如下所示:

  • 根据相关经验判断特征重要性
  • 根据相关经验进行变量加权

不足之处:需要大量的行业经验积累,有时候不太具有说服性

无监督算法

缺乏足够的先验知识,无法对数据进行标记时,使用的一种机器学习方法,代表聚类、降维等。在风控领域中主要使用的是聚类和无监督异常检测。聚类是发现样本之间的相似性,异常检测是发现样本之间的差异性。

聚类

  • K-Means
  • DBSCAN
  • 层次聚类
  • 社区发现

一般主要是对负样本聚类,将有问题的用户细分为几类。社区发现算法一般是识别团伙欺诈的主要手段之一,主要方法是通过知识图谱将小团体筛选出来。在知识图谱中,聚集意味着风险。

异常检测

异常点检测,通常也被称为离群点检测,是找出与预期对象的行为差异较大的对象的一个检测过程。检测出来的数据被称为异常点或者离群点。异常点在生产生活中有比较多的应用,例如广告点击反作弊、设备损坏等。异常点是一个数据对象,明显不同于其他的数据对象。如下所示,N1,N2为区域内的正常数据,而离这两个正常区域比较远的地方的点为异常点。

异常检测和不均衡学习的区别是,异常检测一般是无监督的;与普通的二分类区别是异常检测往往看作为是二分类,但是其实是多分类(由于造成异常的原因各不相同)

异常检测算法的前提假设:1) 异常数据跟样本中大多数数据不太一样  2) 异常数据在整体数据样本中占比相对比较小

异常检测的主要思想是基于样本(小群体)之间的相似度: 距离、密度、簇

异常检测算法的意义:

1). 很多场景没有标签或者标签比较少,不能训练监督模型

2). 样本总是在发生变换,只能从一个小群体内部发现异常

3). 异常检测假设异常样本数据量占比较少,并且在某种维度上远离其他样本,符合个体欺诈的先验知识。在团体欺诈不太适用。

4). 样本群体有异构成分,可以对样本进行筛选

三、异常检测的常用算法

常见的异常检测算法有Z-score算法、KNN算法、Local Outlier Factor、孤立森林等

Z-score算法

假设样本服从正态分布,用于描述样本偏离正态分布的程度。通过计算μ和σ得到当前样本所属于的正态分布的表达式,然后分别计算每个样本在这个概率密度函数下被生成的概率,当概率小于某一阈值我们认为这个样本是不属于这个分布的,因此定义为异常值。计算公式如下所示:

根据获取平均值和方差的估计值,然后给定一个新的训练实例,根据模型计算p(x):

当p(x) < ep(x) < e时候,数据未异常

缺点是需要假设样本满足正态分布,而大部分场景不满足正态分布假设条件

KNN异常检测

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

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

我们有三种方法

  • 最大:使用到第k个邻居的距离作为离群值得分
  • 平均值:使用所有k个邻居的平均值作为离群值得分
  • 中位数:使用到k个邻居的距离的中值作为离群值得分

在实际方法中后两种的应用度较高。然而,分数的绝对值在很大程度上取决于数据集本身、维度数和规范化。参数k的选择当然对结果很重要。如果选择过低,记录的密度估计可能不可靠。(即过拟合)另一方面,如果它太大,密度估计可能太粗略。K值的选择通常在10<k<50这个范围内。所以在分类方法中,选择一个合适的K值,可以用交叉验证法。但是,事实上基于KNN的算法都是不适用于欺诈检测的,因为他们本身就对噪声比较敏感。

Local Outlier Factor

基于密度的LOF算法相对比较更加简单、直观以及不需要对数据的分布有太多的要求,还能量化每个数据点的异常程度。该算法是基于密度的算法,主要核心的部分是关于数据点密度的刻画。算法的整个流程涉及如下概念:

1)k-近邻距离(k-distance): 在距离数据点p最近的几个点中,第k个最近的点跟点p之间的距离称为点p的k-近邻距离,记为k-distance(p).

2)  可达距离(rechability distance): 可达距离的定义跟k-近邻距离是相关的,给定参数k时,数据点p到数据点o的可达距离reach-dist(p,o)为数据点o的K-近邻距离和数据点p与点o之间的直接距离的最大值。即:

reachdist-k(p,o) = max{k-distance(o),d(p,o)}

3) 局部可达密度(local rechablity density):局部可达密度的定义是基于可达距离的,对于数据点p,那些跟点p的距离小于等于k-distance(p)的数据点称为它的k-nearest-neighor,记为Nk(p),数据点p的局部可达密度为它与邻近的数据点的平均可达距离的倒数,即:

4) 局部异常因子: 根据局部可达密度的定义,如果一个数据点跟其他点比较疏远的话,那么显然它的局部可达密度就小。但LOF算法衡量一个数据点的异常程度,并不是看它的绝对局部密度,而是看它跟周围邻近的数据点的相对密度。这样做的好处是可以允许数据分布不均匀、密度不同的情况。局部异常因子即是用局部相对密度来定义的。数据点 p 的局部相对密度(局部异常因子)为点p的邻居们的平均局部可达密度跟数据点p的局部可达密度的比值,即:

根据局部异常因子的定义,如果数据点 p 的 LOF 得分在1附近,表明数据点p的局部密度跟它的邻居们差不多;如果数据点 p 的 LOF 得分小于1,表明数据点p处在一个相对密集的区域,不像是一个异常点;如果数据点 p 的 LOF 得分远大于1,表明数据点p跟其他点比较疏远,很有可能是一个异常点。

小结:整个LOF算法,首先对于每个数据点,计算它与其它所有点的距离,并按从近到远排序,然后对于每个数据点,找到它的k-nearest-neighbor,最后计算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)

计算出每一个数据点的LOF值,然后在二维空间中展示,如下图所示,数据点的LOF值越大表示该点越异常

Trick: LOF算法中关于局部可达密度的定义其实暗含了一个假设,即:不存在大于等于 k 个重复的点。当这样的重复点存在的时候,这些点的平均可达距离为零,局部可达密度就变为无穷大,会给计算带来一些麻烦。在实际应用时,为了避免这样的情况出现,可以把 k-distance 改为 k-distinct-distance,不考虑重复的情况。或者,还可以考虑给可达距离都加一个很小的值,避免可达距离等于零。

Isolation Forest

先用一个简单的例子来说明 Isolation Forest 的基本想法。假设现在有一组一维数据(如下图所示),我们要对这组数据进行随机切分,希望可以把点 A 和点 B 单独切分出来。具体的,我们先在最大值和最小值之间随机选择一个值 x,然后按照 =x 可以把数据分成左右两组。然后,在这两组数据中分别重复这个步骤,直到数据不可再分。显然,点 B 跟其他数据比较疏离,可能用很少的次数就可以把它切分出来;点 A 跟其他数据点聚在一起,可能需要更多的次数才能把它切分出来。

我们把数据从一维扩展到两维。同样的,我们沿着两个坐标轴进行随机切分,尝试把下图中的点A'和点B'分别切分出来。我们先随机选择一个特征维度,在这个特征的最大值和最小值之间随机选择一个值,按照跟特征值的大小关系将数据进行左右切分。然后,在左右两组数据中,我们重复上述步骤,再随机的按某个特征维度的取值把数据进行细分,直到无法细分,即:只剩下一个数据点,或者剩下的数据全部相同。跟先前的例子类似,直观上,点B'跟其他数据点比较疏离,可能只需要很少的几次操作就可以将它细分出来;点A'需要的切分次数可能会更多一些。

按照先前提到的关于“异常”的两个假设,一般情况下,在上面的例子中,点B和点B' 由于跟其他数据隔的比较远,会被认为是异常数据,而点A和点A' 会被认为是正常数据。直观上,异常数据由于跟其他数据点较为疏离,可能需要较少几次切分就可以将它们单独划分出来,而正常数据恰恰相反。这其实正是Isolation Forest(IF)的核心概念。IF采用二叉树去对数据进行切分,数据点在二叉树中所处的深度反应了该条数据的“疏离”程度。整个算法大致可以分为两步:

  • 训练:抽取多个样本,构建多棵二叉树(Isolation Tree,即 iTree);
  • 预测:综合多棵二叉树的结果,计算每个数据点的异常分值。

训练:构建一棵 iTree 时,先从全量数据中抽取一批样本,然后随机选择一个特征作为起始节点,并在该特征的最大值和最小值之间随机选择一个值,将样本中小于该取值的数据划到左分支,大于等于该取值的划到右分支。然后,在左右两个分支数据中,重复上述步骤,直到满足如下条件:

  • 数据不可再分,即:只包含一条数据,或者全部数据相同。
  • 二叉树达到限定的最大深度。

预测:计算数据 x 的异常分值时,先要估算它在每棵 iTree 中的路径长度(也可以叫深度)。具体的,先沿着一棵 iTree,从根节点开始按不同特征的取值从上往下,直到到达某叶子节点。假设 iTree 的训练样本中同样落在 x 所在叶子节点的样本数为 T.size,则数据 x 在这棵 iTree 上的路径长度 h(x),可以用下面这个公式计算:

h(x)=e+C(T.size)

公式中,e 表示数据 x 从 iTree 的根节点到叶节点过程中经过的边的数目,C(T.size) 可以认为是一个修正值,它表示在一棵用 T.size 条样本数据构建的二叉树的平均路径长度。一般的,C(n) 的计算公式如下:

C(n)=2H(n−1)−2(n−1)/n

其中,H(n-1) 可用 ln(n-1)+0.577 估算,这里的常数是欧拉常数。数据 x 最终的异常分值 Score(x) 综合了多棵 iTree 的结果

公式中,E(h(x)) 表示数据 x 在多棵 iTree 的路径长度的均值,φ表示单棵 iTree 的训练样本的样本数,C(φ)表示用φ条数据构建的二叉树的平均路径长度,它在这里主要用来做归一化。

从异常分值的公式看,如果数据 x 在多棵 iTree 中的平均路径长度越短,得分越接近 1,表明数据 x 越异常;如果数据 x 在多棵 iTree 中的平均路径长度越长,得分越接近 0,表示数据 x 越正常;如果数据 x 在多棵 iTree 中的平均路径长度接近整体均值,则打分会在 0.5 附近。

四、应用案例

1、清洗建模数据集,将异常样本通过无监督算法进行筛选

from pyod.models.iforest import IForest
from matplotlib import pyplot as pltclf = 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_predx = train[train.out_pred< 0.7][feature_lst]
y = train[train.out_pred < 0.7]['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)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()

2、通过样本异常程度进行分析

train.out_pred.groupby(train.obs_mth).mean()train.out_pred.groupby(train.obs_mth).max()train.out_pred.groupby(train.obs_mth).var()train['for_pred'] = np.where(train.out_pred>0.7,1,0)train.for_pred.groupby(train.obs_mth).sum()/train.for_pred.groupby(train.obs_mth).count()#看一下badrate
train.bad_ind.groupby(train.for_pred).sum()/train.bad_ind.groupby(train.for_pred).count()

3、冷启动,假设没有标签

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

参考文献:https://pyod.readthedocs.io/en/latest/pyod.html

无监督算法与异常检测相关推荐

  1. AIOps指标异常检测之无监督算法

    随着系统规模的变大.复杂度的提高.监控覆盖的完善,监控数据量越来越大,运维人员无法从海量监控数据中发现质量问题.智能化的异常检测就是要通过AI算法,自动.实时.准确地从监控数据中发现异常,为后续的诊断 ...

  2. LogTAD:无监督跨系统日志异常域检测

    摘要 日志异常检测,其对开发稳定.可持续的系统具有重要意义.但当系统刚上线时,收集足够的数据训练一个无监督模型是不现实的.为此本文提出了一个可转移的日志异常检测(LogTAD)框架,该框架利用对抗域适 ...

  3. 论标签对无监督算法的使用

    说到无监督机器学习(unsupervised machinelearning),头脑中第一个蹦出来的词一定是三个字--"无标签"!那么,是不是说,无监督就一定不需要标签?用了标签就 ...

  4. 聚类dbi指数_一种基于DBI-PD聚类算法的异常检测机制

    一种基于 DBI-PD 聚类算法的异常检测机制 丁姝郁 [期刊名称] <电脑开发与应用> [年 ( 卷 ), 期] 2015(000)002 [摘要] 分析了网络数据维数和检测准确度之间的 ...

  5. 目标检测YOLO实战应用案例100讲-无监督领域自适应目标检测方法研究与应用

    目录 无监督领域自适应目标检测方法研究 领域自适应目标检测 目标检测相关技术介绍

  6. 异常检测:综述(基本都是无监督算法)【时间序列算法:AR/MA/ARMA】【传统机器学习算法:孤独森林、One Class SVM】【深度学习算法:AutoEncoder、LSTM、DeepLog】

    一.什么是异常值? 在机器学习中,异常检测和处理是一个比较小的分支,或者说,是机器学习的一个副产物,因为在一般的预测问题中,模型通常是对整体样本数据结构的一种表达方式,这种表达方式通常抓住的是整体样本 ...

  7. 综述:弱监督下的异常检测算法

    一.前言 文章标题是: Weakly Supervised Anomaly Detection: A Survey 这是一篇针对"弱监督"异常检测的综述. 其中弱监督异常检测 简称 ...

  8. UP-DETR:收敛更快!精度更高!华南理工微信开源无监督预训练目标检测模型...

    关注公众号,发现CV技术之美 0 写在前面 基于Transformer编码器-解码器结构的DETR达到了与Faster R-CNN类似的性能.受预训练Transformer在自然语言处理方面取得巨大成 ...

  9. 文本相似度之五种无监督算法实现代码

    短文本相似度,即求解两个短文本之间的相似程度:它是文本匹配任务或文本蕴含任务的一种特殊形式,返回文本之间相似程度的具体数值.然而在工业界中,短文本相似度计算占有举足轻重的地位. 例如:在问答系统任务( ...

最新文章

  1. Domino Web开发规则之三:以资源管理库为中心开发
  2. 【LeetCode从零单排】No21.MergeTwoSortedLists
  3. Eclipse中查看Android源代码
  4. [NOIP2016 提高组] 天天爱跑步(树上差分)
  5. leetcode 368. 最大整除子集(dp)
  6. 项目日报模板_第一届全国技能大赛现场直击:混凝土建筑项目全场最“高”
  7. Visual C++线程同步技术
  8. VNC Connect Enterprise for mac(远程桌面软件)
  9. windows7怎么升级10_最新主板真的无法安装windows7吗?
  10. 软件工程毕设(六)·论文
  11. linux多线程 进程休眠,转载:Linux多线程之线程休眠
  12. DSP程序死机(跑飞)的一些情况-硬件原因
  13. 红帽linux安装教程
  14. top20万_美国top20大学博士,回国进腾讯后感叹:月入6万憋屈,后悔回国了
  15. 第二天:TypeScript的InterFace接口、类、修饰符、抽象类、implements
  16. 大数据时代的 10 个重大变化
  17. csps2019格雷码
  18. android 支付宝快捷支付
  19. bzoj3039 玉蟾宫【单调栈】
  20. 热浪(单源最短路问题)

热门文章

  1. Mysql 存储引擎和事物基础概念
  2. Unity C#单例模式的实现
  3. Pacemaker+Corosync PostgreSQL流复制HA的部署(pha4pgsql)
  4. java多线程中的异常处理
  5. Linux 上的高可用中间件
  6. JavaScript MVC之Jamal
  7. 最小生成树板子-AcWing 858. Prim算法求最小生成树
  8. 【Linux入门连载一】[Win10下安装Linux虚拟机]VMWare15运行CentOS7(亲测有效)
  9. Leetcode1690. 石子游戏 VII[C++题解]:带有博弈论的区间dp
  10. OpenCV实战中:blender-feed(img_warped_s, mask_warped, corners[img_idx]);这里有异常的处理方法