分类数据的离群点检测
coupled-biased-random-walks的Python项目详细描述
耦合有偏随机游动
分类数据的异常值检测
概述
python[2.7,3.4,3.5,3.6,3.7]实现了pang,cao,chen在https://www.ijcai.org/Proceedings/16/Papers/272.pdf中描述的耦合有偏随机游动(cbrw)离群点检测算法。
此实现操作的是python dict,而不是pandas数据帧。这样做的好处是可以以一种简单的方式用新的观测值更新模型,并且在某些方面更有效。然而,这些优点的代价是,与使用底层数据帧实现所需的次数相比,迭代观察值的(可能很大)指令的次数要多。
如果要处理先前加载到数据帧中的数据,只需使用pandas.DataFrame.to_dict(orient='records')
的结果而不是数据帧本身来向模型添加观察结果。注意,由于数据帧通常用nan
填充缺少的值,因此检测器将忽略任何观察记录中值为nan
的特征。因此,在使用数据帧的to_dict
方法创建记录之前,不需要进一步预处理数据帧。
安装
这个包托管在pypi上,可以通过pip
:
pip install coupled_biased_random_walks
改为从源安装:
$ git clone git@github.com:dkaslovsky/Coupled-Biased-Random-Walks.git
$ cd Coupled-Biased-Random-Walks
$ python setup.py install
示例
让我们对论文中作者的示例数据集运行cbrw检测算法:
此数据在此存储库中保存为.CSV file,并由example.py作为dict列表加载到内存中。注意,我们在加载数据时删除Cheat?
列,因为这实际上是指示要检测的异常活动的目标变量。探测器被实例化,观测结果添加如下:
>>> detector = CBRW()
>>> detector.add_observations(observations)
其中observations
是一个可引用的dict,例如从example.csv文件加载的dict。一旦加载了所有观察结果,就可以通过调用fit()
最终确定检测器进行评分,然后对观察结果进行评分。
>>> detector.fit()
>>> scores = detector.score(observations)
即使在拟合和评分之后,也可以通过add_observations
添加更多的观察值,并且检测器可以再次适合用于评分。这种实现的优点是能够用新的观察值进行增量更新。
示例数据的评分结果如下所示。请注意,存在欺诈的唯一行(Cheat? = yes
)收到的异常分数最大。
Score: 0.1055 | Data: {'Gender': 'male', 'Education': 'master', 'Marriage': 'divorced', 'Income': 'low'}
Score: 0.0797 | Data: {'Gender': 'female', 'Education': 'master', 'Marriage': 'married', 'Income': 'medium'}
Score: 0.0741 | Data: {'Gender': 'male', 'Education': 'master', 'Marriage': 'single', 'Income': 'high'}
Score: 0.0805 | Data: {'Gender': 'male', 'Education': 'bachelor', 'Marriage': 'married', 'Income': 'medium'}
Score: 0.0992 | Data: {'Gender': 'female', 'Education': 'master', 'Marriage': 'divorced', 'Income': 'high'}
Score: 0.0752 | Data: {'Gender': 'male', 'Education': 'PhD', 'Marriage': 'married', 'Income': 'high'}
Score: 0.0741 | Data: {'Gender': 'male', 'Education': 'master', 'Marriage': 'single', 'Income': 'high'}
Score: 0.0815 | Data: {'Gender': 'female', 'Education': 'PhD', 'Marriage': 'single', 'Income': 'medium'}
Score: 0.0728 | Data: {'Gender': 'male', 'Education': 'PhD', 'Marriage': 'married', 'Income': 'medium'}
Score: 0.0979 | Data: {'Gender': 'male', 'Education': 'bachelor', 'Marriage': 'single', 'Income': 'low'}
Score: 0.0812 | Data: {'Gender': 'female', 'Education': 'PhD', 'Marriage': 'married', 'Income': 'medium'}
Score: 0.0887 | Data: {'Gender': 'male', 'Education': 'master', 'Marriage': 'single', 'Income': 'low'}
通过运行:
$ python example.py
cbrw算法也可以用来计算特征权重。这些权重在检测器匹配时计算,并在评分时使用,但也可用于任何其他离群点检测算法。因此,cbrw算法可以简单地计算特征权重,而无需对观测值进行评分。在调用检测器的fit
方法之后,特征权重作为检测器的属性存储:
>>> detector = CBRW()
>>> detector.add_observations(observations)
>>> detector.fit()
>>> detector.feature_weights
对于示例数据,计算的特征权重是
{'Education': 0.26272841835358907,
'Gender': 0.16078750024987953,
'Income': 0.2938981973816106,
'Marriage': 0.2825858840149206}
实施说明
- 为了提高效率,只在调用
.fit()
时(重新)计算检测器状态。因此,在调用.fit()
之前,添加新的观察值(.add_observations()
)不会影响评分。重新调整将覆盖以前的状态,但包括所有添加的观测值的贡献。 - 如果需要一行训练,
.add_observations()
和.fit()
方法可以链接在一起:detector.add_observations(observations).fit()
。 - 包含先前未匹配的特征名称或特征值的观察将被评分为
nan
。若要忽略任何此类“新”功能并仅基于已知功能进行观察,请使用ignore_unknown=True
初始化检测器。
测试
运行单元测试:
$ python -m unittest discover -v