Teilnahme am [1st_Beginner Limited Competition] Bank Customer Targeting von SIGNATE, einer Website für datenwissenschaftliche Analysen.
Da ich erfolgreich zum Intermidiate befördert wurde, schrieb ich einen Artikel, der auf meinen Notizen und Überlegungen basierte, in der Hoffnung, dass mehr Menschen problemlos am Wettbewerb teilnehmen können.
Ein Data-Science-Wettbewerb des japanischen Unternehmens SIGNATE.
Das Ministerium für Wirtschaft, Handel und Industrie, My Navi, NTT, Sansan usw. nehmen ebenfalls teil
Sie können es sich als die japanische Version von kaggle vorstellen.
Da das Forum nicht aktiv ist, scheint es für die Teilnehmer nicht viel Tendenz zu geben, "noch" Meinungen und Informationen auszutauschen. Das Forum hat sich am Ende dieses Anfängerwettbewerbs ein wenig bewegt, daher kann es sich von nun an ändern.
(Übrigens Offizielles Video ), Die korrekte Intonation scheint "Sig (↑) Ney (→) To (↓)" zu sein. Ist es dasselbe wie die Tangente der Dreiecksfunktion?)
Dies ist das erste denkwürdige Ereignis, das jeden Monat nur für Anfänger stattfinden soll Wenn Sie eine bestimmte Punktzahl (AUC beträgt diesmal 0,85) durch absolute Bewertung anstelle von Wettbewerb überschreiten, können Sie zu einem höherstufigen Intermidiate befördert werden.
Weitere Informationen finden Sie unter Offizielle Website.
Betrieben von Benchmark Score Script ) Ist veröffentlicht
Wenn Sie dies 100 Mal mit einer geeigneten Zufallszahl für die Aussage vorhersagen und dann den Durchschnitt nehmen, beträgt die AUC 0,854, sodass Sie sie fördern können.
output_df = pd.DataFrame()
for i in range(100):
#Testdaten von Trainingsdaten trennen
X_train , X_valid , y_train , y_valid = train_test_split(X_train_origin,y_train_origin,test_size = 0.3 , random_state = i , stratify=y_train_origin)
#Das verwendete Modell ist LGB (ohne Parametereinstellung)
lgb_train = lgb.Dataset(X_train,y_train,categorical_feature = categorical_features)
lgb_eval = lgb.Dataset(X_valid , y_valid , reference = lgb_train , categorical_feature = categorical_features)
params = {
"objective":"binary"
}
model = lgb.train(
params,lgb_train,
valid_sets=[lgb_train,lgb_eval],
verbose_eval = 10,
num_boost_round = 1000,
early_stopping_rounds=10
)
y_pred = model.predict(X_test_origin,num_iteration=model.best_iteration)
output_df[i] = y_pred
submit_df["1"] = output_df.mean(axis = 1)
submit_df.to_csv('submit.csv',index=False,header=None)
__ Es stellt sich heraus, dass die Strategie der "Mittelung mehrerer Vorhersageergebnisse" sehr leistungsfähig ist __
Das ist nicht interessant, deshalb habe ich beschlossen, mein Bestes zu geben, um AUC 0,860 zu überschreiten.
Grob wiederholtes Ausprobieren mit dem folgenden Verfahren
Berechnen Sie Statistiken wie Mittelwert und Medianwert durch Gruppierung nach Zielvariablen Visualisierung mit Histogrammen und Balkendiagrammen Ich habe auch den Korrelationskoeffizienten usw. berechnet.
import pandas as pd
import matplotlib.pyplot as plt
pd.set_option('display.max_rows' ,500)
pd.set_option('display.max_columns', 100)
train_df = pd.read_csv("../../data/train.csv")
#Ich werde Monat mit Tag kombinieren, also habe ich es in eine Zahl geändert
#Dezember existiert in diesen Daten nicht
month_dict = {"jan":1,"feb":2,"mar":3,"apr":4,"may":5,"jun":6,"jul":7,"aug":8,"sep":9,"oct":10,"nov":11,"dec":12}
month_int = [train_df["month"][i] for i in range(len(train_df))]
train_df["month"] = month_int
#Alter
#age
#Ich war besorgt darüber, wie ich mit über 60 Jahren umgehen sollte, also rollte ich es zusammen
#Jeder Teenager bis 59 Jahre alt
age_list = list(train_df["age"])
new_age_list = []
for i in range(len(age_list)):
if age_list[i] == 60:
new_age_list.append(60)
elif age_list[i] > 60:
new_age_list.append(70)
else:
new_age_list.append(int(age_list[i]/10)*10)
train_df["age_round"] = new_age_list
train_df.describe()
numeric_col_list = ["age","balance","duration","campaign","pdays","previous"]
categorical_col_list = [categorical_feature for categorical_feature in train_df.columns if categorical_feature not in numeric_col_list]
categorical_col_list.remove("id")
#Für numerische Variablen nach Zielvariablen gruppieren, um Statistiken zu berechnen
for target_col in numeric_col_list:
print("\ntarget_col:",target_col)
display(train_df.groupby("y")[target_col].describe())
#Für kategoriale Gruppierung nach Zielvariable und Anzahl
for target_col in categorical_col_list:
print("\ntarget_col:",target_col)
display(train_df.groupby(["y",target_col])[target_col].count())
#Visualisieren und bestätigen Sie Durchschnitts- und Medianwerte
#Mittelwert und Medianwert um 01 von y
y0_df = train_df.query('y == 0')
y1_df = train_df.query('y == 1')
for target_col in numeric_col_list:
#0,Durchschnittswert um 1
y0_target_col_mean = y0_df[target_col].mean()
y1_target_col_mean = y1_df[target_col].mean()
#0,Median um 1
y0_target_col_median = y0_df[target_col].median()
y1_target_col_median = y1_df[target_col].median()
#Vertikale Achseneinstellung
#1 des Maximums der Durchschnitts- und Medianwerte.1x ist die vertikale Achse
#Die Vergrößerung kann beliebig sein, solange sie leicht zu erkennen ist
graph_y_length = (1.1*max(y0_target_col_mean,y1_target_col_mean,y0_target_col_median,y1_target_col_median))
plt.title(target_col + ": mean")
plt.ylabel(target_col)
plt.ylim([0,graph_y_length],)
plt.bar(["y0_mean","y1_mean"],[y0_target_col_mean,y1_target_col_mean])
#plt.annotate(y0_target_col_mean,y0_target_col_mean)
plt.show()
plt.title(target_col + ": median")
plt.ylabel(target_col)
plt.ylim([0,graph_y_length],)
plt.bar(["y0_median","y1_median"],[y0_target_col_median,y1_target_col_median],color = "green")
plt.show()
#Erfassen Sie das gesamte Bild auch mit einem Histogramm
for target_col in numeric_col_list:
#Achseneinstellungen
graph_x_length = 1.1*max(train_df[target_col])
graph_y_length = len(y0_df)
print("y0",target_col)
plt.xlim([0,graph_x_length],)
plt.ylim([0,graph_y_length],)
plt.hist(y0_df[target_col],bins = 20)
plt.show()
graph_y_length = graph_y_length/10
print("y1",target_col)
plt.xlim([0,graph_x_length],)
plt.ylim([0,graph_y_length],)
plt.hist(y1_df[target_col],bins = 20)
plt.show()
#Berechnung des Korrelationskoeffizienten
train_df.corr()
#Nehmen Sie nur den Korrelationskoeffizienten der Zielvariablen auf
train_df.corr()["y"]
Ich habe auch versucht, ein Faltliniendiagramm in chronologischer Reihenfolge zu zeichnen, aber ich werde es weglassen. Mit dieser Art von Gefühl dachte ich darüber nach, welche Merkmalsmenge wesentlich zur Zielvariablen beitragen würde und ob ich eine Merkmalsmenge erstellen könnte.
Ich habe bestätigt, dass es Daten gibt, die nicht existieren, wie etwa 90 Jahre alt oder der 30. Februar. Ich habe überlegt, ob ich es verarbeiten oder löschen soll, aber ich habe es so verwendet, wie es ist
・ Pdays und Saldo werden gelöscht ・ Erstellen Sie ein Monatsend-Flag -Erstellen Sie eine Datumsspalte, die Monat und Tag kombiniert
Aus der Grundtabelle und Bestätigung der Rohdaten Merkmalsmengen, die wahrscheinlich einen starken Einfluss auf die Zielvariable haben, werden verarbeitet, um neue Merkmalsmengen zu erstellen. Ich habe es gelöscht, wenn ich beschlossen habe, dass es mich nicht betrifft Ich habe auch auf die unten beschriebene Funktionsbedeutung hingewiesen.
optuna ist eine Bibliothek, die Hyperparameter mithilfe der Bayes'schen Optimierung optimiert Höher bewertet als Rastersuche und Zufallssuche
Ich habe auf die folgenden zwei Artikel verwiesen
Automatische Optimierung von Hyperparametern durch die Optuna-Erweiterung LightGBM Tuner
Der Punkt ist, optuna für lightgbm zu verwenden Ich hatte einen Fehler mit optuna 2.0, der sich bereits auf meinem Computer befand, also habe ich ihn mit optuna 1.3 ausgeführt
import pandas as pd
import optuna
import functools
import warnings
warnings.simplefilter('ignore')
from sklearn.model_selection import train_test_split
#Dieser Typ ist wirklich fähig
import optuna.integration.lightgbm as lgb
from sklearn import preprocessing
from sklearn.model_selection import cross_val_score
%matplotlib
#Daten lesen
train_df = pd.read_csv("../../data/train.csv")
test_df = pd.read_csv("../../data/test.csv")
submit_df = pd.read_csv("../../data/submit_sample.csv",header = None)
#Ersetzen Sie Dummy-Zielvariablen, damit Trainingsdaten und Testdaten verstanden werden können
test_df["y"] = -999
#Kombinieren Sie Trainingsdaten und Testdaten
all_df = pd.concat([train_df,test_df])
del train_df , test_df
all_df.reset_index(inplace=True)
#Monatsend-Flagge
month_list = list(all_df["month"])
day_list = list(all_df["day"])
end_of_month_flag = []
for i in range(len(all_df)):
if day_list[i] in [30,31]:
end_of_month_flag.append(1)
elif day_list[i] == 29 and month_list[i] in ["feb","apr","jun","sep","nov"]:
end_of_month_flag.append(1)
elif day_list[i] == 28 and month_list[i] == "feb":
end_of_month_flag.append(1)
else:
end_of_month_flag.append(0)
all_df["end_of_month_flag"] = end_of_month_flag
#Mond(Monatsspalte)Zu einer Nummer
month_dict = {"jan":1,"feb":2,"mar":3,"apr":4,"may":5,"jun":6,"jul":7,"aug":8,"sep":9,"oct":10,"nov":11,"dec":12}
month_int = [month_dict[all_df["month"][i]] for i in range(len(all_df))]
all_df["month"] = month_int
#month_Tagesspaltenerstellung
#Ich denke, es ist in Ordnung, den Entscheidungsbaum als int zu behandeln, da er nur die Größenbeziehung kennen muss.
month_day = []
month_day = all_df["month"]*100 + all_df["day"]
all_df["month_day"] = month_day
#Löschen Sie nicht benötigte Spalten
del all_df["index"]
del all_df["id"]
del all_df["pdays"]
del all_df["balance"]
#Geben Sie den Spaltennamen der Kategorie an
categorical_features = ["job","marital","education","default","housing","loan","contact","month","poutcome","end_of_month_flag"]
#Etikettencodierung
#Ich habe die Zielcodierung durchgeführt, aber die Punktzahl hat sich nicht geändert
for col in categorical_features:
lbl = preprocessing.LabelEncoder()
lbl.fit(all_df[col])
lbl.transform(all_df[col])
all_df[col] = lbl.transform(all_df[col])
#Aufteilung der Trainingsdaten und Testdaten
train_df = all_df[all_df["y"] != -999]
test_df = all_df[all_df["y"] == -999]
#Teilen Sie in erklärende Variablen und objektive Variablen
origin_y_train = train_df["y"]
origin_X_train = train_df.drop(["y"],axis = 1)
origin_X_test = test_df.drop(["y"],axis = 1)
output_df = pd.DataFrame()
##Ausführung von hier auf meinem PC(Core i5-Speicher der 10. Generation 8 GB)Dann dauerte es mehr als 10 Stunden
for i in range(100):
#Testdaten von Trainingsdaten trennen
X_train , X_valid , y_train , y_valid = train_test_split(origin_X_train,origin_y_train,test_size = 0.3 , random_state = i , stratify=origin_y_train)
#Datensatzerstellung
lgb_train = lgb.Dataset(X_train,y_train,categorical_feature = categorical_features,free_raw_data=False)
lgb_eval = lgb.Dataset(X_valid , y_valid , reference = lgb_train , categorical_feature = categorical_features,free_raw_data=False)
params ={"objective":"binary",
"metric":"auc"
}
best_params, tuning_history = dict(), list()
booster = lgb.train(params, lgb_train, valid_sets=[lgb_train,lgb_eval],
verbose_eval=0,
best_params=best_params,
tuning_history=tuning_history)
print("Best Params:", best_params)
print("Tuning history:", tuning_history)
#Hyperparameter mit der höchsten AUC hinzugefügt
params.update(best_params)
#Lernen
model = lgb.train(
params,lgb_train,
valid_sets=[lgb_train,lgb_eval],
verbose_eval = 10,
num_boost_round = 1000,
early_stopping_rounds=10
)
#Vorausgesagt durch Wettbewerbsdaten
y_pred = model.predict(origin_X_test,num_iteration=model.best_iteration)
output_df[i] = y_pred
submit_df = pd.read_csv("../../data/submit_sample.csv",header = None)
del submit_df[1]
submit_df["1"] = output_df.mean(axis = 1)
submit_df
submit_df.to_csv("../../output/result.csv",header=None,index=False)
#Während des Versuchs und Irrtums bestätigte ich die Wichtigkeit des Merkmals und konstruierte die Merkmalsmenge.
lgb.plot_importance(model, height=0.5, figsize=(8,12))
__ Als ich dies einreichte, betrug die AUC 0,859__
Darüber hinaus betrug das Ergebnis der 100-fachen Vorhersage durch Entfernen der Spalte Tag und des Monatsend-Flags 0,859.
Als ich den Durchschnitt dieser __2 Vorhersagen nahm und einreichte, konnte ich 0,860 __ sicher überschreiten Herzliche Glückwünsche
Ich habe versucht, die Punktzahl durch Optimieren der Hyperparameter eines Modells mit Catboost zu erhöhen, aber die Punktzahl ist nur geringfügig erhöht und die Berechnungszeit nicht wert. Es schien hoffnungsvoll, lightgbm mit einer geeigneten Zufallszahl für die Aussage zu drehen, also gab ich es auf.
Ich wünschte, ich hätte xgboost und NN zusammen gestapelt Wenn man es betrachtet, scheint es, dass die Kombination mehrerer Methoden eine der königlichen Straßenstrategien des Wettbewerbs ist.
Ich war zufrieden damit, das Ziel von 0,860 zu überschreiten, und betrat das Lagerhaus.
Ich dachte, es wäre besser, die Verarbeitung von Merkmalsmengen zu einer Funktion zu machen. Ich möchte in der Lage sein, schönen Code auch durch Ausprobieren zu schreiben
Bis zum Ende Danke fürs Lesen Wenn Sie Fragen, Vorschläge oder Verbesserungen haben, die schwer zu verstehen sind, können Sie diese gerne kommentieren.
Recommended Posts