Prédire les flairs Reddit à l’aide de l’apprentissage automatique et déployer le modèle à l’aide de Heroku – Partie 2
Dans cette partie du cours, je travaillerai sur l’analyse de données, l’analyse de texte et la classification de texte. Bien que ce didacticiel soit spécifique au projet sur lequel j’ai travaillé, ces techniques peuvent être appliquées à tout problème de classification de texte. Il est important de noter qu’il s’agit d’un problème de classification de texte à classes multiples et qu’il existe certaines mises en garde qui sont exclusives à ces types de problèmes. La plupart des didacticiels en ligne traitent de la classification de texte binaire comme les filtres anti-spam. Cependant, vous vous occuperez principalement de problèmes multi-classes dans le monde réel. Par conséquent, ce tutoriel devrait être un bon point de départ.
Comme je l’ai déjà expliqué, il s’agit d’un problème de classification de texte multi-classe supervisé. Nous avons déjà collecté les fonctionnalités et les étiquettes et notre objectif est de construire un modèle qui peut prédire le flair d’un message en fonction des fonctionnalités de ce message que nous collectons. Commençons
Bibliothèques importantes
Ce sont les bibliothèques que nous utiliserons dans ce processus.
Dans le cas où ils ne sont pas installés dans votre système, vous pouvez télécharger ce fichier et exécutez la commande suivante dans votre terminal.
pip install -r requirements.txt
Remarque: – Cela installera tous les packages dans votre répertoire de travail. Si vous souhaitez les installer dans un environnement virtuel, reportez-vous à ce lien.
L’analyse exploratoire des données
Commencez par lire les données du fichier csv dans un DataFrame.
# Reading Data
data = pd.read_csv('data.csv')
Si vous avez obtenu les données du lien GitHub, l’étape suivante est importante pour vous. D’autres peuvent ignorer cela. Une explication peut être trouvée ici.
# Data Shuffling
data.drop(['Unnamed: 0'], inplace=True, axis=1)
data[:] = data.sample(frac=1).values
data.head()
Comme il s’agit d’un problème de classification de texte, nous n’utiliserons que les fonctionnalités contenant du texte pour le modèle d’apprentissage automatique. Il s’agit notamment du titre, du corps, des commentaires et de l’URL (facultatif). Examinons les types de données des colonnes et les valeurs manquantes.
# Display data types and null values
data.info()
Il y a beaucoup de valeurs nulles dans le Body
colonne et certaines valeurs manquantes dans le Comments
section. Nous ne pouvons pas les imputer car ils contiennent du contenu généré par l’utilisateur. Cependant, chaque entrée a un Title
et Flair
nous n’avons donc pas à supprimer de ligne et nous pouvons tous les utiliser pour l’analyse. Il existe de nombreuses classes à prévoir dans cet ensemble de données dans le Flair.
print(len(data[‘Flair’].unique()))
data[‘Flair’].unique()OUTPUT:11
['Sports' 'Politics' '[R]eddiquette' 'Business/Finance' 'Food' 'AMA'
'AskIndia' 'Photography' 'Non-Political' 'Science/Technology'
'Policy/Economy']
Il y a donc 11 classes uniques. Pour chaque nouveau message que nous recevons, nous devons le classer dans l’une de ces 11 classes. J’ai déjà mentionné les caractéristiques importantes que nous utiliserons pour notre analyse. Réduisons la taille de notre trame de données et ne conservons que les fonctionnalités pertinentes.
# List of relevant features
features = [‘Flair’, ‘URL’, ‘Title’, ‘Comments’, ‘Body’]
data = data[features]
data.head()
Maintenant que nous avons des données plus pertinentes, nous devons créer quelques dictionnaires pour une utilisation future[1]. La première étape consiste à générer un ID unique pour chaque style. Ensuite, nous créerons les dictionnaires à partir de ceux-ci. Ces dictionnaires nous permettront de faire référence au flair des identifiants uniques que nous avons générés pour eux et vice versa.
Nous avons créé deux dictionnaires: –
-
category_labels
: Ce dictionnaire a des flairs comme clés et l’ID qui leur est attribué comme valeurs qui seront utilisées comme moyen d’attribuer des étiquettes après la prédiction. -
category_reverse
: C’est l’inverse du dictionnaire précédent et utilise les ID comme clés et les flairs comme valeurs.
L’étape suivante consiste à créer une fonction combinée qui est une combinaison des Title
, Body
et Comments
. Je n’utilise pas d’URL pour l’instant et je vous laisse le soin de l’analyser. Il existe de nombreuses façons créatives de le faire et vous pouvez les mentionner dans les commentaires ci-dessous. Je vais créer une nouvelle fonctionnalité Combine
qui incorporera les fonctionnalités susmentionnées.
Nettoyage de texte
C’est l’un des aspects les plus importants d’un projet de classification de texte car tous les mots ne sont pas également importants et certains mots comme et le et est sont si fréquentes qu’elles seront présentes dans les données de toutes les catégories de style et confondent le classificateur. Il est fortement conseillé de les supprimer. Dans un projet d’analyse des sentiments, nous pourrions conserver les signes de ponctuation car le nombre de points d’exclamation pourrait totalement changer le sens. Cependant, je n’ai pas ressenti le besoin de les garder ici et, par conséquent, je les retirerai à l’étape suivante. le Mots communs que je viens de mentionner sont présents dans la bibliothèque nltk afin que vous n’ayez pas à faire votre propre liste.
# Collect all the english stopwords and display them
STOPWORDS = nltk.corpus.stopwords.words(‘english’)
print(STOPWORDS)
Définissons une fonction de nettoyage. Nous passerons nos fonctionnalités à travers cette fonction pour les nettoyer.
Représentation de texte
Les classificateurs et les algorithmes d’apprentissage ne peuvent pas traiter directement les documents texte dans leur forme d’origine, car la plupart d’entre eux attendent des vecteurs de caractéristiques numériques de taille fixe plutôt que des documents texte bruts de longueur variable. Par conséquent, lors de l’étape de prétraitement, les textes sont convertis en une représentation plus gérable[1]. La vectorisation est une méthode pour convertir des mots en longues listes de nombres, qui pourraient contenir une sorte de structuration complexe, seulement pour être compris par un ordinateur en utilisant une sorte d’apprentissage automatique ou un algorithme d’exploration de données. [2]
Je voudrais donner des crédits à Susan Li pour cette partie de l’article. Le test des unigrammes et des bigrammes les plus corrélés qu’elle a présenté dans son article est une technique très perspicace qui nous permet de découvrir ce que les mots apparaissent le plus dans un type particulier de style et nous donne un aperçu de la méthode de prédiction du modèle. Si un style particulier a beaucoup de mots non liés, nous pourrions envisager d’ajouter plus de données ou de supprimer certaines données.
Maintenant, pour chaque terme qui apparaît dans notre ensemble de données, nous allons calculer une mesure appelée Fréquence du terme, fréquence inverse du document, abrégé en tf-idf. Nous utiliserons sklearn.feature_extraction.text.TfidfVectorizer
calculer un tf-idf
vecteur pour chacun des récits de plaintes des consommateurs:
-
sublinear_df
est réglé surTrue
d’utiliser une forme logarithmique pour la fréquence. -
min_df
est le nombre minimum de documents dans lesquels un mot doit être présent pour être conservé. -
norm
est réglé surl2
, pour garantir que tous nos vecteurs de caractéristiques ont une norme euclidienne de 1. -
ngram_range
est réglé sur(1, 2)
pour indiquer que nous voulons considérer à la fois les unigrammes et les bigrammes. -
stop_words
est réglé sur"english"
pour supprimer tous les pronoms courants ("a"
,"the"
, …) pour réduire le nombre de fonctions bruyantes. [1]
Output
(1650, 3299)
Maintenant, chacun des 1650 récits de plaintes des consommateurs est représenté par 3299 fonctionnalités, représentant le score tf-idf pour différents unigrammes et bigrammes.
On peut utiliser sklearn.feature_selection.chi2
pour trouver les termes les plus corrélés avec chacun des produits:
Vous trouverez la sortie ci-dessous assez intuitive pour chaque style.
Flair 'AMA':
Most correlated unigrams:
. hi
. anything
. ask
. questions
. ama
Most correlated bigrams:
. ask us
. us anything
. hi reddit
. answer questions
. ask anythingFlair 'AskIndia':
Most correlated unigrams:
. advice
. dad
. situation
. afraid
. family
Most correlated bigrams:
. ive seen
. want know
. feel like
. work home
. dont want
Flair 'Business/Finance':
Most correlated unigrams:
. firms
. emi
. hdfc
. mukesh
. bank
Most correlated bigrams:
. credit card
. mukesh ambani
. share market
. reliance jio
. yes bank
Flair 'Food':
Most correlated unigrams:
. restaurant
. chutney
. recipe
. chicken
. food
Most correlated bigrams:
. im trying
. every day
. couldnt find
. dont eat
. indian food
Flair 'Non-Political':
Most correlated unigrams:
. rural
. dads
. found
. bored
. comics
Most correlated bigrams:
. im gonna
. palghar lynching
. amazon prime
. india live
. amid lockdown
Flair 'Photography':
Most correlated unigrams:
. mm
. beach
. nikon
. shot
. oc
Most correlated bigrams:
. stay home
. equipment nikon
. one plus
. da mm
. nikon da
Flair 'Policy/Economy':
Most correlated unigrams:
. gdp
. govt
. investments
. nirmala
. economy
Most correlated bigrams:
. health workers
. https internetfreedomin
. petrol diesel
. indian economy
. raghuram rajan
Flair 'Politics':
Most correlated unigrams:
. sonia
. removed
. modi
. arnab
. muslims
Most correlated bigrams:
. home minister
. arnab goswami
. pm modi
. rahul gandhi
. john oliver
Flair 'Science/Technology':
Most correlated unigrams:
. vpn
. iit
. develop
. zoom
. users
Most correlated bigrams:
. anyone else
. covid virus
. home affairs
. ministry home
. cow urine
Flair 'Sports':
Most correlated unigrams:
. ipl
. football
. sports
. cricket
. cup
Most correlated bigrams:
. india pakistan
. know people
. one time
. times india
. world cup
Flair '[R]eddiquette':
Most correlated unigrams:
. boop
. askaway
. beep
. creator
. bot
Most correlated bigrams:
. bot problem
. bot bot
. askaway creator
. beep boop
. discussion thread
Vous verrez que pour la plupart des flairs, les mots les plus corrélés sont assez explicatifs.
Modélisation des entités et étiquettes d’entrée
Notre prochaine tâche consiste à modéliser les données d’entrée d’une manière compréhensible par les classificateurs. Nous devons convertir les entrées en un vecteur de nombres qui se rapporte à une étiquette numérique. Après avoir obtenu cette représentation vectorielle du texte, nous pouvons former des classificateurs supervisés pour prédire le «flair» pour chaque publication Reddit qu’un utilisateur soumet. Commençons par diviser les données en ensembles de formation et de test. Il y a une raison pour laquelle je ne vectorise pas les données en premier et c’est parce que si vous le faites, votre vectoriseur considérera toutes les données comme l’échantillon et les adaptera en fonction de cela. Cela signifie que votre .fit()
ou .fit_transform()
utilisera l’ensemble des données pour l’ajustement. Lorsque nous diviserons les données plus tard, les données de test seront divisées en fonction des données combinées de formation et de test. Cependant, ce modèle va être déployé et nous n’avons pas le même luxe avec des données invisibles, par conséquent, nous ne pouvons pas le transformer sur la base de données combinées. Cela pourrait réduire la précision du test, mais c’est un meilleur modèle à long terme, à mon avis, car il élimine les biais.
Après toutes les transformations de données ci-dessus, maintenant que nous avons toutes les fonctionnalités et les étiquettes, il est temps de former nos classificateurs. Nous pouvons utiliser un certain nombre de classificateurs différents pour ce problème. J’utiliserai quatre types de modèles différents et en raison de la longueur de l’article ici, je ne discuterai que des résultats de référence qui pourraient servir de bon comparateur. J’écrirai un article séparé sur le BERT de Google et le réglage des hyperparamètres pour les modèles actuels. Les modèles que j’utiliserai sont: –
Chacun de ces classificateurs a ses propres avantages et inconvénients. C’est à vous de déterminer celle qui convient le mieux à vos besoins. Je vais simplement vous guider à travers le processus de mise en œuvre et de pipelining. Voici comment vous pouvez former vos données.
# Create an instance
model = MultinomialNB()# Fit to training data
model.fit(X_train_tfidf, y_train)# Predictions on X_test_tfidf
# Obtain X_test_tfidf in the manner described above
model.predict(X_test_tfidf)
C’est assez basique, non? Vous devez avoir fait cela plusieurs fois auparavant si vous avez déjà formé un simple classificateur. Apprenons alors quelque chose de nouveau.
Pipelining
Il existe de nombreuses pièces mobiles dans un modèle d’apprentissage automatique (ML) qui doivent être liées ensemble pour qu’un modèle ML s’exécute et produise des résultats avec succès. Chaque étape d’un pipeline reçoit des données traitées à partir de son étape précédente; c’est-à-dire que la sortie d’une unité de traitement est fournie comme entrée à l’étape suivante. En génie logiciel, les gens créent des pipelines pour développer des logiciels qui s’exercent du code source au déploiement. De même, en ML, un pipeline est créé pour permettre le flux de données de son format brut vers certaines informations utiles. Les données transitent par le pipeline comme l’eau coule dans un tuyau. La maîtrise du concept de pipeline est un moyen puissant de créer des modèles ML sans erreur, et les pipelines sont un élément crucial d’un système AutoML. Il fournit un mécanisme pour construire un système de pipeline parallèle multi-ML afin de comparer les résultats de plusieurs méthodes ML. [3] Voici à quoi ressemblera notre pipeline.
Commençons par le classificateur multinomial Naive Bayes.
nb_fit = Pipeline([(‘vect’, CountVectorizer()),
(‘tfidf’, TfidfTransformer()),
(‘clf’, MultinomialNB())])
De même, nous pouvons créer des fonctions pour chacun de nos classificateurs pour une approche plus rationalisée.
Faire des prédictions et évaluer les résultats
Faire des fonctions comme celles créées ci-dessus modularise votre code et vous facilite la tâche. Vous pouvez maintenant faire des prédictions et évaluer les résultats de manière pratique.
print(“Evaluate Naive Bayes Classifier”)
nb_classifier(X_train, X_test, y_train, y_test)print(“Evaluate Random Forest Classifier”)
random_forest(X_train, X_test, y_train, y_test)print(“Evaluate Logistic Regression Model”)
log_reg(X_train, X_test, y_train, y_test)print(“Evaluate SVC Model”)
svc(X_train, X_test, y_train, y_test)
Les commandes suivantes impriment les résultats. Les résultats peuvent varier en fonction des données que vous avez utilisées et du prétraitement que vous avez effectué. Ce sont des résultats de base et ont ensuite été improvisés en utilisant un réglage d’hyper-paramètre. Cependant, cet article est assez long sans cela, donc je le couvrirai dans un autre article.
Evaluate Naive Bayes Classifier
Model Accuracy: 0.53951612903225806
Evaluate Random Forest Classifier
Model Accuracy: 0.6074193548387097
Evaluate Logistic Regression Model
Model Accuracy: 0.6645161290322581
Evaluate SVC Model
Model Accuracy: 0.5248387096774194
Nous pouvons voir que le modèle de régression logistique semble fonctionner le mieux. Cependant, cela peut changer rapidement après un réglage hyperparamétrique, donc je vous laisse le soin pour l’instant. Il existe de nombreuses raisons pour lesquelles les performances sont faibles pour l’instant, y compris la qualité des données, et elles constitueraient une bonne discussion dans les commentaires ci-dessous. Dans la partie suivante, je sérialiserai ce modèle pour le déploiement. Nous travaillerons également avec Flask pour déployer nos modèles d’apprentissage automatique. L’application Web fonctionnera de telle manière que l’utilisateur publiera un lien et nous récupérerons la classe prévue. Je publierai le lien ici dès que je le publierai. Vous pouvez trouver tous les articles de cette série ici.