DSCAN聚类算法概念和实现

程序需要的数据集见文章结尾。

DSCAN算法:具有噪声的基于密度的聚类算法。

上一节的k-means算法的缺点之一就是K值的选取问题,这里DSCAN聚类算法不需要指定K值,这里的DSCAN算法需要指定两个参数:

epsilon:指定半径

Minpt:密度阈值

这里有两个概念需要解释:直接密度可达和密度可达

宇哥的视频中是这样讲解的

(忽略图丑)

左边这个图中p和q在一个圈里面,它们是直接密度可达的;右边这个图里面,p1和p2是直接密度可达,p2和p3是直接密度可达,这里p1和p3是密度可达(少了直接两个字),密度可达是直接密度可达的“传播”。

DSCAN聚类算法中需要两个参数

epsilon:指定半径

Minpt:密度阈值

那么这两个参数如何选择呢?关于半径,可以根据k距离来设定,寻找突变点,啥叫突变点呢?

 假如将p0到p1-6的距离分别定为d1-d6,这里0.14到0.3跨度较大,所以0.3这里是突变点。

Minpt:K距离中k的值

https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/

介绍DSCAN可视化比较好的一个网站,可以选择不同的数据形状,聚类。

DSCAN聚类的优点:

不需要指定k值;可以发现任意形状的簇;擅长找到离群点(适合做异常检测);两个参数就可以了。

对于这个笑脸数据,就可以分成很好的形状。

但是如果数据集直接比较密集,可能聚类出来的效果就不太好。

 

比如这个数据集。

然后,具体程序看一下kmeans和DSCAN如何实现聚类算法

首先样本数据集是20个样本的关于酒的数据。首先是读入数据--kmeans聚类--可视化--然后标准化数据--可视化结果;聚类实现了,如何评价聚类效果--轮廓系数--根据这个系数确定选取k

# beer dataset
import pandas as pd
beer = pd.read_csv('data.txt', sep=' ')
beer


#无监督学习,不需要标签,输入的是所有的特征
X = beer[["calories","sodium","alcohol","cost"]]


from sklearn.cluster import KMeans

km = KMeans(n_clusters=3).fit(X)
km2 = KMeans(n_clusters=2).fit(X)

#查看聚类以后的标签
km.labels_

 

 

然后查看聚类的中心

from pandas.tools.plotting import scatter_matrix
%matplotlib inline

cluster_centers = km.cluster_centers_
cluster_centers_2 = km2.cluster_centers_


聚类是3类和聚类是两类的中心点分别如下:

 

centers = beer.groupby("cluster").mean().reset_index()
#可视化展示
import matplotlib.pyplot as plt
#标题的字体大小
plt.rcParams['font.size'] = 14

import numpy as np
colors = np.array(['red', 'green', 'blue', 'yellow'])


#可视化展示calories和alcohol的聚类关系
plt.scatter(beer["calories"], beer["alcohol"],c=colors[beer["cluster"]])
plt.scatter(centers.calories, centers.alcohol, linewidths=3, marker='+', s=300, c='black')
plt.xlabel("Calories")
plt.ylabel("Alcohol")

 

如何展示多个变量之间的关系:scatter_matrix(beer['变量名'])

#分成3类的时候
scatter_matrix(beer[["calories","sodium","alcohol","cost"]],s=100, alpha=1, c=colors[beer["cluster"]], figsize=(10,10))
plt.suptitle("With 3 centroids initialized")

#分成2类的时候
scatter_matrix(beer[["calories","sodium","alcohol","cost"]],s=100, alpha=1, c=colors[beer["cluster2"]], figsize=(10,10))
plt.suptitle("With 2 centroids initialized")

 

 

之后尝试对数据做一些预处理(标准化),然后再聚类。 

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

km = KMeans(n_clusters=3).fit(X_scaled)

beer["scaled_cluster"] = km.labels_
beer.sort_values("scaled_cluster")

beer.groupby("scaled_cluster").mean()

 

 然后可视化各个变量之间的聚类效果图,参考前面没做标准化之前的作图。

如何评价聚类的效果呢?

使用轮廓系数

from sklearn import metrics
score_scaled = metrics.silhouette_score(X,beer.scaled_cluster)
score = metrics.silhouette_score(X,beer.cluster)
print(score_scaled, score)

 

这里没做标准化的聚类效果要优于做标准化之后的聚类效果(所以有时候并不是做标准化就一定好)

#查看不同k值的情况下的轮廓系数
scores = []
for k in range(2,20):
    labels = KMeans(n_clusters=k).fit(X).labels_
    score = metrics.silhouette_score(X, labels)
    scores.append(score)

 

 发现k=2的时候轮廓系数比较大,所以选择k=2比较好。

DBSCAN聚类算法(对于不规整数据集比较强大,简单数据集的效果可能还不如k-means)

from sklearn.cluster import DBSCAN
db = DBSCAN(eps=10, min_samples=2).fit(X)

labels = db.labels_

beer['cluster_db'] = labels
beer.sort_values('cluster_db')


beer.groupby('cluster_db').mean()

pd.scatter_matrix(X, c=colors[beer.cluster_db], figsize=(10,10), s=100)

 

数据集链接:https://pan.baidu.com/s/1hfR9CNV0DOhfBhnFy9accQ 
提取码:x519 
 

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值