本文主要记录了关于机器学习中异常值检测和处理的知识。
1. 什么是异常值
在一般的预测问题中,模型通常是对整体样本数据结构的一种表达方式,这种表达方式抓住的是整体样本一般性的性质,而那些在这些性质中表现完全与整体样本不一致的点,称之为异常点。
2. 简单的异常值检测方法
2.1 分位数方法
分位数异常值检测方法是一维特征空间中最简单的非参数异常值检测方法,异常值是通过IQR(Inter Quartile Range)
计算得到的。
计算四分位数的第1和第3分位点,异常值是位于四分位数范围之外的数据点
使用四分位数乘数值
def detect_outliers(df, n, features):
'''
这种方法允许输入是nan值
df: 表示dataFrame类型
n: 表示被多少个特征判定为异常点才输出
features: 表示检测异常点的特征
'''
# 用来保存异常点的索引
outlier_indices = []
for col in features:
## 第1个四分位点
Q1 = np.percentile(df[col], 25)
## 第3个四分位点
Q3 = np.percentile(df[col], 75)
IQR = Q3 - Q1
lower_limit = Q1 - 1.5 * IQR # 下界
upper_limit = Q3 + 1.5 * IQR # 上届
outlier_list_col = df[(df[col]<lower_limit) | (df[col] > upper_limit)].index
outlier_indices.extend(outlier_list_col)
outlier_indices = Counter(outlier_indices)
# 如果被n个特征判定为异常点,则输出
multiple_outliers = list(k for k, v in outlier_indices.items() if v > n)
return multiple_outliers
# 决定如果处理异常点,可以丢弃
df = df.drop(outliers, axis=0).reset_index(drop=True)
2.2 Z-score
这是一种一维或低维特征空间中参数异常检测方法。它假定数据是高斯分布,异常值是分布尾部的数据点,因此远离数据的平均值。距离的远近取决于使用公式归一化数据集
经过标准化处理只有,异常值也进行了标准化处理,其绝对值大于
这里
2.5, 3.0. 3.5
这几个值。
from scipy.stats import zscore
def compute_zscore(df, features, threshold=2.5):
'''
df: 表示要处理的dataFrame
features: 表示要处理的特征
threshold: 表示判断是否是异常值的阈值
'''
for col in features:
all_value = df[col].values.copy()
## 先剔除掉所有nan值
indices = np.array(list(map(lambda x: not x, np.isnan(all_value))))
true_value = all_value[indices]
z_value = zscore(true_value)
all_value[indices] = z_value
## 得到 zscore所在的列,以及是否是异常值的列
df[col+"_zscore"] = all_value
df[col+"_isanomaly"] = df[col+"_zscore"].apply(lambda x: int(abs(x) >= abs(threshold)))
3. 模型异常值检测方法
3.1 PyOD库介绍
(1)该库包含20种常见的异常检测算法,比如经典的ABOD以及最新的GAN和集成异常检测(outlier ensemble)。
(2)常用的包括iforest
,knn
, lof
, pca
等等,KNN对于低维数据表现较好,Isolation Forest则对高维特征表现较好;abod
整体表现较差。
PCA整体运行效率比较好,LOF和KNN效率相对较差,Isolation Forest在低维数据上效率也不太有优势。
(3)简单的示例
from pyod.models.knn import KNN
clf = KNN()
clf.fit(X_train) # 这里X_train的维度是 [n_samples, n_features],必须是数值型,不能包含缺失值
## 返回训练数据的标签和分值
y_train_pred = clf.labels_ # (0表示正常值,1表示异常值)
y_train_scores = clf.decision_scores_ # 分值越大越异常
## 用训练好的数据预测未知数据中的异常值
y_test_pred = clf.predict(X_test)
y_test_scores = clf.decision_function(X_test)
4. 异常值的处理方法
- 删除含有异常值的记录
- 将异常值视为缺失值
- 平均值修正:使用前后两个观测值修正异常值
参考
- 异常值检测和处理
- 比较好的异常值检测的方法
- 使用PyOD进行异常值检测的教程
- 数据挖掘中常用的异常值检测方法
- 用PyOD进行异常值检测
- PyOD使用API