Phát hiện bất thường bằng kỹ
thuật phân cụm dữ liệu
(Outlier Detection by
Clustering)
chuc1803@gmail.com
Phát hiện bất thường (Outlier) là nhiệm quan trọng
trong phân tích dữ liệu. Các Outlier trong dữ liệu thường chứa rất nhiều thông
tin quan trọng, có ích. Có rất nhiều kỹ thuật phát hiện Outlier như LOF(Local Outlier Factor), dựa vào biểu đồ hộp (boxplot), dựa vào các
phương pháp thống kê…Bài viết này giới thiệu cách phát hiện Outlier dựa vào kỹ
thuật phân cụm dữ liệu. Ý tưởng chính là sử dụng kỹ thuật phân cụm dữ liệu
K-Means để nhóm các đối tượng vào K nhóm cho trước. Sau đó tính khoảng cách giữa
các đối tượng trong nhóm đến tâm của nhóm đó và
chọn ta n đối tượng (n xác định trước) có khoảng cách đến tâm lớn nhất
có thể xem là các Outliers.
Trong ví dụ này sử dụng Data set: iris
(iris.xlsx). Download tại ĐÂY và sử dụng Ngôn ngữ R để minh họa (Download
code để thực hiện trong R tại ĐÂY).
Bước
1. Đọc dữ liệu từ file iris.xlsx
setwd("D:/R") # Xác định thư mục chứa file
dữ liệu
library("xlsx") # Gọi thư viện đọc file
Excel
iris=read.xlsx("iris.xlsx",1,header=T) # Đọc
dữ liệu vào
attach(iris) # Load dữ liệu vào phân tích
fix(iris) # Xem trước dữ liệu
Bước
2. Tiền xử lý dữ liệu
Loại bỏ
côt Species vì trong kỹ thuật phân cụm không dùng cột này
iris1=iris[,1:4]
# Tạo ra đối tượng iris1 từ iris và loại bỏ cột cuối cùng (Specicies)
Bước
3. Phân cụm dữ liệu bằng thuật toán K-Means
kmeans.result=
kmeans(iris1, centers=3) # Gọi hàm kmeans để phân cụm dữ liệu trên data set
iris1 với số cụm là 3
kmeans.result$centers
# Xem kết quả các tâm (centers) của 3 cụm
kmeans.result$cluster
# Xem kết quả phân cụm
Bước
3. Xác định các Outliers
# Tính
khoảng cách từ các đối tượng đến tâm nhóm của nó
centers=kmeans.result$centers[kmeans.result$cluster,
]
distances
= sqrt(rowSums((iris1 - centers)^2))
# Lấy 5
đối tượng có khoảng cách đến tâm lớn nhất (Outliers)
outliers
= order(distances, decreasing=T)[1:5]
print(outliers)
# Xem các Outliers
print(iris1[outliers,])
# Vẽ
các cụm theo Sepal.Length và Sepal.Width
plot(iris1[,c("Sepal.Length",
"Sepal.Width")], pch="o",col=kmeans.result$cluster,
cex=0.8)
# Vẽ
tâm các cụm (pch=8: dấu sao)
points(kmeans.result$centers[,c("Sepal.Length",
"Sepal.Width")], col=1:3, pch=8, cex=2.5)
# Vẽ
các Outlier (dấu cộng (+), màu xanh)
points(iris1[outliers,
c("Sepal.Length", "Sepal.Width")], pch="+",
col=4, cex=2.5)