Erstausgabe: 2020/3/10
Verfasser: Soichi Takashige, Masahiro Ito, Hitachi, Ltd.
In diesem Beitrag werden wir das Design-Know-how der Datenvorverarbeitung und die Ergebnisse der Leistungsüberprüfung der Datenvorverarbeitung beim Entwurf eines Systems vorstellen, das ein Modell für maschinelles Lernen enthält.
In der zweiten Folge werden wir das Know-how zur Leistungsverbesserung und die Überprüfungsergebnisse bei der Datenvorverarbeitung mit Python vorstellen.
** Beitragsliste: **
Bevor wir das Design-Know-how und die Ergebnisse der Leistungsüberprüfung vorstellen, werden wir die Benchmarks einführen, die in der Überprüfung als Referenzen bezeichnet werden. Dieses Mal habe ich BigBench verwendet, eines der Benchmark-Programme für die Big-Data-Analyse. BigBench ist ein Benchmark-Programm, das ein System simuliert, das Daten wie den Zugriff auf Benutzer auf Online-E-Commerce-Websites analysiert und auf strukturierte oder halbstrukturierte Daten wie Daten in RDB- und Webprotokollen abzielt. Individuelle Geschäftsszenarien und Benchmark-Programme werden definiert. Abbildung 1 zeigt die BigBench-Datenstruktur.
Abbildung 1 BigBench-Datenstruktur
Dieses Mal haben wir uns unter den 30 Geschäftsszenarien von BigBench auf das Geschäftsszenario Nr. 5 bezogen, das die komplizierteste Verarbeitung darstellt und als typisches Beispiel für die Datenvorverarbeitung als Verifizierungsziel bezeichnet werden kann, und den ursprünglichen Code unabhängig in Python implementiert. .. Das Geschäftsszenario Nr. 5 sieht folgendermaßen aus:
Erstellen Sie ein logistisches Regressionsmodell, das die Produktkategorien, an denen der Benutzer interessiert ist, aus dem Webzugriffsverlauf des Online-Shop-Benutzers schätzt.
Abbildung 2 zeigt eine Übersicht über die Verarbeitung des Geschäftsszenarios Nr. 5.
Abbildung 2 Überblick über die Verarbeitung des BigBench-Geschäftsszenarios Nr. 5
Dieses Szenario ist in eine Lernphase und eine Inferenzphase unterteilt. In der Lernphase basiert jeder Benutzer (Kunde) auf verwandten Informationen wie dem Zugriffsverlauf (web_clickstreams) auf Online-Shops im Web, der Produktinformationsdatenbank (Artikel) und der Benutzerinformationsdatenbank (Kunde) (Kunde, Kundendemografie). Organisieren Sie den Übergangsverlauf des Online-Shops und die Benutzereigenschaften (Bildungshintergrund, Geschlecht usw.) als statistische Daten. Basierend auf diesen statistischen Daten erstellen wir ein Regressionsmodell, das schätzt, ob ein Benutzer an einem bestimmten Bereich interessiert ist (z. B. "Bücher"). In der Inferenzphase werden statistische Daten erstellt, die den Zugriffsverlauf usw. für einen Benutzer aggregieren, und auf das in der Lernphase erstellte Regressionsmodell angewendet, um abzuschätzen, wie interessiert der Benutzer am Feld "Bücher" ist. Ich werde. Hier zeigt 3 den Fluss der Datenvorverarbeitung, die für diese Überprüfung implementiert wurde, unter Bezugnahme auf das Innere des Geschäftsszenarios Nr. 5.
Abbildung 3 Überblick über den Vorverarbeitungsalgorithmus für das BigBench-Geschäftsszenario Nr. 5 (Lernphase)
Diese Vorverarbeitung besteht aus den folgenden vier Phasen.
** 1) [Zugriffshistorie und Produktinformationen kombinieren] ** Verknüpfen Sie den Webzugriffsverlauf mit der Produktdatenbank, damit er nach Kategorie ((1) in Abb. 3) klassifiziert werden kann.
** 2) [Nach Benutzer aggregieren] ** Die Häufigkeit, mit der auf das Produkt in jeder Kategorie für jeden zugreifenden Benutzer geklickt wird, ist in der Tabelle aufgeführt (②③ in Abb. 3).
** 3) [Benutzerinformationen kombinieren] ** Durch Verknüpfen der Attributinformationen des zugreifenden Benutzers mit den aggregierten Informationen für jeden Benutzer ist es möglich, nach dem Attribut des Benutzers zu klassifizieren (④⑤ in 3).
** 4) [Eigenschaften] ** Konvertieren Sie Textinformationen usw. in eine numerische Zeichenfolge, damit sie beim maschinellen Lernen verwendet werden können (⑥ und ⑦ in Abb. 3).
Abbildung 4 zeigt ein Beispiel für die Implementierung der Datenvorverarbeitung in Python für das BigBench-Geschäftsszenario Nr. 5. Dieses Mal werden wir basierend auf diesem Code eine Verbesserung der Verarbeitung in Betracht ziehen.
Anfangscode(Für PoC)
import pandas as pd
import numpy as np
#Daten gelesen
web_clickstreams = pd.read_csv("web_clickstreams.csv")
item = pd.read_csv("item.csv");
customer = pd.read_csv("customer.csv")
customer_demographics = pd.read_csv("customer_demographics.csv")
#Prozess (1): Kombinieren von Zugriffshistorie und Produktinformationen
data = web_clickstreams.loc[web_clickstreams['web_clickstreams.wcs_user_sk'].notnull(), :]
data = pd.merge(data, item, how='inner', left_on=['wcs_item_sk'], right_on=['i_item_sk'])
#Prozess (2): Teilen Sie die Daten durch die Benutzer-ID
data = data.groupby('wcs_user_sk')
#Prozess ③: Nach Benutzer aggregieren
i_category_index = "Books"
types = ['wcs_user_sk', 'clicks_in_category']+['clicks_in_%d'%i for i in range(1, 8)]
def summarize_per_user(data_mr):
wcs_user_sk_index = data_mr.name
# ③-1,③-2 Eine bestimmte Produktkategorie(Books)Aggregieren Sie die Anzahl der Zugriffe auf
clicks_in_category = len(data_mr[data_mr['i_category'] == i_category_index])
# ③-3 ‘i_category_id’==Berechnen Sie für 1… 7
# ③-3-1, ③-3-2 ‘i_category_id’==Aggregieren Sie die Anzahl der i-Zugriffsprotokolle
return pd.Series([wcs_user_sk_index, i_category_index] + \
[len(data_mr[data_mr['i_category_id']==i]) for i in range(1, 8)], \
index = types)
data = data.apply(summarize_per_user)
#Prozess ④: Mit Benutzerinformationen kombinieren
data = pd.merge(data, customer, how='inner', left_on=['wcs_user_sk'], right_on=['c_customer_sk'])
#Prozess ⑤: Mit Benutzerattributinformationen kombinieren
data = pd.merge(data, customer_demographics, how='inner', \
left_on=['c_current_cdemo_sk'], right_on=['cd_demo_sk'])
#Prozess ⑥: Merkmalsquantifizierung
data['college_education'] = data['cd_education_status'].apply( \
lambda x: 1 if x == 'Advanced Degree' or x == 'College' or \
x == '4 yr Degree' or x == '2 yr Degree' else 0)
data['male'] = data['cd_gender'].apply(lambda x: 1 if x == 'M' else 0)
#Verarbeitung ⑦:Extrahieren Sie die erforderlichen Informationen und ersetzen Sie sie
result = pd.DataFrame(data[['clicks_in_category', 'college_education', 'male', \
'clicks_in_1', 'clicks_in_2', 'clicks_in_3', \
'clicks_in_4', 'clicks_in_5', 'clicks_in_6', 'clicks_in_7']])
#Ergebnisse speichern
result.to_csv('result-apply.csv')
Abbildung 4 Codebeispiel für das BigBench-Geschäftsszenario Nr. 5
Beginnen wir mit den Verbesserungen, die in reinem Python vorgenommen werden können. Bei der Python-Codierung ist die Logikoptimierung als Know-how zur Verbesserung der Leistung wichtig. Die folgenden zwei Punkte wurden untersucht und als logische Optimierung angewendet, von der diesmal ein großer Einfluss auf den Code des Zielgeschäfts erwartet werden kann.
Wenn die iterative Verarbeitung in einer for-Schleife usw. ausgeführt wird, wird die Verarbeitung aufgrund von Python-Einschränkungen nur auf einer einzelnen CPU ausgeführt. Durch Umschreiben in Pandas-Funktionen wie Apply und Map kann es parallel zu mehreren Threads intern ausgeführt und beschleunigt werden.
Wenn in verschiedenen Fällen derselbe Datenbereich verarbeitet wird, kann die Datenfilterung, z. B. Filter, viele Male mit unterschiedlichen bedingten Ausdrücken ausgeführt werden. Ein solcher Code führt mehrere bedingte Vergleiche der Daten für denselben Datenbereich durch, was zu einer schlechten Ausführungseffizienz führt. Eine solche Verarbeitung kann beschleunigt werden, indem sie neu geschrieben wird, so dass sie in einer Schleife durchgeführt werden kann.
In diesem Beispiel wird die Pandas-Funktion zum Zeitpunkt des Codes in Abbildung 4 verwendet.
In dem Code vor der Optimierung im oberen Teil von Fig. 5 unten ist "③-3-Kartenschleife (Wiederholung von 0 ... 7)" in Fig. 3 geschrieben. In diesem Zusammenhang verweisen wir auf die Spalte "i_category_id" der Elemente des Arrays mit dem Namen "data_mr" und zählen die Anzahl der Elemente, deren Werte 1 bis 7 betragen. In dieser Implementierung wird derselbe Datenbereich siebenmal mehr als einmal durchsucht. Durch Umschreiben dieses Prozesses mit groupby kann die Anzahl der Suchvorgänge auf eins reduziert werden.
```python:Vor der Verbesserung
#[Vor der Optimierung] Führen Sie die gesamte Elementsuche siebenmal durch
return pd.Series([wcs_user_sk_index, i_category_index] + \
[len(data_mr[data_mr['i_category_id']==i]) for i in range(1, 8)],\
index=types)
```
```python:Nach der Verbesserung
#[Nach der Optimierung] Führen Sie die gesamte Elementsuche nur einmal durch
clicks_in = [0] * 8
for name, df in data_mr.groupby('i_category_id'):
if name < len(clicks_in):
clicks_in[name] = len(df)
return pd.Series([wcs_user_sk_index, i_category_index] + clicks_in[1:], \
index = types);
```
Abbildung 5 Beispiel für das Ersetzen des Suchvorgangs in einer Schleife durch eine einzelne Suche
Hier messen wir tatsächlich die Leistung des Effekts der in Abb. 5 gezeigten Logikoptimierung.
Bei dieser Leistungsüberprüfung wird AWS verwendet, und seine Spezifikationen sind in der folgenden Tabelle 1 aufgeführt.
Tabelle 1 Hardwarespezifikationen der Verifizierungsumgebung
Überprüfungsumgebung für die Vorverarbeitung von Python-Daten | |
---|---|
Beispiel | AWS EC2 |
OS | CentOS 7 64bit |
CPU(Zahl der Kerne) | 32 |
Memory(GB) | 256 |
HDD(TB) | 5 (1 TB Festplatte x 5) |
Die zur Überprüfung verwendeten Softwareversionen sind in der folgenden Tabelle 2 aufgeführt.
Tabelle 2 Softwareversion der Überprüfungsumgebung
Software | Ausführung |
---|---|
Python | 3.7.3 |
Pandas | 0.24.2 |
Numpy | 1.16.4 |
Dieses Mal haben wir die Leistung mit den folgenden zwei Verarbeitungsmethoden gemessen.
Einzelknotenverarbeitung durch Python (ohne Logikoptimierung in Abbildung 5)
Führen Sie den Code in Abbildung 4 unter Python aus.
Einzelknotenverarbeitung durch Python (mit Logikoptimierung in Abb. 5)
Führen Sie den Code in Abb. 4 mit der Optimierung in Abb. 5 in Python aus.
Bei der Messung wird die Gesamtzeit gemessen, die für die folgenden drei Prozesse benötigt wird.
Lesen Sie zur Verarbeitung der Daten alle Daten in den Tabellen (web_clickstream, item, customer, customer-demographics), die für die Verarbeitung von der Festplatte zum Datenrahmen erforderlich sind. Die zu lesenden Daten sind Textdateien und werden von der lokalen Festplatte gelesen.
Vorverarbeitung wie Datenkombination und Aggregation für die gelesenen Daten
Schreiben Sie das Verarbeitungsergebnis in den Datenspeicher
Schreiben Sie Daten im Textformat auf Ihre lokale Festplatte.
Unter der Annahme, dass die vom Produktionssystem verarbeitete Datengröße etwa 50 GB beträgt (geschätzte Größe bei Erweiterung des Arbeitsspeichers), messen Sie mit einigen Datengrößen zwischen 1/100 dieser Datengröße und der erwarteten Produktionsgröße. Und ich habe überprüft, wie sich die Bearbeitungszeit ändert. Tabelle 3 zeigt für jede Messgröße die Größe, wenn die zu verarbeitenden Eingabedaten im Speicher erweitert werden, und die Datengröße, wenn sie ursprünglich im Textformat auf der Festplatte gespeichert wurden. Von nun an verwendet die Datengröße im Messergebnis den Wert der Datengröße im Speicher.
Tabelle 3 Größe der Messdaten
Prozentsatz der Größe der Produktionsdaten[%] | 1 | 5 | 10 | 25 | 50 | 75 | 100 | 200 | 300 |
---|---|---|---|---|---|---|---|---|---|
Anzahl der Datenzeilen- web_clickstreams | 6.7M | 39M | 83M | 226M | 481M | 749M | 1.09G | 2.18G | 3.39G |
Anzahl der Datenzeilen- item | 18K | 40K | 56K | 89K | 126K | 154K | 178K | 252K | 309K |
Anzahl der Datenzeilen- customer | 99K | 221K | 313K | 495K | 700K | 857K | 990K | 1.4M | 1,715 |
Anzahl der Datenzeilen- customer_demographics | 1.9M | 1.9M | 1.9M | 1.9M | 1.9M | 1.9M | 1.9M | 1.9M | 1.9M |
Datengröße im Speicher(GB) | 0.4 | 1.9 | 3.9 | 10.3 | 21.8 | 33.7 | 49.1 | 97.9 | 152.1 |
Datengröße auf der Festplatte(GB) | 0.2 | 1.0 | 2.2 | 6.3 | 13.8 | 21.7 | 29.8 | 63.6 | 100.6 |
Abbildung 6 zeigt die Ergebnisse der Messung der Verarbeitungszeit durch Ausführen jeder der beiden Verarbeitungsarten (mit / ohne Logikoptimierung in Abbildung 5) für jede Datengröße für das BigBench-Geschäftsszenario Nr. 5. .. Außerdem betrug die Datengröße bis zu 22 GB (50% der Produktionsdatengröße), und als ich versuchte, Daten größerer Größe zu verarbeiten, konnte sie aufgrund unzureichenden Speichers nicht verarbeitet werden. Wenn hier die Eingangsdatengröße 0,4 GB beträgt (der Punkt ganz links im Diagramm in Abb. 6), beträgt die Ausführungszeit 412 Sekunden ohne Logikoptimierung und 246 Sekunden mit Logikoptimierung, was etwa 40% entspricht. Es wurde gekürzt. Wenn die Eingangsdatengröße 22 GB beträgt (der Punkt ganz rechts im Diagramm in Abb. 6), beträgt die Ausführungszeit 5.039 Sekunden ohne Logikoptimierung und 3.892 Sekunden mit Logikoptimierung, was einer Reduzierung von ca. 23% entspricht. Ich war im.
Abbildung 6 Messergebnisse der Datenvorverarbeitungszeit für jede Eingangsdatengröße
Abbildung 7 zeigt den Fortschritt der CPU-, Speicher- und Festplatten-E / A-Nutzung bei der Verarbeitung von Daten mit einer Größe von 22 GB. Diesmal hat die Verifizierungsmaschine 32 Kerne, aber Python kann nur 1 Kern verwenden. Daher beträgt die CPU-Auslastungsrate immer etwa 1/32 = 3%. Auf der anderen Seite können Sie sehen, dass ungefähr 200 GB Speicher für die Verarbeitung von Eingabedaten mit einer Größe von ungefähr 22 GB im Speicher verbraucht werden. Dies liegt wahrscheinlich daran, dass das Zwischenverarbeitungsergebnis während der Datenverarbeitung im Speicher verbleibt, sodass auch seine Größe verbraucht wird. Es kann bestätigt werden, dass die E / A nur zum Zeitpunkt des anfänglichen Datenlesens ausgeführt wird und dass die E / A während der Datenverarbeitung nicht auftritt und grundsätzlich im Speicher verarbeitet wird.
Abbildung 7 Zeitliche Änderungen der CPU-, Speicher- und E / A-Nutzung in der Python + Pandas-Umgebung
Es wurde bestätigt, dass ein Leistungsverbesserungseffekt von 40 bis 23% durch Logikoptimierung erzielt werden kann, bei der vermieden wird, dass dieselben Daten wiederholt durchsucht werden. Zu diesem Zeitpunkt nahm der Effekt der Leistungsverbesserung mit zunehmender Datengröße ab. Dies liegt jedoch daran, dass der Verbesserungseffekt von den Dateneigenschaften (Wertebereich und Verteilung) abhängt und sich die Eigenschaften ändern, wenn die Datengröße zunimmt. Ich denke, das lag daran. Selbst wenn die Logik mit Daten einer anderen Größe (einer Teilmenge einer kleinen Größe) wie PoC überoptimiert ist, kann sich der Effekt daher mit Daten im Produktionsmaßstab ändern. Daher wird empfohlen, bei der endgültigen Abstimmung eine Logikoptimierung durchzuführen.
In diesem Beitrag haben wir das Know-how zur Leistungsverbesserung bei der Vorverarbeitung numerischer Daten mit Python und die Ergebnisse der Leistungsüberprüfung auf dem tatsächlichen Computer vorgestellt. Das nächste Mal werde ich die Ergebnisse der Leistungsüberprüfung vorstellen, wenn Spark, eine Plattform für parallele verteilte Verarbeitung, für die Vorverarbeitung numerischer Daten verwendet wird.
Der dritte: Leistungsüberprüfung der Datenvorverarbeitung für maschinelles Lernen (numerische Daten) (Teil 2)
Recommended Posts