Comment trouver la similitude entre différents facteurs dans un ensemble de données

8

introduction

Disons que j'ai un ensemble de données d'observation différente de différentes personnes et je veux regrouper des personnes pour savoir quelle personne est la plus proche de l'autre. Je veux aussi avoir une mesure pour savoir à quel point ils sont proches les uns des autres et connaître la signification statistique.

Les données

       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

Reproduisez-le:

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")

Question

Étant donné un ensemble de données en tant que boursier (avec une caractéristique continue et catégorique), comment puis-je savoir si une personne (une réponse catégorique) identifiée par un nom est plus corrélée à une autre personne?

zipp
la source

Réponses:

6

Une façon consiste à normaliser vos valeurs quantitatives (jouer, manger, boire, dormir) afin qu'elles aient toutes la même plage (par exemple, 0 -> 1), puis attribuer chaque jeu à sa propre "dimension", qui prend la valeur 0 ou 1. Transformez chaque ligne en vecteur et normalisez la longueur à 1. Maintenant, vous pouvez comparer le produit intérieur des vecteurs normalisés de deux personnes comme mesure de similitude. Quelque chose comme ça est utilisé dans l'exploration de texte assez souvent


Code R pour la matrice de similarité

Suppose que vous avez enregistré votre trame de données dans la variable "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)

la source
Merci d'avoir répondu. Pourriez-vous donner un code R pour le faire avec l'exemple que j'ai donné afin d'avoir la réponse parfaite?
zipp
1
@zipp c'est parti. Je l'ai fait calculer les vecteurs normalisés, j'ai également créé un vecteur normalisé pour chaque personne, en normalisant la somme vectorielle des lignes qui correspondent à cette personne. Enfin, je prends le produit scalaire de chaque personne contre toute autre personne en utilisant la formuleXXT
2

Malgré la distance euclidienne normalisée, vous pouvez également consulter la distance Pearson comme mesure de similitude. Voici une description soignée: http://mines.humanoriented.com/classes/2010/fall/csci568/portfolio_exports/sphilip/pear.html

Thomas Pazur
la source
Le problème que j'ai avec le Pearson est que je ne sais pas comment joindre mes données et prendre soin de la variable catégorielle (peut-être pourrait-on le faire avec une variable fictive comme Bey l'a suggéré, mais je ne suis pas sûr que cela fonctionnerait avec)
zipp
0
  • Vous voudrez peut-être normaliser toutes les variables continues dans une plage (0-1)
  • Normaliser les variables catégorielles en tant que One Hot Enconder
  • Appliquer des algorithmes de similarité comme les algorithmes de corrélation / distance de Pearson comme (similitude euclidienne, cosinus)
Shravan Shetty
la source