google traduit http://scikit-learn.org/0.18/tutorial/text_analytics/working_with_text_data.html Table des matières du didacticiel scikit-learn 0.18 / Didacticiel précédent
Le but de ce guide est d'explorer certains des principaux outils scikit-learn
sur une tâche pratique: l'analyse de documents texte (messages de groupes de discussion) sur 20 sujets différents.
Cette section décrit comment:
--Charger le contenu et les catégories du fichier
Pour démarrer ce didacticiel, vous devez d'abord installer scicit-learn et toutes les dépendances requises. Consultez la page Instructions d'installation (http://scikit-learn.org/0.18/install.html#installation-instructions) pour plus d'informations et des instructions spécifiques au système. La source de ce didacticiel se trouve dans le dossier scikit-learn:
scikit-learn/doc/tutorial/text_analytics/
Le dossier du didacticiel doit contenir les dossiers suivants:
-- * .rst file
--Source du document didacticiel écrit en sphinx
--data
--Folder pour stocker l'ensemble de données utilisé dans le didacticiel
--squelettes
- Exemple de script incomplet pour les exercices
--solutions
--Solutions pratiques
Copiez skeltons
dans un nouveau dossier appelé sklearn_tut_workspace
quelque part sur votre disque dur. En conservant le squelette d'origine, cet exercice modifie le fichier copié:
% cp -r skeletons work_directory/sklearn_tut_workspace
Les données sont nécessaires pour l'apprentissage automatique. Allez dans chaque sous-dossier $ STRUCT_HOME / data
et exécutez le script fetch_data.py
à partir de là (après le premier chargement).
Par exemple:
% cd $TUTORIAL_HOME/data/languages
% less fetch_data.py
% python fetch_data.py
L'ensemble de données s'appelle «20 groupes de discussion». Voici la description officielle tirée du site Web (http://people.csail.mit.edu/jrennie/20Newsgroups/):
Un jeu de données de 20 groupes de discussion est une collection d'environ 20 000 documents de groupes de discussion qui sont (presque) uniformément répartis sur 20 groupes de discussion. Autant que nous le sachions, il a été initialement recueilli par Ken Lang pour son article "Newsweeder: Apprendre à filtrer les nouvelles du Net", mais il n'est pas explicitement mentionné dans cette collection. La collection de 20 groupes de discussion est un ensemble de données populaire pour expérimenter des applications de texte dans des techniques d'apprentissage automatique telles que la classification de texte et le clustering de texte.
Ce qui suit utilise le chargeur de jeu de données intégré pour les 20 groupes de discussion de scikit-learn. Vous pouvez également télécharger manuellement l'ensemble de données depuis le site Web et [sklearn.datasets.load_files](http://scikit-learn.org/0.18/modules/generated/sklearn.datasets.load_files.html#sklearn.datasets.load_files] Vous pouvez également utiliser la fonction) pour spécifier le sous-dossier 20news-bydate-train
du dossier d'archive non compressé.
Pour réduire le temps d'exécution de ce premier exemple, créez un ensemble de données partiel en utilisant seulement 4 des 20 catégories disponibles dans l'ensemble de données.
>>> categories = ['alt.atheism', 'soc.religion.christian',
... 'comp.graphics', 'sci.med']
Vous pouvez charger une liste de fichiers correspondant à ces catégories comme suit:
>>> from sklearn.datasets import fetch_20newsgroups
>>> twenty_train = fetch_20newsgroups(subset='train',
... categories=categories, shuffle=True, random_state=42)
L'ensemble de données renvoyé est un "groupe" d'apprentissage scicit. Un simple objet détenteur avec des champs accessibles en tant qu'attribut de la clé dict
ou de ʻobject` de Python pour plus de commodité. Par exemple, target_names contient une liste de noms de catégories demandés.
>>> twenty_train.target_names
['alt.atheism', 'comp.graphics', 'sci.med', 'soc.religion.christian']
Le fichier lui-même est chargé dans la mémoire de l'attribut data. Les noms de fichiers sont également disponibles pour référence:
>>> len(twenty_train.data)
2257
>>> len(twenty_train.filenames)
2257
Maintenant, imprimons la première ligne du fichier chargé:
>>> print("\n".join(twenty_train.data[0].split("\n")[:3]))
From: [email protected] (Michael Collier)
Subject: Converting images to HP LaserJet III?
Nntp-Posting-Host: hampton
>>> print(twenty_train.target_names[twenty_train.target[0]])
comp.graphics
L'algorithme d'apprentissage supervisé nécessite une étiquette de catégorie pour chaque document de l'ensemble d'apprentissage. Dans ce cas, la catégorie est le nom du groupe de discussion et également le nom du dossier contenant les documents individuels.
Pour des raisons de vitesse et d'efficacité d'espace, scikit-learn charge l'attribut target
comme un tableau d'entiers correspondant à l'index du nom de la catégorie dans la liste target_names
. L'ID entier de catégorie pour chaque échantillon est stocké dans l'attribut «target».
>>> twenty_train.target[:10]
array([1, 1, 3, 3, 3, 3, 3, 2, 2, 2])
Vous pouvez obtenir le nom de la catégorie comme suit:
>>> for t in twenty_train.target[:10]:
... print(twenty_train.target_names[t])
...
comp.graphics
comp.graphics
soc.religion.christian
soc.religion.christian
soc.religion.christian
soc.religion.christian
soc.religion.christian
sci.med
sci.med
sci.med
Vous remarquerez que les échantillons sont mélangés au hasard (avec des graines aléatoires fixes). Il est utile de former rapidement le modèle en utilisant uniquement le premier échantillon et d'essayer les résultats de la première idée avant d'entraîner l'ensemble de données complet.
Afin d'effectuer l'apprentissage automatique d'un document texte, il est d'abord nécessaire de convertir le contenu du texte en un vecteur de caractéristiques numériques.
Bag of Words
Le moyen le plus intuitif de le faire est d'utiliser la représentation Bag of Words:
L'expression Sacs de mots signifie que «n_features» est le nombre de mots distincts dans le corpus. Ce nombre dépasse généralement 100 000.
Avec n_samples == 10000
, stocker X
en tant que tableau à virgule flottante de numpy
nécessite 10000 x 100000 x 4 octets = ** 4 Go de RAM **, ce qui est difficile sur les ordinateurs d'aujourd'hui.
Heureusement, la plupart des valeurs de ** X seront 0 **. En effet, le document spécifié utilise des milliers de mots différents. Pour cette raison, le sac de mots est un ** ensemble de données de grande dimension et clairsemé **. Une grande quantité de mémoire peut être économisée en ne stockant que la partie non nulle du vecteur de caractéristiques dans la mémoire.
La matrice scipy.sparse
est exactement la structure de données qui fait cela, et scikit-learn a un support intégré pour ces structures.
Le prétraitement, la création de jetons et le filtrage du texte des mots vides sont inclus dans des composants de niveau supérieur qui peuvent créer un dictionnaire d'entités et convertir des documents en vecteurs d'entités.
>>> from sklearn.feature_extraction.text import CountVectorizer
>>> count_vect = CountVectorizer()
>>> X_train_counts = count_vect.fit_transform(twenty_train.data)
>>> X_train_counts.shape
(2257, 35788)
CountVectorizer est destiné aux mots de N-grammes ou aux caractères consécutifs. Prend en charge le comptage. Une fois installé, le vectoriseur crée un dictionnaire d'indicateurs de caractéristiques:
>>> count_vect.vocabulary_.get(u'algorithm')
4690
Les valeurs d'index des mots du vocabulaire sont liées à la fréquence de l'ensemble du corpus d'apprentissage.
Le comptage de mots est un bon début, mais plus le document est long, plus le nombre moyen est élevé, même si vous parlez du même sujet. Pour éviter ces éventuelles divergences, il suffit de diviser le nombre d'occurrences de chaque mot du document par le nombre total de mots du document. Ces nouvelles fonctionnalités sont appelées «tf» dans les fréquences des termes. Une autre amélioration de tf est de réduire le poids des mots qui apparaissent dans de nombreux documents de corpus. Il est moins utile que les mots qui apparaissent rarement dans le corpus. Cette mise à l'échelle est appelée tf-idf "Fréquence du terme multipliée par la fréquence inverse du document". ** tf ** et ** tf-idf ** peuvent être calculés comme suit:
>> from sklearn.feature_extraction.text import TfidfTransformer
>>> tf_transformer = TfidfTransformer(use_idf=False).fit(X_train_counts)
>>> X_train_tf = tf_transformer.transform(X_train_counts)
>>> X_train_tf.shape
(2257, 35788)
Le code de l'exemple ci-dessus utilise d'abord la méthode fit (...)
pour ajuster l'estimation aux données, puis transforme count-matrix en une représentation tf-idf transform (... ) ʻUtiliser la méthode. En combinant ces deux étapes et en ignorant le traitement redondant, vous pouvez obtenir le même résultat final plus rapidement. Ceci est fait en utilisant la méthode
fit_transform (..)`, comme décrit dans les notes de la section précédente, comme indiqué ci-dessous.
>>> tfidf_transformer = TfidfTransformer()
>>> X_train_tfidf = tfidf_transformer.fit_transform(X_train_counts)
>>> X_train_tfidf.shape
(2257, 35788)
>>> from sklearn.naive_bayes import MultinomialNB
>>> clf = MultinomialNB().fit(X_train_tfidf, twenty_train.target)
>>> docs_new = ['God is love', 'OpenGL on the GPU is fast']
>>> X_new_counts = count_vect.transform(docs_new)
>>> X_new_tfidf = tfidf_transformer.transform(X_new_counts)
>>> predicted = clf.predict(X_new_tfidf)
>>> for doc, category in zip(docs_new, predicted):
... print('%r => %s' % (doc, twenty_train.target_names[category]))
...
'God is love' => soc.religion.christian
'OpenGL on the GPU is fast' => comp.graphics
>>> from sklearn.pipeline import Pipeline
>>> text_clf = Pipeline([('vect', CountVectorizer()),
... ('tfidf', TfidfTransformer()),
... ('clf', MultinomialNB()),
... ])
>>> text_clf = text_clf.fit(twenty_train.data, twenty_train.target)
transform
au lieu de fit_transform
dans le convertisseur. Construire un pipeline Pour faciliter l'utilisation d'une série d'opérations telles que "vectorizer => convertisseur => classifier", scikit-learn fournit une classe Pipeline
qui se comporte comme un classificateur composé. Les noms «vect», «tfidf» et «clf» (abréviation de classificateur) sont arbitraires. Ci-dessous, nous verrons comment l'utiliser dans la section Grid Search. Vous pouvez entraîner votre modèle à l'aide des commandes suivantes: Évaluation des performances de l'ensemble de testL'évaluation de la précision de prédiction d'un modèle est tout aussi simple.
>>> twenty_test = fetch_20newsgroups(subset='test',
... categories=categories, shuffle=True, random_state=42)
>>> docs_test = twenty_test.data
>>> predicted = text_clf.predict(docs_test)
>>> np.mean(predicted == twenty_test.target)
0.834...
Nous avons atteint une précision de 83,4%. Largement reconnu comme l'un des meilleurs algorithmes de classification de texte (bien qu'un peu plus lent que Naive Bayes) Linear Support Vector Machine (SVM) Voyons si cela fonctionne avec #svm). Vous pouvez changer l'apprenant en branchant simplement un objet classificateur différent dans le pipeline:
>>> from sklearn.linear_model import SGDClassifier
>>> text_clf = Pipeline([('vect', CountVectorizer()),
... ('tfidf', TfidfTransformer()),
... ('clf', SGDClassifier(loss='hinge', penalty='l2',
... alpha=1e-3, n_iter=5, random_state=42)),
... ])
>>> _ = text_clf.fit(twenty_train.data, twenty_train.target)
>>> predicted = text_clf.predict(docs_test)
>>> np.mean(predicted == twenty_test.target)
0.912...
scikit-learn fournit également un utilitaire pour une analyse plus détaillée des performances des résultats:
>>> from sklearn import metrics
>>> print(metrics.classification_report(twenty_test.target, predicted,
... target_names=twenty_test.target_names))
...
precision recall f1-score support
alt.atheism 0.95 0.81 0.87 319
comp.graphics 0.88 0.97 0.92 389
sci.med 0.94 0.90 0.92 396
soc.religion.christian 0.90 0.95 0.93 398
avg / total 0.92 0.91 0.91 1502
>>> metrics.confusion_matrix(twenty_test.target, predicted)
array([[258, 11, 15, 35],
[ 4, 379, 3, 3],
[ 5, 33, 355, 3],
[ 5, 10, 4, 379]])
Comme prévu, la matrice du chaos montre que les messages des groupes de presse sur l'athéisme et les chrétiens sont souvent confondus les uns avec les autres plutôt que des infographies.
Des paramètres tels que ʻuse_idfsont déjà apparus dans
TfidfTransformer. Les classificateurs ont également tendance à avoir de nombreux paramètres.
MultinomialNB contient le paramètre de lissage ʻalpha
, et SGDClassifier
a un paramètre de pénalité ʻalphaet un terme de perte et de pénalité qui peut être défini dans la fonction objectif (voir la documentation du module ou se référer à la documentation du module. Consultez ces instructions en utilisant la fonction
help` de Python).
Au lieu d'affiner les paramètres des différents composants de la chaîne, vous pouvez rechercher de manière exhaustive les meilleurs paramètres sur une grille de valeurs possibles. Essayez la présence ou l'absence de idf, le paramètre de pénalité (alpha) 0,01 ou 0,001 pour SVM linéaire et la méthode de fractionnement du vectoriseur, soit mot ou bigramme.
>>> from sklearn.model_selection import GridSearchCV
>>> parameters = {'vect__ngram_range': [(1, 1), (1, 2)],
... 'tfidf__use_idf': (True, False),
... 'clf__alpha': (1e-2, 1e-3),
... }
De toute évidence, une recherche aussi approfondie peut être coûteuse. Si vous avez plusieurs cœurs de processeur, vous pouvez passer le paramètre n_jobs
au chercheur de grille pour lui demander d'essayer une combinaison de huit paramètres en parallèle. Si vous spécifiez une valeur de «-1» pour ce paramètre, le nombre de cœurs installés sera détecté et tous seront utilisés.
>>> gs_clf = GridSearchCV(text_clf, parameters, n_jobs=-1)
L'instance de recherche de grille se comporte comme un modèle d'apprentissage Scikit normal. Effectuez des recherches sur des sous-ensembles plus petits de données d'entraînement pour accélérer les calculs:
>>> gs_clf = gs_clf.fit(twenty_train.data[:400], twenty_train.target[:400])
Le résultat de fitʻing un objet
GridSearchCV est un classificateur que
prédire` peut utiliser.
>>> twenty_train.target_names[gs_clf.predict(['God is love'])[0]]
'soc.religion.christian'
Les attributs «best_score_» et «best_params_» de l'objet stockent le meilleur score moyen et les meilleurs paramètres pour ce score.
>>> gs_clf.best_score_
0.900...
>>> for param_name in sorted(parameters.keys()):
... print("%s: %r" % (param_name, gs_clf.best_params_[param_name]))
...
clf__alpha: 0.001
tfidf__use_idf: True
vect__ngram_range: (1, 1)
Voir gs_clf.cv_results_
pour plus d'informations sur la recherche.
Le paramètre cv_results_
peut être facilement importé dans les pandas en tant que DataFrame
pour une inspection ultérieure.
Pour faire de l'exercice, copiez le contenu du dossier skeletons
dans un nouveau dossier nommé workspace
.
% cp -r skeletons workspace
Vous pouvez ensuite modifier le contenu de l'espace de travail sans perdre les instructions d'exercice d'origine. Ensuite, lancez le shell ipython et exécutez le script de travail en cours.
[1] %run workspace/exercise_XX_script.py arg1 arg2 arg3
Si une exception est déclenchée, utilisez % debug
pour démarrer une session de débogage d'autopsie.
Améliorez votre mise en œuvre et répétez jusqu'à ce que l'exercice soit résolu.
Chaque exercice fournit toutes les instructions d'importation nécessaires pour un fichier squelette, un code standard pour lire les données et un exemple de code pour évaluer la précision prédictive du modèle.
--Utilisez un préprocesseur personnalisé et CharNGramAnalyzer
pour créer un pipeline de classification de texte en utilisant les données d'article de Wikipedia comme ensemble d'entraînement.
ligne de commande ipython:
%run workspace/exercise_01_language_train_model.py data/languages/paragraphs/
--Créez un pipeline de classification de texte pour classer les critiques de films de manière positive ou négative. --Utilisez une recherche de grille pour trouver l'ensemble de paramètres approprié.
ligne de commande ipython:
%run workspace/exercise_02_sentiment.py data/movie_reviews/txt_sentoken/
--Utilisez les résultats de l'exercice précédent et le module cPickle
de la bibliothèque standard pour détecter la langue du texte fourni par stdin et estimer la polarité (positive ou négative) si le texte est écrit en anglais. Décrit l'utilitaire de ligne de commande à utiliser.
Après avoir terminé ce didacticiel, vous trouverez quelques suggestions pour vous aider à comprendre scikit de manière intuitive:
et
token normalization`` S'il vous plaît essayezTable des matières du didacticiel / Tutoriel suivant
© 2010 --2016, développeurs scikit-learn (licence BSD).
Recommended Posts