Dies ist die Aufzeichnung der 77. "Messung der Genauigkeitsrate" von Language Processing 100 Knock 2015. Der Inhalt der Klopffrage ist die Messung der richtigen Antwortrate für die Trainingsdaten, aber dieses Mal wagen wir es, die Testdaten wie in der vorherigen Zeit zu verwenden. Bis jetzt habe ich es nicht in den Block gepostet, da es im Grunde dasselbe war wie "Amateur-Sprachverarbeitung 100 Klopfen". , "Kapitel 8: Maschinelles Lernen" wurde ernst genommen und teilweise geändert. Ich werde posten. Ich benutze hauptsächlich scikit-learn.
Verknüpfung | Bemerkungen |
---|---|
077.Messung der richtigen Antwortrate.ipynb | Antwortprogramm GitHub Link |
100 Klicks Amateur-Sprachverarbeitung:77 | Ich bin Ihnen immer zu Dank verpflichtet, wenn ich auf 100 Sprachverarbeitung klopfe |
Einführung in Python mit 100 Klopfen Sprachverarbeitung#77 -Maschinelles Lernen, Scikit-Messung der richtigen Antwortrate mit Lernen | scikit-Klopfen Sie das Ergebnis mit lernen |
Art | Ausführung | Inhalt |
---|---|---|
OS | Ubuntu18.04.01 LTS | Es läuft virtuell |
pyenv | 1.2.15 | Ich benutze pyenv, weil ich manchmal mehrere Python-Umgebungen benutze |
Python | 3.6.9 | python3 auf pyenv.6.Ich benutze 9 3.7 oder 3.Es gibt keinen tiefen Grund, keine 8er-Serie zu verwenden Pakete werden mit venv verwaltet |
In der obigen Umgebung verwende ich die folgenden zusätzlichen Python-Pakete. Einfach mit normalem Pip installieren.
Art | Ausführung |
---|---|
matplotlib | 3.1.1 |
numpy | 1.17.4 |
pandas | 0.25.3 |
scikit-learn | 0.21.3 |
In diesem Kapitel [Satzpolaritätsdatensatz] von Movie Review Data, veröffentlicht von Bo Pang und Lillian Lee. v1.0](http://www.cs.cornell.edu/people/pabo/movie-review-data/rt-polaritydata.README.1.0.txt) wird verwendet, um den Satz positiv oder negativ zu machen. Arbeiten Sie an der Aufgabe (Polaritätsanalyse), um sie als (negativ) zu klassifizieren.
Erstellen Sie ein Programm, das> 76 Ausgaben empfängt und die richtige Antwortrate der Vorhersage, die richtige Antwortrate für das richtige Beispiel, die Rückrufrate und die F1-Punktzahl berechnet.
Dieses Mal wird der Teil "76 Ausgänge empfangen" ignoriert und die Testdaten werden verwendet. Dies liegt daran, dass ich dachte, dass die Testdaten nützlicher wären als die Trainingsdaten wie zuvor.
Grundsätzlich [vorheriges "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) Richtige Antwortrate und zugehörige Indikatoren Es geht nur darum, eine Ausgabelogik hinzuzufügen.
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
#Klasse zur Verwendung der Wortvektorisierung in 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)
#Parameter für GridSearchCV
PARAMETERS = [
{
'vectorizer__method':['tfidf', 'count'],
'vectorizer__min_df': [0.0003, 0.0004],
'vectorizer__max_df': [0.07, 0.10],
'classifier__C': [1, 3], #Ich habe auch 10 ausprobiert, aber der SCORE ist niedrig, nur weil er langsam ist
'classifier__solver': ['newton-cg', 'liblinear']},
]
#Datei lesen
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 steht für Klassifizierung
clf = GridSearchCV(
pipline, #
PARAMETERS, #Parametersatz, den Sie optimieren möchten
cv = 5) #Anzahl der Kreuztests
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))
#Ausgabe des Elementgewichts
output_coef(clf.best_estimator_)
return clf.best_estimator_
#Ausgabe des Elementgewichts
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:Die richtige Antwort ist positiv und die Vorhersage ist positiv'
else:
result = 'TN:Die richtige Antwort ist negativ und die Vorhersage ist negativ'
else:
if y == '1':
result = 'FN:Die richtige Antwort ist positiv und die Vorhersage ist negativ'
else:
result = 'FP:Die richtige Antwort ist negativ und die Vorhersage ist positiv'
print(result, y_pred, x)
if i == 29:
break
#TSV-Listenausgabe
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: 'Richtige Antwort', 1 : 'Prognose', 2: 'Prognose確率(positiv)', 3 :'Wortzeichenfolge'})
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)
Ich benutze nur den "Klassifizierungsbericht" von scikit-learn und habe nicht viel darüber geschrieben. Das Ergebnis "y_pred" der "Vorhersage" -Funktion, die in der vorherigen "Beschriftung" verwendet wurde, wird verwendet.
y_pred = estimator.predict(x_test)
Alles, was Sie tun müssen, ist, es an die Funktion "Klassifizierungsbericht" mit der ursprünglichen korrekten Bezeichnung "y_test" zu übergeben.
print('\n', classification_report(y_test, y_pred))
Die Präzisionsrate, Rückrufrate, F1-Punktzahl, korrekte Antwortrate usw. werden ausgegeben.
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
Da die zu übergebenden Parameter dieselben sind, gibt die Funktion "confusion_matrix" auch die Verwirrungsmatrix aus.
print('\n', confusion_matrix(y_test, y_pred))
Eine gemischte Matrix erscheint in einfacher Form. Einzelheiten zur gemischten Matrix finden Sie in [Separater Artikel "[Für Anfänger] Erläuterung der Bewertungsindizes für Klassifizierungsprobleme beim maschinellen Lernen (korrekte Antwortrate, Präzisionsrate, Rückrufrate usw.)" (https://qiita.com/FukuharaYohei/items/be89a99c53586fa4e2e4) ).
[[992 359]
[329 986]]