异常检测之孤立森林(isolate forest)

大家好,我是菜菜卷!今天开始陆续和大家分享一些关于异常检测入门相关的实战项目(包括使用sklearn实现一些简单的机器学习模型或者使用pytorch实现简单的深度学习模型)
今天我们使用的模型是集成于sklearn内部实现的孤立森林算法。

什么是孤立森林(isolate forest)?

孤立森林是一种传统的异常检测机器学习算法,他属于无监督学习的boost 树模型,对于每棵子树来说,针对数据集的不同特征值,会随机挑选特征值取值范围内的一个随机值,然后将所有数据按照该特征的这个随机值划分为两部分(根据该特征值大于或者小于该随机值),这样我们就可以逐渐将所有的数据分开,因为异常数据通常来说所占的比例都较少,所以一般使用较少的属性就可以将他们从正常数据中区分开来,因此平均路径长度便可以作为是否是异常值的衡量指标(异常数据的平均路径长度会比正常数据更短)

所用数据集

数据集获取地址:KDD1999Data
前往以上的地址,下载kddcup.data.gz即可。
该数据集是由若干正常和异常的数据分类,有41和特征和1个标签构成,因为后面我们只想对网页攻击方向的数据进行分析,所以要强调一下,第三个特征是表示异常的方向(即是哪种方面的异常,比如http还是其他)

项目所用环境

numpy 1.15.3
pandas 0.23.4
scikit-learn 0.19.1
matplotlib 2.2.2

大家可以使用pip或者conda自行安装项目环境,为保证顺利无bug复现结果,建议使用所示版本的包

项目实战

1、包的导入

首先我们先导入实验所需的第三方包

import time
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.ensemble import IsolationForest
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import roc_auc_score

其中time可以用来记录时间和程序运行时间;numpy可以高效做矩阵运算,在数据处理中有广泛的运用;pandas可以快速方便的读入和处理数据的格式;matplotlib用于部分实验结果的可视化;sklearn是一个非常丰富的机器学习库,内部集成了基本的机器学习方法、数据集处理方法、模型衡量指标等功能。

2.使用pandas读入和处理数据

首先我们使用以下代码来读入数据:

data_path = r'dataset/kddcup.data.corrected'
columns = [str(i) for i in range(1, 42)]
columns.append('label')
df = pd.read_csv(data_path, sep=',', names=columns, index_col=None)

其中columns是我们给每个特征的命名,具体是什么都可以,只需要后续操作特征的时候可以对应上最开始的命名就可以了,这里我就简单的将最开始的41列命名为1-41的str类型数字,最后一列(第42列)命名为'label'names=columns表示我们使用自定义的columns来命名数据中的42个列。
下面我们使用print(df.shape)看一下数据的大小,结果如下所示:

(4898431, 42)

说明我们的数据集有接近500w的数据,其中每个数据有42个属性(其中前41个位特征值,第42个是标签label)。
接下来我们简单的处理一下数据,假设目前我们仅关心与http相关的数据是否正常(第3列特征描述数据的分类),我们使用如下代码来挑选出数据集中所有和http相关的数据:

df = df[df['3'] == 'http']
df = df.drop('3', axis=1)
columns.remove('3')

其中df['3'] == 'http'用来判断数据df的第三个属性是否是http,是的话就是True,否的话就是False,所以df = df[df['3'] == 'http']实现的功能就是找到所有第三列属性是http的数据,因为在找到后,我们的第三列属性就无用了(因为都是http了),所以我们用df = df.drop('3', axis=1)将第三列属性去掉,下面我们再使用print(df.shape)看看数据的shape,结果如下所示:

(623091, 41)

我们可以发现,数据从原来的接近500w变成了现在的62w个,属性值也从42变成了41,说明我们以上操作成功了!

然后我们运行print(df['label'].value_counts())来观察一下label的取值,结果如下所示:

normal.       619046
back.           2203
neptune.        1801
portsweep.        16
ipsweep.          13
satan.             7
phf.               4
nmap.              1
Name: label, dtype: int64

从结果中我们可以发现,大多数数据都是正常的(normal.),但是也有一些其他异常的数据,我们本次的核心任务就是使用孤立森林模型来完成对数据正常与否的检测。

我们希望更详细的观察一些数据的情况,使用print(df.head(5))来显示前五个数据的详细信息:

  1    2   4    5</
  • 11
    点赞
  • 91
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值