孤立森林在信用卡盗刷样本上的应用示例

前面我们对孤立森林算法的原理作了了解,本篇使用 kaggle 比赛中用到的信用卡盗刷数据集对该算法的应用进行说明。

一、孤立森林算法参数介绍

sklearn调用方法说明

https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.IsolationForest.html#sklearn.ensemble.IsolationForest

官网给出的应用示例

调用方法(Methods)

decision_function(X):获取异常得分,分数有正负,越低越异常,负数代表异常,正数代表正常。注意这里与论文里的分数定义有出入,此处分数=-(论文口径得分)-偏移量;若contamination设置为’auto’,则偏移量=-0.5,得分区间为:-0.5-0.5(对应论文口径得分区间:0-1)。

predict(X):获取预测标签,-1代表异常,1代表正常

算法参数(Parameters)

class sklearn.ensemble.IsolationForest(*, n_estimators=100, max_samples=’auto’, contamination=’auto’, max_features=1.0, bootstrap=False, n_jobs=None, random_state=None, verbose=0, warm_start=False)(默认参数)
1.n_estimators:基学习器的个数,默认100

2.max_samples:训练每个基学习器所抽取的样本量,默认’auto’;参数值如果超过样本量,相当于不作抽样,每颗树都会用到所有样本。

3.contamination:数据集的污染量,即数据集中异常值的比例;在拟合时用于确定样本得分的阈值;从版本0.22开始,默认值从0.1调整为’auto’。

4.max_features:训练每个基学习器所抽取的特征个数,默认1.0,即100%抽取

5.bootstrap:是否有放回抽样,默认False

6.n_jobs:fit和predict时并行运行的作业数,默认None;None表示1,除非在joblib.parallel_backend有定义;-1表示使用所有处理器。
7.random_state:int, RandomState instance or None,默认None

8.verbose:打印树构建过程的详细程度,越打越详细,默认0
9.warm_start:默认False

算法属性(Attributes)

1.base_estimator_

2.estimators_:子学习器列表,存储了所有iTree
3.estimators_features_:list of ndarray,The subset of drawn features for each base estimator

4.estimators_samples_:list of ndarray,The subset of drawn samples for each base estimator.
5.max_samples_:int,The actual number of samples.
6.offset_:float

7.n_features_:int,已移除
8.n_features_in_:int,Number of features seen during fit.
9.feature_names_in_:ndarray of shape (n_features_in_,),Names of features seen during fit. Defined only when X has feature names that are all strings.

二、孤立森林算法应用示例
导入数据集

使用2013年9月欧洲持卡人的信用卡交易数据,在284,807笔交易中,有492起欺诈盗刷行为,欺诈占比仅0.172%。除了包含28个经过PCA转换过得无法拿到业务解释的变量,还有”时间”和”交易金额”,以及欺诈标签。数据集具体介绍和下载地址如下:

https://www.kaggle.com/datasets/mlg-ulb/creditcardfraud

”’导入数据集”’
import pandas as pd
df=pd.read_csv(r”D:\creditcard.csv”)
df.head()
df.Class.value_counts()

模型训练

”’拆分训练和测试集”’
from sklearn.model_selection import train_test_split
df_train,df_test = train_test_split(df,train_size=0.8,test_size=0.2,random_state=27)
df_train.Class.value_counts(normalize=True)
df_test.Class.value_counts(normalize=True)

”’模型训练”’
from sklearn.ensemble import IsolationForest
clf = IsolationForest(random_state=1)
X_train = df_train.drop([‘Class’,’Time’],axis=1)
clf.fit(X_train)

得到预测标签

df_train=df_train.copy()
df_train[‘label’] = clf.predict(X_train)

得到异常评分

df_train[‘score’] = clf.decision_function(X_train)

模型评估

”’模型评估”’

TopN准确率评估

n = 1000
badRt=df_train.Class.value_counts(normalize=True)[1]
df2 = df_train.sort_values(by=’score’,ascending=True).head(n)
rate = df2[df2[‘Class’]==1].shape[0]/n
print(‘Top {} 的准确率为: {}’.format(n,rate))
print(‘Top {} 的提升度为: {}’.format(n,rate/badRt))

TopN%准确率评估

n = 0.01
df2 = df_train.sort_values(by=’score’,ascending=True).head(round(df_train.shape[0]n)) rate = df2[df2[‘Class’]==1].shape[0]/(df2.shape[0]) print(‘Top {}% 的准确率为: {}’.format(n100,rate))
print(‘Top {}% 的提升度为: {}’.format(n*100,rate/badRt))

以下使用到的自定义排序函数详见之前文章 cal_lift。

”’模型评分排序效果”’
tmp=df_train.copy()
i=’score’
tmp[i+’_bin’]=pd.qcut(tmp[i],q=100)
out=cal_lift(tmp,i+’_bin’,’Class’,True)
out.style.bar(subset=[‘badtimes’],align=’mid’)

”’在测试集上打分”’
X_test = df_test.drop([‘Class’,’Time’],axis=1)
df_test=df_test.copy()
df_test[‘score’] = clf.decision_function(X_test)#得到异常评分

测试集的准确率和提升度获取代码类似前面

模型可视化

孤立森林也是树集成算法,基模型用的是决策树,因此可以画出来。建议将graphviz安装在位置:\Anaconda\Lib\site-packages\graphviz;如使用出现报错可参考:

blog.csdn.net/gj18405655459/article/details/123234866

def visualize_tree(clf,features,clf_name):
from sklearn import tree
import graphviz
dot_data = tree.export_graphviz(decision_tree=clf,feature_names=features,filled=True,special_characters=True)
graph = graphviz.Source(dot_data)
graph.render(‘孤立森林_’+clf_name,view=True)

”’以第二棵iTree为例”’
n=2
visualize_tree(clf=clf.estimators_[n],
features=[X_train.columns[i] for i in clf.estimators_features_[n]],
clf_name=’iTree{}’.format(n))

模型预测的异常观测在样本中的分布示例:

import matplotlib.pyplot as plt
plt.title(“孤立森立二维效果示例图”)
plt.rcParams[‘font.sans-serif’] = [‘SimHei’] #解决图表中文乱码问题
plt.rcParams[‘axes.unicode_minus’] = False #解决图表负号无法显示的问题
abnormal = df_train.sort_values(by=’score’,ascending=True).head(500)
normal = df_train.sort_values(by=’score’,ascending=False).head(df_train.shape[0]-500)

normal=df_train[df_train[‘label’]==1]

b1 = plt.scatter(abnormal[‘V1’], abnormal[‘V2’], c=”red”, s=20, edgecolor=”k”)
b2 = plt.scatter(normal[‘V1’], normal[‘V2’], c=”green”, s=20, edgecolor=”k”)
plt.xlim((-70,10))
plt.ylim((-80,30))
plt.xlabel(‘V1’)
plt.ylabel(‘V2’)
plt.legend( [b1, b2],
[“异常得分top500观测样本”, “其余观测样本”],
loc=”upper left”,)
plt.show()

模型最优参数探索示例

”’以基树个数为例,示例最优参数探索”’
df_train,df_test = train_test_split(df,train_size=0.8,test_size=0.2,random_state=27)
X_train = df_train.drop([‘Class’,’Time’],axis=1)
n_ests = list(range(50,150,10))
rates = []
for i in n_ests:
#模型训练
clf = IsolationForest(n_estimators=i, random_state=27)
clf.fit(X_train)
#得到异常评分
df_train=df_train.copy()
df_train[‘score’] = clf.decision_function(X_train)
#TopN准确率评估
n = 0.01
df2 = df_train.sort_values(by=’score’,ascending=True).head(round(df_train.shape[0]n)) rate = df2[df2[‘Class’]==1].shape[0]/(df2.shape[0]) print(‘树个数 = {},Top {}% 的准确率为: {}’.format(i,n100,rate))
rates.append(rate)

plt.title(“基树个数与异常得分Top1%观测的准确率关系”)
plt.plot(n_ests,rates,marker=’o’)
plt.ylim(0.05,0.12)
plt.show()

至此,我们对孤立森林的原理和应用都有了一定的理解。

题图来源:网站Pixabay

声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/239494.html

(0)
联系我们
联系我们
分享本页
返回顶部