M1 MABS BBS Data Mining TD KNIME
From silico.biotoul.fr
(→Contexte: changement de jeu de données : données cardiaques) |
m (→Classification) |
||
(6 intermediate revisions not shown) | |||
Line 37: | Line 37: | ||
Pour cette partie, nous allons principalement utiliser l'environnement pour la fouille de données [http://www.knime.org/ KNIME]. C'est un logiciel en Java développé à l'origine par l'université de Constance (Allemagne). | Pour cette partie, nous allons principalement utiliser l'environnement pour la fouille de données [http://www.knime.org/ KNIME]. C'est un logiciel en Java développé à l'origine par l'université de Constance (Allemagne). | ||
- | La première étape consiste à charger les données. Dans KNIME, ajoutez un noeud <tt>File Reader</tt> (section IO pour Input/Output) et configurez-le afin de charger le fichier [[Media: | + | La première étape consiste à charger les données. Dans KNIME, ajoutez un noeud <tt>File Reader</tt> (section IO pour Input/Output) et configurez-le afin de charger le fichier [[Media:Data_Mining_heart.txt]]. |
- | Comme premier exercice, ajoutez un noeud Decision Tree Learner (induction d'arbre de décision) et connectez la sortie du File Reader à l'entrée du Decision Tree Learner. Configurez ce dernier pour qu'il cherche à prédire | + | Comme premier exercice, ajoutez un noeud Decision Tree Learner (induction d'arbre de décision) et connectez la sortie du File Reader à l'entrée du Decision Tree Learner. Configurez ce dernier pour qu'il cherche à prédire si un individu est malade. Lancez l'éxécution de ces noeuds et visualisez l'arbre de décision induit. Quels sont les variables les plus importantes ? Comparez les résultats avec ou sans élagage. |
Ensuite, évaluez les performance de ce type de classificateur en ajoutant et en configurant un noeud <tt>Cross validation</tt> (section Meta). Vous lui ferez effectuer une leave-one-out cross validation. Examiner ensuite le taux d'erreurs à l'aide d'un noeud <tt>Statistics view</tt>. | Ensuite, évaluez les performance de ce type de classificateur en ajoutant et en configurant un noeud <tt>Cross validation</tt> (section Meta). Vous lui ferez effectuer une leave-one-out cross validation. Examiner ensuite le taux d'erreurs à l'aide d'un noeud <tt>Statistics view</tt>. | ||
Line 47: | Line 47: | ||
* k plus proches voisins (essayez différentes valeurs de k), | * k plus proches voisins (essayez différentes valeurs de k), | ||
* Réseau de neurones. | * Réseau de neurones. | ||
- | |||
- | |||
Quel est le classificateur le plus performant sur ce jeu de données ? | Quel est le classificateur le plus performant sur ce jeu de données ? | ||
Line 91: | Line 89: | ||
<source lang="python"> | <source lang="python"> | ||
# LOAD DATASET | # LOAD DATASET | ||
- | data = orange.ExampleTable(" | + | data = orange.ExampleTable("Data_Mining_heart.orange.tab") |
</source> | </source> | ||
Line 175: | Line 173: | ||
# BUILD TEST SAMPLE | # BUILD TEST SAMPLE | ||
- | test = orange.Example(data.domain, [ | + | test = orange.Example(data.domain, [61, 'M', 4, 138, 166, 'FALSE', 2, 125, 'TRUE', 3.6, 2, 1, 'normal', 'TRUE']) |
print "Test object ",test | print "Test object ",test | ||
Line 214: | Line 212: | ||
</source> | </source> | ||
- | Jeu de données : [[Media: | + | Jeu de données : [[Media:Data_Mining_heart.txt]] [[Media:Data_Mining_heart.orange.txt]] |
Current revision as of 15:34, 20 November 2013
Contents |
Contexte
Afin de mettre en pratique les concepts vus en cours, nous allons nous appuyer sur un jeu de données publiques hébergées par le UC Irvine Machine Learning Repository. Il s'agit d'une petite base de données sur des données cliniques de patients (âge, sexe, ...) associées à la présence ou l'absence d'une maladie cardiaque.
Pour chaque personne (270 en tout), vous disposez de 13 variables :
- âge (age) : continue
- sexe (sex) : discrète M/F
- type de douleur à la poitrine (chest_pain_type) : discrète, 4 valeurs 1/2/3/4
- pression sanguine au repos (resting_blood_pressure) : continue
- taux de cholestérol en mg/dl (serum_cholesterol) : continue
- glycémie à jeun > 120 mg/dl (fasting_blood_sugar) : discrète FALSE/TRUE
- électrocardiogramme au repos (resting_ecg_results) : discrète 0/1/2
- fréquence cardiaque maximale (max_heart_rate) : continue
- angine induite par l'exercice (excerise_induced_angina) : discrète FALSE/TRUE
- "oldpeak = ST depression induced by exercise relative to rest" (depression_induced) : continue
- pente de la crête du segment ST (slope) : ordinale 1/2/3
- nombre de vaisseaux (major_vessels) : continue
- thal (thal) : discrète normal/fixed_defect/reversable_defect
ainsi que de la présence ou l'absence d'une maladie cardiaque. Il va donc s'agir à partir des variables de construire un modèle (arbre de décision, bayésien, ...) afin de prédire la présence d'une maladie cardiaque chez une personne.
Classification
Utilisation d'un environnement de fouille de données
Pour cette partie, nous allons principalement utiliser l'environnement pour la fouille de données KNIME. C'est un logiciel en Java développé à l'origine par l'université de Constance (Allemagne).
La première étape consiste à charger les données. Dans KNIME, ajoutez un noeud File Reader (section IO pour Input/Output) et configurez-le afin de charger le fichier Media:Data_Mining_heart.txt.
Comme premier exercice, ajoutez un noeud Decision Tree Learner (induction d'arbre de décision) et connectez la sortie du File Reader à l'entrée du Decision Tree Learner. Configurez ce dernier pour qu'il cherche à prédire si un individu est malade. Lancez l'éxécution de ces noeuds et visualisez l'arbre de décision induit. Quels sont les variables les plus importantes ? Comparez les résultats avec ou sans élagage.
Ensuite, évaluez les performance de ce type de classificateur en ajoutant et en configurant un noeud Cross validation (section Meta). Vous lui ferez effectuer une leave-one-out cross validation. Examiner ensuite le taux d'erreurs à l'aide d'un noeud Statistics view.
Effectuer le même travail avec les types de classificateur suivants :
- Bayésien naïf,
- k plus proches voisins (essayez différentes valeurs de k),
- Réseau de neurones.
Quel est le classificateur le plus performant sur ce jeu de données ?
Utilisation d'une bibliothèque de programmation
Afin d'automatiser la réalisation de certaines tâches, il est possible d'utiliser une librairie/module/bibliothèque proposant des fonctionnalités de fouilles de données. Il en existe pour différents langages de programmation, certaines proposant également une interface utilisateur graphique et/ou des passerelles pour d'autres langages de programmation (ex: RWeka) :
Pour aujourd'hui, nous utiliserons Orange.
Import de la librairie
Si la librairie n'est pas installée, elle peut l'être en téléchargeant la version appropriée (Windows, Mac ou linux). Pour linux, il faut récupérer les sources et en effectuer une installation standard :
python setup.py build
python setup.py install
Si vous ne disposez pas des droits administrateurs sur le poste de travail, il est possible de l'installer comme une librairie utilisateur :
python setup.py install --user
Une fois correctement installée, l'import de la librairie se fait très simplement :
#!/usr/bin/python import orange
Chargement des données
Orange propose différentes facilités pour charger un jeu de données, notamment un format CSV (les colonnes sont en fait séparées par des tabulations) amélioré qui permet de décrire le nom des colonnes, leur type, ainsi que la colonne correspondant à la classe :
- la première ligne contient les noms des colonnes
- la deuxième contient les types des colonnes : discrete, continuous, string, ignore
- la troisième peut contenir le mot class dans la colonne correspondant à la classe
- les lignes suivantes correspondent aux données
Inspection des données
Avant de charger le jeu de données dans votre script python, adaptez le fichier de données en conséquence puis :
# LOAD DATASET data = orange.ExampleTable("Data_Mining_heart.orange.tab")
Avant toute utilisation du jeu de données pour faire de la fouille ou autre technique d'apprentissage, il est bon d'étudier les données dont on dispose.
Inspection des types des données
# report on number of classes and attributes print "Classes:", len(data.domain.classVar.values) print "Attributes:", len(data.domain.attributes), ",", # count number of continuous and discrete attributes ncont=0; ndisc=0 for a in data.domain.attributes: if a.varType == orange.VarTypes.Discrete: ndisc = ndisc + 1 else: ncont = ncont + 1 print ncont, "continuous,", ndisc, "discrete"
Distribution des données
# obtain class distribution c = [0] * len(data.domain.classVar.values) for e in data: c[int(e.getclass())] += 1 print "Instances: ", len(data), "total", for i in range(len(data.domain.classVar.values)): print ",", c[i], "with class", data.domain.classVar.values[i], print print dist = orange.DomainDistributions(data) print "Average values and mean square errors:" for i in range(len(data.domain.attributes)): if data.domain.attributes[i].varType == orange.VarTypes.Continuous: print "%s, mean=%5.2f +- %5.2f" % \ (data.domain.attributes[i].name, dist[i].average(), dist[i].error()) print "\nFrequencies for values of discrete attributes:" for i in range(len(data.domain.attributes)): a = data.domain.attributes[i] if a.varType == orange.VarTypes.Discrete: print "%s:" % a.name for j in range(len(a.values)): print " %s: %d" % (a.values[j], int(dist[i][j]))
Valeurs manquantes
print "\nNumber of items where attribute is not defined:" for i in range(len(data.domain.attributes)): a = data.domain.attributes[i] print " %2d %s" % (dist[i].unknowns, a.name) # missing values manually in % natt = len(data.domain.attributes) missing = [0.] * natt for i in data: for j in range(natt): if i[j].isSpecial(): missing[j] += 1 missing = map(lambda x, l=len(data):x/l*100., missing) print "Missing values per attribute:" atts = data.domain.attributes for i in range(natt): print " %5.1f%s %s" % (missing[i], '%', atts[i].name)
Remarque: L'inspection des données peut-être réalisée avec n'importe quelle suite logicielle ou langage de programmation. Par exemple, il aurait été judicieux d'utiliser R pour ce travail, et notamment afficher différents graphiques tels que des histogrammes, boites à moustache, courbes de densité, graphes d'éparpillement pour chaque paire de variables continues, ... mais ce n'est pas l'objet de la séance d'aujourd'hui. Il s'agissait ici plutôt de se familiariser avec les structures de données de la librairie Orange.
Classification
# BUILD CLASSIFIER classifier = orange.BayesLearner(data) # OUTPUT MODEL (ONLY CLASS PROBABILITIES WHEN continuous VALUES) import orngBayes model = orngBayes.BayesLearner(data) orngBayes.printModel(model) # BUILD TEST SAMPLE test = orange.Example(data.domain, [61, 'M', 4, 138, 166, 'FALSE', 2, 125, 'TRUE', 3.6, 2, 1, 'normal', 'TRUE']) print "Test object ",test c = classifier(test) print "original", test.getclass(), "classified as", c # same with probabilities p = classifier(test, orange.GetProbabilities) for i in range(len(data.domain.classVar.values)): print "%s : %5.3f" % (data.domain.classVar.values[i], p[i])
Evaluation
Orange permet également d'effectuer des validations croisées. Nous allons ainsi comparer les performances de différentes méthodes.
# Validation with various classifiers bayes = orngBayes.BayesLearner() import orngTree tree = orngTree.TreeLearner(mForPruning=2) knn = orange.kNNLearner(k=5) bayes.name = "bayes" tree.name = "tree" knn.name="knn" learners = [bayes, tree, knn] import orngTest # 10 fold cross validation print "Performing 10-fold X validation..." cv10 = orngTest.crossValidation(learners, data, folds=10) # LOOCV print "Performing LOOCV..." loocv = orngTest.leaveOneOut(learners, data) # results import orngStat print "Learner 10-CV LOOCV" for i in range(len(learners)): print "%-8s %5.3f %5.3f" % (learners[i].name, orngStat.CA(cv10)[i], orngStat.CA(loocv)[i])
Jeu de données : Media:Data_Mining_heart.txt Media:Data_Mining_heart.orange.txt