離群點檢測是發現與大部分其他對象顯著不同的對象。大部分數據挖掘都將這種差異信息視為噪聲而丟棄,然而在一些應用中,異常點數據可能蘊含着更大的研究價值。
應用:電信和信用卡的詐騙檢測、貸款審批、電子商務、網絡入侵和天氣預報等領域。例如,可以利用離群點檢測分析運動員的統計數據,來發現異常的運動員。
離群點的成因:
數據來源於不同的類、自然變異、數據測量、收集誤差
離群點的類型:
分類標准 |
分類名稱 |
分類描述 |
從數據范圍 |
全局離群點和局部離群點 |
從整體看,某些對象沒有利群特征,但從局部看,卻有一定的離群性 |
從數據類型 |
數值型離群點和分類型離群點 |
這是以數據集的屬性類型進行划分的 |
從屬性的個數 |
一維離群點和多維離群點 |
一個對象可能有一個或者多個屬性 |
離群點檢測方法
1)基於統計:構建一個概率分布模型,並計算對象符合該模型的概率,把具有低概率的對象視為離群點。該方法的前提是知道數據集服從什么分布。
2)基於臨近度:在數據對象之間定義鄰近性度量,把遠離大部分點的對象視為離群點。
3)基於密度:考慮數據集可能存在不同密度區域這一事實,離群點是在低密度區域中的對象
4)基於聚類:
(1)丟棄遠離其他簇的小簇
該過程可以簡化為丟棄小於某個最小閾值的所有簇。
這個方法可以和其他任何簇類技術一起使用,但是需要最小簇大小的閾值以及小簇與其他簇之間距離的閾值。而且這種方案對簇個數的選擇高度敏感,使用這個方案很難將離群點得分附加到對象上。
(2)聚類首先聚類所有對象,然后評估對象屬於簇的程度。
可以用對象到它的的簇中心的距離來度量屬於簇的程度 。特別的,如果刪除一個對象導致該目標的顯著改進,則可將該對象視為離群點。
距離的兩種評估方法:絕對距離:對象到簇中心的距離
相對距離:對象到簇中心的距離/簇中所有點到簇中心距離的中位數
使用第二種方式來尋找離群點:
#-*- coding: utf-8 -*-
#使用K-Means算法聚類消費行為特征數據
import numpy as np
import pandas as pd
#參數初始化
inputfile = '../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) #每個樣本對應的類別
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
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()