如何找到数据集中不同因素之间的相似性

数据挖掘 机器学习 r 相似 相关性
2021-09-30 11:32:16

介绍

假设我有一个对不同人的不同观察的数据集,我想将人们分组在一起以了解哪个人最接近另一个人。我还想有一个衡量标准,以了解它们彼此之间的接近程度并了解统计意义。

数据

       eat_rate drink_rate   sleep_rate    play_rate  name   game
1  0.0542192259 0.13041721 5.013682e-03 1.023533e-06  Paul Rayman
4  0.0688171511 0.01050611 6.178833e-03 3.238838e-07  Paul  Mario
6  0.0928997660 0.01828468 9.321211e-03 3.525951e-07  Jenn  Mario
7  0.0001631273 0.02212345 7.061524e-05 1.531270e-07  Jean   FIFA
8  0.0028735509 0.05414688 1.341689e-03 4.533366e-07  Mark   FIFA
10 0.0034844717 0.09152440 4.589990e-04 5.802708e-07  Mark Rayman
11 0.0340738956 0.03384180 1.636508e-02 1.354973e-07  Mark   FIFA
12 0.0266112679 0.20002020 3.380704e-02 4.533366e-07  Mark  Sonic
14 0.0046597056 0.01848672 5.472681e-04 4.034696e-07  Paul   FIFA
15 0.0202715299 0.16365289 2.994086e-02 4.044770e-07 Lucas   SSBM

重现它:

structure(list(eat_rate = c(0.0542192259374624, 0.0688171511010916, 
0.0928997659570807, 0.000163127341146237, 0.00287355085557602, 
0.00348447171120939, 0.0340738956099744, 0.0266112679045701, 
0.00465970561072008, 0.0202715299408583), drink_rate = c(0.130417213859986, 
0.0105061117284574, 0.0182846752197192, 0.0221234468128094, 0.0541468835235882, 
0.0915243964036772, 0.0338418022022427, 0.200020204061016, 0.0184867158298818, 
0.163652894231741), sleep_rate = c(0.00501368170182717, 0.00617883308323771, 
0.00932121105128431, 7.06152352370024e-05, 0.00134168946950305, 
0.000458999029040516, 0.0163650807661753, 0.0338070438697149, 
0.000547268073086768, 0.029940859740489), play_rate = c(1.02353325645595e-06, 
3.23883801132467e-07, 3.52595117873603e-07, 1.53127022619393e-07, 
4.53336580123204e-07, 5.80270822557701e-07, 1.35497266725713e-07, 
4.53336580123204e-07, 4.03469556309652e-07, 4.04476970932148e-07
), name = structure(c(5L, 5L, 2L, 1L, 4L, 4L, 4L, 4L, 5L, 3L), .Label = c("Jean", 
"Jenn", "Lucas", "Mark", "Paul"), class = "factor"), game = structure(c(3L, 
2L, 2L, 1L, 1L, 3L, 1L, 4L, 1L, 5L), .Label = c("FIFA", "Mario", 
"Rayman", "Sonic", "SSBM"), class = "factor")), .Names = c("eat_rate", 
"drink_rate", "sleep_rate", "play_rate", "name", "game"), row.names = c(1L, 
4L, 6L, 7L, 8L, 10L, 11L, 12L, 14L, 15L), class = "data.frame")

问题

给定一个数据集作为同伴(具有连续和分类特征),我如何知道由名称识别的人(分类答案)是否与另一个人更相关?

3个回答

一种方法是标准化您的量化值(游戏、吃、喝、睡眠率),使它们都具有相同的范围(例如,0 -> 1),然后将每个游戏分配给它自己的“维度”,取值为 0 或1.将每一行变成一个向量,并将长度归一化为1。现在,您可以比较任何两个人的归一化向量的内积作为相似度的度量。像这样的东西经常用于文本挖掘


相似矩阵的 R 代码

假设您已将数据框保存到变量“D”

#Get normalization factors for quantitative measures
maxvect<-apply(D[,1:4],MARGIN=2,FUN=max)
minvect<-apply(D[,1:4],MARGIN=2,FUN=min)
rangevect<-maxvect-minvect
#Normalize quantative factors
D_matrix <- as.matrix(D[,1:4])
NormDMatrix<-matrix(nrow=10,ncol=4)
colnames(NormDMatrix)<-colnames(D_matrix)
for (i in 1:4) NormDMatrix[,i]<-(D_matrix[,i]-minvect[i]*rep(1,10))/rangevect[i]
gamenames<-unique(D[,"game"])
#Create dimension matrix for games
Ngames<-length(gamenames)
GameMatrix<-matrix(nrow=10,ncol=Ngames)
for (i in 1:Ngames) GameMatrix[,i]<-as.numeric(D[,"game"]==gamenames[i])
colnames(GameMatrix)<-gamenames
#combine game matrix with normalized quantative matrix
People<-D[,"name"]
RowVectors<-cbind(GameMatrix,NormDMatrix)
#normalize each row vector to length of 1 and then store as a data frame with person names
NormRowVectors<-t(apply(RowVectors,MARGIN=1,FUN=function(x) x/sqrt(sum(x*x))))
dfNorm<-data.frame(People,NormRowVectors)

#create person vectors via addition of appropriate row vectors
PersonMatrix<-array(dim=c(length(unique(People)),ncol(RowVectors)))
rownames(PersonMatrix)<-unique(People)
for (p in unique(People)){
  print(p)
  MatchIndex<-(dfNorm[,1]==p)*seq(1,nrow(NormRowVectors))
  MatchIndex<-MatchIndex[MatchIndex>0]
  nclm<-length(MatchIndex)
  SubMatrix<-matrix(NormRowVectors[MatchIndex,],nrow=length(MatchIndex),ncol=dim(NormRowVectors)[2])
  CSUMS<-colSums(SubMatrix)
  NormSum<-sqrt(sum(CSUMS*CSUMS))
  PersonMatrix[p,]<-CSUMS/NormSum
}
colnames(PersonMatrix)<-colnames(NormRowVectors)
#Calculate matrix of dot products
Similarity<-(PersonMatrix)%*%t(PersonMatrix)

尽管归一化欧几里得距离,您也可以将皮尔逊距离视为相似性度量。这是一个简洁的描述: http: //mines.humanorientated.com/classes/2010/fall/csci568/portfolio_exports/sphilip/pear.html

  • 您可能希望将所有连续变量归一化为一个范围 (0-1)
  • 将分类变量归一化为 One Hot Enconder
  • 应用相似度算法,如皮尔逊相关/距离算法,如(欧几里得、余弦相似度)