22 juillet 2013

Noter les chansons de ma bibliothèque iTunes

L'idée, c'est d'utiliser l'algorithme pour classer des participants à des batailles 1 contre 1 comme aux échecs (voir Elo ranking system).

D'abord, on exporte la liste des chansons sur iTunes en format XML.

J'utilise R pour importer le fichier XML, le parcourir et faire un tableau de données avec le nom des chansons et leurs ratings.

library(XML)
library(PlayerRatings)

doc <- xmlTreeParse("Musique.xml", getDTD=F)
r <- xmlRoot(doc)[["dict"]][["dict"]]

if (file.exists("musique.Rdata")){  
  data <- data.frame(title=as.character(""), artist=as.character(""), rating=as.character(""), stringsAsFactors=FALSE)
  for (i in seq(2,xmlSize(r),by=2)){
    values <- xmlSApply(r[[i]], xmlValue)
    name <- values[which(values=="Name")+1]
    artist <- values[which(values=="Artist")+1]
    rating <- values[which(values=="Rating")+1]
    if (length(name)==0){
      name <- "";
    }
    if (length(artist)==0){
      artist <-"";
    }
    if (length(rating)==0){
      rating<-"60";
    }
    
    temp <- data.frame(title=name[[1]], artist = artist[[1]], rating = rating[[1]], stringsAsFactors=FALSE)
    data <- rbind(data, temp)
  } 
} else {
  load("musique.Rdata")
}

data2 <- data[-c(1),]

data2$id=(as.numeric(row.names(data2))-1)

J'écris une fonction pour demander à l'utilisateur quelle est la meilleure chanson parmi deux chansons tirées au sort.


ranksongs <- function(data2, elodata, time){
    roi <-data2[sample(nrow(data), 2, replace=F),]
    cat("Who wins?\n")
    cat("1. ", roi[1,1], ",", roi[1,2], "\n")
    cat("2. ", roi[2,1], ",", roi[2,2], "\n")
    x <- as.integer(readline(" ")) 
    if (is.na(x)){x<-0.5}
    if ((x==1)){
      
    }else if(x==2){
      x <- 0;
    } else {
      x<-0.5
    }  
    temp <- data.frame(Time=time, Song1=roi[1,4], Song2=roi[2,4], Winner=x)
    elodata <- rbind(elodata, temp)
    return(elodata)
  }

#elodata <- ranksongs(data2, elodata, 1)
load("ranking.Rdata")

Cette fonction tourne en boucle.


while(1){
  elodata <- ranksongs(data2,elodata,2)
  save(elodata, file="ranking.Rdata")
}

Cette fonction de la librairie PlayerRatings permet de classer les chansons en fonction des combats menés.


music.rank <- steph(elodata, history=T)


Je me demande combien de combats sont nécessaires pour bien classer les chansons. J'ai hâte de voir si je vais arriver à classer mes chansons, modifier le fichier XML et réimporter les ratings dans iTunes...

Je suis content : je saurais écrire un site web sur ce principe comme dans le film The Social Network. Je talonne Zuckerberg ;-)

Aucun commentaire:

Enregistrer un commentaire