Cette démo reproduit quelques exemples tirés du livre de Lantz (2013), Machine Learning with R.
1. Classification “lazy” avec knn dans le package class.
On utilise un dataset sur des biopsies en vue de détecter des cancers du sein. D’abord, un peu de préparation.
library(class)
library(gmodels)
normalize <- function(x) {
return ((x - min(x)) / (max(x) - min(x)))
}
wbcd <- read.csv("https://github.com/shifteight/R/blob/master/MLwR/wisc_bc_data.csv")
rownames(wbcd) <- wbcd$id
wbcd$id <- NULL
wbcd_n <- as.data.frame(lapply(wbcd[2:31], normalize))
Error in `[.data.frame`(wbcd, 2:31) : undefined columns selected
Ici la magie va opérer. On classifie les données. knn fonctionne comme suit:
knn(train, test, class, k)
Où k est un entier donnant le nombre de “voisins” à considérer (nearest neighbourgs), ce qui correspond grosso-modo à la précision dans le découpage.
wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test, cl = wbcd_train_labels, k=12)
CrossTable(x = wbcd_test_labels, y = wbcd_test_pred, prop.chisq=FALSE)
Cell Contents
|-------------------------|
| N |
| N / Row Total |
| N / Col Total |
| N / Table Total |
|-------------------------|
Total Observations in Table: 100
| wbcd_test_pred
wbcd_test_labels | B | M | Row Total |
-----------------|-----------|-----------|-----------|
B | 75 | 2 | 77 |
| 0.974 | 0.026 | 0.770 |
| 0.987 | 0.083 | |
| 0.750 | 0.020 | |
-----------------|-----------|-----------|-----------|
M | 1 | 22 | 23 |
| 0.043 | 0.957 | 0.230 |
| 0.013 | 0.917 | |
| 0.010 | 0.220 | |
-----------------|-----------|-----------|-----------|
Column Total | 76 | 24 | 100 |
| 0.760 | 0.240 | |
-----------------|-----------|-----------|-----------|
B étant pour bénin et M pour malin, on peut donc déduire les vrais négatifs (B,B), faux positifs (B,M), faux négatifs (M,B) et vrais positifs (M,M).
Amélioration d’une classification “paresseuse”
On peut améliorer cette classification. On va tester deux méthodes: conversion en scores Z et bidouillage avec la valeur de k.
CrossTable(x = wbcd_test_labels, y = wbcd_test_pred, prop.chisq=FALSE)
Error in CrossTable(x = wbcd_test_labels, y = wbcd_test_pred, prop.chisq = FALSE) :
could not find function "CrossTable"
Puisque cette méthode ne produit pas de modèle, on ne peut pas voir la contribution relative de chaque variable afin de sélectionner les variables les plus prometteuses, ni pondérer la contribution des variables. C’est une boite noire. Nous avons peu d’options pour améliorer les prédictions outre le k et des transformations sur les variables.
LS0tDQp0aXRsZTogJ01hY2hpbmUgbGVhcm5pbmcgYXZlYyBSICcNCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBodG1sX2RvY3VtZW50Og0KICAgIGRmX3ByaW50OiBwYWdlZA0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCiAgd29yZF9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQpDZXR0ZSBkw6ltbyByZXByb2R1aXQgcXVlbHF1ZXMgZXhlbXBsZXMgdGlyw6lzIGR1IGxpdnJlIGRlIExhbnR6ICgyMDEzKSwgTWFjaGluZSBMZWFybmluZyB3aXRoIFIuDQoNCiMxLiBDbGFzc2lmaWNhdGlvbiAibGF6eSIgYXZlYyBrbm4gZGFucyBsZSBwYWNrYWdlIGNsYXNzLg0KDQpPbiB1dGlsaXNlIHVuIGRhdGFzZXQgc3VyIGRlcyBiaW9wc2llcyBlbiB2dWUgZGUgZMOpdGVjdGVyIGRlcyBjYW5jZXJzIGR1IHNlaW4uIEQnYWJvcmQsIHVuIHBldSBkZSBwcsOpcGFyYXRpb24uDQpgYGB7ciBoZWFkZXJfbGF6eWxlYXJuaW5nLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQoNCmxpYnJhcnkoY2xhc3MpDQpsaWJyYXJ5KGdtb2RlbHMpDQoNCm5vcm1hbGl6ZSA8LSBmdW5jdGlvbih4KSB7DQogcmV0dXJuICgoeCAtIG1pbih4KSkgLyAobWF4KHgpIC0gbWluKHgpKSkNCn0NCg0Kd2JjZCA8LSByZWFkLmNzdigiaHR0cHM6Ly9yZXNvdXJjZXMub3JlaWxseS5jb20vZXhhbXBsZXMvOTc4MTc4NDM5MzkwOC9yYXcvYWM5ZmU0MTU5NmRkNDJmYzM4NzdjZmE4ZWQ0MTBkZDM0NmM0MzU0OC9NYWNoaW5lJTIwTGVhcm5pbmclMjB3aXRoJTIwUiwlMjBTZWNvbmQlMjBFZGl0aW9uX0NvZGUvQ2hhcHRlciUyMDAzL3dpc2NfYmNfZGF0YS5jc3YiKQ0Kcm93bmFtZXMod2JjZCkgPC0gd2JjZCRpZA0Kd2JjZCRpZCA8LSBOVUxMDQp3YmNkX24gPC0gYXMuZGF0YS5mcmFtZShsYXBwbHkod2JjZFsyOjMxXSwgbm9ybWFsaXplKSkNCndiY2RfdHJhaW4gPC0gd2JjZF9uWzE6NDY5LCBdICNkb25uw6llcyBkZSB0cmFpbmluZw0Kd2JjZF90ZXN0IDwtIHdiY2Rfbls0NzA6NTY5LCBdICNkb25uw6llcyBwb3VyIHbDqXJpZmllciBsZSBtb2TDqGxlDQp3YmNkX3RyYWluX2xhYmVscyA8LSB3YmNkWzE6NDY5LCAxXSAjZGlhZ25vc3RpY3MgZGVzIGRvbm7DqWVzIGRlIHRyYWluaW5nDQp3YmNkX3Rlc3RfbGFiZWxzIDwtIHdiY2RbNDcwOjU2OSwgMV0gI2RpYWdub3N0aWNzIGRlcyBkb25uw6llcyBkZSB0ZXN0DQpgYGANCg0KDQpJY2kgbGEgbWFnaWUgdmEgb3DDqXJlci4gT24gY2xhc3NpZmllIGxlcyBkb25uw6llcy4ga25uIGZvbmN0aW9ubmUgY29tbWUgc3VpdDoNCg0KPiBrbm4odHJhaW4sIHRlc3QsIGNsYXNzLCBrKSANCiANCk/DuSBrIGVzdCB1biBlbnRpZXIgZG9ubmFudCBsZSBub21icmUgZGUgInZvaXNpbnMiIMOgIGNvbnNpZMOpcmVyIChuZWFyZXN0IG5laWdoYm91cmdzKSwgY2UgcXVpIGNvcnJlc3BvbmQgZ3Jvc3NvLW1vZG8gw6AgbGEgcHLDqWNpc2lvbiBkYW5zIGxlIGTDqWNvdXBhZ2UuDQoNCmBgYHtyfQ0Kd2JjZF90ZXN0X3ByZWQgPC0ga25uKHRyYWluID0gd2JjZF90cmFpbiwgdGVzdCA9IHdiY2RfdGVzdCwgY2wgPSB3YmNkX3RyYWluX2xhYmVscywgaz0xMikNCkNyb3NzVGFibGUoeCA9IHdiY2RfdGVzdF9sYWJlbHMsIHkgPSB3YmNkX3Rlc3RfcHJlZCwgcHJvcC5jaGlzcT1GQUxTRSkNCmBgYA0KDQpCIMOpdGFudCBwb3VyIGLDqW5pbiBldCBNIHBvdXIgbWFsaW4sIG9uIHBldXQgZG9uYyBkw6lkdWlyZSBsZXMgdnJhaXMgbsOpZ2F0aWZzIChCLEIpLCBmYXV4IHBvc2l0aWZzIChCLE0pLCBmYXV4IG7DqWdhdGlmcyAoTSxCKSBldCB2cmFpcyBwb3NpdGlmcyAoTSxNKS4NCg0KIyMgQW3DqWxpb3JhdGlvbiBkJ3VuZSBjbGFzc2lmaWNhdGlvbiAicGFyZXNzZXVzZSINCg0KT24gcGV1dCBhbcOpbGlvcmVyIGNldHRlIGNsYXNzaWZpY2F0aW9uLiBPbiB2YSB0ZXN0ZXIgZGV1eCBtw6l0aG9kZXM6IGNvbnZlcnNpb24gZW4gc2NvcmVzIFogZXQgYmlkb3VpbGxhZ2UgYXZlYyBsYSB2YWxldXIgZGUgay4NCg0KYGBge3J9DQp3YmNkX3ogPC0gYXMuZGF0YS5mcmFtZShzY2FsZSh3YmNkWy0xXSkpICNjb252ZXJzaW9uIGRlIHRvdXQgZW4gc2NvcmVzIFogKHNhdWYgbGEgY29sIDEgcXVpIGVzdCBsZSBkaWFnbm9zdGljKQ0Kd2JjZF90cmFpbl96IDwtIHdiY2RfelsxOjQ2OSwgXQ0Kd2JjZF90ZXN0X3ogPC0gd2JjZF96WzQ3MDo1NjksIF0NCg0Kd2JjZF90ZXN0X3ByZWQgPC0ga25uKHRyYWluID0gd2JjZF90cmFpbl96LCB0ZXN0ID0gd2JjZF90ZXN0X3osIGNsID0gd2JjZF90cmFpbl9sYWJlbHMsIGs9MTIpDQpDcm9zc1RhYmxlKHggPSB3YmNkX3Rlc3RfbGFiZWxzLCB5ID0gd2JjZF90ZXN0X3ByZWQsIHByb3AuY2hpc3E9RkFMU0UpDQoNCndiY2RfdGVzdF9wcmVkIDwtIGtubih0cmFpbiA9IHdiY2RfdHJhaW4sIHRlc3QgPSB3YmNkX3Rlc3QsIGNsID0gd2JjZF90cmFpbl9sYWJlbHMsIGs9MjApDQpDcm9zc1RhYmxlKHggPSB3YmNkX3Rlc3RfbGFiZWxzLCB5ID0gd2JjZF90ZXN0X3ByZWQsIHByb3AuY2hpc3E9RkFMU0UpDQpgYGANCg0KUHVpc3F1ZSBjZXR0ZSBtw6l0aG9kZSBuZSBwcm9kdWl0IHBhcyBkZSBtb2TDqGxlLCBvbiBuZSBwZXV0IHBhcyB2b2lyIGxhIGNvbnRyaWJ1dGlvbiByZWxhdGl2ZSBkZSBjaGFxdWUgdmFyaWFibGUgYWZpbiBkZSBzw6lsZWN0aW9ubmVyIGxlcyB2YXJpYWJsZXMgbGVzIHBsdXMgcHJvbWV0dGV1c2VzLCBuaSBwb25kw6lyZXIgbGEgY29udHJpYnV0aW9uIGRlcyB2YXJpYWJsZXMuIEMnZXN0IHVuZSBib2l0ZSBub2lyZS4gTm91cyBhdm9ucyBwZXUgZCdvcHRpb25zIHBvdXIgYW3DqWxpb3JlciBsZXMgcHLDqWRpY3Rpb25zIG91dHJlIGxlIGsgZXQgZGVzIHRyYW5zZm9ybWF0aW9ucyBzdXIgbGVzIHZhcmlhYmxlcy4NCg0KDQo=