发现与大部分其他对象显著不同的对象,大部分数据挖掘将这种差异视为噪声而丢弃,然而在一些应用中,罕见的数据可能蕴含更大的研究价值
# 成因: 数据来源于不同的类,自然变异、数据测量和收集误差
# 离群点的类别
# 从数据范围 全局离群点和局部离群点
# 从数据类型 数值型离群点和类型离群点
# 从属性的个数 一维离群点和多维离群点(一个对象可能有多个属性)
# 常用离群点检测方法
# 基于统计 构建一个概率分布模型,并且计算符合对象的模型概率,具有低概率的点视为离群点
# 基于邻近度 数据对象之间定义邻近度量,把远离大部分的点的对象视为离群点
# 密度常用邻近度
# 一种是定义密度为K个最邻近的平均距离的倒数,如果该距离越小,则密度越高
# 使用DBSCAN聚类算法,一个对象周围的密度等于对象指定距离d对象的个数
# 基于密度 离群点是低密度区域中的对象
# 基于聚类 丢弃远离其他簇的小簇/先聚类所有对象,然后评估对象数据簇的程度
使用K-Means算法聚类消费离群点数据
利用表中的数据进行聚类,并计算各个样本到各个中心的距离,分析离群样本,得到距离误差图,如果距离阈值为2的话,有8个离群点
数据源
import numpy as np
import pandas as pd
#参数初始化
inputfile = 'F:/python 数据挖掘分析实战/Data/consumption_data.xls' #销量及其他属性数据
k = 3 #聚类的类别
threshold = 2 #离散点阈值
iteration = 500 #聚类最大循环次数
data = pd.read_excel(inputfile, index_col = 'Id') #读取数据
data_zs = 1.0*(data - data.mean())/data.std() #数据标准化
from sklearn.cluster import KMeans
model = KMeans(n_clusters = k, n_jobs = 4, max_iter = iteration) #分为k类,并发数4
model.fit(data_zs) #开始聚类
#标准化数据及其类别
r = pd.concat([data_zs, pd.Series(model.labels_, index = data.index)], axis = 1) #每个样本对应的类别,dataframe 和Series组合
r.columns = list(data.columns) + [u'聚类类别'] #重命名表头
norm = []
for i in range(k): #逐一处理
norm_tmp = r[['R', 'F', 'M']][r[u'聚类类别'] == i]-model.cluster_centers_[i]
norm_tmp = norm_tmp.apply(np.linalg.norm, axis = 1) #求出绝对距离
norm.append(norm_tmp/norm_tmp.median()) #求相对距离并添加
norm = pd.concat(norm) #合并
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
norm[norm <= threshold].plot(style = 'go') #正常点
discrete_points = norm[norm > threshold] #离群点
discrete_points.plot(style = 'ro')
for i in range(len(discrete_points)): #离群点做标记
id = discrete_points.index[i]
n = discrete_points.iloc[i]
plt.annotate('(%s, %0.2f)'%(id, n), xy = (id, n), xytext = (id, n))
plt.xlabel(u'编号')
plt.ylabel(u'相对距离')
plt.show()
参考资料:《Python数据分析与挖掘实战》