数据异常点检测

问题描述:当利用数据集进行模型训练前,一般需要先验证一下数据有没有异常点,当然缺省值也要关注,否则读取数据的时候得报错。这里我们先讨论数据集中的异常点检测问题。

当我们百度的时候,发现给出这几种方法,Z-score 方法,IQR(四分位数间距)方法,机器学习方法,One-Class SVM, 散点图,箱型图,组合方法,下面我们讨论一下可用性。

1. Z-score 方法

先塑造一个数据集,释放一个异常点,用来测试算法,波形图如下:

上python代码:

import pandas as pd
import numpy as np
from scipy import stats

# 读取数据
data = pd.read_csv('dataset.csv')

# 计算 z-score
z_scores = np.abs(stats.zscore(data))

# 设置阈值
threshold = 3

# 检测异常点
outliers = (z_scores > threshold).any(axis=1)
print("异常点的索引:", np.where(outliers)[0])

 运行结果:异常点的索引: False []

然后我尝试改动 threshold变量值,但是很遗憾,改了好几轮还是没能成功,太精细化了。下面我们看一下啊第二种方法:

2.  IQR(四分位数间距)方法

IQR 方法基于数据的四分位数计算异常点。通常,将低于 Q1 - 1.5 * IQR 或高于 Q3 + 1.5 * IQR 的数据点视为异常点。

Python 示例:

import pandas as pd

# 读取数据
data = pd.read_csv('dataset.csv')
data  = np.array(data)
data = pd.DataFrame(data)#需要df使用quantile
# 计算 Q1 和 Q3
Q1 = data.quantile(0.25)
Q3 = data.quantile(0.75)
IQR = Q3 - Q1

# 设置异常点的条件
outliers = ((data < (Q1 - 1.5 * IQR)) | (data > (Q3 + 1.5 * IQR))).any(axis=1)
print("异常点的索引:", data[outliers].index.tolist())

得调参数1.5,我放到0.45并且异常值增大,效果如下:

异常点的索引: [67]

找到了点的位置,ok,下面将异常值变小,

异常点的索引: []

将系数调整为0.4,结果如下下:

异常点的索引: [53]

检测错误,还是效果不佳。测试下一种方法:

3. 机器学习方法

3.1 Isolation Forest

Isolation Forest 是一种基于树的模型,通过随机选择特征和切分点来孤立数据点。它适用于高维数据集。  iForest 属于Non-parametric和unsupervised的方法,即不用定义数学模型也不需要有标记的训练。对于如何查找哪些点是否容易被孤立(isolated),iForest使用了一套非常高效的策略。假设我们用一个随机超平面来切割(split)数据空间(data  space),切一次可以生成两个子空间(详细拿刀切蛋糕一分为二)。之后我们再继续用一个随机超平面来切割每个子空间,循环下去,直到每个子空间里面只有一个数据点为止。直观上来讲,我们可以发现那些密度很高的簇是被切分很多次才会停止切割,但是那些密度很低的点很容易很早就停到一个子空间看了。

  iForest 算法得益于随机森林的思想,与随机森林由大量决策树组成一样,iForest森林也由大量的二叉树组成,iForest 中的树叫 isolation tree,简称 iTree,iTree 树和决策树不太一样,其构建过程也比决策树简单,是一个完全随机的过程。

Python 示例:

import pandas as pd
from sklearn.ensemble import IsolationForest

# 读取数据
data = pd.read_csv('dataset.csv')
data = data1.reshape(1,-1)
# 创建 Isolation Forest 模型
iso_forest = IsolationForest(contamination=0.05)  # contamination 是异常点的比例
outliers = iso_forest.fit_predict(data)

# -1 表示异常点,1 表示正常点
print("异常点的索引:", outliers, data[outliers == -1].tolist().index)

 先安装一下sklean库:

pip install scikit-learn -i https://pypi.tuna.tsinghua.edu.cn/simple
实验结果:

异常点的索引: [1] <built-in method index of list object at 0x000002035D9D8B00>

无论我怎么更改系数,实验结果一直不变,不知问题出在哪里。

3.2 One-Class SVM

One-Class SVM 是一种基于支持向量机的模型,用于检测异常点。

Python 示例:

import pandas as pd
from sklearn.svm import OneClassSVM

# 读取数据
data = pd.read_csv('dataset.csv')

# 创建 One-Class SVM 模型
oc_svm = OneClassSVM(nu=0.05, kernel='rbf')  # nu 是异常点的比例
outliers = oc_svm.fit_predict(data)

# -1 表示异常点,1 表示正常点
print("异常点的索引:", data[outliers == -1].index.tolist())

结果如下:

尽管将 nu=0.01还是有异常点

4. 可视化方法

4.1 散点图

对于二维数据集,散点图可以帮助直观地识别异常点。

Python 示例:

import pandas as pd
import matplotlib.pyplot as plt

# 读取数据
data = pd.read_csv('dataset.csv')

# 创建散点图
plt.scatter(data['feature1'], data['feature2'])
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('散点图')

# 可以在图上标记出检测到的异常点
plt.show()

4.2 箱型图

箱型图可以帮助识别离群点,尤其在一维数据中。

Python 示例:

import pandas as pd
import matplotlib.pyplot as plt

# 读取数据
data = pd.read_csv('dataset.csv')

# 创建箱型图
plt.boxplot(data['feature'])
plt.title('箱型图')
plt.ylabel('Feature Value')
plt.show()

 遗憾的是还没检测出来。

总结

采用暴力简单方法直接输出吧,众所周知所谓的异常点直观感受就是这个点鹤立鸡群,与周围点显得格格不入,在直观感受就是突变或者曲线不够丝滑如果用数学形式去描述就是梯度发生突变!OK,让我们先观测一下曲线的梯度图:

 如果设定相应的阈值例如10,是不就可以最直接表现出来,当前保险起见您可以连续检测两个梯度为异常值时在判定为异常点。

 

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值