孤立森林(Isolation Forest)
最近正好在做孤立森林的项目,写下这篇推文记录下项目进程,也给需要做这个项目的同学一点参考。
1. 什么叫异常点
图中红色的点偏离大部分的数据,可以发现这些点分布稀疏且离密度高的群体较远,这样的点称为异常点。
在统计里面,分布稀疏的区域表示数据发生在此区域的概率很低,因而认为落在该区域中的点是异常点。异常点不一定是有问题的点,但是在各行各业中异常点都是重点关注的对象。
像支付风控中的异常点就有可能存在潜在的风险,比如卡片异常金额交易有可能发生了盗刷,商户异常时间交易有可能在干非法勾当等。
那么我们如何发现这些异常点,常见的有基于统计与数据分布(均值、方差)、箱线图、距离、密度等等,本文所讲的孤立森林是一种无监督的异常值检测算法。
2. 孤立森林算法原理
孤立森林算法类似随机森林。但是不根据信息增益或基尼指数来选择划分属性和节点,属性和节点的选择都是随机的。
在建树的过程中,如果一些样本很快到达了叶子节点,那么就被认为很有可能是异常点。为了减少随机性的影响,通过构造多颗树组成森林,再计算样本在所有树中的平均路径长度来寻找异常点。
3. 算法使用注意事项
1. 最好是连续数据
2. 孤立森林适用于维度(特征变量)不是特别多的数据。由于每次切数据空间都是随机选取一个维度,如果维度特别多,建完树后仍然有大量的维度信息没有被使用,导致算法可靠性降低。
高维空间还可能存在大量噪音维度或无关维度(irrelevant attributes),影响树的构建。对这类数据,建议使用子空间异常检测(Subspace Anomaly Detection)技术。
4. python实现代码
from sklearn.ensemble import IsolationForest #从sklearn中引入孤立森林模块
clf = IsolationForest(n_estimators = 100, max_samples = 100*2, contamination = 0.1)
clf.fit(X_train) #用X_train的数据训练训练器
y_pred_test = clf.predict(X_test) #预测test数据集中的数据是否异常,1为正常,-1为异常
#y_pred_train = clf.predict(X_train)
代码解析:
clf: 这一行是生成一个训练器,其中各个参数分别代表:
n_estimators: 森林中树的颗数,不是必有项,如缺失默认值为100
max_samples: 在每一颗树中,样本个数或比例,不是必有项,如缺失默认值 为“auto”
contamination: 用户中异常点的比例(0,0.5),不是必有项,如缺失默认值为0.1
max_features: 每颗树中特征个数或比例函数,不是必有项,默认值为1
5.数据模拟
背景介绍: 对于mcc是夜店商户进行数据分析,发现异常交易的夜店
step1:加载数据
import pandas as pd
import numpy as np
mcc_yd = pd.read_csv('mcc_yd.csv')
step2:挑选变量
coulmns_yd = [
'avg_tran_amt_30d',
'tran_cnt_m1w_suc_pct_30d',
'tran_cnt_nig_pct_30d',
'cred_pct',
'tran_cnt_100int_f5_suc_pct_30d'
]
step3: 使用孤立森林寻找异常样本点
X_yd = mcc_yd[columns_yd]
clf = IsolationForest(n_estimators = 100, max_samples = 100*2, contamination = 0.005)
clf.fit(X_yd)
y_pred_yd = clf.predict(X_yd)
代码解析:
X_yd: 这一步是生成待入模的特征标签
clf =: 这一步是生成特定参数的训练器,注意里面的参数可以根据自己的数据调整,由于我的样本量有1万4左右,我想先生成70个左右的异常点看看数据情况,所以取contamination为0.005。
clf.fit(X_yd) : 这一步是用X_yd的数据训练训练器
y_pred_yd: 这一步是用训练好的训练器预测X_yd中的数据看是否有异常样本,如果结果为1是正常样本,结果为-1是异常样本
找出来的异常样本发现这批商户大部分没有夜间交易(不符合夜店的交易场景),且单笔交易金额较高,借记卡交易占比较高等异常现象。有可能这些商户存在一些风险,需要在后续交易中重点观测,预防有可能的风险,也说明了孤立森林现实的用处。
本文是本人使用孤立森林后的一些见解,如有不当之处恳请指正。
参考文献:
1. https://www.cnblogs.com/hapyygril/p/98025
88.html
2. https://www.jianshu.com/p/5af3c66e0410
- SQL客户端DBvisualize直接导入数据出现中文乱码
- Python基础整理操作积累
- 让AI给颜值打分?应该是最公正的裁判了!
- orion的简单测试 (r8笔记第75天)
- golang ftp客户端示例 支持断点续传
- python 网页特征提取XPATH(两天玩转) 第一天
- 和开发同学讨论的一个技术问题(r8笔记第73天)
- 剖析Oracle中oerr命令(r8笔记第70天)
- 甜品店切蛋糕问题(动态规划,Go语言实现)
- SQL—复制表结构及其数据
- python连接SQL报错:1366, "Incorrect string value: '\xF0\x9F\x98\x81'
- PCIE的简单配置(r8笔记第82天)
- 7个深度神经网络可视化工具,不可错过!
- Pwnhub之奇妙的巨蟒 Writeup
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Celery-分布式任务队列学习笔记
- Java面试高频知识点汇总 数据库专题
- Java面试高频知识点总结 Redis
- Java面试高频知识点总结 Spring
- 杂谈小程序
- pytest封神之路第四步 内置和自定义marker
- (译)SDL编程入门(3)事件驱动编程
- 一个简单的Angular search UI实现
- (译)SDL编程入门(2)在屏幕上显示图像
- 【Vue进阶】手把手教你在 Vue 中使用 JSX
- (译)SDL编程入门(1)Hello SDL
- Django使用Channels实现websocket
- (译)SDL编程入门(6)扩展库SDL_image
- 牛客网剑指offer-2
- 牛客网剑指offer-1