Betrachten wir das Beispiel ** "Identifizieren wir automatisch die handgeschriebene Postleitzahl auf der Postkarte" **.
Dies ist ein Artikel für Anfänger. Grundsätzlich handelt es sich um eine Sammlung von Scikit-Lernprogrammen und -dokumenten, aber auch um andere Inhalte. Wir werden Ziffern für den Datensatz und SVM (SVC um genau zu sein) für die Methode des maschinellen Lernens verwenden.
Ziffern ist ein Datensatz, der aus einem Nummernetikett und Nummernbilddaten besteht. Sie werden dieses Paar von Etiketten und Bildern später lernen. Da die Daten im Voraus von scikit-learn vorbereitet werden, kann jeder sie problemlos ausprobieren.
Sie können die Dataset-Ziffern mit datasets.load_digits () lesen.
from sklearn import datasets
from matplotlib import pyplot as plt
# from sklearn import datasets
digits = datasets.load_digits()
Jedes Bild ist ein handgeschriebenes Zeichenbild von 0 bis 9. Diese Bilder werden programmgesteuert als zweidimensionales Array mit Werten zwischen 0 und 255 dargestellt.
#Bildarraydaten
print(digits.data)
[[ 0. 0. 5. ..., 0. 0. 0.]
[ 0. 0. 0. ..., 10. 0. 0.]
[ 0. 0. 0. ..., 16. 9. 0.]
...,
[ 0. 0. 1. ..., 6. 0. 0.]
[ 0. 0. 2. ..., 12. 0. 0.]
[ 0. 0. 10. ..., 12. 1. 0.]]
Es ist schwer zu verstehen, selbst wenn Sie die Bilddaten als Array betrachten, daher möchte ich sie als Bild anzeigen.
Überprüfen Sie vor dem Anzeigen des Bildes zunächst die Etikettendaten. Wie unten gezeigt, werden die Bezeichnungen 0 bis 9 im Voraus korrekt zugewiesen.
#Etikette
print(digits.target)
[0 1 2 ..., 8 9 8]
Betrachtet man das obige Ergebnis, so erhält beispielsweise das 0, 1, 2. Bild von Anfang an die Bezeichnung 0, 1, 2 und das zweite Bild von hinten die Bezeichnung 9. .. Sie können matplotlib verwenden, um diese Bilder anzuzeigen.
#Bildschirm
# number 0
plt.subplot(141), plt.imshow(digits.images[0], cmap = 'gray')
plt.title('number 0'), plt.xticks([]), plt.yticks([])
# number 1
plt.subplot(142), plt.imshow(digits.images[1], cmap = 'gray')
plt.title('numbert 1'), plt.xticks([]), plt.yticks([])
# number 2
plt.subplot(143), plt.imshow(digits.images[2], cmap = 'gray')
plt.title('numbert 2'), plt.xticks([]), plt.yticks([])
# number 9
plt.subplot(144), plt.imshow(digits.images[-2], cmap = 'gray')
plt.title('numbert 9'), plt.xticks([]), plt.yticks([])
plt.show()
Auf diese Weise können Sie sehen, dass jedes Bild die richtige Beschriftung zu haben scheint.
** SVM (Support Vector Machine) ** ist eine der überwachten Lernmethoden mit hervorragender Erkennungsleistung. Grundsätzlich basiert die Zwei-Klassen-Klassifizierung auf der Maximierung der Marge. Natürlich kann es auch auf die Klassifizierung mehrerer Klassen angewendet werden (indem die Klassifizierung mehrerer Klassen mehrmals durchgeführt wird).
Bei einer strengen SVM ist es nicht möglich, eine geeignete Klassifizierungsgrenze zu erhalten, wenn sich die zu klassifizierenden Daten überschneiden (dh wenn nicht alle Daten vollständig getrennt werden können). Andererseits werden SVMs, die Fehler tolerieren, als ** Soft-Margin-SVMs ** bezeichnet. Durch die Vergabe einer Strafe C für eine Fehlklassifizierung ist es möglich, eine Klassifizierungsgrenze zu zeichnen, die die Fehlklassifizierung selbst für Daten minimiert, die nicht vollständig getrennt werden können.
Es ist wichtig zu beachten, dass je größer die Strafe C ist, desto schwerwiegender der Fehler ist und desto wahrscheinlicher ist es gleichzeitig, dass es zu einer ** Überanpassung ** kommt.
(Hinweis) Übermäßiges Lernen bedeutet, dass das Trainingsmodell in bestimmte zufällige Merkmale (unabhängig von den Merkmalen, die Sie ursprünglich trainieren möchten) in den Trainingsdaten passt. Wenn ein Übertraining auftritt, verbessert sich die Leistung der Trainingsdaten, bei anderen Daten sind die Ergebnisse jedoch schlechter. (Referenz: Überanpassung-Wikipedia)
In der Tat hat Scikit-Learn leicht unterschiedliche Arten von SVMs wie SVC, NuSVC und LinearSVC. NuSVC und SVC sind sehr ähnliche Techniken, haben jedoch leicht unterschiedliche Parametersätze und werden mathematisch durch unterschiedliche Formulierungen dargestellt. LinearSVC ist eine SVM, die einen linearen Kernel verwendet, und es kann kein anderer Kernel angegeben werden.
Dieses Mal werden wir SVC verwenden und einen weichen Rand anwenden. Alles was Sie tun müssen, ist ** (1) einen Klassifikator zu erstellen und (2) ihn auf Ihre Daten anzuwenden **.
from sklearn import svm
# SVM
clf = svm.SVC(gamma=0.001, C=100.)
clf.fit(digits.data[:-10], digits.target[:-10])
SVC(C=100.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape=None, degree=3, gamma=0.001, kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
Obwohl hier selten angegeben, können Sie sehen, dass der SVC einige Parameter hat (C, cache_size, class_weight, coef0, ...), wie oben gezeigt. Mach dir zuerst keine Sorgen, die Standardeinstellungen sind in Ordnung.
Die Beschriftung wird anhand des erstellten Klassifikators tatsächlich aus dem Bild geschätzt. Versuchen wir es mit den letzten 10 Daten, die wir nicht zum Erstellen des Trainingsmodells verwendet haben.
clf.predict(digits.data[-10:])
array([5, 4, 8, 8, 4, 9, 0, 8, 9, 8])
Betrachtet man die tatsächlichen Daten,
print(digits.target[-10:])
[5 4 8 8 4 9 0 8 9 8]
Stimmt mit dem Schätzergebnis überein.
Dies bestätigt, dass eine ungefähr korrekte Schätzung aus dem trainierten Modell möglich ist. Probieren wir verschiedene Parameter aus.
Es gibt verschiedene Bewertungsindizes für die Klassifizierungsgenauigkeit des Klassifizierers, die jedoch grundsätzlich anhand der folgenden Indizes gemessen werden können.
Normalerweise wird die Genauigkeit des Klassifikators häufig anhand des F-Werts bewertet. In der Praxis ist es jedoch häufig der Fall, dass der Schwerpunkt auf der Präzisionsrate oder der Rückrufrate liegt.
Betrachten Sie beispielsweise eine Werksteileinspektion. Es ist kein großes Problem, wenn Sie ein Teil, das nirgendwo kaputt ist, fälschlicherweise als "defekt (Fehler)" klassifizieren. Wenn ein defektes Teil jedoch fälschlicherweise als "nicht defekt (korrekt)" eingestuft wird, kann dies zu Beschwerden und Rückrufen führen und je nach Produkt sogar lebensbedrohlich sein. In solchen Fällen ist die Präzision wichtiger als der Rückruf. Beispielsweise hat in "Konformitätsrate 99% + Rückrufrate 70%" und "Konformitätsrate 80% + Rückrufrate 99%" der letztere einen höheren F-Wert, der erstere ist jedoch überwiegend praktischer. Es ist möglich. Andererseits ist beim Durchsuchen einer Datenbank die Rückrufrate häufig wichtiger als die Genauigkeitsrate. Dies liegt daran, dass selbst wenn Sie viele falsche Suchergebnisse erhalten, diese viel besser sind als viele Daten, die bei der Suche nicht gefunden werden können.
Bisher wurden die Parameter irgendwie auf entsprechende Werte eingestellt. Dies liefert jedoch häufig nicht die erforderliche Klassifizierungsgenauigkeit, und in der Praxis ist die Parameteroptimierung wesentlich. Welche Parameter sollten eingestellt werden und wie sollten sie eingestellt werden, um die Klassifizierungsgenauigkeit des Klassifikators zu verbessern? Sie können die Parameter einzeln manuell einstellen, dies ist jedoch sehr schwierig. Es scheint, dass es einige Kenntnisse darüber gibt, dass ein solcher Wert je nach Datensatz und Methode normalerweise gut ist, aber er kann nicht für einen unbekannten Datensatz verwendet werden. Daher wird häufig eine Methode namens ** Rastersuche ** verwendet. Einfach ausgedrückt, das Modell wird tatsächlich trainiert, während die Parameter im Suchbereich geändert werden, und es wird nach dem Parameter mit der besten Ergebnisgenauigkeit gesucht. Zusätzlich wird ** Kreuzvalidierung ** verwendet, um zu bestätigen, dass das Lernmodell mit den erhaltenen Parametern kein Überlernen verursacht. Bei der Verifizierungsmethode für k-Schnittpunkte werden die Daten zunächst in k Teile unterteilt. Es ist eine Methode, mit k-1 von ihnen zu lernen und mit der verbleibenden zu bewerten, k-mal zu wiederholen (während die Trainingsdaten und Testdaten geändert werden) und das Lernmodell mit dem Durchschnittswert zu bewerten. Auf diese Weise können Sie die ** Generalisierungsleistung ** des Trainingsmodells bewerten.
(Hinweis) Eine gute Generalisierungsleistung ist einfach die Fähigkeit des Trainingsmodells, unbekannte Daten richtig zu identifizieren. Denken Sie daran, dass Sie bei Übertraining Trainingsdaten mit hoher Genauigkeit identifizieren können, bei unbekannten Daten jedoch weniger genau.
Mit scikit-learn können Sie mit GridSearchCV () ganz einfach eine Rastersuche und eine Kreuzungsüberprüfung durchführen. Beispielsweise können Sie die folgenden Parameter angeben:
Konvertieren Sie vor der Parameteroptimierung das Format der gelesenen Daten.
from sklearn import datasets
from sklearn.cross_validation import train_test_split
from sklearn.grid_search import GridSearchCV
from sklearn.metrics import classification_report
from sklearn.svm import SVC
#Laden des Digits-Datasets
digits = datasets.load_digits()
print(len(digits.images))
print(digits.images.shape)
1797
(1797, 8, 8)
# To apply an classifier on this data, we need to flatten the image, to
# turn the data in a (samples, feature) matrix:
n_samples = len(digits.images)
X = digits.images.reshape((n_samples, -1)) # reshape(cols, rows)Konvertieren Sie in Spalten Zeilen Zeilen Spalte mit(Eines der Argumente-Automatische Berechnung, wenn 1)
y = digits.target
print(X.shape)
print(y)
(1797, 64)
[0 1 2 ..., 8 9 8]
Der folgende Code mag entmutigend erscheinen, aber was Sie tatsächlich tun, ist einfach.
Sie versuchen nur alle Kombinationen in den oben genannten Fällen, um die Parameter (best \ _params \ _) zu finden, die jede Genauigkeit und jeden Abruf maximieren. (Beachten Sie, dass Gamma ein Parameter ist, wenn der Kernel rbf ist, daher ist es irrelevant, wenn der Kernel linear ist.)
Danach werden die Rastersuchergebnisse detailliert angezeigt und der detaillierte Bericht der Ergebnisse wird mit classification_report () angezeigt.
#Teilen Sie den Datensatz in Trainingsdaten und Testdaten
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.5, random_state=0)
#Legen Sie die Parameter fest, die Sie mit der Kreuzvalidierung optimieren möchten
tuned_parameters = [{'kernel': ['rbf'], 'gamma': [1e-3, 1e-4],
'C': [1, 10, 100, 1000]},
{'kernel': ['linear'], 'C': [1, 10, 100, 1000]}]
scores = ['precision', 'recall']
for score in scores:
print("# Tuning hyper-parameters for %s" % score)
print()
#Rastersuche und Methode zur Überprüfung von Kreuzungen
clf = GridSearchCV(SVC(C=1), tuned_parameters, cv=5,
scoring='%s_weighted' % score)
clf.fit(X_train, y_train)
print("Best parameters set found on development set:")
print()
print(clf.best_params_)
print()
print("Grid scores on development set:")
print()
for params, mean_score, scores in clf.grid_scores_:
print("%0.3f (+/-%0.03f) for %r"
% (mean_score, scores.std() * 2, params))
print()
print("Detailed classification report:")
print()
print("The model is trained on the full development set.")
print("The scores are computed on the full evaluation set.")
print()
y_true, y_pred = y_test, clf.predict(X_test)
print(classification_report(y_true, y_pred))
print()
# Tuning hyper-parameters for precision
Best parameters set found on development set:
{'gamma': 0.001, 'kernel': 'rbf', 'C': 10}
Grid scores on development set:
0.987 (+/-0.018) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 1}
0.959 (+/-0.030) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 1}
0.988 (+/-0.018) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 10}
0.982 (+/-0.027) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 10}
0.988 (+/-0.018) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 100}
0.982 (+/-0.026) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 100}
0.988 (+/-0.018) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 1000}
0.982 (+/-0.026) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 1000}
0.974 (+/-0.014) for {'kernel': 'linear', 'C': 1}
0.974 (+/-0.014) for {'kernel': 'linear', 'C': 10}
0.974 (+/-0.014) for {'kernel': 'linear', 'C': 100}
0.974 (+/-0.014) for {'kernel': 'linear', 'C': 1000}
Detailed classification report:
The model is trained on the full development set.
The scores are computed on the full evaluation set.
precision recall f1-score support
0 1.00 1.00 1.00 89
1 0.97 1.00 0.98 90
2 0.99 0.98 0.98 92
3 1.00 0.99 0.99 93
4 1.00 1.00 1.00 76
5 0.99 0.98 0.99 108
6 0.99 1.00 0.99 89
7 0.99 1.00 0.99 78
8 1.00 0.98 0.99 92
9 0.99 0.99 0.99 92
avg / total 0.99 0.99 0.99 899
# Tuning hyper-parameters for recall
Best parameters set found on development set:
{'gamma': 0.001, 'kernel': 'rbf', 'C': 10}
Grid scores on development set:
0.986 (+/-0.021) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 1}
0.958 (+/-0.029) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 1}
0.987 (+/-0.021) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 10}
0.981 (+/-0.029) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 10}
0.987 (+/-0.021) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 100}
0.981 (+/-0.027) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 100}
0.987 (+/-0.021) for {'gamma': 0.001, 'kernel': 'rbf', 'C': 1000}
0.981 (+/-0.027) for {'gamma': 0.0001, 'kernel': 'rbf', 'C': 1000}
0.973 (+/-0.015) for {'kernel': 'linear', 'C': 1}
0.973 (+/-0.015) for {'kernel': 'linear', 'C': 10}
0.973 (+/-0.015) for {'kernel': 'linear', 'C': 100}
0.973 (+/-0.015) for {'kernel': 'linear', 'C': 1000}
Detailed classification report:
The model is trained on the full development set.
The scores are computed on the full evaluation set.
precision recall f1-score support
0 1.00 1.00 1.00 89
1 0.97 1.00 0.98 90
2 0.99 0.98 0.98 92
3 1.00 0.99 0.99 93
4 1.00 1.00 1.00 76
5 0.99 0.98 0.99 108
6 0.99 1.00 0.99 89
7 0.99 1.00 0.99 78
8 1.00 0.98 0.99 92
9 0.99 0.99 0.99 92
avg / total 0.99 0.99 0.99 899
Aus dem Ergebnis des Drucks (vgl. Best \ _params \ _) sind 'gamma': 0,001, 'kernel': 'rbf', 'C': 10 unter beiden Gesichtspunkten der Präzision / des Rückrufs die besten. Ich verstehe das. Sie haben jetzt die Parameter optimiert.
Versuchen Sie bei Bedarf, mit einem anderen Kernel oder im Vergleich zu anderen Lernmethoden als SVM zu optimieren.
[1]An introduction to machine learning with scikit-learn — scikit-learn 0.18.1 documentation http://scikit-learn.org/stable/tutorial/basic/tutorial.html#introduction [2]Parameter estimation using grid search with cross-validation — scikit-learn 0.18.1 documentation http://scikit-learn.org/stable/auto_examples/model_selection/grid_search_digits.html#example-model-selection-grid-search-digits-py [3]1.4. Support Vector Machines — scikit-learn 0.18.1 documentation http://scikit-learn.org/stable/modules/svm.html [4] F-Wert-Maschinelles Lernen "Toki no Mori Wiki" http://ibisforest.org/index.php?F%E5%80%A4 [5] Master SVM! 8 Checkpoints-Qiita http://qiita.com/pika_shi/items/5e59bcf69e85fdd9edb2 [6] Parameteroptimierung durch Rastersuche von Scikit lernen http://qiita.com/SE96UoC5AfUt7uY/items/c81f7cea72a44a7bfd3a [7] Einführung in die Bayes'sche Optimierung für maschinelles Lernen | Tech Book Zone Manatee https://book.mynavi.jp/manatee/detail/id=59393 [8]3.3. Model evaluation: quantifying the quality of predictions — scikit-learn 0.18.1 documentation http://scikit-learn.org/stable/modules/model_evaluation.html#scoring-parameter [9] Überanpassung - Wikipedia https://ja.wikipedia.org/wiki/%E9%81%8E%E5%89%B0%E9%81%A9%E5%90%88
Recommended Posts