您的位置:

离群点检测方法详解

离群点(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。每种方法都有其优点和局限性,因此需要根据具体数据集的特点选择适当的方法。