我目前正在制作MasterThesis,对于我的MasterThesis,我想创建一个模拟模型,该模型可以模拟老年人的行走行为。但是为了使我的仿真模型更容易,我想基于聚类分析形成组,这样我就可以轻松地将某些步行行为分配给某个老年人(如果它属于某个组)(因此,如果您属于第1组,则您的步行时间分钟将是大约20分钟)。
但是,我对聚类分析并不那么熟悉。我有一个大数据集,其中包含许多老年人特征的数据(**离散和连续性质的变量**),但是根据文献,目前使用了以下特征:
年龄,性别,计分健康,教育类别,收入类别,职业,社交网络,是/否生活在一个宜人的社区中,是/否在附近社区感到安全,与绿色的距离,有一个狗,步行时间,以分钟为单位。
使用菊花函数并使用 剪影 方法定义理想的群集/因此组的数量后,我得到了群集。但是,现在我想知道如何从集群中得出含义。由于我正在处理类别,因此我发现很难使用诸如均值之类的统计功能。因此,我该怎么做才能从每个群集组中得出有用的含义/ 统计结论,例如,如果您属于群集组1,则您的收入水平应该平均在收入组10左右,年龄应该在70岁左右,步行时间以分钟为单位,例如大约20分钟。理想情况下,我还希望每个聚类组中每个变量的标准偏差。 因此,我可以轻松地在仿真模型中使用这些值将特定的步行行为分配给老年人。
答案 0 :(得分:0)
@Joy,首先应确定相关变量。这也将有助于减少尺寸。由于您尚未提供要使用的示例数据集,因此我将创建自己的数据集。另外,在进行聚类分析之前,您还必须注意,获取pure
的聚类很重要。纯粹是指群集必须包含only those variables that account for maximum variance in the data
。变量几乎没有或可以忽略不计,因此最好将其删除,因为它们不是聚类模型的贡献者。一旦有了这些(统计上)重要变量,聚类分析就将很有意义。
理论概念
聚类是一种预处理算法。必须导出具有统计意义的变量以提取pure clusters
。这些significant variables
在分类任务中的派生称为功能选择,而在聚类任务中的派生称为主成分(PC)。从历史上看,PC仅适用于连续变量。为了从分类变量中导出PC,有一种称为对应分析(CA)的方法,对于名义分类变量,可以使用多对应分析(MCA)。
实际实施
让我们创建一个包含混合变量(即分类变量和连续变量)的数据框,例如
R> digits = 0:9
# set seed for reproducibility
R> set.seed(17)
# function to create random string
R> createRandString <- function(n = 5000) {
a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
}
R> df <- data.frame(ID=c(1:10), name=sample(letters[1:10]),
studLoc=sample(createRandString(10)),
finalmark=sample(c(0:100),10),
subj1mark=sample(c(0:100),10),subj2mark=sample(c(0:100),10)
)
R> str(df)
'data.frame': 10 obs. of 6 variables:
$ ID : int 1 2 3 4 5 6 7 8 9 10
$ name : Factor w/ 10 levels "a","b","c","d",..: 2 9 4 6 3 7 1 8 10 5
$ studLoc : Factor w/ 10 levels "APBQD6181U","GOSWE3283C",..: 5 3 7 9 2 1 8 10 4 6
$ finalmark: int 53 73 95 39 97 58 67 64 15 81
$ subj1mark: int 63 18 98 83 68 80 46 32 99 19
$ subj2mark: int 90 40 8 14 35 82 79 69 91 2
我将在数据中注入随机缺失值,以使其与真实数据集更加相似。
# add random NA values
R> df<-as.data.frame(lapply(df, function(cc) cc[ sample(c(TRUE, NA), prob = c(0.85, 0.15), size = length(cc), replace = TRUE) ]))
R> colSums(is.na(df))
ID name studLoc finalmark subj1mark subj2mark
0 0 0 2 2 0
如您所见,缺少的值在连续变量finalmark
和subj1mark
中。我选择对均值进行均值插补,因为中值比均值更可靠。
# Create a function to impute the missing values
R> ImputeMissing<- function(data=df){
# check if data frame
if(!(is.data.frame(df))){
df<- as.data.frame(df)
}
# Loop through the columns of the dataframe
for(i in seq_along(df))
{
if(class(df[,i]) %in% c("numeric","integer")){
# missing continuous data to be replaced by median
df[is.na(df[,i]),i] <- median(df[,i],na.rm = TRUE)
} # end inner-if
} # end for
return(df)
} # end function
# Remove the missing values
R> df.complete<- ImputeMissing(df)
# check missing values
R> colSums(is.na(df.complete))
ID name studLoc finalmark subj1mark subj2mark
0 0 0 0 0 0
现在,我们可以将FAMD()
包中的方法FactoMineR
应用于cleaned
数据集。您可以在R控制台中输入??FactoMineR::FAMD
来查看此方法的插图。从小插图来看, FAMD是一种主要成分方法,专用于探索具有连续变量和分类变量的数据。可以将其大致视为PCA和MCA的混合体。更准确地说,将连续变量按比例缩放为单位方差,然后将分类变量转换为析取数据表(crisp编码),然后使用MCA的特定缩放比例进行缩放。这样可确保在分析中平衡连续变量和分类变量的影响。这意味着两个变量都在平等的基础上确定可变性的维度。
R> df.princomp <- FactoMineR::FAMD(df.complete, graph = FALSE)
此后,我们可以使用如图1所示的screeplot
来可视化PC,例如
R> factoextra::fviz_screeplot(df.princomp, addlabels = TRUE,
barfill = "gray", barcolor = "black",
ylim = c(0, 50), xlab = "Principal Component",
ylab = "Percentage of explained variance",
main = "Principal Component (PC) for mixed variables")
Scree图(如图1所示)是一个简单的线段图,它显示了数据中总方差的一部分,由每个主成分(PC)解释或表示。因此,我们可以看到前三台PC共同占总方差的44.5%。现在自然会出现一个问题,“这些变量是什么?”。
为了提取变量的贡献,我使用了如图2所示的fviz_contrib()
,
R> factoextra::fviz_contrib(df.princomp, choice = "var",
axes = 1, top = 10, sort.val = c("desc"))
上面的fig2可视化了主成分分析(PCA)结果中的行/列的贡献。从这里我可以看到变量studLoc
,name
,subj2mark
和finalMark
是可用于进一步分析的最重要变量。
现在,您可以进行聚类分析。
# extract the important variables and store in a new dataframe
R> df.princomp.impvars<- df.complete[,c(2:3,6,4)]
# make the distance matrix
R> gower_dist <- cluster::daisy(df.princomp.impvars,
metric = "gower",
type = list(logratio = 3))
R> gower_mat <- as.matrix(gower_dist)
#make a hierarchical cluster model
R> model<-hclust(gower_dist)
#plotting the hierarchy
R> plot(model)
#cutting the tree at your decided level
R> clustmember<-cutree(model,3)
#adding the cluster member as a column to your data
R> df.clusters<-data.frame(df.princomp.impvars,cluster=clustmember)
R> df.clusters
name studLoc subj2mark finalmark cluster
1 b POTYQ0002N 90 53 1
2 i LWMTW1195I 40 73 1
3 d VTUGO1685F 8 95 2
4 f YCGGS5755N 14 70 1
5 c GOSWE3283C 35 97 2
6 g APBQD6181U 82 58 1
7 a VUJOG1460V 79 67 1
8 h YXOGP1897F 69 64 1
9 j NFUOB6042V 91 70 1
10 e QYTHG0783G 2 81 3