Python数据挖掘014-离群点检测
2019-12-09 本文已影响0人
科技老丁哥
离群点检测是数据挖掘中的第五个经典应用领域。它的任务是发现于大部分其他对象显著不同的对象。
离群点的属性值明显偏离期望的或常见的属性值,所以离群点检测也称为偏差检测。已经被广泛应用于电信和信用卡的诈骗检测,贷款审批,电子商务,网络入侵,电子商务,天气预报等领域。
1. 离群点的检测方法
image.png2. 基于模型的离群点检测方法
通过估计概率分布的参数来建立一个数据模型,如果一个数据对象不饿能很好的同该模型拟合,即如果它很可能不服从该分布,则它可能是一个离群点。
下图是正态分布离群点检测的方法之一:
image.png混合模型是一种特殊的统计模型,它使用若干统计分布对数据建模,每一个分布对应一个簇,而每个分布的参数提供对应簇的描述,通常用中心和发散描述。
混合模型将数据看作从不同的概率分布得到的观察值的集合,概率分布可以是任何分布,但通常是多元正态的,
在有些情况下很难建立模型,例如,因为数据的统计分布未知,或没有训练数据可用,这种情况下可以考虑其他不需要建立模型的检测方法。
3. 基于聚类的离群点检测方法
聚类分析用于发现局部强相关的对象组,而异常检测用来发现不与其他对象强相关的对象,故而聚类可以用于离群点检测,有两种基于聚类的离群点检测方法:
3.1 丢弃远离其他簇的小簇
这种方法可以简化为丢弃小于某个最小阈值的所有簇。这种方法可以和其他聚类技术一起使用,但需要最小簇大小和小簇与其他簇之间距离的阈值。这种方案对簇个数的选择高度敏感。
代码为:
data_zs = 1.0*(data - data.mean())/data.std() #数据标准化
from sklearn.cluster import KMeans
k=3 # 聚类的类别
iteration = 500 #聚类最大循环次数
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) #每个样本对应的类别
r.columns = list(data.columns) + [u'聚类类别'] #重命名表头
norm = []
for i in range(k): #逐一处理
norm_tmp = r[['R', 'F', 'M']][r['聚类类别'] == 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) #合并
threshold = 2 #离散点阈值
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'相对距离')
image.png
上面的方法是:先用KMeans对数据点进行聚类,计算出每个数据点的相对距离,该相对距离小于等于阈值的认为是正常点,大于阈值的是离群点,绘制相对距离图便可以看出来。
参考资料:
《Python数据分析和挖掘实战》张良均等