手写算法-python代码实现DBSCAN

手写算法-python代码实现DBSCAN

原理解析

上篇文章我们优化了Kmeans聚类算法,最后留下一个问题:
Kmeans只适合处理凸样本集,不适合处理非凸样本集,这个问题,怎么解决?

链接: 手写算法-python代码实现Kmeans++以及优化

生成演示数据集:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_circles,make_blobs,make_moons

#演示数据集
x2,y2 = make_moons(n_samples=500,noise = 0.1,random_state=2020)
plt.scatter(x2[:,0],x2[:,1],marker='o')
plt.show()

在这里插入图片描述
从图像上看,这个数据集,我们适合聚类成2个类别,下面我们用sklearn里面的Kmeans算法来演示一下:

from sklearn.cluster import KMeans
Kmeans = KMeans(n_clusters=2)
y_preds = Kmeans.fit_predict(x2)
plt.scatter(x2[:,0],x2[:,1],c=y_preds,marker='o')
plt.show()

在这里插入图片描述
然后聚类结果是这样,对于这种非凸样本集,该怎么处理呢?
我们一般用DBSCAN聚类算法
DBSCAN(Density-Based Spatial Clustering of Applications with Noise),
直译就是:具有噪声的基于密度的聚类方法,2个特点:
1、可以找出噪声数据;
2、基于密度的聚类算法(Kmeans是基于划分);

原理解析:
下面引用刘建平博士的一段话:

DBSCAN是基于一组邻域来描述样本集的紧密程度的,参数(ϵ, MinPts)用来描述邻域的样本分布紧密程度。其中,ϵ描述了某一样本的邻域距离阈值,MinPts描述了某一样本的距离为ϵ的邻域中样本个数的阈值。

假设我的样本集是D=(x1,x2,…,xm),则DBSCAN具体的密度描述定义如下:

1) ϵ-邻域:对于xj∈D,其ϵ-邻域包含样本集D中与xj的距离不大于ϵ的子样本集,即Nϵ(xj)={xi∈D|distance(xi,xj)≤ϵ},
这个子样本集的个数记为|Nϵ(xj)|

2) 核心对象:对于任一样本xj∈D,如果其ϵ-邻域对应的Nϵ(xj)至少包含MinPts个样本,即如果|Nϵ(xj)|≥MinPts,则xj是核心对象。

3)密度直达

对于这份数据集,因为是二分类任务,所以准确率达到百分之百指的是将所有样本都正确分类。 以下是手写K-Means++,DBSCAN和AGNES的代码以及能够使得准确率达到百分之百的参数: K-Means++: ```python import numpy as np def k_means_pp(X, K, random_state=0): np.random.seed(random_state) centroids = np.zeros((K, X.shape[1])) centroids[0] = X[np.random.choice(X.shape[0])] for i in range(1, K): distances = np.zeros(X.shape[0]) for j in range(i): distances += np.linalg.norm(X - centroids[j], axis=1) centroids[i] = X[np.argmax(distances)] clusters = np.zeros(X.shape[0], dtype=int) while True: old_clusters = clusters.copy() distances = np.linalg.norm(X[:, None, :] - centroids[None, :, :], axis=-1) clusters = np.argmin(distances, axis=1) for i in range(K): if np.sum(clusters == i) > 0: centroids[i] = np.mean(X[clusters == i], axis=0) if np.all(old_clusters == clusters): break return clusters ``` 使用以上代码,可以使用以下方式调用: ```python from sklearn.datasets import make_moons from sklearn.metrics import accuracy_score X, y = make_moons(n_samples=400, shuffle=True, noise=0.1, random_state=136) preds = k_means_pp(X, 2, random_state=0) accuracy = accuracy_score(y, preds) print("K-Means++ Accuracy:", accuracy) ``` DBSCAN: ```python from sklearn.cluster import DBSCAN X, y = make_moons(n_samples=400, shuffle=True, noise=0.1, random_state=136) dbscan = DBSCAN(eps=0.2, min_samples=10) preds = dbscan.fit_predict(X) accuracy = accuracy_score(y, preds) print("DBSCAN Accuracy:", accuracy) ``` AGNES: ```python from scipy.spatial.distance import pdist, squareform from scipy.cluster.hierarchy import linkage, fcluster X, y = make_moons(n_samples=400, shuffle=True, noise=0.1, random_state=136) distances = pdist(X) linkage_matrix = linkage(distances, method='complete') preds = fcluster(linkage_matrix, 2, criterion='maxclust') accuracy = accuracy_score(y, preds - 1) print("AGNES Accuracy:", accuracy) ``` 注意,以上三种算法的准确率都依赖于初始的随机种子,如果随机种子不同,准确率可能会有所差异。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值