异常值处理

目前还没有在具体项目中用到异常值检验,总结下以备后面项目使用
1)基于马氏距离的异常检验

 基于马氏距离的异常检验是针对异常样本点的检验,与下面基于箱线图的异常检验不同,箱线图的异常检验是针对单一属性的异常检验。

  欧式距离是我们常用的距离度量工具,但是它将目标的不同属性(即各指标或各变量)之间的差别等同看待,这一点有时不能满足实际要求,而马氏距离考虑到各种特性之间的联系(例如:一条关于身高的信息会带来一条关于体重的信息,因为两者是有关联的)并且是尺度无关的(scale-invariant),即独立于测量尺度。对于一个均值为μ,协方差矩阵为Σ的多变量向量,其马氏距离为sqrt( (x-μ)'Σ^(-1)(x-μ) )。当协方差是单位矩阵时,马氏距离与欧式距离等价。


import pandas as pd
import numpy as np
from numpy import float64
from sklearn import preprocessing
from matplotlib import pyplot as plt
from pandas import Series
from scipy.spatial import distance
from mpl_toolkits.mplot3d import Axes3D

Height_cm = np.array([164, 167, 168, 169, 169, 170, 170, 170, 171, 172, 172, 173, 173, 175, 176, 178], dtype=float64)
Weight_kg = np.array([54,  57,  58,  60,  61,  60,  61,  62,  62,  64,  62,  62,  64,  56,  66,  70], dtype=float64)
hw = {'Height_cm': Height_cm, 'Weight_kg': Weight_kg}
hw = pd.DataFrame(hw)
print(hw)

is_height_outlier = abs(preprocessing.scale(hw['Height_cm'])) > 2
is_weight_outlier = abs(preprocessing.scale(hw['Weight_kg'])) > 2
is_outlier = is_height_outlier | is_weight_outlier
color = ['g', 'r']
pch = [1 if is_outlier[i] == True else 0 for i in range(len(is_outlier))]
cValue = [color[is_outlier[i]] for i in range(len(is_outlier))]
# print is_height_outlier
# print cValue
fig = plt.figure()
plt.title('Scatter Plot')
plt.xlabel('Height_cm')
plt.ylabel('Weight_kg')
plt.scatter(hw['Height_cm'], hw['Weight_kg'], s=40, c=cValue)
plt.show()


n_outliers = 2
m_dist_order = Series([float(distance.mahalanobis(hw.iloc[i], hw.mean(), np.mat(hw.cov().as_matrix()).I) ** 2) for i in range(len(hw))]).sort_values(ascending=False).index.tolist()
is_outlier = [False, ] * 16
for i in range(n_outliers):
    is_outlier[m_dist_order[i]] = True
color = ['g', 'r']
pch = [1 if is_outlier[i] == True else 0 for i in range(len(is_outlier))]
cValue = [color[is_outlier[i]] for i in range(len(is_outlier))]
fig = plt.figure()
plt.title('Scatter Plot')
plt.xlabel('Height_cm')
plt.ylabel('Weight_kg')
plt.scatter(hw['Height_cm'], hw['Weight_kg'], s=40, c=cValue)
plt.show()


2)基于标准偏差的异常值检验

  基于标准偏差的异常值检验也称3σ原则,可以针对样本点也可以针对单个属性,一般适用于服从正态分布的数据,即异常值被定义为观测值和平均值的偏差超过3倍标准偏差的值。

   P(|x-u|>3sigma)<=0.003 正态分布情况下,如果|x-u|>3sigma说明x出现的概率很小,所以可以看成是异常值。


3)基于箱线图的异常值检验

   箱线图通过计算中位数(50百分位数)、上四分为数(75百分位数)、上四分为数(25百分位数)、上边缘(100百分位数)、下边缘(0百分位数如下:

   箱型图识别异常值标准: 异常值被定义为大于QU+1.5IQR或小于QL1.5IQR的值,QU是上四分位数,QL是下四分位数,IQR是QUQL的差。

    同时也可以自己定义其他异常值检验,如95百分位数,将上下各2.5%的数看做异常

下面是箱线图检测异常值的python实例

数据集:http://download.csdn.net/detail/u010111016/9524285

源码:http://blog.csdn.net/shuaishuai3409/article/details/51428106

import pandas as pd
import matplotlib.pyplot as plt

# 设定播放数据路径,该路径为代码所在路径的上一个目录data中.
number = 'D:/data/ather/all_musicers.xlsx'
data = pd.read_excel(number)

data1 = data.iloc[:, 0:10]  # 10位歌手的183天音乐播放量
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
plt.figure(1, figsize=(13, 26))  # 可设定图像大小
# plt.figure()  # 建立图像
# 画箱线图,直接使用DataFrame的方法.代码到这为止,就已经可以显示带有异常值的箱型图了,
# 但为了标注出异常值的数值,还需要以下代码进行标注.
p = data1.boxplot(return_type='dict')
# for i in range(0,4):
# 'flies'即为异常值的标签.[0]是用来标注第1位歌手的异常值数值,同理[i]标注第i+1位歌手的异常值.
for j in range(0, 4):
    x = p['fliers'][j].get_xdata()
    y = p['fliers'][j].get_ydata()
    y.sort()  # 从小到大排序

    for i in range(len(x)):
        if i > 0:
            plt.annotate(y[i], xy=(x[i], y[i]), xytext=(x[i]+0.05 - 0.8/(y[i]-y[i-1]), y[i]))
        else:
            plt.annotate(y[i], xy=(x[i], y[i]), xytext=(x[i]+0.08, y[i]))

# 展示箱线图
plt.show()
发布了55 篇原创文章 · 获赞 18 · 访问量 8万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章