Premiers pas avec la bibliothèque NLTK de Python – Real Python

By | janvier 13, 2021

Python pas cher

Une fois que vous aurez compris les bases de Python, vous familiariser avec ses packages les plus populaires augmentera non seulement votre maîtrise du langage, mais augmentera également rapidement votre polyvalence. Dans ce didacticiel, vous découvrirez les incroyables fonctionnalités du Natural Language Toolkit (NLTK) pour le traitement et l'analyse de texte, des fonctions de base à l'analyse des sentiments grâce à l'apprentissage automatique!

Analyse des sentiments peut vous aider à déterminer le rapport entre les engagements positifs et négatifs sur un sujet spécifique. Vous pouvez analyser des corps de texte, tels que des commentaires, des tweets et des critiques de produits, pour obtenir des informations de votre public. Dans ce didacticiel, vous découvrirez les fonctionnalités importantes de NLTK pour le traitement des données textuelles et les différentes approches que vous pouvez utiliser pour effectuer une analyse des sentiments sur vos données.

À la fin de ce didacticiel, vous serez prêt à:

  • Divisé et filtre données textuelles en préparation pour l'analyse
  • Analyser fréquence des mots
  • Trouver concordance et collocations en utilisant différentes méthodes
  • Effectuer rapidement analyse des sentiments avec le classificateur intégré de NLTK
  • Définir les fonctionnalités pour classification personnalisée
  • Utiliser et comparer classificateurs pour l'analyse des sentiments avec NLTK

Premiers pas avec NLTK

La bibliothèque NLTK contient divers utilitaires qui vous permettent de manipuler et d'analyser efficacement les données linguistiques. Parmi ses fonctionnalités avancées figurent classificateurs de texte que vous pouvez utiliser pour de nombreux types de classification, y compris l'analyse des sentiments.

Analyse des sentiments est la pratique consistant à utiliser des algorithmes pour classer divers échantillons de texte apparenté en catégories globales positives et négatives. Avec NLTK, vous pouvez utiliser ces algorithmes via de puissantes opérations d'apprentissage automatique intégrées pour obtenir des informations à partir de données linguistiques.

Installation et importation

Vous allez commencer par installer certains prérequis, notamment NLTK lui-même ainsi que les ressources spécifiques dont vous aurez besoin tout au long de ce didacticiel.

Première utilisation pépin pour installer NLTK:

$ python3 -m pip installer nltk

Bien que cela installera le module NLTK, vous devrez toujours obtenir quelques ressources supplémentaires. Certains d'entre eux sont des échantillons de texte et d'autres sont des modèles de données requis par certaines fonctions NLTK.

Pour obtenir les ressources dont vous aurez besoin, utilisez nltk.download ():

importer nltk

nltk.Télécharger()

NLTK affichera un gestionnaire de téléchargement montrant toutes les ressources disponibles et installées. Voici ceux que vous devrez télécharger pour ce didacticiel:

  • noms: Une liste de noms anglais courants compilée par Mark Kantrowitz
  • mots vides: Une liste de mots très courants, comme des articles, des pronoms, des prépositions et des conjonctions
  • state_union: Un échantillon des discours sur l'état de l'Union transcrits par différents présidents américains, compilé par Kathleen Ahrens
  • twitter_samples: Une liste d'expressions de médias sociaux publiées sur Twitter
  • critiques de films: Deux mille critiques de films classées par Bo Pang et Lillian Lee
  • average_perceptron_tagger: Un modèle de données que NLTK utilise pour catégoriser les mots dans leur partie du discours
  • vader_lexicon: Une liste de mots et de jargon auxquels NLTK fait référence lors de l'analyse des sentiments, créée par C.J. Hutto et Eric Gilbert
  • punkt: Un modèle de données créé par Jan Strunk que NLTK utilise pour diviser les textes complets en listes de mots

Un moyen rapide de télécharger des ressources spécifiques directement à partir de la console consiste à transmettre une liste à nltk.download ():

>>>

>>> importer nltk

>>> nltk.Télécharger([[[[
...     "noms",
...     "mots vides",
...     "state_union",
...     "twitter_samples",
...     "critiques de films",
...     "average_perceptron_tagger",
...     "vader_lexicon",
...     "punkt",
... ])
[nltk_data]    Téléchargement des noms de paquet dans / home / user / nltk_data ...
[nltk_data]            Décompression de corpus / names.zip.
[nltk_data]    Téléchargement des mots vides du paquet dans / home / user / nltk_data ...
[nltk_data]            Décompression corpora / stopwords.zip.
[nltk_data]    Téléchargement du package state_union vers
[nltk_data]                    / home / utilisateur / nltk_data ...
[nltk_data]            Décompression de corpus / state_union.zip.
[nltk_data]    Téléchargement du package twitter_samples sur
[nltk_data]                    / home / utilisateur / nltk_data ...
[nltk_data]            Décompression de corpus / twitter_samples.zip.
[nltk_data]    Téléchargement du package movie_reviews sur
[nltk_data]                    / home / utilisateur / nltk_data ...
[nltk_data]            Décompressez corpora / movie_reviews.zip.
[nltk_data]    Téléchargement du package averaged_perceptron_tagger vers
[nltk_data]                    / home / utilisateur / nltk_data ...
[nltk_data]            Décompression des taggers / averaged_perceptron_tagger.zip.
[nltk_data]    Téléchargement du package vader_lexicon sur
[nltk_data]                    / home / utilisateur / nltk_data ...
[nltk_data]    Téléchargement du paquet punkt dans / home / user / nltk_data ...
[nltk_data]            Décompression des jetons / punkt.zip.
Vrai

Cela indiquera à NLTK de rechercher et de télécharger chaque ressource en fonction de son identifiant.

Si NLTK nécessite des ressources supplémentaires que vous n'avez pas installées, vous verrez un message utile LookupError avec des détails et des instructions pour télécharger la ressource:

>>>

>>> importer nltk

>>> w = nltk.corpus.Shakespeare.mots()
...
LookupError:
************************************************** ********************
        Ressource shakespeare introuvable.
        Veuillez utiliser le téléchargeur NLTK pour obtenir la ressource:

        >>> importer nltk
        >>> nltk.download ('shakespeare')
...

le LookupError spécifie quelle ressource est nécessaire pour l'opération demandée ainsi que des instructions pour la télécharger à l'aide de son identifiant.

Compilation des données

NLTK fournit un certain nombre de fonctions que vous pouvez appeler avec peu ou pas d'arguments qui vous aideront à analyser le texte de manière significative avant même de toucher ses capacités d'apprentissage automatique. De nombreux utilitaires de NLTK sont utiles pour préparer vos données pour une analyse plus avancée.

Bientôt, vous en apprendrez davantage sur les distributions de fréquences, la concordance et les colocations. Mais d'abord, vous avez besoin de quelques données.

Commencez par charger le corpus sur l'état de l'Union que vous avez téléchargé précédemment:

mots = [[[[w pour w dans nltk.corpus.state_union.mots() si w.isalpha()]

Notez que vous créez une liste de mots individuels avec le corpus .mots() méthode, mais vous utilisez str.isalpha () pour n'inclure que les mots composés de lettres. Sinon, votre liste de mots peut se retrouver avec des «mots» qui ne sont que des signes de ponctuation.

Jetez un œil à votre liste. Vous remarquerez de nombreux petits mots tels que «de», «a», «le», etc. Ces mots communs sont appelés mots d'arrêt, et ils peuvent avoir un effet négatif sur votre analyse car ils apparaissent si souvent dans le texte. Heureusement, il existe un moyen pratique de les filtrer.

NLTK fournit un petit corpus de mots vides que vous pouvez charger dans une liste:

mots vides = nltk.corpus.mots vides.mots("Anglais")

Assurez-vous de spécifier Anglais comme langue souhaitée puisque ce corpus contient des mots vides dans différentes langues.

Vous pouvez maintenant supprimer les mots vides de votre liste de mots d'origine:

mots = [[[[w pour w dans mots si w.inférieur() ne pas dans mots vides]

Puisque tous les mots du mots vides liste sont en minuscules, et ceux de la liste d'origine peuvent ne pas l'être, vous utilisez str.lower () pour tenir compte de tout écart. Sinon, vous risquez de vous retrouver avec des mots vides mixtes ou en majuscules dans votre liste.

Bien que vous utilisiez des corpus fournis par NLTK pour ce didacticiel, il est possible de créer vos propres corpus de texte à partir de n'importe quelle source. Construire un corpus peut être aussi simple que de charger du texte brut ou aussi complexe que d'étiqueter et de catégoriser chaque phrase. Reportez-vous à la documentation de NLTK pour plus d’informations sur la façon de travailler avec les lecteurs de corpus.

Pour une analyse rapide, créer un corpus peut être excessif. Si vous n'avez besoin que d'une liste de mots, il existe des moyens plus simples d'atteindre cet objectif. Au-delà des propres méthodes de manipulation de chaînes de Python, NLTK fournit nltk.word_tokenize (), une fonction qui divise le texte brut en mots individuels. Tandis que tokenisation est en soi un sujet plus important (et probablement l’une des étapes que vous suivrez lors de la création d’un corpus personnalisé), ce tokenizer fournit très bien des listes de mots simples.

Pour l'utiliser, appelez word_tokenize () avec le texte brut que vous souhaitez fractionner:

>>>

>>> de impression importer impression

>>> texte = "" "
... Pour une analyse rapide, créer un corpus peut être excessif.
... Si vous n'avez besoin que d'une liste de mots,
... il existe des moyens plus simples d'atteindre cet objectif. "" "
>>> impression(nltk.word_tokenize(texte), largeur=79, compact=Vrai)
['Pour''un''quick''analyse''''créer''un''corpus''pourrait''['Pour''un''quick''analyse''''créer''un''corpus''pourrait''['For''some''quick''analysis''''creating''a''corpus''could'['For''some''quick''analysis''''creating''a''corpus''could'
    'be', 'overkill', '.', 'If', 'all', 'you', 'need', 'is', 'a', 'word', 'list',
    ',', 'là', 'sont', 'plus simples', 'moyens', 'à', 'atteindre', 'cela', 'objectif', '.']

Vous avez maintenant une liste de mots exploitable! N'oubliez pas que la ponctuation sera comptée comme des mots individuels, alors utilisez str.isalpha () pour les filtrer plus tard.

Création de distributions de fréquences

Vous êtes maintenant prêt pour fréquence des distributions. Une distribution de fréquence est essentiellement un tableau qui vous indique combien de fois chaque mot apparaît dans un texte donné. En NLTK, les distributions de fréquences sont un type d'objet spécifique implémenté en tant que classe distincte appelée FreqDist. Cette classe fournit des opérations utiles pour l'analyse de la fréquence des mots.

Pour créer une distribution de fréquence avec NLTK, construisez le nltk.FreqDist classe avec une liste de mots:

mots: liste[[[[str] = nltk.word_tokenize(texte)
fd = nltk.FreqDist(mots)

Cela créera un objet de distribution de fréquence similaire à un dictionnaire Python mais avec des fonctionnalités supplémentaires.

Après avoir construit l'objet, vous pouvez utiliser des méthodes telles que .Le plus commun() et .tabuler() pour commencer à visualiser les informations:

>>>

>>> fd.Le plus commun(3)
[('must', 1568), ('people', 1291), ('world', 1128)]
>>> fd.tabuler(3)
        doit les gens du monde
        1568 1291 1128

Ces méthodes vous permettent de déterminer rapidement les mots fréquemment utilisés dans un échantillon. Avec .Le plus commun(), vous obtenez une liste de tuples contenant chaque mot et combien de fois il apparaît dans votre texte. Vous pouvez obtenir les mêmes informations dans un format plus lisible avec .tabuler().

En plus de ces deux méthodes, vous pouvez utiliser des distributions de fréquences pour interroger des mots particuliers. Vous pouvez également les utiliser comme itérateurs pour effectuer une analyse personnalisée des propriétés des mots.

Par exemple, pour découvrir les différences de casse, vous pouvez rechercher différentes variantes du même mot:

>>>

>>> fd[[[["Amérique"]
1076
>>> fd[[[["Amérique"]  # Notez que cela n'entraîne pas une KeyError
0
>>> fd[[[["AMÉRIQUE"]
3

Ces valeurs de retour indiquent le nombre de fois où chaque mot se produit exactement comme indiqué.

Étant donné que les objets de distribution de fréquence sont itérables, vous pouvez les utiliser dans les compréhensions de liste pour créer des sous-ensembles de la distribution initiale. Vous pouvez concentrer ces sous-ensembles sur des propriétés utiles pour votre propre analyse.

Essayez de créer une nouvelle distribution de fréquences basée sur la distribution initiale mais qui normalise tous les mots en minuscules:

lower_fd = nltk.FreqDist([[[[w.inférieur() pour w dans fd])

Vous disposez désormais d'une représentation plus précise de l'utilisation des mots, quelle que soit la casse.

Pensez aux possibilités: vous pouvez créer des distributions de fréquences de mots commençant par une lettre particulière, ou d'une longueur particulière, ou contenant certaines lettres. La limite, c'est votre imagination!

Extraction de la concordance et des collocations

Dans le contexte de la PNL, un concordance est une collection d'emplacements de mots avec leur contexte. Vous pouvez utiliser des concordances pour trouver:

  1. Combien de fois un mot apparaît
  2. Où chaque occurrence apparaît
  3. Quels mots entourent chaque occurrence

Dans NLTK, vous pouvez le faire en appelant .concordance(). Pour l'utiliser, vous avez besoin d'une instance du nltk.Text class, qui peut également être construite avec une liste de mots.

Avant d'invoquer .concordance(), construisez une nouvelle liste de mots à partir du texte du corpus original afin que tout le contexte, même les mots vides, y soit:

>>>

>>> texte = nltk.Texte(nltk.corpus.state_union.mots())
>>> texte.concordance("Amérique", lignes=5)
Affichage de 5 sur 1079 résultats:
    voudrait que nous fassions. C'est ce que fera l'Amérique. Tant de sang a déjà
oui, le monde entier se tourne vers l'Amérique pour un leadership éclairé vers la paix
sans l'ombre d'un doute, que l'Amérique continuera le combat pour la liberté
    pour s'assurer de la victoire complète, l'Amérique ne deviendra jamais partie à aucun pl
seulement en droit et en justice. Ici en Amérique, nous avons travaillé longtemps et dur pour

Notez que .concordance() ignore déjà la casse, ce qui vous permet de voir le contexte de toutes les variantes de casse d'un mot par ordre d'apparition. Notez également que cette fonction ne vous montre pas l'emplacement de chaque mot dans le texte.

De plus, depuis .concordance() n'imprime que des informations sur la console, ce n'est pas idéal pour la manipulation de données. Pour obtenir une liste utilisable qui vous donnera également des informations sur l'emplacement de chaque occurrence, utilisez .concordance_list ():

>>>

>>> concordance_list = texte.concordance_list("Amérique", lignes=2)
>>> pour entrée dans concordance_list:
...     impression(entrée.ligne)
...
    voudrait que nous fassions. C'est ce que fera l'Amérique. Tant de sang a déjà
oui, le monde entier se tourne vers l'Amérique pour un leadership éclairé vers la paix

.concordance_list () vous donne une liste de ConcordanceLine objets, qui contiennent des informations sur l'emplacement de chaque mot ainsi que quelques propriétés supplémentaires à explorer. La liste est également triée par ordre d'apparition.

le nltk.Text la classe elle-même a quelques autres fonctionnalités intéressantes. L'un d'eux est .vocab (), ce qui vaut la peine d'être mentionné car il crée une distribution de fréquence pour un texte donné.

Revisiter nltk.word_tokenize (), découvrez à quelle vitesse vous pouvez créer une nltk.Text instance et une distribution de fréquence associée:

>>>

>>> mots: liste[[[[str] = nltk.word_tokenize(
...     "" "Beau est mieux que laid.
...                 L'explicite vaut mieux que l'implicite.
...                 Le simple vaut mieux que le complexe. "" "
... )
>>> texte = nltk.Texte(mots)
>>> fd = texte.vocabulaire()  # Équivalent à fd = nltk.FreqDist (mots)
>>> fd.tabuler(3)
                est mieux que
                    3 3 3

.vocab () est essentiellement un raccourci pour créer une distribution de fréquence à partir d'une instance de nltk.Text. De cette façon, vous n'avez pas besoin de passer un appel séparé pour instancier un nouveau nltk.FreqDist objet.

Une autre caractéristique puissante de NLTK est sa capacité à trouver rapidement collocations avec des appels de fonction simples. Les collocations sont des séries de mots qui apparaissent fréquemment ensemble dans un texte donné. Dans le corpus sur l’état de l’Union, par exemple, vous vous attendez à trouver les mots Uni et États apparaissant très souvent côte à côte. Ces deux mots apparaissant ensemble sont une collocation.

Les collocations peuvent être constituées de deux mots ou plus. NLTK fournit des classes pour gérer plusieurs types de collocations:

  • Bigrammes: Combinaisons fréquentes de deux mots
  • Trigrammes: Combinaisons fréquentes de trois mots
  • Quadgrammes: Combinaisons fréquentes de quatre mots

NLTK fournit des classes spécifiques pour vous permettre de trouver des collocations dans votre texte. Suivant le modèle que vous avez vu jusqu'à présent, ces classes sont également construites à partir de listes de mots:

mots = [[[[w pour w dans nltk.corpus.state_union.mots() si w.isalpha()]
chercheur = nltk.collocations.TrigramCollocationFinder.from_words(mots)

le TrigramCollocationFinder instance recherchera spécifiquement les trigrammes. Comme vous l'avez peut-être deviné, NLTK a également le BigramCollocationFinder et QuadgramCollocationFinder classes pour les bigrammes et les quadgrammes, respectivement. Toutes ces classes ont un certain nombre d'utilitaires pour vous donner des informations sur toutes les colocations identifiées.

L'un de leurs outils les plus utiles est le ngram_fd propriété. Cette propriété contient une distribution de fréquence créée pour chaque collocation plutôt que pour des mots individuels.

En utilisant ngram_fd, vous pouvez trouver les collocations les plus courantes dans le texte fourni:

>>>

>>> chercheur.ngram_fd.Le plus commun(2)
[(('the', 'United', 'States'), 294), (('the', 'American', 'people'), 185)]
>>> chercheur.ngram_fd.tabuler(2)
        ('le', 'United', 'States') ('the', 'American', 'people')
                                                                                                        294 185

Vous n'avez même pas besoin de créer la distribution de fréquences, car il s'agit déjà d'une propriété de l'instance de recherche de collocation.

Maintenant que vous avez découvert certains des outils les plus utiles de NLTK, il est temps de vous lancer dans l'analyse des sentiments!

Utilisation de l’analyseur de sentiments pré-formé de NLTK

NLTK dispose déjà d'un analyseur de sentiments pré-entraîné intégré appelé VADER (Valence UNEarticles ictionary et sEntiment Reasoner).

Étant donné que VADER est pré-entraîné, vous pouvez obtenir des résultats plus rapidement qu'avec de nombreux autres analyseurs. Cependant, VADER est le mieux adapté au langage utilisé dans les médias sociaux, comme les phrases courtes avec un peu d'argot et des abréviations. Il est moins précis de noter des phrases plus longues et structurées, mais c'est souvent un bon point de départ.

Pour utiliser VADER, créez d'abord une instance de nltk.sentiment.SentimentIntensityAnalyzer, puis utilisez .polarity_scores () sur une chaîne brute:

>>>

>>> de nltk.sentiment importer SentimentIntensityAnalyzer
>>> sia = SentimentIntensityAnalyzer()
>>> sia.polarity_scores("Wow, NLTK est vraiment puissant!")
'neg': 0,0, 'neu': 0,295, 'pos': 0,705, 'composé': 0.8012

Vous obtiendrez un dictionnaire des différentes partitions. Les scores négatifs, neutres et positifs sont liés: ils totalisent tous 1 et ne peuvent pas être négatifs. Le score composé est calculé différemment. Il ne s’agit pas seulement d’une moyenne et elle peut aller de -1 à 1.

Vous allez maintenant le tester par rapport à des données réelles en utilisant deux corpus différents. Commencez par charger le twitter_samples corpus dans une liste de chaînes, ce qui en fait un remplacement pour rendre les URL inactives pour éviter les clics accidentels:

tweets = [[[[t.remplacer(": //", "//") pour t dans nltk.corpus.twitter_samples.cordes()]

Notez que vous utilisez une méthode de corpus différente, .strings (), au lieu de .mots(). Cela vous donne une liste de tweets bruts sous forme de chaînes.

Différents corpus ont des fonctionnalités différentes, vous devrez donc peut-être utiliser Python Aidez-moi(), un péché aide (nltk.corpus.tweet_samples), ou consultez la documentation de NLTK pour savoir comment utiliser un corpus donné.

Maintenant, utilisez le .polarity_scores () fonction de votre SentimentIntensityAnalyzer instance pour classer les tweets:

de Aléatoire importer mélanger

def est_positif(tweeter: str) -> booléen:
    "" "Vrai si le tweet a un sentiment composé positif, Faux dans le cas contraire." ""
    revenir sia.polarity_scores(tweeter)[[[["composé"] > 0

mélanger(tweets)
pour tweeter dans tweets[:[:[:[:dix]:
    impression(">", est_positif(tweeter), tweeter)

Dans ce cas, is_positive () utilise uniquement la positivité du score composé pour effectuer l'appel. Vous pouvez choisir n'importe quelle combinaison de scores VADER pour adapter la classification à vos besoins.

Jetez maintenant un œil au deuxième corpus, critiques de films. Comme son nom l'indique, il s'agit d'une collection de critiques de films. La particularité de ce corpus est qu’il a déjà été classé. Par conséquent, vous pouvez l'utiliser pour juger de la précision des algorithmes que vous choisissez lors de l'évaluation de textes similaires.

Gardez à l'esprit que VADER est probablement meilleur pour évaluer les tweets que pour évaluer les critiques de longs films. Pour obtenir de meilleurs résultats, vous allez configurer VADER pour qu'il évalue des phrases individuelles dans la révision plutôt que le texte entier.

Étant donné que VADER a besoin de chaînes brutes pour sa notation, vous ne pouvez pas utiliser .mots() comme vous l'avez fait plus tôt. À la place, faites une liste des ID de fichier utilisés par le corpus, que vous pourrez utiliser plus tard pour référencer des avis individuels:

positive_review_ids = nltk.corpus.critiques de films.fileids(catégories=[[[["pos"])
negatif_review_ids = nltk.corpus.critiques de films.fileids(catégories=[[[["nég"])
all_review_ids = positive_review_ids + negatif_review_ids

.fileids () existe dans la plupart des corpus, sinon dans tous. Dans le cas de critiques de films, chaque dossier correspond à une seule revue. Notez également que vous pouvez filtrer la liste des ID de fichier en spécifiant des catégories. Cette catégorisation est une fonctionnalité propre à ce corpus et à d'autres du même type.

Ensuite, redéfinissez is_positive () pour travailler sur une revue entière. Vous devrez obtenir cet avis spécifique à l'aide de son ID de fichier, puis le diviser en phrases avant de procéder à la notation:

de statistiques importer signifier

def est_positif(review_id: str) -> booléen:
    "" "Vrai si la moyenne de tous les scores composés de phrases est positive." ""
    texte = nltk.corpus.critiques de films.brut(review_id)
    scores = [[[[
        sia.polarity_scores(phrase)[[[["composé"]
        pour phrase dans nltk.sent_tokenize(texte)
    ]
    revenir signifier(scores) > 0

.brut() est une autre méthode qui existe dans la plupart des corpus. En spécifiant un ID de fichier ou une liste d'ID de fichier, vous pouvez obtenir des données spécifiques du corpus. Ici, vous obtenez un seul avis, puis utilisez nltk.sent_tokenize () pour obtenir une liste de phrases de la revue. Finalement, is_positive () calcule le score composé moyen pour toutes les phrases et associe un résultat positif à une critique positive.

Vous pouvez profiter de l'occasion pour évaluer tous les avis et voir à quel point VADER est précis avec cette configuration:

>>>

>>> mélanger(all_review_ids)
>>> correct = 0
>>> pour review_id dans all_review_ids:
...     si est_positif(review_id):
...         si la revue dans positive_review_ids:
...             correct + = 1
...     autre:
...         si la revue dans negatif_review_ids:
...             correct + = 1
...
>>> impression(F"correct / len(all_review_ids):0,2%    correct")
64,00% correct

Après avoir noté tous les avis, vous pouvez voir que seuls 64% ont été correctement classés par VADER en utilisant la logique définie dans is_positive ().

Un taux de précision de 64% n'est pas génial, mais c'est un début. Amusez-vous un peu à peaufiner is_positive () pour voir si vous pouvez augmenter la précision.

Dans la section suivante, vous allez créer un classificateur personnalisé qui vous permet d'utiliser des fonctionnalités supplémentaires pour la classification et éventuellement d'augmenter sa précision à un niveau acceptable.

Personnalisation de l'analyse des sentiments de NLTK

NLTK propose quelques classificateurs intégrés qui conviennent à divers types d'analyses, y compris l'analyse des sentiments. L'astuce consiste à déterminer quelles propriétés de votre ensemble de données sont utiles pour classer chaque élément de données dans les catégories souhaitées.

Dans le monde de l'apprentissage automatique, ces propriétés de données sont appelées fonctionnalités, que vous devez révéler et sélectionner lorsque vous travaillez avec vos données. Bien que ce didacticiel ne vous plongera pas trop dans la sélection des fonctionnalités et l'ingénierie des fonctionnalités, vous serez en mesure de voir leurs effets sur la précision des classificateurs.

Sélection de fonctionnalités utiles

Puisque vous avez appris à utiliser les distributions de fréquences, pourquoi ne pas les utiliser comme point de départ pour une fonctionnalité supplémentaire?

En utilisant les catégories prédéfinies dans le critiques de films corpus, vous pouvez créer des ensembles de mots positifs et négatifs, puis déterminer ceux qui apparaissent le plus fréquemment dans chaque ensemble. Commencez par exclure les mots indésirables et construisez les groupes de catégories initiaux:

    1indésirable = nltk.corpus.mots vides.mots("Anglais")
    2indésirable.étendre([[[[w.inférieur() pour w dans nltk.corpus.noms.mots()])
    3
    4def skip_unwanted(pos_tuple):
    5    mot, marque = pos_tuple
    6    si ne pas mot.isalpha() ou mot dans indésirable:
    sept        revenir Faux
    8    si marque.commence avec("NN"):
    9        revenir Faux
dix    revenir Vrai
11
12mots_ positifs = [[[[mot pour mot, marque dans filtre(
13    skip_unwanted,
14    nltk.pos_tag(nltk.corpus.critiques de films.mots(catégories=[[[["pos"]))
15)]
16mots_ négatifs = [[[[mot pour mot, marque dans filtre(
17    skip_unwanted,
18    nltk.pos_tag(nltk.corpus.critiques de films.mots(catégories=[[[["nég"]))
19)]

Cette fois, vous ajoutez également des mots du noms corpus au indésirable liste à la ligne 2, car les critiques de films sont susceptibles de comporter de nombreux noms d'acteurs, qui ne devraient pas faire partie de vos ensembles de fonctionnalités. Remarquer pos_tag () aux lignes 14 et 18, qui identifie les mots par leur partie du discours.

Il est important d'appeler pos_tag () avant filtrer vos listes de mots afin que NLTK puisse baliser plus précisément tous les mots. skip_unwanted (), défini à la ligne 4, utilise ensuite ces balises pour exclure les noms, conformément au jeu de balises par défaut de NLTK.

Vous êtes maintenant prêt à créer les distributions de fréquences pour votre fonctionnalité personnalisée. Étant donné que de nombreux mots sont présents dans les ensembles positifs et négatifs, commencez par trouver l'ensemble commun afin de pouvoir le supprimer des objets de distribution:

positive_fd = nltk.FreqDist(mots_ positifs)
negatif_fd = nltk.FreqDist(mots_ négatifs)

common_set = ensemble(positive_fd).intersection(negatif_fd)

pour mot dans common_set:
    del positive_fd[[[[mot]
    del negatif_fd[[[[mot]

top_100_positive = mot pour mot, compter dans positive_fd.Le plus commun(100)
top_100_negative = mot pour mot, compter dans negatif_fd.Le plus commun(100)

Une fois qu'il vous reste des mots positifs et négatifs uniques dans chaque objet de distribution de fréquence, vous pouvez enfin créer des ensembles à partir des mots les plus courants dans chaque distribution. La quantité de mots dans chaque ensemble est quelque chose que vous pouvez modifier afin de déterminer son effet sur l'analyse des sentiments.

Voici un exemple de fonctionnalité que vous pouvez extraire de vos données, et il est loin d’être parfait. En regardant de près ces ensembles, vous remarquerez des noms et des mots inhabituels qui ne sont pas nécessairement positifs ou négatifs. En outre, les autres outils NLTK que vous avez appris jusqu'à présent peuvent être utiles pour créer davantage de fonctionnalités. Une possibilité est de tirer parti des collocations qui ont une signification positive, comme le bigramme «thumbs up!»

Voici comment configurer les moteurs de recherche de bigrammes positifs et négatifs:

indésirable = nltk.corpus.mots vides.mots("Anglais")
indésirable.étendre([[[[w.inférieur() pour w dans nltk.corpus.noms.mots()])

positive_bigram_finder = nltk.collocations.BigramCollocationFinder.from_words([[[[
    w pour w dans nltk.corpus.critiques de films.mots(catégories=[[[["pos"])
    si w.isalpha() et w ne pas dans indésirable
])
negatif_bigram_finder = nltk.collocations.BigramCollocationFinder.from_words([[[[
    w pour w dans nltk.corpus.critiques de films.mots(catégories=[[[["nég"])
    si w.isalpha() et w ne pas dans indésirable
])

Le reste dépend de toi! Essayez différentes combinaisons de fonctionnalités, réfléchissez à des moyens d'utiliser les scores VADER négatifs, créez des ratios, polissez les distributions de fréquences. Les possibilités sont infinies!

Formation et utilisation d'un classificateur

Avec votre nouvel ensemble de fonctionnalités prêt à être utilisé, la première condition préalable à la formation d'un classificateur est de définir une fonction qui extraira les fonctionnalités d'une donnée donnée.

Puisque vous recherchez des critiques de films positives, concentrez-vous sur les fonctionnalités qui indiquent la positivité, y compris les scores VADER:

def extract_features(texte):
    fonctionnalités = dict()
    nombre de mots = 0
    scores_composés = liste()
    scores_ positifs = liste()

    pour phrase dans nltk.sent_tokenize(texte):
        pour mot dans nltk.word_tokenize(phrase):
            si mot.inférieur() dans top_100_positive:
                nombre de mots + = 1
        scores_composés.ajouter(sia.polarity_scores(phrase)[[[["composé"])
        scores_ positifs.ajouter(sia.polarity_scores(phrase)[[[["pos"])

    # Ajout de 1 au score composé final pour toujours avoir des nombres positifs
    # puisque certains classificateurs que vous utiliserez plus tard ne fonctionnent pas avec des nombres négatifs.
    fonctionnalités[[[["mean_compound"] = signifier(scores_composés) + 1
    features[[[["mean_positive"] = mean(positive_scores)
    features[[[["wordcount"] = wordcount

    return features

extract_features() should return a dictionary, and it will create three features for each piece of text:

  1. The average compound score
  2. The average positive score
  3. The amount of words in the text that are also part of the top 100 words in all positive reviews

In order to train and evaluate a classifier, you’ll need to build a list of features for each text you’ll analyze:

features = [[[[
    (extract_features(nltk.corpus.movie_reviews.raw(review)), "pos")
    pour review dans nltk.corpus.movie_reviews.fileids(categories=[[[["pos"])
]
features.extend([[[[
    (extract_features(nltk.corpus.movie_reviews.raw(review)), "neg")
    pour review dans nltk.corpus.movie_reviews.fileids(categories=[[[["neg"])
])

Each item in this list of features needs to be a tuple whose first item is the dictionary returned by extract_features and whose second item is the predefined category for the text. After initially training the classifier with some data that has already been categorized (such as the movie_reviews corpus), you’ll be able to classify new data.

Training the classifier involves splitting the feature set so that one portion can be used for training and the other for evaluation, then calling .train():

>>>

>>> # Use 1/4 of the set for training
>>> train_count = len(features) // 4
>>> shuffle(features)
>>> classifier = nltk.NaiveBayesClassifier.train(features[:[:[:[:train_count])
>>> classifier.show_most_informative_features(dix)
Most Informative Features
                                                            wordcount = 2                 pos : neg    =      4.1 : 1.0
                                                            wordcount = 3                 pos : neg    =      3.8 : 1.0
                                                            wordcount = 0                 neg : pos    =      1.6 : 1.0
                                                            wordcount = 1                 pos : neg    =      1.5 : 1.0
>>> nltk.classify.précision(classifier, features[[[[train_count:])
0.668

Since you’re shuffling the feature list, each run will give you different results. In fact, it’s important to shuffle the list to avoid accidentally grouping similarly classified reviews in the first quarter of the list.

Adding a single feature has marginally improved VADER’s initial accuracy, from 64 percent to 67 percent. More features could help, as long as they truly indicate how positive a review is. You can use classifier.show_most_informative_features() to determine which features are most indicative of a specific property.

To classify new data, find a movie review somewhere and pass it to classifier.classify(). You can also use extract_features() to tell you exactly how it was scored:

>>>

>>> new_review = ...
>>> classifier.classify(new_review)
>>> extract_features(new_review)

Was it correct? Based on the scoring output from extract_features(), what can you improve?

Feature engineering is a big part of improving the accuracy of a given algorithm, but it’s not the whole story. Another strategy is to use and compare different classifiers.

Comparing Additional Classifiers

NLTK provides a class that can use most classifiers from the popular machine learning framework scikit-learn.

Many of the classifiers that scikit-learn provides can be instantiated quickly since they have defaults that often work well. In this section, you’ll learn how to integrate them within NLTK to classify linguistic data.

Installing and Importing scikit-learn

Like NLTK, scikit-learn is a third-party Python library, so you’ll have to install it with pip:

$ python3 -m pip install scikit-learn

After you’ve installed scikit-learn, you’ll be able to use its classifiers directly within NLTK.

The following classifiers are a subset of all classifiers available to you. These will work within NLTK for sentiment analysis:

de sklearn.naive_bayes import (
    BernoulliNB,
    ComplementNB,
    MultinomialNB,
)
de sklearn.neighbors import KNeighborsClassifier
de sklearn.tree import DecisionTreeClassifier
de sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier
de sklearn.linear_model import LogisticRegression
de sklearn.neural_network import MLPClassifier
de sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis

With these classifiers imported, you’ll first have to instantiate each one. Thankfully, all of these have pretty good defaults and don’t require much tweaking.

To aid in accuracy evaluation, it’s helpful to have a mapping of classifier names and their instances:

classifiers = 
    "BernoulliNB": BernoulliNB(),
    "ComplementNB": ComplementNB(),
    "MultinomialNB": MultinomialNB(),
    "KNeighborsClassifier": KNeighborsClassifier(),
    "DecisionTreeClassifier": DecisionTreeClassifier(),
    "RandomForestClassifier": RandomForestClassifier(),
    "LogisticRegression": LogisticRegression(),
    "MLPClassifier": MLPClassifier(max_iter=1000),
    "AdaBoostClassifier": AdaBoostClassifier(),

Now you can use these instances for training and accuracy evaluation.

Using scikit-learn Classifiers With NLTK

Since NLTK allows you to integrate scikit-learn classifiers directly into its own classifier class, the training and classification processes will use the same methods you’ve already seen, .train() et .classify().

You’ll also be able to leverage the same features list you built earlier by means of extract_features(). To refresh your memory, here’s how you built the features list:

features = [[[[
    (extract_features(nltk.corpus.movie_reviews.raw(review)), "pos")
    pour review dans nltk.corpus.movie_reviews.fileids(categories=[[[["pos"])
]
features.extend([[[[
    (extract_features(nltk.corpus.movie_reviews.raw(review)), "neg")
    pour review dans nltk.corpus.movie_reviews.fileids(categories=[[[["neg"])
])

le features list contains tuples whose first item is a set of features given by extract_features(), and whose second item is the classification label from preclassified data in the movie_reviews corpus.

Since the first half of the list contains only positive reviews, begin by shuffling it, then iterate over all classifiers to train and evaluate each one:

>>>

>>> # Use 1/4 of the set for training
>>> train_count = len(features) // 4
>>> shuffle(features)
>>> pour Nom, sklearn_classifier dans classifiers.items():
...     classifier = nltk.classify.SklearnClassifier(sklearn_classifier)
...     classifier.train(features[:[:[:[:train_count])
...     précision = nltk.classify.précision(classifier, features[[[[train_count:])
...     print(F"précision:.2%    - Nom")
...
67.00% - BernoulliNB
66.80% - ComplementNB
66.33% - MultinomialNB
69.07% - KNeighborsClassifier
62.73% - DecisionTreeClassifier
66.60% - RandomForestClassifier
72.20% - LogisticRegression
73.13% - MLPClassifier
69.40% - AdaBoostClassifier

For each scikit-learn classifier, call nltk.classify.SklearnClassifier to create a usable NLTK classifier that can be trained and evaluated exactly like you’ve seen before with nltk.NaiveBayesClassifier and its other built-in classifiers. le .train() et .accuracy() methods should receive different portions of the same list of features.

Now you’ve reached over 73 percent accuracy before even adding a second feature! While this doesn’t mean that the MLPClassifier will continue to be the best one as you engineer new features, having additional classification algorithms at your disposal is clearly advantageous.

Conclusion

You’re now familiar with the features of NTLK that allow you to process text into objects that you can filter and manipulate, which allows you to analyze text data to gain information about its properties. You can also use different classifiers to perform sentiment analysis on your data and gain insights about how your audience is responding to content.

In this tutorial, you learned how to:

  • Split et filter text data in preparation for analysis
  • Analyze word frequency
  • Trouver concordance et collocations using different methods
  • Perform quick sentiment analysis with NLTK’s built-in VADER
  • Define features for custom classification
  • Use and compare classifiers from scikit-learn for sentiment analysis within NLTK

With these tools, you can start using NLTK in your own projects. For some inspiration, have a look at a sentiment analysis visualizer, or try augmenting the text processing in a Python web application while learning about additional popular packages!

[ad_2]