マルチモーダルコンペティション!Ridgelinezとの共同開催です
newduck
https://comp.probspace.com/competitions/kiva2021Public(LB)スコア:360.74167(2021.12.21)
##初期設定
モジュールのインストール
!python3 -m pip install -q slackweb !echo "$(pip freeze | grep slackweb) is successfully installed"
ライブラリのインストール
import pandas as pd import numpy as np import datetime import os import warnings warnings.filterwarnings("ignore") import matplotlib import matplotlib.pylab as plt import sklearn from sklearn.model_selection import train_test_split from sklearn.metrics import mean_absolute_error from sklearn import preprocessing import lightgbm as lgb import slackweb from google.colab import drive drive.mount("/content/drive")
コンフィグ
SEED = 42
Google Driveのディレクトリを指定
DRIVE = "/content/drive/My Drive/ML/kiva/" INPUT = os.path.join(DRIVE, "input") SUBMIT = os.path.join(DRIVE, "submit")
trainデータの読み込みと確認
train_df = pd.read_csv(f"{INPUT}/train.csv") display(train_df.info())
testデータの読み込みと確認
test_df = pd.read_csv(f"{INPUT}/test.csv") display(test_df.info())
sample_submission.csvの読み込み
submit_df = pd.read_csv(f"{INPUT}/sample_submission.csv")
画像の読み込み(本サンプルコードでは利用していないが、下記の議論を参考にColabへの読み込みまでを実装)https://comp.probspace.com/competitions/kiva2021/discussions/goukaisei-Post6dbf79c59def6c1b327d(検討事項)画像の有効利用について
# !cp "/content/drive/My Drive/ML/kiva/input/test_images.zip" . # !unzip test_images.zip # print(len(os.listdir("test_images"))) #should be 91819
trainデータの列名の再確認
train_df.columns
trainデータを目的変数と説明変数に分割
train_columns = ["ORIGINAL_LANGUAGE", "ACTIVITY_NAME", "SECTOR_NAME", "COUNTRY_CODE","CURRENCY_POLICY", "CURRENCY","REPAYMENT_INTERVAL", "DISTRIBUTION_MODEL"] target = "LOAN_AMOUNT" X = train_df[train_columns] y = train_df[target]
説明変数をラベルエンコーディング(検討事項)エンコードの方法
for column in X.columns: le = preprocessing.LabelEncoder() target_column = X[column] le.fit(target_column) label_encoded_column = le.transform(target_column) X[column] = pd.Series(label_encoded_column).astype("category")
ラベルエンコード後の説明変数の確認
display(X)
trainデータを訓練用とテスト用に分割(検討事項)K分割交差検証の導入
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state = SEED)
LGBM用のパラメータ設定
params = { "application" : "regression_l1", "metric" : "l1" #mae }
LGBMの学習用のデータを作成
lgb_train = lgb.Dataset(X_train, y_train) lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)
モデルの学習
%%time evaluation_results = {} model = lgb.train(params, train_set=lgb_train, valid_sets=lgb_eval, valid_names=["train"], evals_result=evaluation_results )
学習過程の可視化
plt.plot(evaluation_results["train"]["l1"], label="train") plt.ylabel("MAE") plt.xlabel("Num Boosting round") plt.title("Training performance") plt.legend() plt.show()
テストデータによる予測
y_pred = model.predict(X_test)
真の値(y_test)と予測値(y_pred)の比較
display(pd.DataFrame({"y_test":y_test,"y_pred":y_pred}))
MAE算出
MAE = mean_absolute_error(y_test, y_pred) print("MAE = " + str(MAE))
説明変数の重要度の可視化https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.plot_importance.html
lgb.plot_importance(model) plt.show()
推論
test_X = test_df[train_columns] for column in test_X.columns: le = preprocessing.LabelEncoder() target_column = test_X[column] le.fit(target_column) label_encoded_column = le.transform(target_column) test_X[column] = pd.Series(label_encoded_column).astype("category") test_predicted = model.predict(test_X)
下記の議論よりLOAN_AMOUNTの推論値を25の倍数に整形https://comp.probspace.com/competitions/kiva2021/discussions/XS330-Post2d3ac1900e595ca2f900(検討事項)整形方法について要精査
test_predicted = (np.round(test_predicted/25)*25).astype(int) submit_df["LOAN_AMOUNT"]=test_predicted print(submit_df)
trainファイルとsubmitファイルのLOAN_AMOUNTについて比較
display(pd.DataFrame({"trainファイル":train_df["LOAN_AMOUNT"].describe(),"submitファイル":submit_df["LOAN_AMOUNT"].describe()}))
submitファイルのファイル名に利用する作成時刻の取得
now = datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=1))) date_time = "{0:%Y%m%d_%H%M}".format(now)
submitファイルの出力(Google Driveに出力)形式:submit_yyyymmdd_hhmm_(小数点3位までのMAE).csv例:submit_20211221_0003_311.391.csv
submit_df.to_csv(os.path.join(SUBMIT, f"submit_{date_time}_{MAE:.3f}.csv"), index=False)
Slackへの作業完了通知(ファイル名とMAEのログ保存)https://api.slack.com/messaging/webhooks#posting_with_webhooks(検討事項)ログの追加
SLACK_CHANNEL="#general" SLACK_USER="Colab" SLACK_TEXT="Colab完了通知" slack = slackweb.Slack(url="ご自身のIncoming Webhook URL") attachments=[] attachment={ "color": "#2eb886", "fields":[ { "title": "ファイル作成時刻","value": date_time, }, { "title": "MAE","value": MAE, } ] } attachments.append(attachment) slack.notify(text=SLACK_TEXT, channel=SLACK_CHANNEL, username=SLACK_USER, attachments=attachments)
コメント、質問、気軽に宜しくお願いします。
上記の検討事項を全部実装した上で、 DESCRIPTION_TRNSLATED、IMAGE_ID(画像)、LOAN_USE、TAGSからの特徴量抽出辺りが、 スコア差に響く気がします。
画像へのラベリング、特にハンドラベリングを許可するのかも気になっていますが。
上記の検討事項のうち幾つかを実装しLB:360.74167⇒338.41538となりました。
2021.12.26