侦查欺诈交易郝召马骁为什么研究欺诈交易•数据挖掘的结果有助于公司的事后检查活动•数据挖掘过程能够提供某种欺诈概率排序作为输出结果,可以使公司以最佳方式来利用其事后检查资源应用方面:信用卡交易、税务申报检验等本章新的数据挖掘主题:离群值活异常值检验、聚类分析、办监督预测模型问题的描述与目标•欺诈行为通常与异常的观测值相关联,因为这些欺诈行为是偏离常规的。在多个数据分析领域,这些偏离常规的行为经常称为离群值问题的描述与目标•本案例使用的数据时某公司的销售员所报告的交易数据。这些销售员负责销售该公司的产品并定期报告销售情况。•销售员可以按照自己的策略和市场情况来自由设置销售价格。月末,向公司报告销售情况。•数据挖掘应用的目的是根据公司过去发现的交易报告肿的错误和欺诈企图,帮助公司完成核实这些销售报告的真实性的工作。提供一份欺诈率排名报告,这个欺诈率排名将允许公司把有限的检验资源分配给系统提示的更“可疑”的那些报告可用的数据•数据来自一个未公开的渠道•共401146行,每一行包括来自销售员报告的信息。包括:•ID:说明销售员ID的一个因子变量•Prod:说明销售产品ID号的一个因子变量•Quant:报告该产品销售的数量•Val:报告销售记录的总价值•Insp:有三个可能值的因子变量——ok表示公司检查了该交易并认为该交易有效;fraud表示发现该交易为欺诈;unkn表示该交易未经过公司审核。加载数据•library(DMwR)•data(sales)•head(sales)•得到一个名为sales的数据框探索数据集•Summary()函数可以使人们出不了解数据的统计特征•summary(sales)数据中有大量的产品和销售人员信息探索数据集•还可以用nlevels()来确认这一点•nlevels(sales$ID)•nlevels(sales$Prod)探索数据集•如果在同一个交易中Quant列和Val列有大量的缺失值,就会产生比较严重的问题,这回导致一条销售交易中的有关销售量的关键信息缺失。检验如下:•length(which(is.na(sales$Quant)&is.na(sales$Val)))•sum(is.na(sales$Quant)&is.na(sales$Val))探索数据集•欺诈行为的比例对于总体而言是很低的•table(sales$Insp)/nrow(sales)*100绘制每个交易人员的交易数量和每个产品的交易数量图形•totS-table(sales$ID)•totP-table(sales$Prod)•barplot(totS,main='Transactionspersalespeople',names.arg='',xlab='Salespeople',•ylab='Amount')•barplot(totP,main='Transactionsperproduct',names.arg='',xlab='Products',•ylab='Amount')探索数据集探索数据集•检查产品单位价格的分布:•sales$Uprice-sales$Val/sales$Quant•summary(sales$Uprice)Min.1stQu.MedianMean3rdQu.Max.NA's0.008.4611.8920.3019.1126460.0014136探索数据集•检查最贵的和最便宜的产品•用单位价格的中位数来代表已经销售的产品的标准价格•attach(sales)•upp-aggregate(Uprice,list(Prod),median,na.rm=T)•topP-sapply(c(T,F),function(o)•upp[order(upp[,2],decreasing=o)[1:5],1])•colnames(topP)-c('Expensive','Cheap')•topP探索数据集•用上述5个产品的单位价格的箱图来确认它们完全不同的价格分布:•tops-sales[Prod%in%topP[1,],c('Prod','Uprice')]•tops$Prod-factor(tops$Prod)•boxplot(Uprice~Prod,data=tops,ylab='Uprice',log=y)•••探索数据集•找出那些给公司带来更多(少)资金的销售人员:•vs-aggregate(Val,list(ID),sum,na.rm=T)•scoresSs-sapply(c(T,F),function(o)•vs[order(vs$x,decreasing=o)[1:5],1])•colnames(scoresSs)-c('Most','Least')•scoresSs探索数据集•给公司带来更多资金的前100名销售人员的资金收入几乎占公司资金收入的40%,而底部的2000人的总收入不足公司总收入的2%。这说明,该公司需要进行内部改革。•sum(vs[order(vs$x,decreasing=T)[1:100],2])/sum(Val,na.rm=T)*100•sum(vs[order(vs$x,decreasing=F)[1:2000],2])/sum(Val,na.rm=T)*100探索数据集•对每个产品所销售的数量进行类似的分析,有:•qs-aggregate(Quant,list(Prod),sum,na.rm=T)•scoresPs-sapply(c(T,F),function(o)•qs[order(qs$x,decreasing=o)[1:5],1])•colnames(scoresPs)-c('Most','Least')•scoresPs•sum(as.double(qs[order(qs$x,decreasing=T)[1:100],2]))/•sum(as.double(Quant),na.rm=T)*100•sum(as.double(qs[order(qs$x,decreasing=F)[1:4000],2]))/•sum(as.double(Quant),na.rm=T)*100探索数据集•确定每个产品的异常值个数:•out-tapply(Uprice,list(Prod=Prod),•function(x)length(boxplot.stats(x)$out))•••out[order(out,decreasing=T)[1:10]]探索数据集•找到29446个被认为是离群值的教一,相当于总交易的7%•sum(out)•sum(out)/nrow(sales)*100数据问题•处理缺失值的办法:•1)剔除这些个案•2)用某些策略来填补缺失数据•3)运用可以处理缺失值的工具数据问题•前面提到,主要的问题是变量Quant和Val都有数据缺失的交易,如果移除所有的888个个案将导致剔除某些产品或是销售人员的大部分交易,这时候全部剔除888个个案是有问题的,•下面,检查这种情况是否会发生数据问题•可以用下面的代码显示与存在问题的交易有关的销售人员和产品,以及变量Quant和Val同时有缺失值的交易占很大比例的交易人员:•至少从销售人员方面来看,直接剔除这些同时在两个变量有缺失值的交易时合理的,因为它们代表了很小的一部分交易数据问题•两个变量都有缺失值的交易占较大的比例的产品:•多个产品将被剔除的交易超过20%,特别是产品p2689将有近40%的交易被删除。有点太多了数据问题•如果剔除有缺失数据的交易后只有少量的交易,那么我们就可以和类似产品的交易相结合一增加离群值检验的统计可靠性。总之,剔除所有同事在数量和价格上有缺失值的交易时最好的选择•detach(sales)•sales-sales[-which(is.na(sales$Quant)&is.na(sales$Val)),]•detach()函数是用来禁止直接访问数据框的列•数据问题•分析剩余的在数量或者价格变量上有缺失值的交易。计算每一种产品在数量上有缺失值的交易:•P2442和p2443两个产品所有的交易数量是缺失的,因此我们无法计算其标准价格,所以这些产品的交易信息不可能进行任何分析。•标记为ok的报告,意味着检查员掌握了比这个数据集更多的信息,或者我们得到的数据有输入错误,因为从这些交易中似乎不可能得到任何结论,基于此,将删除这些交易报告:数据问题•sales-sales[!sales$Prod%in%c('p2442','p2443'),]•删除了两种产品,得到新的的Prod的水平•nlevels(sales$Prod)•sales$Prod-factor(sales$Prod)•nlevels(sales$Prod)数据问题•是否有销售人员的所有交易数量为缺失值?•从结果上看,有几个销售人员没有在报告中填写交易的数量信息。•我们只要有其他销售人员报告的相同产品的交易,就可以尝试使用此信息来填补那些缺失值数据问题•对交易的Val列的缺失值进行类似的分析•这些数字是合理的,因为删除这些交易是没有意义的,我们将用其他的交易来填补这些缺失值数据问题•从销售人员方面,计算这些数字的方法如下:•同样,这个比例不是太高•在这个阶段,我们已经删除了所有没有足够信息来填补缺失值的报告•我们将首先获得每一个产品的标准单价,计算标准价格时,跳过标记为欺诈的交易价格数据问题•对剩余的交易,我们将使用每个产品单位价格的中位数作为相应产品的标准价格:•tPrice-tapply(sales[sales$Insp!='fraud','Uprice'],•list(sales[sales$Insp!='fraud','Prod']),•median,na.rm=T)•数据问题•因为我们没有交易同时在这两个变量上有缺失值,所以每一个产品有了一个标准单价后,我们就可以用它来计算两个可能的缺失值(Quant和Val)。下面的代码将填补所有剩余的缺失值。•然后重新计算Uprice列的值来填补先前未知的单位价格•保存数据集•数据问题•有些产品只有极少的交易,因为太少的交易,在要求的统计学显著性下很难做出决定。这种情况下,考虑是否可以喝一些产品的交易一起分析来避免这个问题•尽管缺失产品之间关系的信息,但可以尝试通过观察产品单价分部之间的相似性来推断其中的一些关系,如果可以发现具有类似价格的产品,我们可以考虑合并它们相应的交易并对它们一起进行分析,从而找到异常值•比较两个分布的一种方法是可视化检查法(在此不可行);另一种是比较总结分布的一些统计特性。•连续变量分布的两个重要属性是集中趋势和离散趋势•这里使用中位数作为衡量中心的统计量,应用四分位距(IQR)作为离散指标的统计量更有意义数据问题•上面的代码使用函数boxplot()获得中位数、第一个四分位数和第三个四分位数。对每个产品的所有交易,计算这些统计量,从分析中剔除有欺诈的交易。有了这些统计量以后,得到含有每个产品的中位数和四分位距的一个矩阵•数据问题•根据每个产品的中位数和IQR绘制的图形par(mfrow=c(1,2))•plot(ms[,1],ms[,2],xlab='Median',ylab='IQR',main='')•plot(ms[,1],ms[,2],xlab='Median',ylab='IQR',main='',col='grey',log=xy)•smalls-which(table(Prod)20)•points(log(ms[smalls,1]),log(ms[smalls,2]),pch='+')数据问题•对于交易数量少于20的产品,我们将寻找与它的单位价格分布最相似的产品,然后用Kolmogorow-Smirnov检验来检查两个产品是否在统计意义上相似。•下面的代码用来获得一个矩阵(similar)。矩阵中存储的事这种少于20个交易的每个产品的检查信息,用对象ms来保存前面获得的每个产品的单位价格的中位数和IQR