#Introduction



Le jeu vidéos est devenu un lobby très populaire et est rentré dans nos cultures, à un tel point que nous avons déjà tous au moins jouer une seule fois aux jeux vidéos. Cette popularisation a évolué en plusieurs générations. La première générations de console de jeu est apparu en 1972 avec l’Odyssey de Magnavox, elle est la toute première console de jeu vidéos. Durant cette première génération, plus de 900 consoles sont apparu, toutes se ressemblant plus les unes des autres. Cette génération sera marqué par l’intégration directe des jeux vidéos à la plateforme, les joueurs ne pouvant alors pas acheter des jeux à l’unité. En 1977, c’est le premier krach du jeu vidéo, à cause de la saturation du marché des consoles, et l’arrivée de la seconde génération qui va bouleversé le marché du jeu vidéo. Les consoles de cette génération permettent aux joueurs de pouvoir acheter les jeux qui l’interessent. La console qui a marqué cette génération est la légendaire Atari 2600 avec plus de 30 Million d’exemplaires vendus. Hélas un second krach du jeu vidéo survient en 1983 notamment à cause de la prolifération de jeux de basses qualité, et aussi à cause de la “course à la puissance” car c’est dès la 2ème génération de console que chaque constructeurs avaient pour but de créer la console la plus puissante du marché. L’industrie du jeu vidéo ne redémarrera qu’en 1985 avec l’arrivée de la troisième génération des consoles, notamment avec le succès mondiale de la console de nintendo : la NES, avec des jeux comme Super Mario Bros ou The Legend of Zelda, qui sont aujourd’hui encore des incontournables de la marque Nintendo. C’est à la fin des années 1980 que vient la 4ème génération et le début de la guerre économique. Les consoles de jeux tournent désormais avec des microprocesseurs 16 bits voire 16/32 bits, les prix fluctuent et une réelle concurrence émerge. Cette génération sera marqué par Sega et Nintendo qui se livrent une veritable bataille : d’un côté la MegaDrive de Sega, de l’autre la Super Nintendo de Nintendo. La bataille ne s’arrête pas là, car le conflit s’étend à tel point que les deux firmes sortent deux consoles portables : La GameBoy de Nintendo et la GameGear de Sega. La bataille continuera jusqu’à la 5ème génération, avec l’arrivée d’un nouveau concurrent : Sony présente sa PlayStation. Sega quand à elle sortira la Sega Saturn, Nintendo quand à eux sortiront la Nintendo 64. C’est la PlayStation qui dominera le marché de la 5ème génération, qui marquera aussi le déclin et le début de la faillite de Sega. La 6ème génération sera marqué avec l’arrivée de microsoft présentant la Xbox, mais encore une fois le succès reviendra à Sony avec sa PlayStation 2, la GameCube de Nintendo ne pouvant pas rivaliser, et la Dreamcast de Sega très vite stoppé à cause de la faillite de Sega. Puis s’en suit une bataille acharnée entre Sony, Microsoft et Nintendo depuis cette 6ème génération. Toutefois, cette activité a évolué au fil des années, très souvent critiqué et désigné du doigt par la presse et le gouvernement pour ces caractères allant d’abrutissant à violent, est devenu un loisir dont un grand nombre de personnes en jouissent aujourd’hui. En effet, il existe un multitude de jeu vidéos, pouvant être destiné aux plus jeunes comme aux adultes, et cela est régit par des classement bien spécifiques à chaque région du globe. En Europe, nous avons un système d’évaluation des jeux vidéos les catégorisant et informant le consommateur à quel types de jeux le joueur s’octroit, se système se prénomme PEGI (Pan European Game Information). En Amerique du Nord se système se nomme ESRB (Entertainment Software Rating Board) et comparer au système européen qui indique au consommateur l’âge minimum pour jouer à un jeu, le système américain propose de donner des lettres ayant toute une signification bien particulière:
  • “EC” = Early Childhood (petite enfance).
  • “E” = “Everyone” (tout le monde).
  • “E10+” = “Everyone 10+” (tout le monde au-dessus de 10 ans).
  • “T” = “Teen” (adolescents).
  • “M”= “Mature” (mature à partir de 17ans).
  • “AO”= “Adult Only” (Adultes uniquement à partir de 18ans).
  • “RP” =“Rating Pending” (En attente de classement).
L’étude s’effectuera sur deux jeux de données portant sur le jeu vidéos. Le premier comporte 16574 observations pour 11 variables. Les variables du premier jeu de données représentent :
  • Le rang du jeu, son classement par rapport à sa vente global.
  • Le nom du jeu vidéo.
  • La plateforme sur laquelle le jeu vidéo est sortie.
  • L’année de sortie du jeu vidéo.
  • Le genre du jeu.
  • L’éditeur du jeu.
  • La vente des jeu en millions : en Amérique du Nord, en Europe, au Japon, dans les autres pays, et la vente global d’un jeu (ce qui régit son rang).

Le second jeu de données comportent les mêmes variables, mais a 16712 observations pour 18 variables. Ces 7 autres variables apportent des informations sur le score apporté par la critique, le nombre de critique recueilli, la note moyenne donné par les joueurs, le nombres de joueurs ayant donné une note au jeu vidéo, le studio de developpement du jeu vidéo et le classement ESRB. Une remarque importante à faire est que le second jeu de données est un “update” du premier jeu de données. Toutefois, nous verrons par la suite qu’il manque à ce deuxième jeu de données des informations présentent dans le premier.
Nous avons décidement de nous projeter sur ce projet d’étude car nous sommes tout les deux de grands amateurs passionnés par le jeu vidéos, nous avions alors voulu savoir si il était possible grâce à des paramètres bien définis, prédire la note donné par la critique.

1 Modification du jeu de données

library(cowplot)
library(ggplot2)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tidyr)
library("FactoMineR")
library(lubridate)
## 
## Attaching package: 'lubridate'
## The following object is masked from 'package:cowplot':
## 
##     stamp
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
library(chron)
## 
## Attaching package: 'chron'
## The following objects are masked from 'package:lubridate':
## 
##     days, hours, minutes, seconds, years
library(randomForest)
## randomForest 4.6-14
## Type rfNews() to see new features/changes/bug fixes.
## 
## Attaching package: 'randomForest'
## The following object is masked from 'package:dplyr':
## 
##     combine
## The following object is masked from 'package:ggplot2':
## 
##     margin
library(rpart)
library(rpart.plot)

1.1 Téléchargement des données

data<-read.csv("~/Desktop/BigData/Projet_3/vgsales.csv")
data_second<-read.csv("~/Desktop/BigData/Projet_3/vgsales2.csv")
load("/Users/romain/Desktop/BigData/Projet_3/missing.RData")

#data<-read.csv("C:/Users/Baptiste/Desktop/open_data/vgsales.csv")
#load("C:/Users/Baptiste/Desktop/open_data/missing.RData")
#data_second<-read.csv("C:/Users/Baptiste/Desktop/open_data/Video_Games_Sales_as_at_22_Dec_2016.csv")

1.2 Pré-visualisation du jeu de données

g1<-ggplot(data, aes(x=Year, y=Global_Sales, fill=Genre))+geom_histogram(stat="identity", position="stack")
## Warning: Ignoring unknown parameters: binwidth, bins, pad
g2<- ggplot(data_second, aes(x=Year_of_Release, y=Global_Sales, fill=Genre))+geom_histogram(stat="identity", position="stack")
## Warning: Ignoring unknown parameters: binwidth, bins, pad
plot_grid(g1,g2, ncol=2, nrow=1)
## Warning: Removed 2 rows containing missing values (position_stack).


Nous observons que nos deux jeux de données sont assez similaires. La différence existant entre ces deux est que l’un contient des informations supplémentaires sur la note Metacritric, le nombre de vote, les notes des utilisateurs, le nombre de votes, et le classement ESRB. Toutefois, dans ce jeu de données il manque quelques informations qui sont présentent dans le premier jeu de données. Donc dans un premier temps nous allons faire du nettoyage dans les deux jeux de données sur les observations que l’on jugera inexloitable. Puis nous apporteront a notre jeu de données une petite modification dont l’assemblement des deux jeux de données. Et enfin nous avons décidé de rejouter quelques variables à notre jeu de données grâce aux autres variables présentent.

1.3 Nettoyage


Nous allons faire un premier traitement de données en faisant un premier nettoyage : nous allons retirer toute les données qui nous semblent intraitables ou beaucoup trop longue à recoder. Ce que nous entendons par “intraitable” est que les données sont soient erronées, soient la donnée attribué ne correspond pas à la variable. Par exemple, nous avons un jeu dont son genre est donné par “Sony Coputer Entertainement”, ou un autre où le nom du jeu est “Adventure”, or il s’agit d’une catégorie, et nous n’avons aucun moyen de pouvoir recupérer l’intitulé du jeu complet. Alors nous avons fait le choix de retirer ces jeux. Au final, nous en avons retirer seulement 3 jeux, ce qui est négligeable comparé aux nombres d’observations que nous avons : 16712. Cette partie était necessaire car elle nous a permis de retirer les données que l’on jugeait inexploitables.

ind<-which(data$Genre=="Sony Computer Entertainment")
data<-data[-ind,] #On retire la ligne décalé
ind<-which(data_second$Name=="Adventure")
data_second<-data_second[-ind,] #On retire la ligne décalé
ind<-which(data_second$Genre=="")
data_second<-data_second[-ind,] #On retire les lignes pour le second graphe qui catégorise rien en rouge


1.4 Modification du jeu de données


Après une pré-visualisation de notre jeu de données, nous avons decider interesser à seulement une partition de notre data en raison d’information peu pertinente sur certaine années, en particulier entre 1977-1980 et 2017-2020. En effet, au début de l’essor du jeu vidéo, la vente de celle-ci n’était pas réservé à un aussi large public qu’actuellement. Et pour les données les plus récentes, nous manquons d’observations car elles n’ont pas pu être entré à temps. De ce fait, nous avons décidé de les retirer de notre jeu de données. Nous traiterons nos données à partir de 1980 jusqu’en 2016 afin d’avoir un meilleur aperçu sur cet intervalle de temps. Nous avons également remarqué lorsque nous avons retiré nos données que nous avons des observations dont les années de sorties étaient “CANCELED” et “Adventure”. Il s’agit pour le premier de données sur quelques jeux annulé, donc des données très peu interressante pour la suite car nous n’avons pas la note Metacritic attribué à ces jeux, et pour le deuxième il s’agit d’une anomalie lors de l’écriture du jeu de donnée. Par choix, nous avons également décidé de retirer cette obsrvation.

na_date<- which(data$Year=="N/A")
data$Year[na_date]<-missing
ind<-which(data$Year=="N/A")
data<-data[-ind,]
ind2<-which(data$Year=="1977" | data$Year=="1978" | data$Year=="1979" |data$Year=="2017" | data$Year=="2018" | data$Year=="2019" | data$Year=="2020" | data$Year=="CANCELED" | data$Year=="Adventure")
data<- data[-ind2,]
ind3<-which(data_second$Year_of_Release=="1977" | data_second$Year_of_Release=="1978" | data_second$Year_of_Release=="1979" |data_second$Year_of_Release=="2017" | data_second$Year_of_Release=="2018" | data_second$Year_of_Release=="2019" | data_second$Year_of_Release=="2020" | data_second$Year_of_Release=="CANCELED" | data_second$Year_of_Release=="Adventure")
data_second<-data_second[-ind3, ]


Comme nous l’avons dis précédemment, nous voulons apporter les données manquantes du deuxième jeu de données grâce au premier jeu de données. Nous avons alors créer une fonction capable de réaliser de transférer ces données manquantes. De ce fait, nous serons en mesure de ne conserver qu’un seul jeu de données.

rajout_date<- function(data1,data2){
  ind<-which(data2$Year_of_Release=="N/A")
  name<- data2[ind, 1]
  for(i in 1:length(name)){
      if(length(which(data1$Name==name[i]))<2){
        data2$Year_of_Release[which(data2$Name==name[i])[1]]<-data1$Year[which(data1$Name==name[i])[1]]
      }
    else{
        data2$Year_of_Release[which(data2$Name==name[i])]<-data1$Year[which(data1$Name==name[i])]
    }
  }
  return(data2)
}
data_second<-rajout_date(data,data_second)
## Warning in data2$Year_of_Release[which(data2$Name == name[i])] <-
## data1$Year[which(data1$Name == : le nombre d'objets à remplacer n'est pas
## multiple de la taille du remplacement

## Warning in data2$Year_of_Release[which(data2$Name == name[i])] <-
## data1$Year[which(data1$Name == : le nombre d'objets à remplacer n'est pas
## multiple de la taille du remplacement

## Warning in data2$Year_of_Release[which(data2$Name == name[i])] <-
## data1$Year[which(data1$Name == : le nombre d'objets à remplacer n'est pas
## multiple de la taille du remplacement
ind<-which(data_second$Name=="Brothers in Arms: Furious 4")
y<- data_second$Year_of_Release[ind][1]
data_second$Year_of_Release[ind[2]]<- y


1.5 Transformation de nos données


Dans cette partie, nos transformations consistent à rajouter dans notre jeu de données deux variables qui nous a semblé utile dans nos statistiques descriptives et dans nos prédictions. Nous avons aussi à faire un petit recodage de données sur la variable “Rating”.
La première transformation consiste à créer une variable qui rassemble les données par intervalle de 4 années. Par exemple les jeux sorties entre 1981 et 1984 appartiendront à un même groupe, et les jeux sorties entre 1985 et 1988 appartiendront à un autre groupe. Cette transformation nous a semblé judicieuse car elle est moins discriminante qu’un jeu sortie sur une année. Il est très possible qu’il y ai beaucoup de jeux bien notés ou bien vendu qui soient sortie sur un intervalle de temps. Dans ce cas nous pourrions dire que la période aurait son importance dans l’attribution d’une bonne note à un jeu, ou bien que la vente d’un jeu est influencé par la période d’où il sort.

data_second$FourYear<- recode_factor(as.factor(data_second$Year_of_Release),
                              "1981"="1981-1984",
                              "1982"="1981-1984",
                              "1983"="1981-1984",
                              "1984"="1981-1984",
                              "1985"="1985-1988",
                              "1986"="1985-1988",
                              "1987"="1985-1988",
                              "1988"="1985-1988",
                              "1989"="1989-1992",
                              "1990"="1989-1992",
                              "1991"="1989-1992",
                              "1992"="1989-1992",
                              "1993"="1993-1996",
                              "1994"="1993-1996",
                              "1995"="1993-1996",
                              "1996"="1993-1996",
                              "1997"="1997-2000",
                              "1998"="1997-2000",
                              "1999"="1997-2000",
                              "2000"="1997-2000",
                              "2001"="2001-2004",
                              "2002"="2001-2004",
                              "2003"="2001-2004",
                              "2004"="2001-2004",
                              "2005"="2005-2008",
                              "2006"="2005-2008",
                              "2007"="2005-2008",
                              "2008"="2005-2008",
                              "2009"="2009-2012",
                              "2010"="2009-2012",
                              "2011"="2009-2012",
                              "2012"="2009-2012",
                              "2013"="2013-2016",
                              "2014"="2013-2016",
                              "2015"="2013-2016",
                              "2016"="2013-2016")


Puis, nous rajoutons aussi une variable “marque de la plateforme” afin de pouvoir regarder certaines données liées à la marque des consoles vendue a travers le temps. Pour les mêmes raisons que précédemment, il existe plus de console que de constructeur de console. En effet, si on prend l’exemple de Nintendo, ils ont créé 8 consoles de notre jeu de données. De ce fait, cette variable aura un caractère moisn discriminant que la variable “Plateforme”. Il sera alors interressant de regarder si ce caractère est meilleure dans nos paramètres de prédictions.

data_second$Platform_mark<- recode_factor(as.factor(data_second$Platform),
                               "2600" = "Atari",
                               "3DO" = "Panasonic",
                               "3DS" = "Nintendo",
                               "DC" = "Sega",
                               "DS" = "Nintendo",
                               "GB" = "Nintendo",
                               "GBA" = "Nintendo",
                               "GC" = "Nintendo",
                               "GEN" = "Sega",
                               "GG" = "Sega",
                               "N64"= "Nintendo",
                               "NES"="Nintendo",
                               "NG"="SNK",
                               "PCFX"="NEC",
                               "PS"="Sony",
                               "PS2"="Sony",
                               "PS3"="Sony",
                               "PS4"="Sony",
                               "PSP"="Sony",
                               "PSV"="Sony",
                               "SAT"="Sega",
                               "SCD"="Sega",
                               "SNES"="Nintendo",
                               "TG16"="Sega",
                               "Wii"="Sony",
                               "WiiU"="Sony",
                               "WS"="Bandai",
                               "X360"="Microsoft",
                               "XB"="Microsoft",
                               "XOne"="Microsoft"
)


Il s’agit d’un recodage que nous avons déjà évoqué. En effet, notre jeu de données va de 1980 à 2016, de ce fait les classement ESRB ont eu droit à certaine mise à jour au niveau de l’intitulée de leur classement. Ici, il s’agit de recoder les observations de classement “K-A” qui désignait les jeux de la catégorie “Kids to Adult”. Cette abréviation a été mise à jour en 1998 par “E” signifiant “Everyone”.

data_second$Rating<-recode_factor(as.factor(data_second$Rating),
                                  "K-A"="E"
                                  )


2 Statistiques descriptives.


Après le nettoyage et traitement de nos données, nous allons passer à l’analyse descriptive de nos données. Nous allons voir si il est utile de considérer la vente des jeux vidéos pour la suite dans nos prédictions de notes Metacritic. Puis, nous verrons la répartition de nos notes Metacritic afin d’affirmer ou d’infirmer qu’elles suivent une certaine loi Normale. Et enfin, nous verrons qu’elles sont les variables qui ont un impact sur la note Metacritic afin de conserver seulement les variables les plus importantes lors de nos prédictions. À savoir que notre première partie devrait exclure ou non le fait que la vente des jeux vidéos ait une corrélation avec la note Metacritic d’un jeu.

2.1 Evolution des ventes de jeux.


Comme nous l’avons dis précedemment, nous interressons à savoir si la vente des jeux vidéos a un impact sur la note Metacritic d’un jeu vidéos. Nous possédons pour cela des données de vente au Japon, en Amérique, en Europe, et dans les autres pays pour un jeu. Le marché du jeu vidéo est très populaire en Amérique, en Europe et au Japon surtout, étant donné que l’on peut considérer que la popularisation du jeu vidéo est né au Japon.

ggplot(data_second,aes(x=Year_of_Release, y=Global_Sales, fill=Genre))+geom_histogram(stat="identity", position="stack")+labs(title=" Evolution de la vente des jeux videos au fil des années")
## Warning: Ignoring unknown parameters: binwidth, bins, pad


On peut voir que l’évolution de la vente des jeux vidéos est flagrante On peut aussi remarquer que le marché du jeu vidéo à bien changer avec l’arrivée de nouveau genre de jeu, comme par exemple les jeux de sport. On distingue aussi une augmentation du nombre de jeu d’action vendus dès le début du XXIème siècle, alors que ce genre une décénnie auparavant ne se vendait que très peu. On peut également distinguer qu’au début des années 80 la vente des jeux vidéos il n’y avait pas assez de jeux sorti pour que le public puisse avoir de réelle préférence pour un genre de jeu. On peut remarquer que cette explosion du jeux vidéos a commencé dès 1996 avec la sortie internationnale de Pokemon Rouge/Bleu sur GameBoy, Super Mario 64 et Mario Kart 64 sur la Nintendo 64. On peut aussi remarquer que le marché du jeu vidéo d’action a commencé a exploser à partir de 1996 avec l’arrivée de nouvelle licence comme Resident Evil et Tomb Raider, qui sont aujourd’hui encore des références en jeux d’actions.
Toutefois, il serait interessant de se demander si le marché du jeu vidéo est le même qu’en Amérique du Nord, au Japon, en Europe et dans le reste du monde.

gNA<-ggplot(data_second, aes(x=Year_of_Release, y=NA_Sales, fill=Genre))+geom_histogram(stat="identity", position="stack",binwidth=2)
## Warning: Ignoring unknown parameters: binwidth, bins, pad
gEU<-ggplot(data_second, aes(x=Year_of_Release, y=EU_Sales, fill=Genre))+geom_histogram(stat="identity", position="stack",binwidth=2)
## Warning: Ignoring unknown parameters: binwidth, bins, pad
gJP<-ggplot(data_second, aes(x=Year_of_Release, y=JP_Sales, fill=Genre))+geom_histogram(stat="identity", position="stack",binwidth=2)
## Warning: Ignoring unknown parameters: binwidth, bins, pad
gOther<-ggplot(data_second, aes(x=Year_of_Release, y=Other_Sales, fill=Genre))+geom_histogram(stat="identity", position="stack",binwidth=2)
## Warning: Ignoring unknown parameters: binwidth, bins, pad
plot_grid(gNA, gEU, gJP, gOther,ncol=2,nrow=2)

On peut très clairement voir que le marché du jeu vidéo est très différent au Japon qu’en Amerique du Nord ou en Europe. En effet, comme nous l’aviosn evoquer précédemment, on peut voir que le succès du jeu vidéos a commencé au Japon avant d’être inter-planetaire. On remarque egalement que le marché de vente est assez homogène au Japon contrairement en Amérique ou en Europe où on peut observer une préfère à un genre de jeu : les jeux d’actions. Il est important de souligner que les jeux d’arcade ne sont pas compté, et que c’ets pour cette raison qu’on n’arrive pas a voir l’importance du jeu vidéo au Japon, étant donné que les bornes d’arcades sont très populaire dans cette région du monde.
Toutefois, on sait qu’un jeu vidéo peut être vendu sur plusieurs plateforme, nous allons alors voir si le caractère multi-plateforme est indépendant ou non de la vente d’un jeu.

data_oneVG<-data_second[,-2]
data_oneVG<- data_oneVG%>%group_by(Name)%>%mutate(NA_Sales=sum(NA_Sales),EU_Sales=sum(EU_Sales),JP_Sales=sum(JP_Sales),Other_Sales=sum(Other_Sales),Global_Sales=sum(Global_Sales))%>%slice(1)
#test<-data_frame(Year=names(table(data2$Year)), nb_jeux=as.vector(table(data2$Year)))
g3<-ggplot(data_oneVG, aes(x=Year_of_Release,fill=Genre))+geom_histogram(stat="count",position="stack")
## Warning: Ignoring unknown parameters: binwidth, bins, pad
g4<-ggplot(data_second, aes(x=Year_of_Release, y=Global_Sales, fill=Genre))+geom_histogram(stat="identity", position="stack")
## Warning: Ignoring unknown parameters: binwidth, bins, pad
plot_grid(g4,g3, label=c("Vente des VG au fil des années", "Nombre de VG sortie au fil des années"), ncol=1, nrow=2)
## Warning in as_grob.default(plot): Cannot convert object of class character into
## a grob.


On peut voir que les ventes sont impacté par les jeux qui sortent, mais que certain genre de jeux echappent à cette règle, comme par exemple les jeux d’actions et qui ne sortent pas en grand nombre mais qui sont vendu en grande quantité. On peut également noter que les jeux d’aventure sont créer en grand nombre mais ne connaissent pas un succès flagrant car il ne sont pas bien vendu. Nous pensons alors que la vente des jeux vidéos n’a pas d’impact sur la note d’un jeu vidéos. Pour cela, nous allons faire un test d’hypothèse.

2.2 Étude sur la répartition de nos notes de jeux vidéos.

ind<-which(data_second$Developer=="")
ggplot(data_second[-ind,], aes(x=Critic_Score,fill=Genre))+geom_histogram(stat="count",position="stack")
## Warning: Ignoring unknown parameters: binwidth, bins, pad
## Warning: Removed 1964 rows containing non-finite values (stat_count).


On peut donc observer que la répartition de nos notes Metacritic suivi relativement une certaine gaussienne. On remarque également que contrairement à ce qu’on pourrait penser, tout les genres de jeux peuvent avoir une note Metacritic relativement correcte, même si le jeu n’est pas vendu en grand nombre. (Ce qui accentue notre test d’hypothèse réalisé précédemment que la vente d’un jeu vidéo ne veut pas signifie que le jeu est “mauvais” ou mal noté). Afin de s’assurer que notre répartition suit bien une certaine gaussienne, nous allons réaliser un test de normalité grâce à un test de Shapiro-Wilk.

library(rstatix)
## 
## Attaching package: 'rstatix'
## The following object is masked from 'package:stats':
## 
##     filter
tr<-sample(1:nrow(data_second), 5000)
test<-na.omit(data_second$Critic_Score[tr])
shapiro.test(test)
## 
##  Shapiro-Wilk normality test
## 
## data:  test
## W = 0.98009, p-value < 2.2e-16


Contrairement à ce que l’on pensait, la répartition de nos notes Metacritic ne suit pas une loi Normale car notre p-value < 0.05, ce qui signifie que notre hypothèse nulle “la distribution de notre loi est significativement différente de celle d’une loi normale” n’est pas rejetée. Ainsi la répartition de nos notes ne suit pas une certaine gaussienne.
Nous allons maintenant nous interesser à la recherche des variables significatives à la prédiction de nos notes Metacritic.

2.3 Identification des variables pertinente :


Afin d’identifier les variables les plus importantes, plusieurs choix s’offrent à nous. Nous avons préférer réaliser une ACP afin d’identifier les variables qui sont le plus corrélées avec la variable réponse “Critic_Score”.

data_second$User_Score<-as.numeric(data_second$User_Score)
## Warning: NAs introduits lors de la conversion automatique
acp<-PCA(data_second, scale.unit = TRUE, quali.sup = c(1,2,3,4,5,15,16,17,18), graph = FALSE)
## Warning in PCA(data_second, scale.unit = TRUE, quali.sup = c(1, 2, 3, 4, :
## Missing values are imputed by the mean of the variable: you should use the
## imputePCA function of the missMDA package
plot(acp, axis=c(1,2),choix="var")

Nous pouvons voir que la vente de jeu n’a pas un impact sur la note qu’il aura par la suite. Il ne nous semble pas alors pertinent de devoir garder les données sur la vente de jeux pour l’apprentissage, mais de garder nos données sur l’identité du jeu.

data_second2 <- data_second
data_second2$Platform<- as.numeric(as.factor(data_second2$Platform))
data_second2$Genre<- as.numeric(as.factor(data_second2$Genre))
data_second2$Rating<- as.numeric(as.factor(data_second2$Rating))
data_second2$Platform<- as.numeric(data_second2$Platform)
data_second2$Platform_mark<-as.numeric(as.factor(data_second2$Platform_mark))
data_second2$Year_of_Release<- as.numeric(data_second2$Year_of_Release)
acp2<-PCA(data_second2, scale.unit = TRUE, quali.sup = c(1,5,15,17,18), graph = FALSE)
## Warning in PCA(data_second2, scale.unit = TRUE, quali.sup = c(1, 5, 15, :
## Missing values are imputed by the mean of the variable: you should use the
## imputePCA function of the missMDA package
plot(acp2, axes=c(1,2),choix="var")

#barplot(acp2$eig[,1], main="Eigenvalues", names.arg=1:nrow(acp2$eig))
#abline(h=1,col=2,lwd=2)

Faire un lasso pour donner de l’importance a nos variables significatives ?

3 Prédiction

Nous allons nous interesser maintenant à la possibilité de prédire la note d’un jeu vidéo en fonction de plusieurs caractéristique :
  • Son genre
  • L’année de sortie du jeu
  • L’éditeur du jeu
  • La plateforme
  • Le developpeur du jeu
  • Le nombre de critiques

Nous allons appliquer pour cela différentes méthodes d’apprentissages, à savoir KNN, les arbres CART et les forêts aléatoires.

ind<- which(is.na(data_second$Critic_Score))
train<- data_second[-ind,-c(1,6,7,8,9,10,13,14,17,18)]
ind<-which(train$Developer=="")
train<-train[-ind,]
ind<-which(train$Rating=="")
train<-train[-ind,]
train<-train %>% drop_na()

Nous allons transformer nos données textuelles en données numerique.

train<- train[,-c(4,7)]
train$Platform<- as.numeric(as.factor(train$Platform))
train$Genre<- as.numeric(as.factor(train$Genre))
train$Rating<- as.numeric(as.factor(train$Rating))
train$Platform<- as.numeric(train$Platform)
train$Year_of_Release<- as.numeric(train$Year_of_Release)

3.1 KNN

4 Sans les editeurs et les developpeurs

Nous commençons dans un premier temps par optimiser le nombre de voisins pris pour notre méthode. Nous commençons notre nombre de voisins a 30 afin de ne pas prendre trop de temps de calcul, et afin de conserver un graphique visible. Cela ne pose pas de problème car nous avons observé qu’un nombre de voisins inferieur a 30 ne donnais pas de résultats probants.

#library(class)
#B<- 30
#kpp<-30:60
#err_knn<-matrix(NA, ncol=B, nrow=length(kpp))
#for(k in kpp){
#  for( i in 1:B){
#    tr<-sample(1:nrow(train), 0.8*nrow(train))
#    Xtrain<- train[tr,-4 ]
 #   Ytrain <- train[tr,4]
 #   Xtest<- train[-tr,-4 ]
 #   Ytest <- train[-tr,4]
 #   pred<-knn(Xtrain, Xtest, Ytrain, k=k)
 #   err_knn[k-29,i]<- sum(sqrt((as.numeric(pred)-Ytest)^2))/length(Ytest)
 # }
#}
#print(paste("Erreur moyenne de prediction est de",mean(err_knn)))
#boxplot(t(err_knn))

#knn_mean <- apply(t(err_knn),2,mean)
#k_opt <- which.min(knn_mean)+29

#print(paste("Le k optimal obtenue est :",k_opt))
#par(mfrow=c(1,2))
#hist(as.numeric(pred), main = "histogramme de nos predictions")
#hist(Ytest, main = "histogramme de nos données réelles")

5 Arbre CART ``

6 Sans les editeurs et developpeurs

tr<-sample(1:nrow(train), 0.8*nrow(train))
Xtrain<- train[tr,-4 ]
Ytrain <- train[tr,4]
Xtest<- train[-tr,-4 ]
Ytest <- train[-tr,4]

tree <- rpart(Ytrain~.,data=cbind(Xtrain,Ytrain))
pred <- predict(tree,Xtest)
rpart.plot(tree,extra=1)

7 Foret aleatoire

8 Sans les editeurs et developpeurs

#rf_base <- randomForest(x=train[,-4], y=train[,4])
#print(paste("L'erreur de notre foret aléatoire de base est :",sum(sqrt((train$Critic_Score-rf_base$predicted)^2))/length(rf$predicted)))

On va tenter d’optimiser les parametres mtry et ntree

run_mtry <- FALSE

if (run_mtry == TRUE){
mtry <- seq(from=1, to =6, by=1)
B<-5
err_OOB<-matrix(NA, nrow=length(mtry),ncol=B)
debut<- Sys.time()
for(k in 1:B){
  for(i in mtry){
    rf<-randomForest(x=train[,-4], y=train[,4],mtry=i)
    err_OOB[i,k]<-rf$mse[500]
  }
}
fin<-Sys.time()
time<-as.period(difftime(fin,debut))
print(paste("Temps mis pour optimiser mtry en ",B,"-folds :",round(time,digits=0)))
#plot(err_OOB,type="l")
}
#boxplot(err_OOB)
run_rf_opt <- FALSE

if (run_rf_opt==TRUE){

ntree<-seq(100,2000,100)
B<-10 
err_ntree<-matrix(NA, nrow=length(ntree),ncol=B)
#err_ntree<-rep(NA, length(ntree))
debut<- Sys.time()
for(k in 1:B){
  for(i in 1:length(ntree)){
    rf<-randomForest(x=train[,-4], y=train[,4],ntree=ntree[i])
    err_ntree[i,k]<-sum(sqrt((train$Critic_Score-rf$predicted)^2))/length(rf$predicted)
    #err_ntree[i]<-sum(sqrt((train$Critic_Score-rf$predicted)^2))/length(rf$predicted)
  }
}
fin<-Sys.time()
time<-as.period(difftime(fin,debut))
print(paste("Temps mis pour optimiser mtry en ",B,"-folds :",round(time,digits=0)))
#print(paste("Temps mis pour optimiser ntree :", round(time,digits=0)))
}
#saveRDS(err_ntree, "~/Desktop/BigData/Projet_3/erreur_ntree.RData")
#boxplot(t(err_ntree))
#plot(x=ntree,apply(err_ntree, 1, median),type="l")
#which.min(apply(err_ntree,1,median))
#ntree_opt<- ntree[13]
#B<- 20
#err_rf_opt<-rep(NA, B)
#err_knn_opt <- rep(NA,B)
#err_tree_opt <- rep(NA,B)

#for(i in 1:B){
  
  # ECHANTILLONAGE
#  tr<-sample(1:nrow(train), 0.8*nrow(train))
#  Xtrain<- train[tr,-4 ]
#  Ytrain <- train[tr,4]
#  Xtest<- train[-tr,-4 ]
#  Ytest <- train[-tr,4]
  
  # KNN 
#  pred_knn <-knn(Xtrain, Xtest, Ytrain, k=k_opt)
#  err_knn_opt[i]<- sum(sqrt((as.numeric(pred_knn)-Ytest)^2))/length(Ytest)
  
  # ARBRE CART
#  tree <- rpart(Ytrain~.,data=cbind(Xtrain,Ytrain))
#  pred_tree <- predict(tree,Xtest)
#  err_tree_opt[i] <- sum(sqrt((as.numeric(pred_tree)-Ytest)^2))/length(Ytest)
  
  # Random Forest
#  rf <- randomForest(x=train[,-4], y=train[,4],ntree=1300)
#  err_rf_opt[i]<-sum(sqrt((train$Critic_Score-rf$predicted)^2))/length(rf$predicted)
  
  
#}

#boxplot(err_knn_opt,err_tree_opt,err_rf_opt, main = "Erreur de nos trois méthodes sans les editeurs et producteurs", names = c("KNN","ARBRE","RandomForest"))

9 Avec les producteur et les editeurs

ind<- which(is.na(data_second$Critic_Score))
train<- data_second[-ind,-c(1,6,7,8,9,10,13,14,17,18)]
ind<-which(train$Developer=="")
train<-train[-ind,]
ind<-which(train$Rating=="")
train<-train[-ind,]
train<-train %>% drop_na()
train$Platform<- as.numeric(as.factor(train$Platform))
train$Genre<- as.numeric(as.factor(train$Genre))
train$Rating<- as.numeric(as.factor(train$Rating))
train$Platform<- as.numeric(train$Platform)
train$Year_of_Release<- as.numeric(train$Year_of_Release)
train$Publisher<- as.numeric(as.factor(train$Publisher))
train$Developer<- as.numeric(as.factor(train$Developer))
#B<- 15
#kpp<-1:50
#err_knn<-matrix(NA, ncol=B, nrow=length(kpp))
#for(k in kpp){
#  for( i in 1:B){
#    tr<-sample(1:nrow(train), 0.8*nrow(train))
#    Xtrain<- train[tr,-5 ]
#    Ytrain <- train[tr,5]
#    Xtest<- train[-tr,-5 ]
#    Ytest <- train[-tr,5]
#    pred<-knn(Xtrain, Xtest, Ytrain, k=k)
#    err_knn[k,i]<- sum(sqrt((as.numeric(pred)-Ytest)^2))/length(Ytest)
#  }
#}
#boxplot(t(err_knn))
#k_opt<- which(apply(t(err_knn), 2, mean)==min(apply(t(err_knn), 2, mean)))
#par(mfrow=c(1,2))
#hist(as.numeric(pred))
#hist(Ytest)

On voit que nos prediction

9.1 Arbre CART

10 Avec les editeurs et developpeurs

tr<-sample(1:nrow(train), 0.8*nrow(train))
Xtrain<- train[tr,-5 ]
Ytrain <- train[tr,5]
Xtest<- train[-tr,-5 ]
Ytest <- train[-tr,5]
tree <- rpart(Ytrain~.,data=cbind(Xtrain,Ytrain))
pred <- predict(tree,Xtest)
rpart.plot(tree,extra=1)

err_1 <- sum(sqrt((pred-Ytest)^2))/length(Ytest)

err_1
## [1] 9.80793

10.1 Forêt Aleatoire

11 Avec les editeurs et developpeurs

#ntree<-seq(100,2000,100)
#B<-10 
#err_ntree<-matrix(NA, nrow=length(ntree),ncol=B)
#err_ntree<-rep(NA, length(ntree))
#debut<- Sys.time()
#for(k in 1:B){
#  for(i in 1:length(ntree)){
 #   rf<-randomForest(x=train[,-5], y=train[,5],ntree=ntree[i])
 #   err_ntree[i,k]<-sum(sqrt((train$Critic_Score-rf$predicted)^2))/length(rf$predicted)
    #err_ntree[i]<-sum(sqrt((train$Critic_Score-rf$predicted)^2))/length(rf$predicted)
  #}
#}
#fin<-Sys.time()
#time<-as.period(difftime(fin,debut))
#print(paste("Temps mis pour optimiser mtry en ",B,"-folds :",round(time,digits=0)))
#print(paste("Temps mis pour optimiser ntree :", round(time,digits=0)))
#boxplot(t(err_ntree))
#plot(x=ntree,apply(err_ntree, 1, median),type="l")
#tree_opt2 <- which.min(apply(err_ntree,1,median))
#B<- 30

#err_knn_opt2<-rep(NA,B)
#err_tree_opt2 <- rep(NA,B)
#err_rf_opt2 <- rep(NA,B)

#for( i in 1:B){
    
  # ECHANTILLONAGE
#  tr<-sample(1:nrow(train), 0.8*nrow(train))
#  Xtrain<- train[tr,-5 ]
#  Ytrain <- train[tr,5]
#  Xtest<- train[-tr,-5 ]
#  Ytest <- train[-tr,5]
  
  # KNN 
#  pred_knn2<-knn(Xtrain, Xtest, Ytrain, k=k_opt)
#  err_knn_opt2[i]<- sum(sqrt((as.numeric(pred_knn2)-Ytest)^2))/length(Ytest)
 
  # ARBRE 
 # tree_opt2 <- rpart(Ytrain~.,data=cbind(Xtrain,Ytrain))
 # pred_tree_opt2 <- predict(tree_opt2,Xtest)
 # err_tree_opt2[i] <- sum(sqrt((as.numeric(pred_tree_opt2)-Ytest)^2))/length(Ytest)
  
  # RandomForest
 # rf_opt2 <- randomForest(x=train[,-5], y=train[,5],ntree=ntree_opt2)
 # err_rf_opt2[i] <- sum(sqrt((train$Critic_Score-rf_opt2$predicted)^2))/length(rf$predicted)
  
#}

#boxplot(err_knn_opt2,err_tree_opt2,err_rf_opt2, main = "Erreur de nos méthodes ", names = c("KNN","Arbre","RandomForest"))

Nous allons devoir rendre les variables textuelles en binaire pour de meilleur résultat

11.0.1 BINARISATION

binarisation <- function(data,col){
  data_retour <- data[,-col]
  n <- length(data[,1])
  for(i in 1:length(col)){
        temp_matrix <- matrix(0,nrow = n, ncol = max(data[,col[i]]))
        rows <- c(1:n)
        cols <- data[,col[i]]
        positions <- cbind(rows,cols)
        temp_matrix[positions] <- 1
        data_retour <- cbind(data_retour,temp_matrix)
  }
  return(data_retour)
}

12 Sans les publishers et developpers

ind<- which(is.na(data_second$Critic_Score))
train<- data_second[-ind,-c(1,6,7,8,9,10,13,14,17,18)]
ind<-which(train$Developer=="")
train<-train[-ind,]
ind<-which(train$Rating=="")
train<-train[-ind,]
train<-train %>% drop_na()

train<- train[,-c(4,7)]
train$Platform<- as.numeric(as.factor(train$Platform))
train$Genre<- as.numeric(as.factor(train$Genre))
train$Rating<- as.numeric(as.factor(train$Rating))
train$Platform<- as.numeric(train$Platform)
train$Year_of_Release<- as.numeric(train$Year_of_Release)


# train
train_bin <- binarisation(train, c(1,3,6))
Xtrain<- train_bin[tr,-2 ]
Ytrain <- train_bin[tr,2]
Xtest<- train_bin[-tr,-2 ]
Ytest <- train_bin[-tr,2]
    
fit2 <- randomForest(x=Xtrain,y = Ytrain, ntree = 1300)

pred.rf <- predict(fit2, Xtest, predict.all=TRUE)

pred.rf.int <- apply(pred.rf$individual, 1, function(x) {
  c(mean(x) + c(-1, 1) * sd(x), 
  quantile(x, c(0.025, 0.975)))
})

head(t(pred.rf.int))
##                          2.5%    97.5%
## 7  72.29423 90.26406 59.86875 90.36833
## 11 66.45399 84.07845 56.26333 88.63500
## 15 77.91143 94.88572 69.74750 97.00000
## 16 68.19869 76.71449 62.00000 80.29375
## 25 71.01936 89.96106 59.15833 93.58750
## 29 73.33105 87.32245 61.00000 90.00000

test de la méthode des K plus proches voisins

#library(class)
#B<- 10
#kpp<-30:80
#err_knn<-matrix(NA, ncol=B, nrow=length(kpp))
#for(k in kpp){
 # for( i in 1:B){
 #   tr<-sample(1:nrow(train), 0.8*nrow(train))
 #   Xtrain<- train_bin[tr,-2 ]
  #  Ytrain <- train_bin[tr,2]
 #   Xtest<- train_bin[-tr,-2 ]
  #  Ytest <- train_bin[-tr,2]
  #  pred<-knn(Xtrain, Xtest, Ytrain, k=k)
  #  err_knn[k-29,i]<- sum(sqrt((as.numeric(pred)-Ytest)^2))/length(Ytest)
  #}
#}
#print(paste("Erreur moyenne de prediction est de",mean(err_knn)))
#boxplot(t(err_knn))

Le k optimal est 78 ici ( cependant, on va devoir trouver une maniere de le faire automatiquement).

#B <- 50
#err_knn<-matrix(NA, ncol=B, nrow=1)

#for( i in 1:B){
#  tr<-sample(1:nrow(train), 0.8*nrow(train))
#  Xtrain<- train_bin[tr,-2 ]
#  Ytrain <- train_bin[tr,2]
#  Xtest<- train_bin[-tr,-2 ]
#  Ytest <- train_bin[-tr,2]
#  pred<-knn(Xtrain, Xtest, Ytrain, k=78)
#  err_knn[i]<- sum(sqrt((as.numeric(pred)-Ytest)^2))/length(Ytest)
#}

#print(paste("Erreur moyenne de prediction est de",mean(err_knn)))
#boxplot(t(err_knn))
tr<-sample(1:nrow(train), 0.8*nrow(train))
Xtrain<- train_bin[tr,-2 ]
Ytrain <- train_bin[tr,2]
Xtest<- train_bin[-tr,-2 ]
Ytest <- train_bin[-tr,2]


tree <- rpart(Ytrain~.,data=cbind(Xtrain,Ytrain))
pred <- predict(tree,Xtest)
err_1 <- sum(sqrt((pred-Ytest)^2))/length(Ytest)

err_1
## [1] 9.79404
rpart.plot(tree,extra=1)

#randomForest(x=train_bin[,-2], y=train_bin[,2])

13 AVEC DELVELOPPER ET PUBLISHER

ind<- which(is.na(data_second$Critic_Score))
train<- data_second[-ind,-c(1,6,7,8,9,10,13,14,17,18)]
ind<-which(train$Developer=="")
train<-train[-ind,]
ind<-which(train$Rating=="")
train<-train[-ind,]
train<-train %>% drop_na()
train$Platform<- as.numeric(as.factor(train$Platform))
train$Genre<- as.numeric(as.factor(train$Genre))
train$Rating<- as.numeric(as.factor(train$Rating))
train$Platform<- as.numeric(train$Platform)
train$Year_of_Release<- as.numeric(train$Year_of_Release)
train$Publisher<- as.numeric(as.factor(train$Publisher))
train$Developer<- as.numeric(as.factor(train$Developer))

train_bin2 <- binarisation(train,c(1,3,4,7))
run <- FALSE

if (run==TRUE){
B<- 10
kpp<-1:20
err_knn<-matrix(NA, ncol=B, nrow=length(kpp))
for(k in kpp){
  for( i in 1:B){
    tr<-sample(1:nrow(train), 0.8*nrow(train))
    Xtrain<- train_bin2[tr,-2]
    Ytrain <- train_bin2[tr,2]
    Xtest<- train_bin2[-tr,-2]
    Ytest <- train_bin2[-tr,2]
    pred<-knn(Xtrain, Xtest, Ytrain, k=k)
    err_knn[k,i]<- sum(sqrt((as.numeric(pred)-Ytest)^2))/length(Ytest)
  }
}
boxplot(t(err_knn))
k_opt<- which(apply(t(err_knn), 2, mean)==min(apply(t(err_knn), 2, mean)))
}
tr<-sample(1:nrow(train), 0.8*nrow(train))
Xtrain<- train_bin2[tr,-2 ]
Ytrain <- train_bin2[tr,2]
Xtest<- train_bin2[-tr,-2 ]
Ytest <- train_bin2[-tr,2]


tree <- rpart(Ytrain~.,data=cbind(Xtrain,Ytrain))
pred <- predict(tree,Xtest)
err_1 <- sum(sqrt((pred-Ytest)^2))/length(Ytest)

err_1
## [1] 9.369761
rpart.plot(tree,extra=1)

#randomForest(x=Xtrain[,-2], y=Xtrain[,2],ntree = 1300)