Dies ist der Datensatz des 79. "Compliance Rate-Drawing Recall Rate Graph" von Language Processing 100 Knocks 2015. Ein Diagramm, das zeigt, wie die Genauigkeits- und Rückrufraten, die in einer Kompromissbeziehung stehen, zusammenhängen. Die ROC-Kurve wird auch als ähnliches Diagramm ausgegeben. 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 |
---|---|
079.Compliance-Rate-Rückrufdiagramm zeichnen.ipynb | Antwortprogramm GitHub Link |
100 Klicks Amateur-Sprachverarbeitung:79 | Ich bin Ihnen immer zu Dank verpflichtet, wenn ich auf 100 Sprachverarbeitung klopfe |
Einführung in Python mit 100 Klopfen Sprachverarbeitung#79 -Maschinelles Lernen, Scikit-Übereinstimmungsrate mit lernen-Erinnern&Zeichnen eines Diagramms | 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.
Zeichnen Sie ein Präzisionsrückrufdiagramm, indem Sie den Klassifizierungsschwellenwert des logistischen Regressionsmodells ändern.
Es wird nicht nur das Diagramm der Präzisionsrückrufrate, sondern auch die ROC-Kurve ausgegeben. Zusätzlich wird die Lernkurve als Bonus ausgegeben. Dies ist ein vollständiger "Bonus", unabhängig von der Präzisionsrückrufkurve oder der ROC-Kurve.
Grundsätzlich [vorherige [077.Messung der korrekten Antwortrate.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/08.%E6%A9%9F%E6%A2%B0%E5%] AD% A6% E7% BF% 92/07 7.% E6% AD% A3% E8% A7% A3% E7% 8E% 87% E3% 81% AE% E8% A8% 88% E6% B8% AC.ipynb ) Mit drei hinzugefügten Grafikausgabelogiken.
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, learning_curve
from sklearn.metrics import classification_report, confusion_matrix, roc_curve, auc, precision_recall_curve
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))
#Grafikausgabe
def output_graphs(estimator, x_all, y_all, x_test, y_test):
#Lernkurvenausgabe
output_learning_curve(estimator, x_all, y_all)
y_pred = estimator.predict_proba(x_test)
#ROC-Kurvenausgabe
output_roc(y_test, y_pred)
#Compliance-Rate-Rate Graph Ausgabe ausgeben
output_pr_curve(y_test, y_pred)
#Lernkurvenausgabe
def output_learning_curve(estimator, x_all, y_all):
training_sizes, train_scores, test_scores = learning_curve(estimator,
x_all, y_all, cv=5,
train_sizes=[0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0])
plt.plot(training_sizes, train_scores.mean(axis=1), label="training scores")
plt.plot(training_sizes, test_scores.mean(axis=1), label="test scores")
plt.legend(loc="best")
plt.show()
#ROC-Kurvenausgabe
def output_roc(y_test, y_pred):
# FPR, TPR(,Schwelle)Berechnung
fpr, tpr, thresholds = roc_curve(y_test, y_pred[:,1], pos_label='1')
#Übrigens AUC
auc_ = auc(fpr, tpr)
#Zeichnen Sie die ROC-Kurve
plt.plot(fpr, tpr, label='ROC curve (area = %.2f)'%auc_)
plt.legend()
plt.title('ROC curve')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.grid(True)
plt.show()
#Compliance-Rate-Rate Graph Ausgabe ausgeben
def output_pr_curve(y_test, y_pred):
#Übereinstimmungsrate und Rückrufrate bei einem bestimmten Schwellenwert,Schwellenwert abrufen
precisions, recalls, thresholds = precision_recall_curve(y_test, y_pred[:,1], pos_label='1')
#0 bis 1 0.Plotten ○ in Schritten von 05
for i in range(21):
close_point = np.argmin(np.abs(thresholds - (i * 0.05)))
plt.plot(precisions[close_point], recalls[close_point], 'o')
#Compliance-Rate-Rückrufkurve
plt.plot(precisions, recalls)
plt.xlabel('Precision')
plt.ylabel('Recall')
plt.show()
estimator = train(x_train, y_train, 'gs_result.csv')
validate(estimator, x_test, y_test)
output_graphs(estimator, x_all, y_all, x_test, y_test)
Die Precision_recall_curve` von scikit-learn wird verwendet, um die Präzisions-, Rückruf- und Schwellenwerte zu empfangen und als Diagramm auszugeben.
#Compliance-Rate-Rate Graph Ausgabe ausgeben
def output_pr_curve(y_test, y_pred):
#Übereinstimmungsrate und Rückrufrate bei einem bestimmten Schwellenwert,Schwellenwert abrufen
precisions, recalls, thresholds = precision_recall_curve(y_test, y_pred[:,1], pos_label='1')
#0 bis 1 0.Plotten ○ in Schritten von 05
for i in range(21):
close_point = np.argmin(np.abs(thresholds - (i * 0.05)))
plt.plot(precisions[close_point], recalls[close_point], 'o')
#Compliance-Rate-Rückrufkurve
plt.plot(precisions, recalls)
plt.xlabel('Precision')
plt.ylabel('Recall')
plt.show()
Es ist ein Diagramm des Ausgabeergebnisses.
Sie können die folgenden Kompromisse sehen.
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) ).
Verwenden Sie die Funktion roc_curve
, um die False Positive Rate, die True Positive Rate und den Schwellenwert zu ermitteln. Berechnen Sie auch den Wert von auc mit der Funktion auc
.
Drucken Sie abschließend das Diagramm (AUC-Werte werden in der Legende angezeigt).
def output_roc(y_test, y_pred):
# FPR, TPR(,Schwelle)Berechnung
fpr, tpr, thresholds = roc_curve(y_test, y_pred[:,1], pos_label='1')
#Übrigens AUC
auc_ = auc(fpr, tpr)
#Zeichnen Sie die ROC-Kurve
plt.plot(fpr, tpr, label='ROC curve (area = %.2f)'%auc_)
plt.legend()
plt.title('ROC curve')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.grid(True)
plt.show()
Selbst wenn Sie nicht sicher sind, können Sie sehen, dass durch die Beurteilung als positiv die Anzahl der True Positives und die Anzahl der False Positives zunimmt.
Am Ende unterscheidet sich die Bedeutung von den beiden vorherigen Grafiken, aber ich werde die Lernkurve als Bonus schreiben.
Ich wollte sehen, ob es eine hohe Vorspannung oder eine hohe Varianz ist, also habe ich es ausgegeben. Über hohe Voreingenommenheit und hohe Varianz Separater Artikel "Coursera Machine Learning-Einführungskurs (6. Woche - verschiedene Ratschläge)" Ich schrieb in (Es ist ein grober Artikel ...).
learning_curve
function mit erklärenden Variablen und Bezeichnungen, Anzahl der Kreuzvalidierungen (5-mal), Größe der Trainingsdaten Übergeben Sie die Liste. Dadurch wird die richtige Antwortrate für Training und Test entsprechend der Größe der Trainingsdaten zurückgegeben.
#Lernkurvenausgabe
def output_learning_curve(estimator, x_all, y_all):
training_sizes, train_scores, test_scores = learning_curve(estimator,
x_all, y_all, cv=5,
train_sizes=[0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0])
plt.plot(training_sizes, train_scores.mean(axis=1), label="training scores")
plt.plot(training_sizes, test_scores.mean(axis=1), label="test scores")
plt.legend(loc="best")
plt.show()
Als ich mir die Ausgabeergebnisse ansah, dachte ich, dass sich der Unterschied zwischen Training und Test immer noch verringert, also versuchte ich Folgendes, aber die Genauigkeit verbesserte sich nicht. Beides sind Optionen für die Rastersuche.
min_df
erhöhen)