Advertisement
Guest User

Untitled

a guest
Jan 16th, 2019
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.69 KB | None | 0 0
  1. ---
  2. title: "Séance de travaux pratiques 5 : Défi analyse d'opinion (IMDB)"
  3. output:
  4. html_document: default
  5. html_notebook: default
  6. ---
  7.  
  8. ** **
  9.  
  10. #### [Tutoriaux et introductions à R](https://cran.r-project.org/doc/manuals/r-release/R-intro.pdf)
  11.  
  12. * Livre en français de [Vincent Goulet](https://cran.r-project.org/doc/contrib/Goulet_introduction_programmation_R.pdf)
  13.  
  14. * R pour les débutants [Emmanuel Paradis](https://cran.r-project.org/doc/contrib/Paradis-rdebuts_fr.pdf)
  15.  
  16.  
  17. * Liste des [fonctions de base](https://stat.ethz.ch/R-manual/R-devel/library/base/html/00Index.html).
  18.  
  19. ** **
  20. Ce TP sera réalisé en plus grande autonomie que les précédents et les codes seront moins guidés. La note attribuée au rendu de ce TP aura un poids plus important que celles concernant les TPs précédents.
  21.  
  22. Le rendu comportera en particulier
  23.  
  24. - Un fichier intitulé "Rendu_TP5.html" correspond au document "Rendu_TP5.Rmd" complété et commenté. Ce fichier décrira le modèle de prédiction choisi pour le défi de classification.
  25.  
  26. - Un "objet" R sauvé sous forme compressée contenant le modèle choisi pour être évalué par l'enseignant sur l'ensemble test. Le fichier compressé devra être sauvé sous le format RDS ou hdf5. Son intitulé devra être personnalisé sous la forme "my_login_bestmodel.ext" ("ext" désigne une extension particulière, "hdf5" ou "rds", voir les exemples à la fin du TP).
  27.  
  28. - Un script R, contenant une fonction permettant d'évaluer le modèle (voir les exemples à la fin du TP).
  29.  
  30.  
  31. ** **
  32.  
  33. L'objectif de cette séance de travaux pratiques est de répondre à un défi de classification portant sur l'analyse d'opinion à partir de documents textuels ("natural language processing").
  34.  
  35. Les documents analysés sont des critiques de films écrites par des utilisateurs du site web "Internet Movie Data Base" (IMDB). À chaque critique est associée une note donnée par l'utilisateur du site. Seules les notes extrêmes ont été conservées et converties en valeurs binaires représentant des opinions positives ou négatives envers le film.
  36.  
  37. La base de données comporte 50000 critiques de films. Chaque document est prétraité et représenté sous le format d'un _sac de mots_ ("bag of words") pour en faciliter l'analyse. Un sac de mots peut être vu comme une représentation des termes d'un document partir de leur fréquence d'occurrence.
  38.  
  39. Dans cette séance de TP, nous téléchargerons un échantillon de la base de données et constituerons un sous-échantillon comportant 10000 documents annotés. Chaque document est associé à une évaluation traduisant une opinion positive (valeur 1) ou négative (valeur 0) des utilisateurs.
  40.  
  41. Le but de ce TP est de prédire le mieux possible l'opinion ou le _sentiment_ des utilisateurs à partir des fréquences d'occurrence de certains termes apparaissant dans les textes. Un échantillon de test comportant 5000 critiques indépendantes sera utilisé par l'enseignant pour évaluer la méthode sélectionnée dans le défi final.
  42.  
  43.  
  44.  
  45. ```{r}
  46. library(magrittr)
  47. library(keras)
  48. ```
  49.  
  50. #### Index des termes et sacs de mots.
  51.  
  52. À chaque terme d'un texte (aussi appelé _document_) est associé une fréquence d'apparition globale dans la base de données IMDB. Les termes sont référencés dans un index à l'aide d'un nombre indiquant leur rang d'apparition dans la base de données. Dans l'index, les termes sont triés du plus fréquent au moins fréquent.
  53.  
  54. L'index peut être consulté à partir de la bibliothèque `keras`, sous forme de liste dont les attributs sont les termes utilisés dans la base de données. Pour cela, on utlise la fonction `dataset_imdb_word_index()`. L'index est illustré ci-dessous.
  55.  
  56. Le numéro trouvé dans l'index correspond au rang d'un terme donné. Pour trouver le mot le plus fréquemment utilisé dans l'IMDB, on peut chercher le terme dont la valeur est égale au rang 1. L'index contient aussi quatres valeurs spéciales (start, pad, unknown, unused).
  57.  
  58.  
  59. ```{r}
  60. index <- keras::dataset_imdb_word_index()
  61. names(index[index == 1])
  62. ```
  63.  
  64. Sans surprise, le terme le plus fréquemment utilisé est l'article "the". Sa valeur dans l'index est donc égale à 1.
  65.  
  66. L'article "the" se retrouve à la position 85976 dans l'index. L'index n'est donc pas ordonné par la fréquence des termes, mais par une permutation arbitraire. Nous pouvons utiliser la fonction `order()` pour réordonner l'index et trouver les 10 termes les plus utilisés dans l'ensemble des critiques de films.
  67.  
  68. ```{r}
  69. o <- as.numeric(index) %>% order()
  70. index[o[1:10]] %>% names()
  71. ```
  72.  
  73. Nous voyons qu'il s'agit d'articles, de prépositions ou de termes non-informatifs, comme par exemple, des éléments extraits des balises html (br). Il sera peut-être préférable de filtrer les termes les plus utilisés. L'entrée 49 correspondant au terme "good", nous nous arrêtons juste avant et nous filtrons les 48 premières entrées.
  74.  
  75. Pour réduire le temps de calcul, nous conservons uniquement les 2000 termes les plus fréquents. Dans la suite, chaque document sera représenté par une suite de fréquences de termes représentés par les codes de l'index. Le jeu de données résultant de cette étape est nommé `ìmbd`.
  76.  
  77. ```{r}
  78. imbd <- keras::dataset_imdb(path = "imdb.npz",
  79. num_words = 2048,
  80. skip_top = 48)
  81. ```
  82.  
  83. Les données enregistrées dans l'objet `imbd` se présentent sous la forme de listes de documents (train et test). On utilisera les "double-crochets" ou le symbole dollar pour accéder aux attributs de ces listes.
  84.  
  85. ```{r}
  86. summary(imbd)
  87. ```
  88.  
  89.  
  90. Par exemple le document numéro 13 dans l'ensemble d'apprentissage est lu de la manière suivante.
  91.  
  92. ```{r}
  93. document13 <- imbd$train$x[[13]]
  94. document13
  95. ```
  96.  
  97. Nous voyons que le terme d'indice 2 est très fréquent. Après filtrage, il correspond en fait à la chaîne de caractères **UNK** signifiant unknown. Cette chaîne apparait car nous nous sommes restreint à un dictionnaire de 2000 mots.
  98.  
  99. Les fréquences des termes apparaissant dans le document 13 peuvent être données par la fonction `table()`. Cette fonction utilise l'ordre alphabétique pour représenter les comptages de chaque terme.
  100.  
  101. ```{r}
  102. table( sapply(document13[document13 > 3] - 3, FUN = function(x) names(index[index == x]) ))
  103. ```
  104.  
  105. Le document 13 contient les termes "liked", "love", mais aussi "annoying" et "scary". Il est associé à une opinion négative (valeur 0). Cela se vérifie en affichant la variable $y$.
  106.  
  107.  
  108. ```{r}
  109. imbd$train$y[13]
  110. ```
  111.  
  112. Pour la suite, c'est à vous de jouer. Pour ne pas entrer dans les subtilités du traitement du langage et de du pre-processing avec keras, nous nous appuierons sur un codage simplifié des textes basé sur les fréquences des mots de l'index.
  113.  
  114.  
  115. ## Exercice : Défi "analyse de sentiments"
  116.  
  117. #### Lecture des données
  118.  
  119. * Ecrire une ligne de commande R permettant convertir le document 13 en un vecteur de longueur 2000, indiquant le nombre d'apparition de chacun des indices allant de 49 à 2048 dans ce document.
  120.  
  121.  
  122. ```{r}
  123. # comment 1
  124. help(sapply)
  125. sapply(49:2048, FUN = function(x) sum(document13 == x) )
  126. ```
  127.  
  128.  
  129.  
  130. * Constituer un jeu de données comportant 10000 documents choisis pour moitié dans l'ensemble "train" et pour moitié dans l'ensemble "test" de l'IMBD. Techniquement nous le constituerons en 20 étapes, pour limiter l'impact sur la mémoire. Commenter et exécuter le code suivant
  131.  
  132.  
  133. ```{r}
  134. x_imbd <- NULL
  135.  
  136. for (i in 1:10){
  137.  
  138. x_imbd_500 <- NULL
  139.  
  140. for (j in (500*(i-1)+1):(500*i)){
  141.  
  142. # Pour chaque document de l'ensemble train, on stocke les indices des mots constituant le document.
  143.  
  144. doc_temp <- imbd$train$x[[j]]
  145.  
  146. # Pour chaque document, on applique la fonction permettant d'indiquer le nombre d'apparition de chacun des indices.
  147. # On stocke ensuite cela dans x_imbd_500 (matrice).
  148. x_imbd_500 <- rbind(x_imbd_500,
  149. sapply(49:2048,
  150. FUN = function(ind) sum(doc_temp == ind)))
  151.  
  152. if (j%%500 == 0) print(j) # ca rassure
  153. }
  154.  
  155. # On stocke dans x_imbd par tranche de 500
  156. x_imbd <- rbind(x_imbd, x_imbd_500)
  157. }
  158.  
  159. for (i in 1:10){
  160.  
  161. x_imbd_500 <- NULL
  162.  
  163. for (j in (500*(i-1)+1):(500*i)){
  164.  
  165. # On fait la même pour l'ensemble test.
  166.  
  167. doc_temp <- imbd$test$x[[j]]
  168.  
  169. # On continue de stocker tout ça dans x_imbd_500.
  170. x_imbd_500 <- rbind(x_imbd_500,
  171. sapply(49:2048,
  172. FUN = function(ind) sum(doc_temp == ind)))
  173.  
  174. if (j%%500 == 0) print(j) # ca rassure
  175. }
  176.  
  177. # On stocke dans x_imbd par tranche de 500
  178. x_imbd <- rbind(x_imbd, x_imbd_500)
  179. }
  180. ```
  181.  
  182. * Que contient l'objet `x_imbd` ?
  183. L'objet x_imbd contient 10000 documents, et pour chaque document il contient le nombre d'apparitions de chacun des mots d'indice 49 à 2048.
  184.  
  185. * Pour représenter les classes 0 et 1 en format matriciel, on peut utiliser la fonction `to_categoretical()` de `keras`. C'est plus simple.
  186.  
  187. ```{r}
  188. y_imbd <- to_categorical(imbd$train$y[1:5000], 2)
  189. y_imbd <- rbind(y_imbd, to_categorical(imbd$test$y[1:5000], 2))
  190. ```
  191.  
  192. Et voilà. On est en pleine forme et on dispose d'une base d'apprentissage comportant les fréquences d'apparition des mots de l'index pour 10000 documents (`x_train`) et les opinions des utilisateurs `y_train`. Le TP peut vraiment commencer.
  193.  
  194.  
  195. #### Etude d'association
  196.  
  197. Le but d'une étude d'association est d'identifier les termes les plus associés aux opinions positives ou négatives des utilisateurs. Pour cela, nous evaluons la correlation au carré entre l'occurrence de chaque terme et l'opinion de l'utilisateur (présence d'un 1). Il se peut que certaines valeurs de corrélation ne soient pas calculables à cause d'un écart-type nul. Cela arrive pour la 2000e valeur. Nous l'écarterons donc (il en restera 1999).
  198.  
  199. * Calculer le coefficient de corrélation au carré entre les fréquences d'apparition des termes de l'index et opinion des utilsateurs (1999 valeurs).
  200.  
  201. ```{r}
  202. # comment
  203. x <- x_imbd[,-2000]
  204.  
  205. # comment
  206. y <- y_imbd[,2]
  207.  
  208. # comment
  209. r2 <- cor(x,y)^2
  210. ```
  211.  
  212.  
  213. * Montrer les termes dont la valeur d'association $r^2$ est supérieure à trois pourcent (0.03), puis supérieure à 0.02, et à 0.005. _Note_ : Il faut effectuer un décalage de 45 indices dans l'index pour trouver le codage correct (et non 48 indices, car il y a des termes spéciaux).
  214.  
  215.  
  216. ```{r}
  217. # quelque chose à changer
  218. index[o[ which(r2 > 0.03) + 45]] %>% names()
  219. index[o[ which(r2 > 0.02) + 45]] %>% names()
  220. index[o[ which(r2 > 0.005) + 45]] %>% names()
  221. ```
  222.  
  223. * Dans quelles proportions les termes de valeur d'association $r^2$ supérieure à 0.02 apparaissent-ils dans les documents ? Représenter graphiquement ces proportions à l'aide d'un diagramme en barre.
  224.  
  225.  
  226. ```{r}
  227. # Calculer la frequence des termes realisant la condition
  228. freq <- x[, which(r2 > 0.02) + 45 ] %>% apply(2, mean)
  229.  
  230. # mots dans l'index et barplot
  231. names(freq) <- index[o[which(r2 > 0.02) + 45]] %>% names()
  232. barplot(sort(freq, decreasing = TRUE), col = "lightblue", las = 2)
  233. ```
  234.  
  235.  
  236.  
  237. * Dans quelles proportions les termes de valeur d'association $r^2$ supérieure à 0.02 apparaissent-ils dans les documents **à connotation positive** ? Représenter graphiquement ces proportions à l'aide d'un diagramme en barre.
  238.  
  239.  
  240. ```{r}
  241.  
  242. freq <- x[y==1, which(r2 > 0.02) + 45 ] %>% apply(2, mean)
  243.  
  244. # mots dans l'index et barplot
  245. names(freq) <- index[o[which(r2 > 0.02) + 45]] %>% names()
  246. barplot(sort(freq, decreasing = TRUE), col = "lightblue", las = 2)
  247. ```
  248.  
  249.  
  250. * Dans quelles proportions les termes de valeur d'association $r^2$ supérieure à 0.02 apparaissent-ils dans les documents **à connotation négative** ? Représenter graphiquement ces proportions à l'aide d'un diagramme en barre.
  251.  
  252.  
  253. ```{r}
  254. freq <- x[y==0, which(r2 > 0.02) + 45 ] %>% apply(2, mean)
  255.  
  256. # mots dans l'index et barplot
  257. names(freq) <- index[o[which(r2 > 0.02) + 45]] %>% names()
  258. barplot(sort(freq, decreasing = TRUE), col = "lightblue", las = 2)
  259. ```
  260.  
  261.  
  262. * *Question subsidiaire*. Dans quelles proportions les termes de valeur d'association $r = cor(x,y)$ supérieure à 0.1 (resp. inférieure à $-0.1$) apparaissent-ils dans les documents **à connotation positive** (resp. **négative**) ? Représenter graphiquement ces proportions à l'aide d'un diagramme en barre.
  263.  
  264. #### Modèles d'apprentissage
  265.  
  266.  
  267. * \`A l'aide des outils vus dans les séances précédentes, tels que _keras_, (_lda_, _nnet_, ou d'autres bibliothèques de programmes que vous pourriez trouver dans R), ajuster des modèles d'apprentissage aux données contenues dans le TP : **"x_imbd" et "y_imbd"**.
  268.  
  269. * Dans un tableau, décrire les performances de 6 méthodes choisies pour des échantillons d'apprentissage et de test que vous aurez créés vous-mêmes **à partir de "x_imbd" et "y_imbd"**. Les performances seront mesurées par les erreurs de classification et d'entropie (log loss).
  270.  
  271. ```{r}
  272. # initialisation pour le tableau
  273. acc <- NULL
  274. loss <- NULL
  275. name <- NULL
  276. ```
  277.  
  278. ```{r}
  279. # index_train correspond à la séparation entre les données de test et les données train (train correspondent aux données de 0 à 5000 et test de 5001 à 10000).
  280. index_train = 0:5000
  281. # Création des ensembles de train et de test
  282. x_train <- x_imbd[index_train,]
  283. y_train <- y_imbd[index_train,]
  284. x_test <- x_imbd[-index_train,]
  285. y_test <- y_imbd[-index_train,]
  286. ```
  287.  
  288. ```{r}
  289. # keras 1_10_2
  290.  
  291. # On crée le réseau
  292.  
  293. model <- keras_model_sequential()
  294. model %>%
  295. layer_dense(units = 10, activation = 'relu', input_shape = 2000) %>%
  296. layer_dropout(rate = 0.2) %>%
  297. layer_dense(units = 3, activation = 'softmax')
  298.  
  299. # On définit les paramètres à optimiser
  300. model %>% compile(
  301. loss = 'sparse_categorical_crossentropy',
  302. optimizer = optimizer_rmsprop(lr = 0.001, decay = 0.1),
  303. metrics = c('accuracy')
  304. )
  305.  
  306. # On entraîne le réseau et on le stocke l'historique dans une variable
  307. history <- model %>% fit(
  308. x_train,
  309. y_train[,1],
  310. epochs = 20,
  311. batch_size = 100,
  312. validation_split = 0.2
  313. )
  314.  
  315. # On stocke les données sur la précision et le logloss dans une variable à chaque fois
  316. res = model %>% evaluate(x_test, y_test[,1])
  317. acc = c(acc, res$acc)
  318. loss = c(loss, res$loss)
  319. name = c(name, 'keras_1_10_2')
  320. ```
  321.  
  322. ```{r}
  323. # keras 2_1000_5
  324.  
  325. # On crée le réseau
  326.  
  327. model <- keras_model_sequential()
  328. model %>%
  329. layer_dense(units = 1000, activation = 'relu', input_shape = 2000) %>%
  330. layer_dropout(rate = 0.5) %>%
  331. layer_dense(units = 1000, activation = 'relu') %>%
  332. layer_dropout(rate = 0.5) %>%
  333. layer_dense(units = 3, activation = 'softmax')
  334.  
  335. # On définit les paramètres à optimiser
  336. model %>% compile(
  337. loss = 'sparse_categorical_crossentropy',
  338. optimizer = optimizer_rmsprop(lr = 0.001, decay = 0.1),
  339. metrics = c('accuracy')
  340. )
  341.  
  342. # On entraîne le réseau et on le stocke l'historique dans une variable
  343. history <- model %>% fit(
  344. x_train,
  345. y_train[,1],
  346. epochs = 20,
  347. batch_size = 100,
  348. validation_split = 0.2
  349. )
  350.  
  351. # On stocke les données sur la précision et le logloss dans une variable à chaque fois
  352. res = model %>% evaluate(x_test, y_test[,1])
  353. acc = c(acc, res$acc)
  354. loss = c(loss, res$loss)
  355. name = c(name, 'keras_2_1000_5')
  356. ```
  357.  
  358. ```{r}
  359. # keras 2_1000_2
  360.  
  361. # On crée le réseau
  362.  
  363. model <- keras_model_sequential()
  364. model %>%
  365. layer_dense(units = 1000, activation = 'relu', input_shape = 2000) %>%
  366. layer_dropout(rate = 0.2) %>%
  367. layer_dense(units = 1000, activation = 'relu') %>%
  368. layer_dropout(rate = 0.2) %>%
  369. layer_dense(units = 3, activation = 'softmax')
  370.  
  371. # On définit les paramètres à optimiser
  372. model %>% compile(
  373. loss = 'sparse_categorical_crossentropy',
  374. optimizer = optimizer_rmsprop(lr = 0.001, decay = 0.1),
  375. metrics = c('accuracy')
  376. )
  377.  
  378. # On entraîne le réseau et on le stocke l'historique dans une variable
  379. history <- model %>% fit(
  380. x_train,
  381. y_train[,1],
  382. epochs = 20,
  383. batch_size = 100,
  384. validation_split = 0.2
  385. )
  386.  
  387. # On stocke les données sur la précision et le logloss dans une variable à chaque fois
  388. res = model %>% evaluate(x_test, y_test[,1])
  389. acc = c(acc, res$acc)
  390. loss = c(loss, res$loss)
  391. name = c(name, 'keras_2_1000_2')
  392. ```
  393.  
  394. ```{r}
  395. # keras 2_5000_10
  396.  
  397. # On crée le réseau
  398.  
  399. model <- keras_model_sequential()
  400. model %>%
  401. layer_dense(units = 5000, activation = 'relu', input_shape = 2000) %>%
  402. layer_dropout(rate = 1) %>%
  403. layer_dense(units = 5000, activation = 'relu') %>%
  404. layer_dropout(rate = 1) %>%
  405. layer_dense(units = 3, activation = 'softmax')
  406.  
  407. # On définit les paramètres à optimiser
  408. model %>% compile(
  409. loss = 'sparse_categorical_crossentropy',
  410. optimizer = optimizer_rmsprop(lr = 0.001, decay = 0.1),
  411. metrics = c('accuracy')
  412. )
  413.  
  414. # On entraîne le réseau et on le stocke l'historique dans une variable
  415. history <- model %>% fit(
  416. x_train,
  417. y_train[,1],
  418. epochs = 20,
  419. batch_size = 100,
  420. validation_split = 0.2
  421. )
  422.  
  423. # On stocke les données sur la précision et le logloss dans une variable à chaque fois
  424. res = model %>% evaluate(x_test, y_test[,1])
  425. acc = c(acc, res$acc)
  426. loss = c(loss, res$loss)
  427. name = c(name, 'keras_2_5000_10')
  428. ```
  429.  
  430. ```{r}
  431. # keras 3_2000_5
  432.  
  433. # On crée le réseau
  434.  
  435. model <- keras_model_sequential()
  436. model %>%
  437. layer_dense(units = 2000, activation = 'relu', input_shape = 2000) %>%
  438. layer_dropout(rate = 0.5) %>%
  439. layer_dense(units = 2000, activation = 'relu') %>%
  440. layer_dropout(rate = 0.5) %>%
  441. layer_dense(units = 2000, activation = 'relu') %>%
  442. layer_dropout(rate = 0.5) %>%
  443. layer_dense(units = 3, activation = 'softmax')
  444.  
  445. # On définit les paramètres à optimiser
  446. model %>% compile(
  447. loss = 'sparse_categorical_crossentropy',
  448. optimizer = optimizer_rmsprop(lr = 0.001, decay = 0.1),
  449. metrics = c('accuracy')
  450. )
  451.  
  452. # On entraîne le réseau et on le stocke l'historique dans une variable
  453. history <- model %>% fit(
  454. x_train,
  455. y_train[,1],
  456. epochs = 20,
  457. batch_size = 100,
  458. validation_split = 0.2
  459. )
  460.  
  461. # On stocke les données sur la précision et le logloss dans une variable à chaque fois
  462. res = model %>% evaluate(x_test, y_test[,1])
  463. acc = c(acc, res$acc)
  464. loss = c(loss, res$loss)
  465. name = c(name, 'keras_3_2000_5')
  466. ```
  467.  
  468. ```{r}
  469. # keras 2_100_2
  470.  
  471. # On crée le réseau
  472.  
  473. model <- keras_model_sequential()
  474. model %>%
  475. layer_dense(units = 100, activation = 'relu', input_shape = 2000) %>%
  476. layer_dropout(rate = 0.2) %>%
  477. layer_dense(units = 100, activation = 'relu') %>%
  478. layer_dropout(rate = 0.2) %>%
  479. layer_dense(units = 3, activation = 'softmax')
  480.  
  481. # On définit les paramètres à optimiser
  482. model %>% compile(
  483. loss = 'sparse_categorical_crossentropy',
  484. optimizer = optimizer_rmsprop(lr = 0.001, decay = 0.1),
  485. metrics = c('accuracy')
  486. )
  487.  
  488. # On entraîne le réseau et on le stocke l'historique dans une variable
  489. history <- model %>% fit(
  490. x_train,
  491. y_train[,1],
  492. epochs = 20,
  493. batch_size = 100,
  494. validation_split = 0.2
  495. )
  496.  
  497. # On stocke les données sur la précision et le logloss dans une variable à chaque fois
  498. res = model %>% evaluate(x_test, y_test[,1])
  499. acc = c(acc, res$acc)
  500. loss = c(loss, res$loss)
  501. name = c(name, 'keras_2_100_2')
  502. ```
  503. * Sauver votre modèle dans un format compressé (RDS ou HDF5 pour `keras`). Remplacer la chaîne de caractère "my_login" par votre propre login ensimag.
  504.  
  505. ```{r eval = FALSE}
  506. # standard r packages:
  507. saveRDS(model, file = "zhujo_model.RDS")
  508.  
  509. #keras
  510. save_model_hdf5(object = model, filepath = "zhujo_model_keras.hdf5")
  511. ```
  512.  
  513.  
  514.  
  515. * Ecrire et appliquer une fonction appelée "prediction_finale" pouvant prendre par défaut en entrée une matrice appelé "x_ultime" de taille 5000 lignes et 2000 colonnes contenant des valeurs binaires et une matrice "y_ultime" de taille 5000 lignes et 2 colonnes contenant des valeurs binaires. Cette fonction devra prédire les classes contenues dans "y_ultime" à partir des données "x_ultime" en chargeant le modèle que vous aurez choisi pour le défi. Des exemples de fonctions sont décrits ci-dessous
  516.  
  517.  
  518. ```{r, eval = FALSE}
  519. prediction_finale <- function(x_ultime,
  520. y_ultime,
  521. file_path = "my_login_model_keras.hdf5"){
  522. #Remplacer "my_login" par votre propre login ensimag.
  523.  
  524. require(magrittr)
  525.  
  526. #tests
  527. if (nrow(x_ultime) != 5000 | ncol(x_ultime) != 2000)
  528. stop("Dimensions de x incorrectes.")
  529.  
  530. if (nrow(y_ultime) != 5000 | ncol(y_ultime) != 2)
  531. stop("Dimensions de y incorrectes.")
  532.  
  533. #if keras
  534. require(keras)
  535.  
  536. model <- load_model_hdf5(filepath = file_path)
  537. model %>% evaluate(x_ultime, y_ultime)
  538. }
  539. ```
  540.  
  541. ```{r eval = FALSE}
  542. prediction_finale(x_test, y_test)
  543. ```
  544.  
  545. * *Note* : pour d'autres modèles que ceux _keras()_, on sauvera l'objet correspondant au modèle ajusté avec la fonction _save()_ ou _saveRDS()_. On écrira une fonction permettant de charger l'objet créé (_load()_) et lui appliquant la fonction _predict()_ dans le format spécifique à la classe du modèle choisi (_knn_, _nnet_, _lda_, etc).
  546.  
  547. Par exemple, si l'objet est de classe "nnet", on pourra s'inspirer des commandes suivantes pour sauver l'objet créé et écrire la fonction demandée.
  548.  
  549.  
  550. ```{r, eval = FALSE}
  551. # Remplacer "my_login" par votre propre login ensimag.
  552. # saveRDS(mod_nnet, file = "my_login_bestmodel.RDS")
  553.  
  554. prediction_finale <- function(x_ultime,
  555. y_ultime,
  556. file_path = "my_login_bestmodel.RDS"){
  557. require(magrittr)
  558. #tests
  559. if (nrow(x_ultime) != 5000 | ncol(x_ultime) != 2000)
  560. stop("Dimensions de x incorrectes.")
  561.  
  562. if (nrow(y_ultime) != 5000 | ncol(y_ultime) != 2)
  563. stop("Dimensions de y incorrectes.")
  564.  
  565. #if nnet
  566. require(nnet)
  567. mod_nnet <- readRDS(file = file_path)
  568. proba <- mod_nnet %>% predict(x_ultime)
  569. acc <- mean(y_ultime[,1] == (proba < 0.5))
  570. #logloss <- completer
  571. return(list(acc = acc, log.loss = logloss))
  572. }
  573. ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement