离群点(Outlier)在数据分析中经常出现,它们是指与大多数数据点显著不同的数据点。数据中的离群点可能是异常值、错误或者不符合数据模型的数据。所以在数据分析中需要将离群点进行检测和剔除。下面详细介绍离群点检测方法相关知识。
一、离群点定义
对数据集进行统计学分析时,离群点经常是需要关注的问题。一般来说,离群值可以定义为数据集中显著偏离其他观测值的单个观测值。这些值通常是数据中存在的异常值或者数据的错误。
离群点根据异常值的分布,通常分为两种类型:
- 点异常(Point Anomaly):是指单个数据点在整个数据集上嚣张突出。通常,这些异常点是数据集中的错误或噪声。例如,由于传感器失效导致的异常数据。
- 上下文异常(Contextual Anomaly):通常发生在数据集的某个区域,而不仅仅是单个数据点。例如,在普通时段中,每天的银行交易通常在正常范围内。但在大型交易活动之后,数量可能会显著偏离正常范围。
二、离群点检测方法
1. 简单统计学方法
简单统计学方法是最基本和最简单的离群点检测方法。它使用均值或中位数来找到偏差。如果一个数据点大于或小于设定的阈值,则将其标记为离群点。
这是一个快速的方法,但它只限于数据分布正常,存在明显偏差并且离群值不太常见的情况。下面是使用Python实现的简单统计学方法:
import numpy as np
def is_outlier(points, threshold=3.5):
"""
较低的分位数、较高的分位数、分位距 计算 离群点界限
:param points:
:param threshold:
:return:
"""
if len(points.shape) == 1:
# 维度是1的
points = points[:, None]
# calculate the median value
median = np.median(points, axis=0)
# calculate the quartile values
#1/4分位数
q25, q75 = np.percentile(points, [25, 75], axis=0)
q_dist = q75 - q25
print("Median: ", median)
print("Q25: ", q25)
print("Q75: ", q75)
print("Q Distance: ", q_dist)
# calculate the outlier cutoff
cut_off = threshold * q_dist
outlier_min = q25 - cut_off
outlier_max = q75 + cut_off
return outlier_min, outlier_max
# create dataset
np.random.seed(0)
x = np.random.randn(100)
# add in some outliers
x = np.concatenate((x, np.array([ -10, 10, -15, 15])))
# detect outliers
min_out, max_out = is_outlier(x, threshold=2)
print("Mininum cutoff: ", min_out)
print("Maximum cutoff: ", max_out)
2. DBSCAN(Density-Based Spatial Clustering of Applications with Noise)
DBSCAN是一种密度聚类算法,可以识别以高密度区域为中心的区域,并将低密度区域标记为噪声。它的输出同时包括集群和噪声,因此比简单的统计方法更具描述性。
它的主要优点是可以自适应地匹配数据集的密度分布。下面是使用Python实现的DBSCAN算法:
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
import pandas as pd
# Import data
data = pd.read_csv("data.csv")
# Standardize the data
X = StandardScaler().fit_transform(data)
# DBSCAN Clustering
db = DBSCAN(eps=0.3, min_samples=10).fit(X)
labels = db.labels_
# results
print("Data points: ", len(X))
print("No. clusters:", len(set(labels)))
3. Elliptic Envelope
椭圆信封法允许您对数据进行建模,以确定正常点与离群点之间的边界。该算法使用最大似然方法来拟合椭圆,并标记远离椭圆中心的点为离群点。
由于该算法是在高斯分布假设下计算的,因此对于非高斯分布的数据可能不适用。下面是使用Python实现的Elliptic Envelope算法:
from sklearn.covariance import EllipticEnvelope
import numpy as np
rng = np.random.RandomState(42)
# Generate data
n_samples = 200
n_outliers = 20
X = 0.3 * rng.randn(n_samples, 2)
# Add outliers
X[:n_outliers] = 2 + 0.3 * rng.randn(n_outliers, 2)
# Fit the Elliptic Envelope
clf = EllipticEnvelope(random_state=rng, contamination=0.1)
clf.fit(X)
# Predict Outliers
y_pred = clf.predict(X)
4. Isolation Forest
孤立森林是一种基于树的方法,适用于高维数据。它通过对所有非离群点进行随机分割,并基于规则计算所有分割路径的平均长度来查找离群点。孤立森林的主要优点是适用于修饰数据集,且计算成本较低。
下面是使用Python实现的孤立森林算法:
from sklearn.ensemble import IsolationForest
import pandas as pd
data = pd.read_csv("data.csv").iloc[:, 1:]
isof = IsolationForest(n_estimators=50, max_samples='auto', contamination='auto', max_features=1.0,
bootstrap=False, n_jobs=1, random_state=None, verbose=0, behaviour='deprecated')
isof.fit(data)
pred = isof.predict(data)
print("Outlier values: ", pred[pred == -1])
总结
本文主要介绍了离群点检测方法。这些方法包括简单统计学方法、DBSCAN、Elliptic Envelope和Isolation Forest。每种方法都有其优点和局限性,因此需要根据具体数据集的特点选择适当的方法。