[PYTHON] 100 traitements linguistiques knock-77 (en utilisant scicit-learn): mesure du taux de réponse

Il s'agit du record de la 77ème «Mesure du taux de précision» de Traitement du langage 100 coups 2015. Le contenu de la question knock est la mesure du taux de réponse correct pour les données d'entraînement, mais cette fois, nous osons utiliser les données de test comme dans le temps précédent. Jusqu'à présent, je ne l'ai pas posté sur le blog car c'était fondamentalement la même chose que "Traitement du langage amateur 100 coups". , "Chapitre 8: Machine Learning" a été pris au sérieux et modifié dans une certaine mesure. Je posterai. J'utilise principalement scikit-learn.

Lien de référence

Lien Remarques
077.Mesure du taux de réponse correcte.ipynb Lien GitHub du programme de réponse
100 coups de traitement du langage amateur:77 Je vous suis toujours redevable de 100 coups de traitement linguistique
Introduction à Python avec 100 coups de traitement du langage#77 -Apprentissage automatique, scikit-Mesure du taux de réponse correct avec apprentissage scikit-Résultat Knock en utilisant Learn

environnement

type version Contenu
OS Ubuntu18.04.01 LTS Il fonctionne virtuellement
pyenv 1.2.15 J'utilise pyenv car j'utilise parfois plusieurs environnements Python
Python 3.6.9 python3 sur pyenv.6.J'utilise 9
3.7 ou 3.Il n'y a aucune raison profonde de ne pas utiliser la série 8
Les packages sont gérés à l'aide de venv

Dans l'environnement ci-dessus, j'utilise les packages Python supplémentaires suivants. Installez simplement avec pip ordinaire.

type version
matplotlib 3.1.1
numpy 1.17.4
pandas 0.25.3
scikit-learn 0.21.3

Tâche

Chapitre 8: Machine Learning

Dans ce chapitre, [jeu de données de polarité des phrases] de Movie Review Data publié par Bo Pang et Lillian Lee. v1.0](http://www.cs.cornell.edu/people/pabo/movie-review-data/rt-polaritydata.README.1.0.txt) est utilisé pour rendre la phrase positive ou négative. Travaillez sur la tâche (analyse de polarité) à classer comme (négative).

77. Mesure du taux de réponse correcte

Créez un programme qui reçoit plus de 76 sorties et calcule le taux de réponse correct de la prédiction, le taux de réponse correct pour l'exemple correct, le taux de rappel et le score F1.

Cette fois, j'ai ignoré la partie "Recevoir 76 sorties" et l'ai implémentée pour les données de test. C'est parce que je pensais que les données de test seraient plus utiles que les données d'entraînement comme avant.

Répondre

Programme de réponse [077. Mesure du taux de réponse correct.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/08.%E6%A9%9F%E6%A2%B0%E5%AD%A6% E7% BF% 92 / 077.% E6% AD% A3% E8% A7% A3% E7% 8E% 87% E3% 81% AE% E8% A8% 88% E6% B8% AC.ipynb)

En gros [précédent "076. Labeling.ipynb"](https://github.com/YoheiFukuhara/nlp100/blob/master/08.%E6%A9%9F%E6%A2%B0%E5%AD % A6% E7% BF% 92 / 076.% E3% 83% A9% E3% 83% 99% E3% 83% AB% E4% BB% 98% E3% 81% 91.ipynb) Taux de réponse correcte et indicateurs associés Il s'agit simplement d'ajouter une logique de sortie.

import csv

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.pipeline import Pipeline
from sklearn.base import BaseEstimator, TransformerMixin

#Classe d'utilisation de la vectorisation de mots dans GridSearchCV
class myVectorizer(BaseEstimator, TransformerMixin):
    def __init__(self, method='tfidf', min_df=0.0005, max_df=0.10):
        self.method = method
        self.min_df = min_df
        self.max_df = max_df

    def fit(self, x, y=None):
        if self.method == 'tfidf':
            self.vectorizer = TfidfVectorizer(min_df=self.min_df, max_df=self.max_df)
        else:
            self.vectorizer = CountVectorizer(min_df=self.min_df, max_df=self.max_df)
        self.vectorizer.fit(x)
        return self

    def transform(self, x, y=None):
        return self.vectorizer.transform(x)
		
#Paramètres de GridSearchCV
PARAMETERS = [
    {
        'vectorizer__method':['tfidf', 'count'], 
        'vectorizer__min_df': [0.0003, 0.0004], 
        'vectorizer__max_df': [0.07, 0.10], 
        'classifier__C': [1, 3],    #J'ai aussi essayé 10 mais le SCORE est faible juste parce qu'il est lent
        'classifier__solver': ['newton-cg', 'liblinear']},
    ]

#Lire le fichier
def read_csv_column(col):
    with open('./sentiment_stem.txt') as file:
        reader = csv.reader(file, delimiter='\t')
        header = next(reader)
        return [row[col] for row in reader]    
		
x_all = read_csv_column(1)
y_all = read_csv_column(0)
x_train, x_test, y_train, y_test = train_test_split(x_all, y_all)

def train(x_train, y_train, file):
    pipline = Pipeline([('vectorizer', myVectorizer()), ('classifier', LogisticRegression())])
    
    #clf signifie classification
    clf = GridSearchCV(
            pipline, # 
            PARAMETERS,           #Jeu de paramètres que vous souhaitez optimiser
            cv = 5)               #Nombre de tests croisés
    
    clf.fit(x_train, y_train)
    pd.DataFrame.from_dict(clf.cv_results_).to_csv(file)

    print('Grid Search Best parameters:', clf.best_params_)
    print('Grid Search Best validation score:', clf.best_score_)
    print('Grid Search Best training score:', clf.best_estimator_.score(x_train, y_train))    
    
    #Sortie de poids d'élément
    output_coef(clf.best_estimator_)
    
    return clf.best_estimator_

#Sortie de poids d'élément
def output_coef(estimator):
    vec = estimator.named_steps['vectorizer']
    clf = estimator.named_steps['classifier']

    coef_df = pd.DataFrame([clf.coef_[0]]).T.rename(columns={0: 'Coefficients'})
    coef_df.index = vec.vectorizer.get_feature_names()
    coef_sort = coef_df.sort_values('Coefficients')
    coef_sort[:10].plot.barh()
    coef_sort.tail(10).plot.barh()

def validate(estimator, x_test, y_test):
    
    for i, (x, y) in enumerate(zip(x_test, y_test)):
        y_pred = estimator.predict_proba([x])
        if y == np.argmax(y_pred).astype( str ):
            if y == '1':
                result = 'TP:La bonne réponse est positive et la prédiction est positive'
            else:
                result = 'TN:La bonne réponse est négative et la prédiction est négative'
        else:
            if y == '1':
                result = 'FN:La bonne réponse est positive et la prédiction est négative'
            else:
                result = 'FP:La bonne réponse est négative et la prédiction est positive'
        print(result, y_pred, x)
        if i == 29:
            break

    #Sortie de liste TSV
    y_pred = estimator.predict(x_test)
    y_prob = estimator.predict_proba(x_test)

    results = pd.DataFrame([y_test, y_pred, y_prob.T[1], x_test]).T.rename(columns={ 0: 'Bonne réponse', 1 : 'Prévoir', 2: 'Prévoir確率(positif)', 3 :'Chaîne de mots'})
    results.to_csv('./predict.txt' , sep='\t')

    print('\n', classification_report(y_test, y_pred))
    print('\n', confusion_matrix(y_test, y_pred))

estimator = train(x_train, y_train, 'gs_result.csv')
validate(estimator, x_test, y_test)

Répondre au commentaire

J'utilise juste le classification_report de scikit-learn, et je n'ai pas beaucoup écrit à ce sujet. Le résultat «y_pred» de la fonction «prédire» utilisée dans le «étiquetage» précédent est utilisé.

y_pred = estimator.predict(x_test)

Tout ce que vous avez à faire est de le passer à la fonction classification_report avec l'étiquette correcte d'origine y_test.

print('\n', classification_report(y_test, y_pred))

Le taux de précision, le taux de rappel, le score F1, le taux de réponse correcte, etc. sont affichés.

              precision    recall  f1-score   support

           0       0.75      0.73      0.74      1351
           1       0.73      0.75      0.74      1315

    accuracy                           0.74      2666
   macro avg       0.74      0.74      0.74      2666
weighted avg       0.74      0.74      0.74      2666

Puisque les paramètres à passer sont les mêmes, la fonction confusion_matrix produit également la matrice de confusion.

print('\n', confusion_matrix(y_test, y_pred))

Une matrice mixte apparaît sous une forme simple. Pour plus de détails sur la matrice mixte, voir [Article séparé "[Pour les débutants] Explication des index d'évaluation des problèmes de classification pour l'apprentissage automatique (taux de réponse correct, taux de précision, taux de rappel, etc.)" (https://qiita.com/FukuharaYohei/items/be89a99c53586fa4e2e4) ).

 [[992 359]
 [329 986]]

Recommended Posts

100 traitements linguistiques knock-77 (en utilisant scicit-learn): mesure du taux de réponse
100 traitement du langage knock-75 (en utilisant scicit-learn): poids de l'identité
100 traitement du langage knock-76 (en utilisant scicit-learn): étiquetage
100 traitement du langage knock-73 (en utilisant scikit-learn): apprentissage
100 traitement du langage knock-74 (en utilisant scicit-learn): prédiction
100 traitement du langage knock-97 (en utilisant scicit-learn): clustering k-means
100 traitements linguistiques Knock 2020 [00 ~ 39 réponse]
100 langues de traitement knock 2020 [00-79 réponse]
100 traitements linguistiques Knock 2020 [00 ~ 49 réponse]
100 traitements linguistiques Knock 2020 [00 ~ 59 réponse]
100 langage de traitement knock-79 (en utilisant scikit-learn): dessin de graphe avec rappel de précision
100 Language Processing Knock-32 (utilisant des pandas): Prototype de verbe
100 traitement du langage knock-93 (en utilisant des pandas): calcul du taux de précision de la tâche d'analogie
100 traitement du langage knock-36 (en utilisant des pandas): fréquence d'occurrence des mots
100 traitement du langage knock-59: analyse de la formule S
100 traitement du langage knock-31 (en utilisant des pandas): verbe
100 traitement du langage knock-38 (en utilisant des pandas): histogramme
100 traitement de la langue knock-96 (en utilisant Gensim): Extraction du vecteur lié au nom du pays
100 Language Processing Knock-33 (en utilisant des pandas): nom sahen
100 traitement du langage knock-91: Préparation des données d'analogie
Traitement du langage 100 knocks-44: Visualisation des arbres dépendants
100 Language Processing Knock-26: suppression du balisage accentué
100 Language Processing Knock-71 (en utilisant Stanford NLP): Stopword
100 traitement du langage knock-35 (utilisant des pandas): concaténation de nomenclature
100 Language Processing Knock-39 (en utilisant des pandas): la loi de Zipf
100 traitement de langage knock-34 (utilisant des pandas): "B of A"
100 coups de traitement linguistique (2020): 28
100 coups de traitement linguistique (2020): 38
100 traitement de la langue frapper 00 ~ 02
100 traitement du langage knock-90 (en utilisant Gensim): apprendre avec word2vec
100 langage de traitement knock-20 (à l'aide de pandas): lecture de données JSON
Traitement de 100 langues knock-98 (en utilisant des pandas): Clustering par méthode Ward
Traitement du langage 100 knocks-45: Extraction de modèles de cas verbaux
100 traitement du langage knock-99 (à l'aide de pandas): visualisation par t-SNE
100 traitement du langage knock-95 (en utilisant des pandas): Note avec WordSimilarity-353
100 traitement du langage knock-72 (en utilisant Stanford NLP): Extraction d'identité
100 Language Processing Knock 2020 Chapitre 1
100 coups de traitement du langage amateur: 17
100 Traitement du langage Knock-52: Stemming
100 Traitement du langage Knock Chapitre 1
100 traitements linguistiques Knock 2020 [00 ~ 89 réponse]
100 coups de langue amateur: 07
Traitement du langage 100 coups 00 ~ 09 Réponse
100 Language Processing Knock 2020 Chapitre 3
100 Language Processing Knock 2020 Chapitre 2
100 coups de traitement du langage amateur: 09
100 coups en traitement du langage amateur: 47
Traitement 100 langues knock-53: Tokenisation
100 coups de traitement du langage amateur: 97
100 coups de traitement du langage amateur: 67
[Traitement du langage 100 coups 2020] Résumé des exemples de réponses par Python
100 langage traitement knock-92 (utilisant Gensim): application aux données d'analogie
[Chapitre 6] Introduction à scicit-learn avec 100 coups de traitement du langage
100 Language Processing Knock: Chapitre 2 Principes de base des commandes UNIX (à l'aide de pandas)
100 Language Processing Knock-83 (en utilisant des pandas): Mesure de la fréquence des mots / contextes
100 Language Processing Knock-30 (en utilisant des pandas): lecture des résultats de l'analyse morphologique
Traitement du langage 100 knocks-49: Extraction de chemins de dépendances entre nomenclature
100 traitement de langage knock-94 (en utilisant Gensim): calcul de similarité avec WordSimilarity-353
Apprenez facilement 100 traitements linguistiques Knock 2020 avec "Google Colaboratory"
100 coups de traitement du langage avec Python 2015
100 traitement du langage Knock-51: découpage de mots