我们知道『物以类聚,人以群分』,这里并不是分类问题,而是聚类问题。
两者主要区别在于,分类是将一组数据根据不同的类区分,已经知道有哪些类,也就是数据已经有了类的标签。而聚类是一种事先不知道有多少类,通过算法学习,分出来了一些类别。
分类跟聚类也分别是有监督学习和无监督学习的范畴。
k-means算法
k-means是聚类算法中最简单的,也是最常用的一种方法。
这里的
指的是初始规定要将数据集分成的类别,means是各类别数据的均值作为中心点。
算法步骤:
1.初始设置要分成的类别
,及随机选取数据集中
个点作为初始点
2.根据相似性度量函数将其他点与初始点做比较,离哪个值近就分到哪一个类
3.将分出来的
类求取平均值,作为新的中心点
4.重复步骤,直到中心点不变或者变化不大(即收敛)或者达到规定的迭代次数则停止
相似性度量有多种函数,一般使用欧式距离。相似性度量函数
补充:为什么会使用均值作为中心点的选择呢?
这主要是因为目标函数的设置决定的。我们使用误差平方和作为聚类的目标函数,即
。
这里的
表示
个类,
表示第
个中心,
,
是欧几里得距离。
对第
个中心
求解,最小化上述公式。对上述公式求导并令导数等于0,得到如下公式:
可以看到,每个簇中能够让目标函数达到最小的中心点就是这个簇的均值。
举例说明
下面以一个具体例子来说明k-means算法步骤。数据集如下。
因为是二维的,可以画下散点图看下。
直观来看,这个数据集是有两类的,也就是两个簇,一个是在右上角,一个是在左下角。可以使用算法看下是否符合预判。
Step1:
那我们可以设置
为2,初始中心值就选
。
Step2:
下面就是计算剩下的点到中心点的距离,使用欧氏距离。
比较之后,发现剩下的点到
距离更近,那现在有了两类:
Step3:
然后重新选择中心点,第一类只有一个值,则仍然为
。第二类按照5个点的均值作为中心点
: ((1+3+8+9+10)/5, (2+1+8+10+7)/5) = (6.2,5.6)。重新计算距离。
现在分成的两类为
Step4:
Step2和Step3中心点相差较大,重新选择中心点。
这次就是两个类中数据的均值作为新的中心点了。分别为
。
现在仍然是两类
继续下去,中心点不变,也就是达到收敛了。分成的两类就是上面两组,与散点图观察到的一致。
R语言实现
使用R语言自带的函数及可视化包。
数据及包的准备
# 载入数据
data("USArrests")
# 数据标准化
data
head(data)
# 可视化包
library(factoextra)
确定最佳聚类数,选择坡度不明显的点作为聚类数。
# 确定聚类数
fviz_nbclust(data, kmeans, method = "wss") + geom_vline(xintercept = 4, linetype = 2)
# 另一种方法
wss
for (i in 2:15)
wss[i]
plot(1:15, wss, type="b", xlab="Number of Clusters",ylab="Within groups sum of squares")
可以选择4个类别。下面进行聚类。
#利用k-mean是进行聚类
km
# 查看结果
print(km)
查看结果并分析数据:print(km)
K-means clustering with 4 clusters of sizes 13, 16, 8, 13
Cluster means:
Murder Assault UrbanPop Rape
1 0.6950701 1.0394414 0.7226370 1.27693964
2 -0.4894375 -0.3826001 0.5758298 -0.26165379
3 1.4118898 0.8743346 -0.8145211 0.01927104
4 -0.9615407 -1.1066010 -0.9301069 -0.96676331
Clustering vector:
Alabama Alaska Arizona Arkansas
3 1 1 3
California Colorado Connecticut Delaware
1 1 2 2
Florida Georgia Hawaii Idaho
1 3 2 4
Illinois Indiana Iowa Kansas
1 2 4 2
Kentucky Louisiana Maine Maryland
4 3 4 1
Massachusetts Michigan Minnesota Mississippi
2 1 4 3
Missouri Montana Nebraska Nevada
1 4 4 1
New Hampshire New Jersey New Mexico New York
4 2 1 1
North Carolina North Dakota Ohio Oklahoma
3 4 2 2
Oregon Pennsylvania Rhode Island South Carolina
2 2 2 3
South Dakota Tennessee Texas Utah
4 3 1 2
Vermont Virginia Washington West Virginia
4 2 2 4
Wisconsin Wyoming
4 2
Within cluster sum of squares by cluster:
[1] 19.922437 16.212213 8.316061 11.952463
(between_SS / total_SS = 71.2 %)
Available components:
[1] "cluster" "centers" "totss" "withinss"
[5] "tot.withinss" "betweenss" "size" "iter"
[9] "ifault"
第一行结果是4类,每个类别的数据个数。
下面是聚类的中心点。
然后是每个值所属哪个类别。
Within cluster sum of squares by cluster:是组间距离平方和。
聚类的目的是组内距离小,组间距离大。between_SS / total_SS就是组间距离占总距离的占比,越接近1越好。
聚类可视化
fviz_cluster(km, data = data,
palette = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
ellipse.type = "euclid",
star.plot = TRUE,
repel = TRUE,
ggtheme = theme_minimal()
)
k-means不足
①需要确定分类数
,一般根据经验或者已经有预判,其次是根据上面的方法确定分类数量。
②初始值的选取会影响最终聚类效果,并且目标函数
可能会达到局部最优解。这个有相应的改进方法,包括k-means++和二分k-means。
③对于类似下面圆形的数据集,聚类效果很差,主要是算法原因。所以还有其他的聚类算法,比如基于密度的方法等。
不过k-means实现简单,易于理解,应用很广泛。