kmean法和dbscan法的直观比较

转自:kmean法和dbscan法的直观比较
K均值聚类使用非常广泛,作为更为古老的聚类方法,它的算法非常简单,而且速度很快。但是其缺点在于它不能识别非球形的簇。我们可以用一个简单的例子来观察K均值聚类的弱点。我们先构造一些人为数据,它是基于sin函数和cos函数构成的两组点。如果我们用传统的K均值聚类,结果如下图所示。其聚类结果是不理想的,因为它不能识别非球形的簇。
 


DBSCAN的算法是将所有点标记为核心点、边界点或噪声点,将任意两个距离小于eps的核心点归为同一个簇。任何与核心点足够近的边界点也放到与之相同的簇中。下面我们来使用R语言中的fpc包来对上面的例子实施密度聚类。其中eps参数设为0.6,即两个点之间距离小于0.6则归为一个簇,而阀值MinPts设为4。


从上图可以看到,DBSCAN方法很好的划分了两个簇。其中要注意参数eps的设置,如果eps设置过大,则所有的点都会归为一个簇,如果设置过小,那么簇的数目会过多。如果MinPts设置过大的话,很多点将被视为噪声点。

从这个例子中,我们可以看到基于密度聚类的优良特性,它可以对抗噪声,能处理任意形状和大小的簇,这样可以发现K均值不能发现的簇。但是对于高维数据,点之间极为稀疏,密度就很难定义了。

 



实现代码如下:
# 生成数据
x1 <- seq(0,pi,length.out=100)
y1 <- sin(x1) + 0.1*rnorm(100)
x2 <- 1.5+ seq(0,pi,length.out=100)
y2 <- cos(x2) + 0.1*rnorm(100)
data <- data.frame(c(x1,x2),c(y1,y2))
names(data) <- c('x','y')

# 用K均值聚类
model1 <- kmeans(data,centers=2,nstart=10)
library(ggplot2)
p <- ggplot(data,aes(x,y))
p + geom_point(size=2.5,aes(colour=factor(model1$cluster)))+
               opts(legend.position='top')

# 用fpc包中的dbscan函数进行密度聚类
library('fpc')
model2 <- dbscan(data,eps=0.6,MinPts=4)
p + geom_point(size=2.5, aes(colour=factor(model2$cluster)))+
               opts(legend.position='top')
以上为转载
在MATLAB中,可以使用自带的kmeans函数进行k-means聚类。首先,使用kmeans函数将数据分成指定数量的簇,例如cluster_num=3,即将数据分成3个簇。然后,可以使用unique函数找出分类出的个数,并使用cell数组存储每个簇中的数据索引。接下来,遍历每个簇,获取对应的数据并使用scatter函数绘制散点图表示每个簇的数据。同时,可以使用plot函数绘制簇的中心点。最后,可以计算轮廓系数(SC)来评估聚类效果。轮廓系数可以使用mean函数计算silhouette函数返回的值。整个过程的代码示例如下: ``` cluster_num=3; %自定义分类数 [index_km,center_km]=kmeans(data,cluster_num); %MATLAB自带kmeans函数 a=unique(index_km); %找出分类出的个数 C=cell(1,length(a)); for i=1:length(a) C(1,i)={find(index_km==a(i))}; end figure subplot(2,1,2) for j=1:cluster_num data_get=data(C{1,j},:); scatter(data_get(:,1),data_get(:,2),100,'filled','MarkerFaceAlpha',.6,'MarkerEdgeAlpha',.9); hold on end plot(center_km(:,1),center_km(:,2),'kd','LineWidth',2); hold on sc_k=mean(silhouette(data,index_km)); title_str1=['MATLAB自带kmeans函数',' 聚类数为:',num2str(cluster_num),' SC轮廓系数:',num2str(sc_k)]; title(title_str1); ``` 可以在MATLAB中运行以上代码来进行k-means聚类,并可视化聚类结果。 此外,您还可以参考GitHub的一个示例代码,链接如下:[https://github.com/Qyokizzzz/AI-Algorithm/tree/master/K-means](https://github.com/Qyokizzzz/AI-Algorithm/tree/master/K-means) 。 另外,您还可以通过分析数据,选择最佳的k值进行聚类。例如,可以加载fisheriris数据集,并使用其meas的前两个维度来进行聚类。以下是一个示例脚本: ``` load fisheriris data = normalization(meas); [idx,C,~ = Kmeans(data(:,1:2),3,0,5000); figure gscatter(data(:,1),data(:,2),idx,'bgm') hold on plot(C(:,1),C(:,2),'kx') legend('Cluster 1','Cluster 2','Cluster 3','ClusterCentroid') ``` 上述代码将fisheriris数据集进行了归一化处理,并使用Kmeans函数将数据聚类成3个簇。通过gscatter函数绘制散点图表示不同簇的数据,并使用plot函数绘制簇的中心点。 最后,您还可以编写一个计算"有序属性"距离的函数来计算样本点之间的闵可夫斯基距离。例如,可以使用cal_dist函数计算两个样本点之间的欧氏距离或曼哈顿距离。以下是一个示例代码: ``` function dist = cal_dist(X,p) dim = size(X); sum = 0; for i = 1:dim(2) sum = sum + abs(X(1,i)-X(2,i))^p; end dist = sum^(1/p); end ``` 该函数可以根据指定的p值计算两个样本点之间的闵可夫斯基距离,其中p=2为欧氏距离,p=1为曼哈顿距离。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值