栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

数据集中异常值的处理之lof,iforest算法

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据集中异常值的处理之lof,iforest算法

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录
  • 前言
  • 一、预定义的函数和数据
  • 二、具体实践
    • 1.z-score异常检测
    • 2.Local Outlier Factor
    • 3.孤立森林异常点检测
  • 总结


前言

异常点检测(Outlier detection),又称为离群点检测,是找出与预期对象的行为差异较大的对象的一个检测过程。这些被检测出的对象被称为异常点或者离群点。异常点检测应用非常广泛

  • 信用卡反欺诈
  • 工业损毁检测
  • 广告点击反作弊
  • 刷好评,刷单检测
  • 羊毛党检测
    异常点(outlier)是一个数据对象,它明显不同于其他的数据对象。如下图1所示,N1、N2区域内的点是正常数据。而离N1、N2较远的O1、O2、O3区域内的点是异常点。


异常点检验常用算法:

  • Z-score检验
  • Local Outlier Factor
  • 孤立森林

一、预定义的函数和数据
data = pd.read_csv(r'F:教师培训ppd7df_Master_merge_clean.csv',encoding='gb18030')
x = data[data.target.notnull()].drop(columns=['Idx', 'target', 'sample_status', 'ListingInfo'])
y = data[data.target.notnull()]['target']

def get_auc(x, y):
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import roc_auc_score, roc_curve
    import lightgbm as lgb
    
    #画出auc图的函数     
    def roc_auc_plot(clf,x_train,y_train,x_test, y_test):
        train_auc = roc_auc_score(y_train,clf.predict_proba(x_train)[:,1])
        train_fpr, train_tpr, _ = roc_curve(y_train,clf.predict_proba(x_train)[:,1])
        train_ks = abs(train_fpr-train_tpr).max()
        print('train_ks = ', train_ks)
        print('train_auc = ', train_auc)

        test_auc = roc_auc_score(y_test,clf.predict_proba(x_test)[:,1])
        test_fpr, test_tpr, _ = roc_curve(y_test,clf.predict_proba(x_test)[:,1])
        test_ks = abs(test_fpr-test_tpr).max()
        print('test_ks = ', test_ks)
        print('test_auc = ', test_auc)

        from matplotlib import pyplot as plt
        plt.plot(train_fpr,train_tpr,label = 'train_auc='+str(train_auc))
        plt.plot(test_fpr,test_tpr,label = 'test_auc='+str(test_auc))
        plt.plot([0,1],[0,1],'k--', c='r')
        plt.xlabel('False positive rate')
        plt.ylabel('True positive rate')
        plt.title('ROC Curve')
        plt.legend(loc = 'best')
        plt.show()

    x_train,x_test, y_train, y_test = train_test_split(x,y,random_state=2,test_size=0.2)

    lgb_model = lgb.LGBMClassifier(n_estimators=800,
                                    boosting_type='gbdt',
                                   learning_rate=0.04,
                                   min_child_samples=68,
                                   min_child_weight=0.01,
                                      max_depth=4,
                                  num_leaves=16,
                                  colsample_bytree=0.8,
                                  subsample=0.8,
                                  reg_alpha=0.7777777777777778,
                                  reg_lambda=0.3,
                                   objective='binary')

    clf = lgb_model.fit(x_train, y_train,
                  eval_set=[(x_train, y_train),(x_test,y_test)],
                  eval_metric='auc',early_stopping_rounds=100)
    roc_auc_plot(clf,x_train,y_train,x_test, y_test)

二、具体实践 1.z-score异常检测

假设样本服从正态分布,用于描述样本偏离正态分布的程度。

通过计算 μ mu μ和 σ sigma σ得到当前样本所属于的正态分布的表达式,然后分别计算每个样本在这个概率密度函数下被生成的概率,当概率小于某一阈值我们认为这个样本是不属于这个分布的,因此定义为异常值。
缺点:需要假设样本满足正态分布,而我们大部分场景都不满足这种假设条件。
代码如下(示例):

2.Local Outlier Factor

LOF是基于密度的经典算法(Breuning et. al. 2000), 文章发表于 SIGMOD 2000

  • 在 LOF 之前的异常检测算法大多是基于统计方法的,或者是借用了一些聚类算法用于异常点的识别(比如 ,DBSCAN,OPTICS)。
  • 基于统计的异常检测算法通常需要假设数据服从特定的概率分布,但假设往往不成立
  • 聚类方法通常只能给出 0/1 的判断(即:是不是异常点),不能量化每个数据点的异常程度
  • 基于密度的LOF算法要更简单、直观,不需要对数据的分布做太多要求,还能量化每个数据点的异常程度(outlierness)。
    代码如下(示例):

LOF ≈1 ⇒ 非异常 LOF ≫1 ⇒ 异常
核心基于密度聚类算法,K-邻近距离,可达距离,局部可达密度,LOF 局部异常因子(local outlier factor)等概念

  • 如果数据点 p 的 LOF 得分在1附近,表明数据点p的局部密度跟它的邻居们差不多;
  • 如果数据点 p 的 LOF 得分小于1,表明数据点p处在一个相对密集的区域,不像是一个异常点;
  • 如果数据点 p 的 LOF 得分远大于1,表明数据点p跟其他点比较疏远,很有可能是一个异常点
#PyOD是一个用于检测数据中异常值的库。它提供对20多种不同算法的访问,以检测异常值,下面的算法都通过PYOD实现

from pyod.models.lof import LOF

data = pd.read_csv(r'F:教师培训ppd7df_Master_merge_clean.csv',encoding='gb18030')
x = data[data.target.notnull()].drop(columns=['Idx', 'target', 'sample_status', 'ListingInfo'])
y = data[data.target.notnull()]['target']

def my_lof(x,y):
    lof = LOF(n_neighbors=20,
                algorithm='auto',
                leaf_size=30,
                metric='minkowski',
                p=2,
                metric_params=None,
                contamination=0.1,
                n_jobs=1,
                novelty=False)
    lof.fit(x)
    out_pred = lof.predict_proba(x, method='linear')[:,1]
    x = pd.concat([y,x], axis=1)
    x['out_pred'] = out_pred
    q = x['out_pred'].quantile(0.93)
    y = x[x.out_pred < q]['target']
    x = x[x.out_pred < q].drop(columns=['out_pred','target'])
    
    return x, y
    
new_x, new_y = my_lof(x, y)
get_auc(new_x, new_y)
效果从原来的test_auc =  0.7414488664969987提高到0.7501722664490398

3.孤立森林异常点检测

论文地址(https://ieeexplore.ieee.org/document/4781136)
先用一个简单的例子来说明 Isolation Forest 的基本想法

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

# Isolation Forest孤立森林异常点检测

from pyod.models.iforest import IForest

def my_Ifo(x,y):
    ifo = IForest(n_estimators=500,
            max_samples='auto',
            contamination=0.1,
            max_features=1.0,
            bootstrap=False,
            n_jobs=1,
            behaviour='new',
            random_state=None,
            verbose=0,)
    ifo.fit(x)
    out_pred = ifo.predict_proba(x, method='linear')[:,1]
    x = pd.concat([y,x], axis=1)
    x['out_pred'] = out_pred
    y = x[x.out_pred < 0.7]['target']
    x = x[x.out_pred < 0.7].drop(columns=['out_pred','target'])
    return x, y

    
new_x, new_y = my_Ifo(x, y)
get_auc(new_x, new_y)
效果从原来的test_auc =  0.7414488664969987提高到0.7577292212472797


总结

通过对比分析,我们发现孤立森林的效果要好于lof算法。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/290739.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号