[PYTHON] Lernen Sie aus dem siegreichen Code-Mercari-Wettbewerb ①-

Einführung

Als ich Kaggle studierte, entschied ich mich, nach dem Code der Person zu lernen, die den ersten Platz im vergangenen Wettbewerb gewonnen hatte, also diesmal Mercari-Wettbewerb -herausforderung "Qiita") 1. Platz Code War das Thema des Studiums.

Was ich gelernt habe

・ Zeitmessung mit Kontextmanager ・ Pipeline- und Funktionstransformator ・ TF-IDF, Itemgetter, TfidfVectorizer ・ Die Genauigkeit kann auch mit 4-Schicht-MLP (Multilayer Perceptron) erreicht werden. ・ Verwenden Sie partiell, um y_train zu reparieren und nur x_train zu ändern

Mercari Wettbewerbsübersicht

Inhalt

Erstellen eines Modells, das zum Zeitpunkt der Auflistung einen angemessenen Preis vorhersagt

Bedeutung

Durch die automatische Vorlage eines angemessenen Preises aus den Produktinformationen zum Zeitpunkt der Auflistung wird der Arbeitsaufwand zum Zeitpunkt der Auflistung reduziert. Auflistung ist einfach.

Hintergrund

Wenn Sie zu einem hohen Preis außerhalb des Marktpreises von Mercari verkaufen, werden Sie nicht verkaufen Im Gegenteil, wenn der Artikel zu einem Preis angeboten wird, der unter dem Marktpreis von Mercari liegt, verliert der Kunde.

Wettbewerbsbeschränkungen

Kernel-Wettbewerb: Senden Sie den Quellcode selbst an Kaggle. Nach der Übermittlung wird es auf Kaggle ausgeführt und die Punktzahl berechnet. Es gibt Einschränkungen hinsichtlich der Computerressourcen und der Berechnungszeit

CPU: 4 cores Memory: 16GB Disk: 1GB Zeitlimit: 1 Stunde GPU: Keine

Auswertung

RMLSE:Root Mean Squared Logarithmic Error Je niedriger die Punktzahl, desto geringer ist der Fehler bei der Schätzung des Preises. image.png

Das erste Modell ist RMLSE: 0.3875 image.png

Nutzungsdaten

image.png

Spaltenname Erläuterung
name Produktname
item_condition_id Der Zustand des Produkts, wie gebraucht oder neu.(1~5)Der größere ist in einem besseren Zustand.
category_name Grobe Kategorie/Detaillierte Kategorie/よりDetaillierte Kategorie
brand_name Markenname. Beispiel: Nike, Apple
price Vergangener Verkaufspreis(USD)
shipping Ob der Verkäufer oder der Käufer die Versandkosten bezahlt. 1->Verkäufer zahlt, 0 ->Der Käufer zahlt.
item_description Produktdetails

Ausgabeformat

Test_id und Preis image.png

Der Hauptpunkt des 1. Platzcodes

・ Nur 100 Zeilen. einfach. ・ 4-lagiges MLP. Es ist genau. Wurde das neuronale Netz in dieser Zeit noch nicht genutzt? ・ TF-IDF. df ['name']. Fillna ('') + '' '+ df [' markenname ']. Fillna (' ') wird verwendet, um Zeichenfolgen zu kombinieren, um die Genauigkeit zu verbessern? ・ Standardisierung von y_train ・ Lernen Sie 4 Modelle mit 4 Kernen-> Ensemble

Vorbereitung der Lehrerdaten

Messung der für jeden Prozess erforderlichen Zeit

Da es ein Limit von einer Stunde gibt, wird gemessen, wie viel Zeit in welchem Prozess verbracht wird. Mit Timer wird an die Stelle jeder Verarbeitung gesetzt. Beschreibung mit Timer. image.png

Erstellung von Lehrerdaten

qiita.rb


 with timer('process train'):
#Straße
        train = pd.read_table('../input/train.tsv')
#Es ist abstoßend, weil es einen Preis von 0 $ gibt
        train = train[train['price'] > 0].reset_index(drop=True)
#Vorbereiten der Aufteilung der Daten für Schulung und Validierung
        cv = KFold(n_splits=20, shuffle=True, random_state=42)
#Teilen Sie die Daten in Training und Validierung
#.split()Das iterierbare Objekt wird zurückgegeben. "Index zum Lernen und Index zur Verifizierung können abgerufen werden.
#next()Holen Sie sich das Element aus dem Iterator mit
        train_ids, valid_ids = next(cv.split(train))
#Aufteilung für Training und Validierung mit dem erhaltenen Index
        train, valid = train.iloc[train_ids], train.iloc[valid_ids]
#Preis konvertiert 1 Zeile n Spalten in n Zeilen 1 Spalte. Log(a+1)Konvertieren mit. Normalisierung
        y_train = y_scaler.fit_transform(np.log1p(train['price'].values.reshape(-1, 1)))
#In der Pipeline verarbeitet
        X_train = vectorizer.fit_transform(preprocess(train)).astype(np.float32)
        print(f'X_train: {X_train.shape} of {X_train.dtype}')
        del train
#Auch die Vorverarbeitung von Verifizierungsdaten
  with timer('process valid'):
        X_valid = vectorizer.transform(preprocess(valid)).astype(np.float32)

Vorverarbeitung

Da der Markenname einen fehlenden Wert hat, wird er durch ein Leerzeichen ersetzt. Darüber hinaus werden Produktname und Markenname kombiniert. Um es später einfacher zu machen, TF-IDF. Ich erstelle ein neues Element namens Text. 'Name', 'Text', 'Versand' und 'Artikel_Zustand_ID' werden in der nachfolgenden Pipeline-Verarbeitung verwendet.

qiita.rb


def preprocess(df: pd.DataFrame) -> pd.DataFrame:
    df['name'] = df['name'].fillna('') + ' ' + df['brand_name'].fillna('')
    df['text'] = (df['item_description'].fillna('') + ' ' + df['name'] + ' ' + df['category_name'].fillna(''))
    return df[['name', 'text', 'shipping', 'item_condition_id']]

Die Pipeline wird verwendet, damit die Zeichenextraktion und die TF-IDF-Berechnung in einer Reihe von Schritten durchgeführt werden können.

Beschreibung von PipeLine.

qiita.rb


def on_field(f: str, *vec) -> Pipeline:
    return make_pipeline(FunctionTransformer(itemgetter(f), validate=False), *vec)

def to_records(df: pd.DataFrame) -> List[Dict]:
    return df.to_dict(orient='records')

 vectorizer = make_union(
        on_field('name', Tfidf(max_features=100000, token_pattern='\w+')),
        on_field('text', Tfidf(max_features=100000, token_pattern='\w+', ngram_range=(1, 2))),
        on_field(['shipping', 'item_condition_id'],
                 FunctionTransformer(to_records, validate=False), DictVectorizer()),
        n_jobs=4)
    y_scaler = StandardScaler()

 X_train = vectorizer.fit_transform(preprocess(train)).astype(np.float32)

Die Ausgabe ist die Punktzahl (Bag of Words) für den Charaktertyp (200000) und die Gesamtpunktzahl für Versand und Artikelbedingung 200002. image.png

Lernen

Es lernt mit 4 Kernen und 4 Threads und mittelt dann das Ensemble. Beim Lernen ist y_train auf [teilweise] festgelegt (https://qiita.com/asparagasu/items/6554ce52bd980fab7a11 "Qiita") und nur xs wird geändert.

qiita.rb


def fit_predict(xs, y_train) -> np.ndarray:
    X_train, X_test = xs
    config = tf.ConfigProto(
        intra_op_parallelism_threads=1, use_per_session_threads=1, inter_op_parallelism_threads=1)
    with tf.Session(graph=tf.Graph(), config=config) as sess, timer('fit_predict'):
        ks.backend.set_session(sess)
        model_in = ks.Input(shape=(X_train.shape[1],), dtype='float32', sparse=True)#MLP-Design
        out = ks.layers.Dense(192, activation='relu')(model_in)
        out = ks.layers.Dense(64, activation='relu')(out)
        out = ks.layers.Dense(64, activation='relu')(out)
        out = ks.layers.Dense(1)(out)
        model = ks.Model(model_in, out)
        model.compile(loss='mean_squared_error', optimizer=ks.optimizers.Adam(lr=3e-3))
        for i in range(3):#3 Epoche
            with timer(f'epoch {i + 1}'):
                model.fit(x=X_train, y=y_train, batch_size=2**(11 + i), epochs=1, verbose=0)#Die Stapelgröße nimmt exponentiell zu
        return model.predict(X_test)[:, 0]#Renditeerwartungen


 with ThreadPool(processes=4) as pool: #4 Fäden
        Xb_train, Xb_valid = [x.astype(np.bool).astype(np.float32) for x in [X_train, X_valid]]
        xs = [[Xb_train, Xb_valid], [X_train, X_valid]] * 2
        y_pred = np.mean(pool.map(partial(fit_predict, y_train=y_train), xs), axis=0)#Nimmt den Durchschnitt von dem, was Sie in 4 Kernen gelernt haben
    y_pred = np.expm1(y_scaler.inverse_transform(y_pred.reshape(-1, 1))[:, 0])#Geben Sie das, was per Protokoll konvertiert wurde, in den Preis zurück
    print('Valid RMSLE: {:.4f}'.format(np.sqrt(mean_squared_log_error(valid['price'], y_pred))))

Referenz

[Referenz ①](https://copypaste-ds.hatenablog.com/entry/2019/02/15/170121#1-%E3%82%B7%E3%83%B3%E3%83%97%E3% 83% AB% E3% 81% AAMLP "Qiita") Referenz ② Referenz ③ Referenz ④ Methode des BRONZE-Erwerbers Mercari HP

Recommended Posts

Lernen Sie aus dem siegreichen Code-Mercari-Wettbewerb ①-
Lerne Nim mit Python (ab Anfang des Jahres).
Kaggle-Wettbewerbsprozess unter dem Gesichtspunkt des Punkteübergangs
Lassen Sie uns von der Linie suchen
Entfernen Sie den Rahmen aus dem Bild
Ich habe vom Terminal getwittert!
Lernen Sie Best Practices von Cookiecutter-Django
Lernen stärken Lernen Sie von heute
Aus einem Buch, das der Programmierer lernen kann ... (Python): Finden Sie den häufigsten Wert
Lernen Sie die M-H- und HMC-Methoden, indem Sie die Bayes'schen Statistiken anhand der Grundlagen lesen
Bewerten Sie die Genauigkeit des Lernmodells durch einen Kreuztest von scikit learn