本文和你一起学习无监督机器学习算法 ———— kmeans算法,并在R中给详细的实现示例和步骤。
聚类是从数据集中对观测值进行聚类的机器学习方法。它的目标是聚类相似观测值,不同类别之间差异较大。聚类是一种无监督学习方法,因为它仅尝试从数据集中发现结构,而不是预测应变量的值。
下面是一个市场营销中对客户分类的场景,通过下面客户信息:
我们利用这些信息进行聚类,可识别相似家庭,从而能够识别某类型家庭可能购买某种产品或对某种类型的广告反应更好。
最常用的聚类算法就是k-means聚类算法,下面我们介绍k-means算法并通过示例进行说明。
k-means聚类算法把数据集中每个观测值分为K个类别。每个分类中的观测值相当类似,K类之间彼此差异较大。实际应用中执行下列几步实现k-means聚类算法:
首先确定把数据集分为几类。通常我们简单测试几个不同值K,然后分析结果,确定那个值更有现实意义。
将每个观察结果随机分配到一个初始簇中,从1到K。
执行以下步骤,直到集群分配停止变化。
下面通过示例展示R的实现过程。
首先加载两个包,包括kmeans算法的一些辅助函数。
library(factoextra)
library(cluster)
对于本例我们将使用R中内置的usarrest数据集,该数据集包含1973年美国每个州每10万居民因谋杀、袭击和强奸而被捕的人数,以及每个州居住在城市地区的人口百分比(UrbanPop)。
#load data
df <- USArrests
#remove rows with missing values
df <- na.omit(df)
#scale each variable to have a mean of 0 and sd of 1
df <- scale(df)
#view first six rows of dataset
head(df)
# Murder Assault UrbanPop Rape
# Alabama 1.24256408 0.7828393 -0.5209066 -0.003416473
# Alaska 0.50786248 1.1068225 -1.2117642 2.484202941
# Arizona 0.07163341 1.4788032 0.9989801 1.042878388
# Arkansas 0.23234938 0.2308680 -1.0735927 -0.184916602
# California 0.27826823 1.2628144 1.7589234 2.067820292
# Colorado 0.02571456 0.3988593 0.8608085 1.864967207
上面代码首先加载USArrests数据集,删除缺失值,对数据值进行标准化。
执行kmeans聚类算法,我们可以使用内置包stat中的kmeans()函数,语法如下:
kmeans(data, centers, nstart)
既然在使用kmeans函数之前并不确定最优聚类数量,下面通过两个图来辅助我们决定:
首先使用 fviz_nbclust 函数创建一个图,展示聚类数量及总体平方和之间的关系:
fviz_nbclust(df, kmeans, method = "wss")

通常我们创建这类图形寻找某个K类对应的平方和值开始弯曲或趋于平缓的肘形。这通常是最理想的聚类数量。上图中显然在k = 4个时出现肘形。
另一个决定最佳聚类数量的是使用指标:差距统计。它用于比较不同k值聚类差距变化情况。使用cluster包中的clusGap()以及fviz_gap_stat()函数画图:
#calculate gap statistic based on number of clusters
gap_stat <- clusGap(df,
FUN = kmeans,
nstart = 25,
K.max = 10,
B = 50)
#plot number of clusters vs. gap statistic
fviz_gap_stat(gap_stat)

从上图可以看到k=4时,差距统计最大,这与前面图的结果一致。
最后,我们执行kmeans函数,使用k=4作为最优值:
# 设置随机种子,让结果可以重现
set.seed(1)
# 调用kmeans聚类算法 k = 4
km <- kmeans(df, centers = 4, nstart = 25)
# 查看结果
km
# Show in New Window
# Clustering k = 1,2,..., K.max (= 10): .. done
# Bootstrapping, b = 1,2,..., B (= 50) [one "." per sample]:
# .................................................. 50
# R Console
#
#
# Show in New Window
# K-means clustering with 4 clusters of sizes 13, 13, 16, 8
#
# Cluster means:
# Murder Assault UrbanPop Rape
# 1 -0.9615407 -1.1066010 -0.9301069 -0.96676331
# 2 0.6950701 1.0394414 0.7226370 1.27693964
# 3 -0.4894375 -0.3826001 0.5758298 -0.26165379
# 4 1.4118898 0.8743346 -0.8145211 0.01927104
#
# Clustering vector:
# Alabama Alaska Arizona Arkansas California Colorado
# 4 2 2 4 2 2
# Connecticut Delaware Florida Georgia Hawaii Idaho
# 3 3 2 4 3 1
# Illinois Indiana Iowa Kansas Kentucky Louisiana
# 2 3 1 3 1 4
# Maine Maryland Massachusetts Michigan Minnesota Mississippi
# 1 2 3 2 1 4
# Missouri Montana Nebraska Nevada New Hampshire New Jersey
# 2 1 1 2 1 3
# New Mexico New York North Carolina North Dakota Ohio Oklahoma
# 2 2 4 1 3 3
# Oregon Pennsylvania Rhode Island South Carolina South Dakota Tennessee
# 3 3 3 4 1 4
# Texas Utah Vermont Virginia Washington West Virginia
# 2 3 1 3 3 1
# Wisconsin Wyoming
# 1 3
#
# Within cluster sum of squares by cluster:
# [1] 11.952463 19.922437 16.212213 8.316061
# (between_SS / total_SS = 71.2 %)
#
# Available components:
#
# [1] "cluster" "centers" "totss" "withinss" "tot.withinss"
# [6] "betweenss" "size" "iter" "ifault"
从结果可见:
我们可以通过fviz_cluster()函数在二维空间中以散点图方式展示结果:
#plot results of final k-means model
fviz_cluster(km, data = df)

也可以使用aggregate()函数查看每个类中变量的均值:
#find means of each cluster
aggregate(USArrests, by=list(cluster=km$cluster), mean)
# cluster Murder Assault UrbanPop Rape
#
# 1 3.60000 78.53846 52.07692 12.17692
# 2 10.81538 257.38462 76.00000 33.19231
# 3 5.65625 138.87500 73.87500 18.78125
# 4 13.93750 243.62500 53.75000 21.41250
输出结果解释如下:
最后我们把聚类结果附加到原始数据集中:
#add cluster assigment to original data
final_data <- cbind(USArrests, cluster = km$cluster)
#view final data
head(final_data)
# Murder Assault UrbanPop Rape cluster
#
# Alabama 13.2 236 58 21.2 4
# Alaska 10.0 263 48 44.5 2
# Arizona 8.1 294 80 31.0 2
# Arkansas 8.8 190 50 19.5 4
# California 9.0 276 91 40.6 2
# Colorado 7.9 204 78 38.7 2
优点:
缺点:
本文我们讨论了kmeans算法的概念,并在R中给详细实现示例和步骤。
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
1.1.1 YARN的介绍 为克服Hadoop1.0中HDFS和MapReduce存在的各种问题⽽提出的,针对Hadoop1.0中的MapReduce在扩展性和多框架⽀持⽅⾯的不⾜,提出了全新的资源管理框架YARN. ApacheYARN(YetanotherResourceNegotiator的缩写)是Hadoop集群的资源管理系统,负责为计算程序提供服务器计算资源,相当于⼀个分布式的操作系统平台,⽽MapReduce等计算程序则相当于运⾏于操作系统之上的应⽤程序。 YARN被引⼊Hadoop2,最初是为了改善MapReduce的实现,但是因为具有⾜够的通⽤性,同样可以⽀持其他的分布式计算模
通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复