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.
・ 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
Erstellen eines Modells, das zum Zeitpunkt der Auflistung einen angemessenen Preis vorhersagt
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.
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.
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
RMLSE:Root Mean Squared Logarithmic Error Je niedriger die Punktzahl, desto geringer ist der Fehler bei der Schätzung des Preises.
Das erste Modell ist RMLSE: 0.3875
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 |
Test_id und Preis
・ 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
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.
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)
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.
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.
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 ①](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