
Vor einem Monat startete Lenta einen Wettbewerb, bei dem der gleiche Talking Hat von Harry Potter Teilnehmer identifiziert, die Zugang zu dem sozialen Netzwerk einer von vier FakultĂ€ten haben. Die Konkurrenz ist nicht schlecht, die Namen, die unterschiedlich klingen, werden von verschiedenen FakultĂ€ten bestimmt, und Ă€hnliche englische und russische Vor- und Nachnamen werden auf Ă€hnliche Weise verteilt. Ich weiĂ nicht, ob die Verteilung nur von den Vor- und Nachnamen abhĂ€ngt und ob die Anzahl der Freunde oder andere Faktoren irgendwie berĂŒcksichtigt werden, aber dieser Wettbewerb schlug die Idee dieses Artikels vor: Versuchen Sie, einen Klassifikator von Grund auf neu zu trainieren, damit Benutzer auf verschiedene FakultĂ€ten verteilt werden können.
In diesem Artikel werden wir ein einfaches ML-Modell erstellen, das Personen je nach Vor- und Nachnamen an die Abteilungen von Harry Potter verteilt, nachdem sie einen kleinen Forschungsprozess nach der CRISP- Methodik durchlaufen haben. NĂ€mlich wir:
- Wir formulieren das Problem;
- Wir untersuchen mögliche LösungsansÀtze und formulieren Datenanforderungen (Lösungsmethoden und Daten);
- Wir werden die notwendigen Daten (Lösungsmethoden und Daten) sammeln;
- Wir werden den gesammelten Datensatz untersuchen (Exploratory Research);
- Features aus Rohdaten extrahieren (Feature Engineering);
- Lassen Sie uns ein Modell des maschinellen Lernens lehren (Modellbewertung);
- Vergleichen Sie die erzielten Ergebnisse, bewerten Sie die QualitÀt der Lösungen und wiederholen Sie gegebenenfalls die AbsÀtze 2-6.
- Wir verpacken die Lösung in einen Service, der genutzt werden kann (Produktion).

Diese Aufgabe mag trivial erscheinen, daher werden wir den gesamten Prozess (so dass es weniger als 2 Stunden dauert) und diesen Artikel (so dass seine Lesezeit weniger als 15 Minuten betrÀgt) zusÀtzlich einschrÀnken.
Wenn Sie bereits in die wunderschöne und wunderbare Welt der Datenwissenschaft eingetaucht sind und Kagglite nicht stĂ€ndig sehen oder (Gott bewahre) die LĂ€nge Ihres Hadup bei Besprechungen mit Kollegen messen möchten, erscheint Ihnen der Artikel höchstwahrscheinlich einfach und uninteressant. DarĂŒber hinaus: Die QualitĂ€t der endgĂŒltigen Modelle ist nicht der Hauptwert dieses Artikels. Wir haben dich gewarnt. Lass uns gehen.
Ein Github-Repository mit dem im Artikel verwendeten Code steht auch neugierigen Lesern zur VerfĂŒgung. Im Fehlerfall öffnen Sie bitte PR.
Es ist möglich, ein Problem zu lösen, fĂŒr das es unendlich lange keine klaren Entscheidungskriterien gibt. Daher werden wir sofort entscheiden, ob wir eine Lösung suchen, mit der wir die Antwort "Gryffindor", "Ravenclaw", "Hufflepuff" oder "Slytherin" als Antwort auf die eingegebene Zeile erhalten.
TatsÀchlich wollen wir eine Black Box bekommen:
" " => [?] => Griffindor
Der ursprĂŒngliche schwarze Hut verteilte junge Zauberer je nach Art und persönlichen QualitĂ€ten an Abteilungen. Da uns keine Daten ĂŒber den Charakter und die Persönlichkeit gemÀà den Bedingungen des Problems zur VerfĂŒgung stehen, verwenden wir den Vor- und Nachnamen des Teilnehmers, wobei wir uns daran erinnern, dass wir in diesem Fall die Charaktere des Buches an diejenigen FakultĂ€ten verteilen sollten, die ihren einheimischen FĂ€higkeiten aus dem Buch entsprechen. Und die Potteromanen wĂ€ren definitiv verĂ€rgert, wenn unsere Entscheidung Harry an Hufflepuff oder Ravenclaw verteilen wĂŒrde (aber es sollte Harry mit gleicher Wahrscheinlichkeit zu Gryffindor und Slytherin schicken, um den Geist des Buches zu vermitteln).
Da es sich um Wahrscheinlichkeiten handelt, formalisieren wir das Problem in strengeren mathematischen Begriffen. Aus Sicht von Data Science lösen wir das Klassifizierungsproblem, indem wir einem Objekt (Linie in Form eines Vor- und Nachnamens) eine bestimmte Klasse zuweisen (tatsÀchlich handelt es sich nur um eine Bezeichnung oder Bezeichnung, bei der es sich um eine Zahl oder 4 Variablen mit einem Ja / Nein-Wert handeln kann ) Wir verstehen, dass es zumindest im Fall von Harry richtig ist, zwei Antworten zu geben: Gryffindor und Slytherin. Es ist daher besser, nicht die spezifische FakultÀt vorherzusagen, die der Hut definiert, sondern die Wahrscheinlichkeit, dass eine Person dieser FakultÀt zugeordnet wird, damit unsere Entscheidung getroffen wird eine Art Funktion
Metriken und QualitÀtsbewertung
Die Aufgabe und das Ziel sind formuliert, Jetzt werden wir ĂŒberlegen, wie wir es lösen können aber das ist noch nicht alles Um die Studie zu starten, mĂŒssen Sie QualitĂ€tsmetriken eingeben. Mit anderen Worten, um zu bestimmen, wie wir zwei verschiedene Lösungen untereinander vergleichen.
Alles im Leben ist gut und einfach - wir verstehen intuitiv, dass ein Spam-Detektor ein Minimum an Spam an eingehende Nachrichten sowie ein Maximum an erforderlichen Briefen weiterleiten muss und auf keinen Fall die erforderlichen Briefe an Spam senden sollte.
In Wirklichkeit ist alles komplizierter und die BestĂ€tigung dafĂŒr ist eine groĂe Anzahl von Artikeln , die erklĂ€ren, wie und welche Metriken verwendet werden. Ăbung hilft, dies am besten zu verstehen, aber dies ist ein so umfangreiches Thema, dass wir versprechen, einen separaten Beitrag darĂŒber zu schreiben und einen offenen Tisch zu erstellen, damit jeder herumspielen und in der Praxis verstehen kann, wie sich dies unterscheidet.
Der Haushalt "aber wĂ€hlen wir das Beste" fĂŒr uns wird ROC AUC sein . Dies ist genau das, was wir in diesem Fall von der Metrik erwarten: Je weniger Fehlalarme und je genauer die tatsĂ€chliche Vorhersage ist, desto gröĂer ist die ROC-AUC.
FĂŒr ein ideales ROC-Modell ist AUC 1, fĂŒr ein ideales Zufallsmodell, das Klassen absolut zufĂ€llig definiert - 0,5.
Algorithmen
Unsere Black Box sollte die Verteilung der Helden der BĂŒcher berĂŒcksichtigen, einen anderen Vor- und Nachnamen als Eingabe verwenden und das Ergebnis angeben. Um das Klassifizierungsproblem zu lösen, können Sie verschiedene Algorithmen fĂŒr maschinelles Lernen verwenden:
Neuronale Netze, Faktorisierungsmaschinen, lineare Regression oder beispielsweise SVM.
Entgegen der landlĂ€ufigen Meinung beschrĂ€nkt sich Data Science nicht nur auf neuronale Netze. Um diese Idee bekannt zu machen, werden neuronale Netze in diesem Artikel als Ăbung fĂŒr einen neugierigen Leser belassen. Diejenigen, die keinen einzigen Kurs in Datenanalyse belegt haben (insbesondere den subjektiv besseren aus dem ODS) oder einfach n Nachrichten ĂŒber maschinelles Lernen oder KI gelesen haben, die jetzt sogar in den Amateurfischermagazinen veröffentlicht werden, mĂŒssen die Namen allgemeiner Gruppen von Algorithmen getroffen haben : Absacken, Boosten, Support Vector Method (SVM), lineare Regression. Mit ihnen werden wir unser Problem lösen.
Und um genauer zu sein, vergleichen wir:
- Lineare Regression
- Boosting (XGboost, LightGBM)
- BĂ€ume entscheiden (genau genommen ist dies der gleiche Schub, aber wir werden ihn separat herausnehmen: Extra BĂ€ume)
- Absacken (Random Forest)
- SVM
Wir können das Problem der Verteilung jedes Hogwarts-SchĂŒlers auf eine der FakultĂ€ten lösen, indem wir die ihm entsprechende FakultĂ€t definieren. Genau genommen besteht diese Aufgabe darin, das Problem der Bestimmung zu lösen, ob jede Klasse einzeln gehört. Daher haben wir uns im Rahmen dieses Artikels das Ziel gesetzt, 4 Modelle zu erhalten, eines fĂŒr jede FakultĂ€t.
Daten
Das Finden des richtigen Datensatzes fĂŒr die Schulung und vor allem der legalen Verwendung fĂŒr den richtigen Zweck ist eine der komplexesten und zeitaufwĂ€ndigsten Aufgaben in Data Science. FĂŒr unsere Aufgabe werden wir die Daten von Wikia aus der ganzen Welt von Harry Potter ĂŒbernehmen. Unter diesem Link finden Sie beispielsweise alle Charaktere, die an der FakultĂ€t von Gryffindor studiert haben. Es ist wichtig, dass wir in diesem Fall die Daten fĂŒr nichtkommerzielle Zwecke verwenden, daher verletzen wir nicht die Lizenz dieser Website.

FĂŒr diejenigen, die Data Scientists fĂŒr so coole Typen halten, gehe ich zu Data Scientists und lasse mich unterrichten. Wir erinnern Sie daran, dass es einen Schritt wie das Bereinigen und Vorbereiten von Daten gibt. Heruntergeladene Daten mĂŒssen manuell moderiert werden, um beispielsweise "Der siebte PrĂ€fekt von Gryffindor" und das "Unbekannte MĂ€dchen aus Gryffindor" halbautomatisch zu löschen. In der realen Arbeit ist ein proportional groĂer Teil der Aufgabe immer mit der Vorbereitung, Reinigung und Wiederherstellung fehlender Werte im Datensatz verbunden.
Ein wenig Strg + C & Strg + V und am Ausgang erhalten wir 4 Textdateien, die die Namen der Zeichen in 2 Sprachen enthalten: Englisch und Russisch.
Wir untersuchen die gesammelten Daten (EDA, Exploratory Data Analysis)
FĂŒr diese Phase haben wir 4 Dateien mit den Namen der Studierenden der FakultĂ€ten, wir werden genauer hinschauen:
$ ls ../input griffindor.txt hufflpuff.txt ravenclaw.txt slitherin.txt
Jede Datei enthĂ€lt 1 Vor- und Nachnamen (falls vorhanden) des SchĂŒlers pro Zeile:
$ wc -l ../input/*.txt 250 ../input/griffindor.txt 167 ../input/hufflpuff.txt 180 ../input/ravenclaw.txt 254 ../input/slitherin.txt 851 total
Die gesammelten Daten haben die Form:
$ cat ../input/griffindor.txt | head -3 && cat ../input/griffindor.txt | tail -3 Charlie Stainforth Melanie Stanmore Stewart
Unsere ganze Idee basiert auf der Annahme, dass die Vor- und Nachnamen etwas Ăhnliches enthalten, das unsere Black Box (oder unser schwarzer Hut) unterscheiden kann.
Der Algorithmus kann die Zeilen so wie sie sind fĂŒttern, aber das Ergebnis wird nicht gut sein, da die Grundmodelle nicht unabhĂ€ngig verstehen können, wie sich âDracoâ von âHarryâ unterscheidet. Daher mĂŒssen wir Zeichen aus unseren Vor- und Nachnamen extrahieren.
Datenvorbereitung (Feature Engineering)
Zeichen (oder Merkmale aus dem englischen Merkmal - Eigenschaft) sind die unterscheidenden Eigenschaften eines Objekts. Die HĂ€ufigkeit, mit der eine Person im letzten Jahr den Arbeitsplatz gewechselt hat, die Anzahl der Finger an der linken Hand, die Motorleistung des Motors, unabhĂ€ngig davon, ob der Kilometerstand des Autos 100.000 km ĂŒberschreitet oder nicht. Alle Arten von Klassifikationen von Zeichen wurden von einer sehr groĂen Anzahl erfunden. Es gibt in dieser Hinsicht kein und kann kein einziges System geben. Wir werden daher Beispiele dafĂŒr geben, was Zeichen sein können:
- Rationale Nummer
- Kategorie (bis zu 12, 12-18 oder 18+)
- BinĂ€rwert (Erstes Darlehen zurĂŒckgegeben oder nicht)
- Datum, Farbe, Anteile usw.
Die Suche (oder Bildung) von Features (im englischen Feature Engineering ) fĂ€llt sehr oft als separate Forschungsphase oder als Arbeit eines Datenanalysespezialisten auf. In der Tat helfen gesunder Menschenverstand, Erfahrung und Hypothesentests im Prozess selbst. Das richtige Erraten der richtigen Zeichen ist eine Frage der Kombination von voller Hand, grundlegendem Wissen und GlĂŒck. Manchmal steckt Schamanismus darin, aber der allgemeine Ansatz ist sehr einfach: Sie mĂŒssen das tun, was Ihnen in den Sinn kommt, und dann prĂŒfen, ob es möglich war, die Lösung durch HinzufĂŒgen eines neuen Attributs zu verbessern. Als Zeichen fĂŒr unsere Aufgabe können wir beispielsweise die Anzahl der Brutzeln im Namen nehmen.
In der ersten Version (da die eigentliche Data Science-Studie - als Meisterwerk niemals abgeschlossen werden kann) unseres Modells werden wir die folgenden Funktionen fĂŒr den Vor- und Nachnamen verwenden:
- 1 und der letzte Buchstabe des Wortes - Vokal oder Konsonant
- Doppelvokale und Konsonanten
- Anzahl der Vokale, Konsonanten, taub, stimmhaft
- NamenslÀnge, NachnamenlÀnge
- ...
Dazu nehmen wir dieses Repository als Grundlage und fĂŒgen eine Klasse hinzu, damit es fĂŒr lateinische Buchstaben verwendet werden kann. Dies gibt uns die Möglichkeit zu bestimmen, wie jeder Buchstabe klingt.
>> from Phonetic import RussianLetter, EnglishLetter >> RussianLetter('').classify() {'consonant': True, 'deaf': False, 'hard': False, 'mark': False, 'paired': False, 'shock': False, 'soft': False, 'sonorus': True, 'vowel': False} >> EnglishLetter('d').classify() {'consonant': True, 'deaf': False, 'hard': True, 'mark': False, 'paired': False, 'shock': False, 'soft': False, 'sonorus': True, 'vowel': False}
Jetzt können wir einfache Funktionen zur Berechnung von Statistiken definieren, zum Beispiel:
def starts_with_letter(word, letter_type='vowel'): """ , . :param word: :param letter_type: 'vowel' 'consonant'. . :return: Boolean """ if len(word) == 0: return False return Letter(word[0]).classify()[letter_type] def count_letter_type(word): """ . :param word: :param debug: :return: :obj:`dict` of :obj:`str` => :int:count """ count = { 'consonant': 0, 'deaf': 0, 'hard': 0, 'mark': 0, 'paired': 0, 'shock': 0, 'soft': 0, 'sonorus': 0, 'vowel': 0 } for letter in word: classes = Letter(letter).classify() for key in count.keys(): if classes[key]: count[key] += 1 return count
Mit diesen Funktionen können wir bereits die ersten Anzeichen erhalten:
from feature_engineering import * >> print(" («»): ", len("")) («»): 5 >> print(" («») : ", starts_with_letter('', 'vowel')) («») : False >> print(" («») : ", starts_with_letter('', 'consonant')) («») : True >> count_Harry = count_letter_type("") >> print (" («»): ", count_Harry['paired']) («»): 1
Genau genommen können wir mit Hilfe dieser Funktionen eine Vektordarstellung des Strings erhalten, dh wir erhalten das Mapping:
Jetzt können wir unsere Daten in Form eines Datensatzes prĂ€sentieren, der in den Algorithmus fĂŒr maschinelles Lernen eingegeben werden kann:
>> from data_loaders import load_processed_data >> hogwarts_df = load_processed_data() >> hogwarts_df.head()

DarĂŒber hinaus erhalten wir fĂŒr jeden SchĂŒler die folgenden Symptome:
>> hogwarts_df[hogwarts_df.columns].dtypes
Zeichen erhalten name object surname object is_english bool name_starts_with_vowel bool name_starts_with_consonant bool name_ends_with_vowel bool name_ends_with_consonant bool name_length int64 name_vowels_count int64 name_double_vowels_count int64 name_consonant_count int64 name_double_consonant_count int64 name_paired_count int64 name_deaf_count int64 name_sonorus_count int64 surname_starts_with_vowel bool surname_starts_with_consonant bool surname_ends_with_vowel bool surname_ends_with_consonant bool surname_length int64 surname_vowels_count int64 surname_double_vowels_count int64 surname_consonant_count int64 surname_double_consonant_count int64 surname_paired_count int64 surname_deaf_count int64 surname_sonorus_count int64 is_griffindor int64 is_hufflpuff int64 is_ravenclaw int64 is_slitherin int64 dtype: object
Die letzten 4 Spalten sind zielgerichtet - sie enthalten Informationen darĂŒber, an welcher FakultĂ€t ein Student eingeschrieben ist.
Algorithmus-Training
Kurz gesagt, Algorithmen werden wie Menschen trainiert: Sie machen Fehler und lernen daraus. Um zu verstehen, wie viel sie einen Fehler gemacht haben, verwenden die Algorithmen Fehlerfunktionen (Verlustfunktionen, englische Verlustfunktion ).
Der Lernprozess ist in der Regel sehr einfach und besteht aus mehreren Schritten:
- Machen Sie eine Vorhersage.
- Bewerten Sie den Fehler.
- Korrigieren Sie die Modellparameter.
- Wiederholen Sie 1-3, bis das Ziel erreicht ist, der Prozess stoppt oder die Daten enden.
Bewerten Sie die QualitÀt des resultierenden Modells.
In der Praxis ist natĂŒrlich alles etwas komplizierter. Zum Beispiel gibt es das PhĂ€nomen der Ăberanpassung - der Algorithmus kann sich buchstĂ€blich merken, welche Merkmale der Antwort entsprechen, und somit das Ergebnis fĂŒr Objekte verschlechtern, die denen, auf denen er trainiert wurde, nicht Ă€hnlich sind. Um dies zu vermeiden, gibt es verschiedene Techniken und Hacks.
Wie oben erwĂ€hnt, werden wir 4 Probleme lösen: eines fĂŒr jede FakultĂ€t. Daher werden wir Daten fĂŒr Slytherin vorbereiten:
WĂ€hrend des Lernens vergleicht der Algorithmus seine Ergebnisse stĂ€ndig mit realen Daten, da dieser Teil des Datensatzes zur Validierung zugewiesen wird. Die Regel des guten Tons wird auch berĂŒcksichtigt, um das Ergebnis des Algorithmus anhand einzelner Daten zu bewerten, die der Algorithmus ĂŒberhaupt nicht gesehen hat. Daher teilen wir jetzt die Stichprobe im VerhĂ€ltnis 70/30 und trainieren den ersten Algorithmus:
from sklearn.cross_validation import train_test_split from sklearn.ensemble import RandomForestClassifier
Fertig. Wenn Sie nun Daten an die Eingabe dieses Modells senden, wird ein Ergebnis erstellt. Das macht SpaĂ, also werden wir zuerst prĂŒfen, ob das Modell in Harry den Slytherin erkennt. Bereiten Sie dazu zunĂ€chst die Funktionen vor, um die Vorhersage des Algorithmus zu erhalten:
Code anzeigen from data_loaders import parse_line_to_hogwarts_df import pandas as pd def get_single_student_features (name): """ :param name: string :return: pd.DataFrame """ featurized_person_df = parse_line_to_hogwarts_df(name) person_df = pd.DataFrame(featurized_person_df, columns=[ 'name', 'surname', 'is_english', 'name_starts_with_vowel', 'name_starts_with_consonant', 'name_ends_with_vowel', 'name_ends_with_consonant', 'name_length', 'name_vowels_count', 'name_double_vowels_count', 'name_consonant_count', 'name_double_consonant_count', 'name_paired_count', 'name_deaf_count', 'name_sonorus_count', 'surname_starts_with_vowel', 'surname_starts_with_consonant', 'surname_ends_with_vowel', 'surname_ends_with_consonant', 'surname_length', 'surname_vowels_count', 'surname_double_vowels_count', 'surname_consonant_count', 'surname_double_consonant_count', 'surname_paired_count', 'surname_deaf_count', 'surname_sonorus_count', ], index=[0] ) featurized_person = person_df.drop( ['name', 'surname'], axis = 1 ) return featurized_person def get_predictions_vector (model, person): """ :param model: :param person: string :return: list """ encoded_person = get_single_student_features(person) return model.predict_proba(encoded_person)[0]
Stellen wir nun einen kleinen Testdatensatz ein, um die Ergebnisse des Algorithmus zu berĂŒcksichtigen.
def score_testing_dataset (model): """ . :param model: """ testing_dataset = [ " ", "Kirill Malev", " ", "Harry Potter", " ", " ","Severus Snape", " ", "Tom Riddle", " ", "Salazar Slytherin"] for name in testing_dataset: print ("{} â {}".format(name, get_predictions_vector(model, name)[1])) score_testing_dataset(rfc_model)
â 0.5 Kirill Malev â 0.5 â 0.0 Harry Potter â 0.0 â 0.75 â 0.9 Severus Snape â 0.5 â 0.2 Tom Riddle â 0.5 â 0.2 Salazar Slytherin â 0.3
Die Ergebnisse waren zweifelhaft. Selbst der GrĂŒnder der FakultĂ€t wĂ€re nach diesem Modell nicht in seiner FakultĂ€t. Daher mĂŒssen Sie die strenge QualitĂ€t bewerten: Sehen Sie sich die Metriken an, die wir zu Beginn gefragt haben:
from sklearn.metrics import accuracy_score, roc_auc_score, classification_report predictions = rfc_model.predict(X_test) print("Classification report: ") print(classification_report(y_test, predictions)) print("Accuracy for Random Forest Model: %.2f" % (accuracy_score(y_test, predictions) * 100)) print("ROC AUC from first Random Forest Model: %.2f" % (roc_auc_score(y_test, predictions)))
Classification report: precision recall f1-score support 0 0.66 0.88 0.75 168 1 0.38 0.15 0.21 89 avg / total 0.56 0.62 0.56 257 Accuracy for Random Forest Model: 62.26 ROC AUC from first Random Forest Model: 0.51
Es ist nicht ĂŒberraschend, dass die Ergebnisse so zweifelhaft waren - die ROC AUC von etwa 0,51 legt nahe, dass das Modell etwas besser vorhersagt als ein MĂŒnzwurf.
Testen der Ergebnisse. QualitÀtsmetriken
Anhand eines obigen Beispiels haben wir uns angesehen, wie 1 Algorithmus trainiert wird, der sklearn-Schnittstellen unterstĂŒtzt. Der Rest wird genauso trainiert, so dass wir nur alle Algorithmen trainieren und jeweils den besten auswĂ€hlen können.

Dies ist nicht kompliziert, da wir fĂŒr jeden Algorithmus 1 mit Standardeinstellungen trainieren und auch einen ganzen Satz trainieren, wobei verschiedene Optionen sortiert werden, die sich auf die QualitĂ€t des Algorithmus auswirken. Diese Phase wird als Modelloptimierung oder Hyperparameteroptimierung bezeichnet und ist im Wesentlichen sehr einfach: Der Satz von Einstellungen, der das beste Ergebnis liefert, wird ausgewĂ€hlt.
from model_training import train_classifiers from data_loaders import load_processed_data import warnings warnings.filterwarnings('ignore')
â 0.09437856871661066 Kirill Malev â 0.20820536334902712 â 0.07550095601699099 Harry Potter â 0.07683794773639624 â 0.9414529336862744 â 0.9293671807790949 Severus Snape â 0.6576783576162999 â 0.18577792617672767 Tom Riddle â 0.8351835484058869 â 0.25930925139546795 Salazar Slytherin â 0.24008788903854789
Die Zahlen in dieser Version sehen subjektiv besser aus als in der Vergangenheit, sind aber fĂŒr einen internen Perfektionisten immer noch nicht gut genug. Daher werden wir eine Ebene tiefer gehen und zum ProduktgefĂŒhl unserer Aufgabe zurĂŒckkehren: Wir mĂŒssen die wahrscheinlichste FĂ€higkeit vorhersagen, fĂŒr die der Held durch den verteilenden Hut bestimmt wird. Dies bedeutet, dass Sie Modelle fĂŒr jede der FakultĂ€ten trainieren mĂŒssen.

>> from model_training import train_all_models
Langer Abschluss der Ergebnisse und Ergebnisse der multinomialen Regression SVM Default Report Accuracy for SVM Default: 73.93 ROC AUC for SVM Default: 0.53 Tuned SVM Report Accuracy for Tuned SVM: 72.37 ROC AUC for Tuned SVM: 0.50 KNN Default Report Accuracy for KNN Default: 70.04 ROC AUC for KNN Default: 0.58 Tuned KNN Report Accuracy for Tuned KNN: 69.65 ROC AUC for Tuned KNN: 0.58 XGBoost Default Report Accuracy for XGBoost Default: 70.43 ROC AUC for XGBoost Default: 0.54 Tuned XGBoost Report Accuracy for Tuned XGBoost: 68.09 ROC AUC for Tuned XGBoost: 0.56 Random Forest Default Report Accuracy for Random Forest Default: 73.93 ROC AUC for Random Forest Default: 0.62 Tuned Random Forest Report Accuracy for Tuned Random Forest: 74.32 ROC AUC for Tuned Random Forest: 0.54 Extra Trees Default Report Accuracy for Extra Trees Default: 69.26 ROC AUC for Extra Trees Default: 0.57 Tuned Extra Trees Report Accuracy for Tuned Extra Trees: 73.54 ROC AUC for Tuned Extra Trees: 0.55 LGBM Default Report Accuracy for LGBM Default: 70.82 ROC AUC for LGBM Default: 0.62 Tuned LGBM Report Accuracy for Tuned LGBM: 74.71 ROC AUC for Tuned LGBM: 0.53 RGF Default Report Accuracy for RGF Default: 70.43 ROC AUC for RGF Default: 0.58 Tuned RGF Report Accuracy for Tuned RGF: 71.60 ROC AUC for Tuned RGF: 0.60 FRGF Default Report Accuracy for FRGF Default: 68.87 ROC AUC for FRGF Default: 0.59 Tuned FRGF Report Accuracy for Tuned FRGF: 69.26 ROC AUC for Tuned FRGF: 0.59 SVM Default Report Accuracy for SVM Default: 70.43 ROC AUC for SVM Default: 0.50 Tuned SVM Report Accuracy for Tuned SVM: 71.60 ROC AUC for Tuned SVM: 0.50 KNN Default Report Accuracy for KNN Default: 63.04 ROC AUC for KNN Default: 0.49 Tuned KNN Report Accuracy for Tuned KNN: 65.76 ROC AUC for Tuned KNN: 0.50 XGBoost Default Report Accuracy for XGBoost Default: 69.65 ROC AUC for XGBoost Default: 0.54 Tuned XGBoost Report Accuracy for Tuned XGBoost: 68.09 ROC AUC for Tuned XGBoost: 0.50 Random Forest Default Report Accuracy for Random Forest Default: 66.15 ROC AUC for Random Forest Default: 0.51 Tuned Random Forest Report Accuracy for Tuned Random Forest: 70.43 ROC AUC for Tuned Random Forest: 0.50 Extra Trees Default Report Accuracy for Extra Trees Default: 64.20 ROC AUC for Extra Trees Default: 0.49 Tuned Extra Trees Report Accuracy for Tuned Extra Trees: 70.82 ROC AUC for Tuned Extra Trees: 0.51 LGBM Default Report Accuracy for LGBM Default: 67.70 ROC AUC for LGBM Default: 0.56 Tuned LGBM Report Accuracy for Tuned LGBM: 70.82 ROC AUC for Tuned LGBM: 0.50 RGF Default Report Accuracy for RGF Default: 66.54 ROC AUC for RGF Default: 0.52 Tuned RGF Report Accuracy for Tuned RGF: 65.76 ROC AUC for Tuned RGF: 0.53 FRGF Default Report Accuracy for FRGF Default: 65.76 ROC AUC for FRGF Default: 0.53 Tuned FRGF Report Accuracy for Tuned FRGF: 69.65 ROC AUC for Tuned FRGF: 0.52 SVM Default Report Accuracy for SVM Default: 74.32 ROC AUC for SVM Default: 0.50 Tuned SVM Report Accuracy for Tuned SVM: 74.71 ROC AUC for Tuned SVM: 0.51 KNN Default Report Accuracy for KNN Default: 69.26 ROC AUC for KNN Default: 0.48 Tuned KNN Report Accuracy for Tuned KNN: 73.15 ROC AUC for Tuned KNN: 0.49 XGBoost Default Report Accuracy for XGBoost Default: 72.76 ROC AUC for XGBoost Default: 0.49 Tuned XGBoost Report Accuracy for Tuned XGBoost: 74.32 ROC AUC for Tuned XGBoost: 0.50 Random Forest Default Report Accuracy for Random Forest Default: 73.93 ROC AUC for Random Forest Default: 0.52 Tuned Random Forest Report Accuracy for Tuned Random Forest: 74.32 ROC AUC for Tuned Random Forest: 0.50 Extra Trees Default Report Accuracy for Extra Trees Default: 73.93 ROC AUC for Extra Trees Default: 0.52 Tuned Extra Trees Report Accuracy for Tuned Extra Trees: 73.93 ROC AUC for Tuned Extra Trees: 0.50 LGBM Default Report Accuracy for LGBM Default: 73.54 ROC AUC for LGBM Default: 0.52 Tuned LGBM Report Accuracy for Tuned LGBM: 74.32 ROC AUC for Tuned LGBM: 0.50 RGF Default Report Accuracy for RGF Default: 73.54 ROC AUC for RGF Default: 0.51 Tuned RGF Report Accuracy for Tuned RGF: 73.93 ROC AUC for Tuned RGF: 0.50 FRGF Default Report Accuracy for FRGF Default: 73.93 ROC AUC for FRGF Default: 0.53 Tuned FRGF Report Accuracy for Tuned FRGF: 73.93 ROC AUC for Tuned FRGF: 0.50 SVM Default Report Accuracy for SVM Default: 80.54 ROC AUC for SVM Default: 0.50 Tuned SVM Report Accuracy for Tuned SVM: 80.93 ROC AUC for Tuned SVM: 0.52 KNN Default Report Accuracy for KNN Default: 78.60 ROC AUC for KNN Default: 0.50 Tuned KNN Report Accuracy for Tuned KNN: 80.16 ROC AUC for Tuned KNN: 0.51 XGBoost Default Report Accuracy for XGBoost Default: 80.54 ROC AUC for XGBoost Default: 0.50 Tuned XGBoost Report Accuracy for Tuned XGBoost: 77.04 ROC AUC for Tuned XGBoost: 0.52 Random Forest Default Report Accuracy for Random Forest Default: 77.43 ROC AUC for Random Forest Default: 0.49 Tuned Random Forest Report Accuracy for Tuned Random Forest: 80.54 ROC AUC for Tuned Random Forest: 0.50 Extra Trees Default Report Accuracy for Extra Trees Default: 76.26 ROC AUC for Extra Trees Default: 0.48 Tuned Extra Trees Report Accuracy for Tuned Extra Trees: 78.60 ROC AUC for Tuned Extra Trees: 0.50 LGBM Default Report Accuracy for LGBM Default: 75.49 ROC AUC for LGBM Default: 0.51 Tuned LGBM Report Accuracy for Tuned LGBM: 80.54 ROC AUC for Tuned LGBM: 0.50 RGF Default Report Accuracy for RGF Default: 78.99 ROC AUC for RGF Default: 0.52 Tuned RGF Report Accuracy for Tuned RGF: 75.88 ROC AUC for Tuned RGF: 0.55 FRGF Default Report Accuracy for FRGF Default: 76.65 ROC AUC for FRGF Default: 0.50 # ,
from sklearn.linear_model import LogisticRegression clf = LogisticRegression(random_state=0, solver='lbfgs', multi_class='multinomial') hogwarts_df = load_processed_data_multi()
â [0.3602361 0.16166944 0.16771712 0.31037733] Kirill Malev â [0.47473072 0.16051924 0.13511385 0.22963619] â [0.38697926 0.19330242 0.17451052 0.2452078 ] Harry Potter â [0.40245098 0.16410043 0.16023278 0.27321581] â [0.13197025 0.16438855 0.17739254 0.52624866] â [0.17170203 0.1205678 0.14341742 0.56431275] Severus Snape â [0.15558044 0.21589378 0.17370406 0.45482172] â [0.39301231 0.07397324 0.1212741 0.41174035] Tom Riddle â [0.26623969 0.14194379 0.1728505 0.41896601] â [0.24843037 0.21632736 0.21532696 0.3199153 ] Salazar Slytherin â [0.09359144 0.26735897 0.2742305 0.36481909]
Und confusion_matrix:
confusion_matrix(clf.predict(X_data), y)
array([[144, 68, 64, 78], [ 8, 9, 8, 6], [ 22, 18, 31, 20], [ 77, 73, 78, 151]])
def get_predctions_vector (models, person): predictions = [get_predictions_vector (model, person)[1] for model in models] return { 'slitherin': predictions[0], 'griffindor': predictions[1], 'ravenclaw': predictions[2], 'hufflpuff': predictions[3] } def score_testing_dataset (models): testing_dataset = [ " ", "Kirill Malev", " ", "Harry Potter", " ", " ","Severus Snape", " ", "Tom Riddle", " ", "Salazar Slytherin"] data = [] for name in testing_dataset: predictions = get_predctions_vector(models, name) predictions['name'] = name data.append(predictions) scoring_df = pd.DataFrame(data, columns=['name', 'slitherin', 'griffindor', 'hufflpuff', 'ravenclaw']) return scoring_df
name slitherin griffindor hufflpuff ravenclaw 0 0.349084 0.266909 0.110311 0.091045 1 Kirill Malev 0.289914 0.376122 0.384986 0.103056 2 0.338258 0.400841 0.016668 0.124825 3 Harry Potter 0.245377 0.357934 0.026287 0.154592 4 0.917423 0.126997 0.176640 0.096570 5 0.969693 0.106384 0.150146 0.082195 6 Severus Snape 0.663732 0.259189 0.290252 0.074148 7 0.268466 0.579401 0.007900 0.083195 8 Tom Riddle 0.639731 0.541184 0.084395 0.156245 9 0.653595 0.147506 0.172940 0.137134 10 Salazar Slytherin 0.647399 0.169964 0.095450 0.26126

, . ROC AUC , 0.5. , :
, , , , XGBoost CV , .
Wichtig! , 70% . , 4 .
from model_training import train_production_models from xgboost import XGBClassifier best_models = [] for i in range (0,4): best_models.append(XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1, colsample_bytree=0.7, gamma=0, learning_rate=0.05, max_delta_step=0, max_depth=6, min_child_weight=11, missing=-999, n_estimators=1000, n_jobs=1, nthread=4, objective='binary:logistic', random_state=0, reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=1337, silent=1, subsample=0.8)) slitherin_model, griffindor_model, ravenclaw_model, hufflpuff_model = \ train_production_models(best_models) top_models = slitherin_model, griffindor_model, ravenclaw_model, hufflpuff_model score_testing_dataset(top_models)
name slitherin griffindor hufflpuff ravenclaw 0 0.273713 0.372337 0.065923 0.279577 1 Kirill Malev 0.401603 0.761467 0.111068 0.023902 2 0.031540 0.616535 0.196342 0.217829 3 Harry Potter 0.183760 0.422733 0.119393 0.173184 4 0.945895 0.021788 0.209820 0.019449 5 0.950932 0.088979 0.084131 0.012575 6 Severus Snape 0.634035 0.088230 0.249871 0.036682 7 0.426440 0.431351 0.028444 0.083636 8 Tom Riddle 0.816804 0.136530 0.069564 0.035500 9 0.409634 0.213925 0.028631 0.252723 10 Salazar Slytherin 0.824590 0.067910 0.111147 0.085710
, , .
, , . .
import pickle pickle.dump(slitherin_model, open("../output/slitherin.xgbm", "wb")) pickle.dump(griffindor_model, open("../output/griffindor.xgbm", "wb")) pickle.dump(ravenclaw_model, open("../output/ravenclaw.xgbm", "wb")) pickle.dump(hufflpuff_model, open("../output/hufflpuff.xgbm", "wb"))
, . , , , .
, , . , . , Data Scientist â -.
:
, docker-, python-. , flask.
from __future__ import print_function
Dockerfile:
FROM datmo/python-base:cpu-py35
:
docker build -t talking_hat . && docker rm talking_hat && docker run --name talking_hat -p 5000:5000 talking_hat
â . , Apache Benchmark . , . â .
$ ab -p data.json -T application/json -c 50 -n 10000 http://0.0.0.0:5000/predict
ab This is ApacheBench, Version 2.3 <$Revision: 1807734 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 0.0.0.0 (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: Werkzeug/0.14.1 Server Hostname: 0.0.0.0 Server Port: 5000 Document Path: /predict Document Length: 141 bytes Concurrency Level: 50 Time taken for tests: 238.552 seconds Complete requests: 10000 Failed requests: 0 Total transferred: 2880000 bytes Total body sent: 1800000 HTML transferred: 1410000 bytes Requests per second: 41.92 [#/sec] (mean) Time per request: 1192.758 [ms] (mean) Time per request: 23.855 [ms] (mean, across all concurrent requests) Transfer rate: 11.79 [Kbytes/sec] received 7.37 kb/s sent 19.16 kb/s total Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.1 0 3 Processing: 199 1191 352.5 1128 3352 Waiting: 198 1190 352.5 1127 3351 Total: 202 1191 352.5 1128 3352 Percentage of the requests served within a certain time (ms) 50% 1128 66% 1277 75% 1378 80% 1451 90% 1668 95% 1860 98% 2096 99% 2260 100% 3352 (longest request)
, :
def prod_predict_classes_for_name (full_name): <...> predictions = get_predctions_vector([ app.slitherin_model, app.griffindor_model, app.ravenclaw_model, app.hufflpuff_model ], person_df.drop(['name', 'surname'], axis=1)) return { 'slitherin': float(predictions[0][1]), 'griffindor': float(predictions[1][1]), 'ravenclaw': float(predictions[2][1]), 'hufflpuff': float(predictions[3][1]) } def create_app(): <...> with app.app_context(): app.slitherin_model = pickle.load(open("models/slitherin.xgbm", "rb")) app.griffindor_model = pickle.load(open("models/griffindor.xgbm", "rb")) app.ravenclaw_model = pickle.load(open("models/ravenclaw.xgbm", "rb")) app.hufflpuff_model = pickle.load(open("models/hufflpuff.xgbm", "rb")) return app
:
$ docker build -t talking_hat . && docker rm talking_hat && docker run --name talking_hat -p 5000:5000 talking_hat $ ab -p data.json -T application/json -c 50 -n 10000 http://0.0.0.0:5000/predict
ab This is ApacheBench, Version 2.3 <$Revision: 1807734 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 0.0.0.0 (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: Werkzeug/0.14.1 Server Hostname: 0.0.0.0 Server Port: 5000 Document Path: /predict Document Length: 141 bytes Concurrency Level: 50 Time taken for tests: 219.812 seconds Complete requests: 10000 Failed requests: 3 (Connect: 0, Receive: 0, Length: 3, Exceptions: 0) Total transferred: 2879997 bytes Total body sent: 1800000 HTML transferred: 1409997 bytes Requests per second: 45.49 [#/sec] (mean) Time per request: 1099.062 [ms] (mean) Time per request: 21.981 [ms] (mean, across all concurrent requests) Transfer rate: 12.79 [Kbytes/sec] received 8.00 kb/s sent 20.79 kb/s total Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.1 0 2 Processing: 235 1098 335.2 1035 3464 Waiting: 235 1097 335.2 1034 3462 Total: 238 1098 335.2 1035 3464 Percentage of the requests served within a certain time (ms) 50% 1035 66% 1176 75% 1278 80% 1349 90% 1541 95% 1736 98% 1967 99% 2141 100% 3464 (longest request)
Fertig. . , .
Fazit
, . - .
, :
- feature engineering- ( ), , Soundex .
- PyTorch . , , .
- flask Quart , , .
- - -, .
, , . , !
Dieser Artikel wĂ€re ohne die Open Data Science-Community, die eine groĂe Anzahl russischsprachiger Experten auf dem Gebiet der Datenanalyse zusammenbringt, nicht veröffentlicht worden.