聚类算法也可以异常检测?DBSCAN算法详解。
一、算法概述
二、 基本概念
1、1个核心思想
2、2个算法参数
3、3种点的类别
噪声点:对于非核心点的样本n,若n不在任意核心点p的
4、4种点的关系
三、算法思想
1、寻找核心点形成临时聚类簇
2、合并临时聚类簇得到聚类簇
四、sklearn算法实现
1、基本用法
sklearn.cluster.DBSCAN(eps=0.5, *,
min_samples=5,
metric='euclidean',
metric_params=None,
algorithm='auto',
leaf_size=30,
p=None,
n_jobs=None
)
2、核心参数
-
eps: float,ϵ-邻域的距离阈值 -
min_samples :int,样本点要成为核心对象所需要的 ϵ-邻域的样本数阈值
3、其他参数
-
metric :度量方式,默认为欧式距离,可以使用的距离度量参数有:
-
欧式距离 “euclidean” -
曼哈顿距离 “manhattan” -
切比雪夫距离“chebyshev” -
闵可夫斯基距离 “minkowski” -
带权重闵可夫斯基距离 “wminkowski” -
标准化欧式距离 “seuclidean” -
马氏距离“mahalanobis” -
自己定义距离函数
-
algorithm:近邻算法求解方式,有四种:
-
“brute”蛮力实现 -
“kd_tree” KD树实现 -
“ball_tree”球树实现 -
“auto”上面三种算法中做权衡,选择一个拟合最好的最优算法。
-
leaf_size:使用“ball_tree”或“kd_tree”时,停止建子树的叶子节点数量的阈值 -
p:只用于闵可夫斯基距离和带权重闵可夫斯基距离中p值的选择,p=1为曼哈顿距离, p=2为欧式距离。如果使用默认的欧式距离不需要管这个参数。 -
n_jobs :CPU并行数,若值为 -1,则用所有的CPU进行运算
4、属性
-
core_sample_indices_ : 核心点的索引,因为labels_不能区分核心点还是边界点,所以需要用这个索引确定核心点 -
components_:训练样本的核心点 -
labels_:每个点所属集群的标签,也就是聚类的编号,-1代表噪声点
5、算法案例
from sklearn.cluster import DBSCAN
import numpy as np
X = np.array([[1, 2], [2, 2], [2, 3],
[8, 7], [8, 8], [25, 80]])
clustering = DBSCAN(eps=3, min_samples=2).fit(X)
clustering.labels_
array([ 0, 0, 0, 1, 1, -1])
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
# 生成随机簇类数据,样本数为600,类别为5
X, y = make_blobs(random_state=170,
n_samples=600,
centers=5
)
# 绘制延伸图
plt.scatter(X[:,0],X[:,1])
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
plt.show()
# dbscan聚类算法 按照经验MinPts=2*ndims,因此我们设置MinPts=4。
dbscan = DBSCAN(eps=1,
min_samples=4)
clusters = dbscan.fit_predict(X)
# dbscan聚类结果
plt.scatter(X[:,0],X[:,1],
c=clusters,
cmap="plasma")
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
plt.title("eps=0.5,minPts=4")
plt.show()
# 性能评价指标ARI
from sklearn.metrics.cluster import adjusted_rand_score
# ARI指数 ARI= 0.99为了较少算法的计算量,我们尝试减小MinPts的值。
print("ARI=",round(adjusted_rand_score(y,clusters),2))
五、 DBSCAN算法的参数估计
由图可知或者根据k-距离曲线的定义可知:样本点第k个近邻距离值小于eps归为簇类,大于eps的样本点归为噪声点。根据经验,一般选择eps值等于第(minPts-1)的距离,计算样本间的距离前需要对数据进行归一化,使所有特征值处于同一尺度范围,有利于eps参数的设置。
六、实战应用
1、数据集介绍
2、数据来源
3、算法案例
import os
import pandas as pd
import numpy as np
# 工作空间设置
os.chdir('/Users/wuzhengxiang/Documents/DataSets/CreditCardFraudDetection')
os.getcwd()
# 数据读取
data = pd.read_csv('creditcard.csv')
# 查看 0 - 1 个数
import matplotlib.pyplot as plt
data.Class.value_counts()
num_nonfraud = np.sum(data['Class'] == 0)
num_fraud = np.sum(data['Class'] == 1)
plt.bar(['Fraud', 'non-fraud'], [num_fraud, num_nonfraud], color='red')
plt.show()
# 数据集划分 + 简单的特征工程
data['Hour'] = data["Time"].apply(lambda x : divmod(x, 3600)[0])
X = data.drop(['Time','Class'],axis=1)
Y = data.Class
# 数据归一化
from sklearn.preprocessing import StandardScaler
sd = StandardScaler()
column = X.columns
X[column] = sd.fit_transform(X[column])
#训练集交叉验证,开发集测试泛化性能
from sklearn.model_selection import train_test_split
X_train,X_test,Y_train,Y_test = train_test_split(X,Y,
test_size=0.55,
random_state=0
)
from sklearn.cluster import DBSCAN
import numpy as np
clustering = DBSCAN(eps=3.8, min_samples=13).fit(X_train)
pd.Series(clustering.labels_).value_counts()
0 113644
1 8372
-1 6016
2 32
4 16
8 15
3 14
5 14
6 13
10 9
9 9
7 9
X_train['labels_'] = clustering.labels_
X_train['labels'] = Y_train
X_train[X_train['labels']==1]
[218 rows x 32 columns]
X_train[(X_train['labels']==1)&(X_train['labels_']==-1)]
[186 rows x 32 columns]
七、DBSCAN算法优缺点
1、优点
2、缺点
往期精彩:
长按关注本号 长按加我好友
