ある会社の人事担当である赤池くんは社員の給与を定めるための給与規定を紛失してしまいました。 それと同時に通帳を紛失してしまったため、 一部の社員の給与の額がわからなくなってしまいました。
社員の情報と給与のデータが与えられるので困っている赤池くん助けるために失われた社員の給与情報を予測してあげましょう。
1位 100,000円
データをダウンロードするにはログインまたはユーザー登録して下さい
データは2つのグループに分けられます。
なお訓練データセットとテストデータセットにはそれぞれ21,000と9,000のサンプルが含まれています。
訓練データセットは、機械学習モデルを構築するために使用してください。訓練データセットについては、給与の値が振られています。
テストデータセットを使用して、どの程度新しいデータに対してモデルが実行されているかを確認する必要があるので、テストデータセットについては、
社員ごとの給与データは存在しません。
なので、テストデータセットを使用して、各社員の給与を予測してください。
また、提出ファイルの例に関しては 評価方法 のタグを参照してください。
データセットのカラムは以下の通りになっています。
カラム名 | 説明 |
---|---|
position | 役職(0=役職なし, 1=主任, 2=係長, 3=課長, 4=部長) |
age | 年齢(歳) |
area | 勤務地 |
sex | 性別(1=男性, 2=女性) |
partner | 配偶者の有無(0=なし, 1=あり) |
num_child | 子供の人数(人) |
education | 教育(0=高校, 1=短大専門学校, 2=大学, 3=修士, 4=博士) |
service_length | 勤続年数(年) |
study_time | 一週間あたりの勉強時間(h) |
commute | 通勤時間(h) |
overtime | 一ヶ月あたりの残業時間(h) |
ラベル | 説明 |
---|---|
salary | 給与月額(千円) |
目標は、テストデータセットの社員のデータに基づき、社員の給与額を予測することです。y(給与)を実数値で予測してくだい。
モデルの予測性能は9,000のテストデータセットのうち、予測値と真値のMAE(mean absolute error)で評価されます。
$ MAE = \frac{1}{N} \sum^{N}_{i=1} | y - \hat{y}|$
ここで$y$は真の値, $\hat{y}$は予測値です。
回答用のsubmission.csvを用意する(9,000のエントリーとヘッダー行を含む) 。
提出されたファイルに余分な行や列(idとy以外)が含まれていた場合はエラーとなります。
提出ファイルは以下の列のみを必ず含んでください:
以下は提出ファイルの例です。
id,y
0, 324.5
1, 694.3
2, 495.2
3, 200.4
本コンペでは、開催期間終了後 賞金対象者のコードを公開し、ユーザーの皆様にチーティング有無をレビューしていただき順位確定させる、オープンレビュー方式のコンペティションを行います。
賞金対象ユーザー
コンペ終了後1週間以内:
トピックにて、学習過程の分かるコードの公開をお願いいたします。
(簡易解説までつけていただけると助かります。)
1.5か月以内:
レビュアー(ユーザー)より、チーティングの疑いに関するコメントがある場合は、ご回答をお願いいたします。
※チーティングとは無関係のコメント(ノウハウに関する質疑 等)についてもご回答いただけると幸いですが、順位確定の判断材料とは致しません。
レビュアー(ユーザーの皆様)
コンペ終了後1か月以内:
公開コードを確認いただき、チーティングが疑われる場合は、トピックを通して質疑の投稿をお願いいたします。
レビュアーからの質疑と、回答状況をふまえて、最終的に運営側で順位確定を判断します。
不正発覚の場合は失格とし、リーダーボードの順位を繰上げます。
順位繰上げにより賞金対象者となられた場合は、繰上げ日より一週間以内に、トピックにてコードを公開いただき、「Open Review Competition」と同様のフローにて順位を確定させていただきます。
開始日 2019/11/6 0:00 JST
終了日 2010/12/23 0:00 JST
エントリー締め切り なし
・参加者ごとに1つのアカウントでご参加ください
・チーム参加にの場合は、最大5名での参加が可能です
・1日あたり、最大5回までの提出が可能です
・ユーザー間での情報共有
コンペティションに関連するコード・データを、チーム外のユーザーと共有することはできません。全参加者が利用できる場合に限り、共有可能です。
・外部データの使用
本コンペティションで公開されているデータのみを用いてチャレンジして下さい。コンペ外データを用いて学習されたモデルの使用も禁止とします。
公平性の担保、チーティング等の不正防止のため、予告なくルールの追加・変更を行う場合がございます。
ご不便をおかけすることもあるかと思いますが、サービス向上のためご了承ください。
はい。最も精度の高い学習モデルを作成した優勝者には、賞金10万円を贈呈します。
順位確定までのプロセスについては、ルール「Open Review Competition」を参照ください。
可能です。チームページから作成いただけます。
こちらから作成いただけます。
コンペティション参加にはアカウント登録が必要となりますのでご注意ください。
本コンペティションで公開されているデータのみを用いてチャレンジして下さい。コンペ外データを用いて学習されたモデルの使用も禁止とします。
Seed を固定することが推奨です。ただし、Seed を固定しなくても提出用コードとしては認めていく方針です。
全く同じスコアの場合、提出時間の早いユーザーが上位となります。
このチュートリアルでは給与データに対して
を行います。
まずはデータを読み込んで見ましょう。csvデータの読み込みは複数のやり方がありえますが、pandas
のread_csv
関数はその中でも機能が豊富で、扱いやすいためこれを使います。
これを使うと、csvデータを読み込み、pandas.DataFrame
にして返してくれます。
import pandas as pd
train_df = pd.read_csv('train_data.csv', index_col=0)
test_df = pd.read_csv('test_data.csv', index_col=0)
train_data_df = train_df.iloc[:, :-1]
train_target_df = train_df.iloc[:, -1:]
test_data_df = test_df
また、DataFrame
には.head()
というメソッドが定義されており、これを呼び出すとDataFrame
の先頭の数行を確認できます。
train_data_df.head()
id | position | age | area | partner | num_child | education | service_length | commute | overtime |
---|---|---|---|---|---|---|---|---|---|
0 | 1 | 44 | 愛知県 | 1 | 2 | 1 | 24 | 1.6 | 9.2 |
1 | 2 | 31 | 奈良県 | 0 | 0 | 0 | 13 | 0.7 | 12.4 |
2 | 2 | 36 | 山口県 | 0 | 0 | 2 | 14 | 0.4 | 16.9 |
3 | 0 | 22 | 東京都 | 0 | 0 | 0 | 4 | 0.4 | 6.1 |
4 | 0 | 25 | 鹿児島県 | 0 | 0 | 1 | 5 | 0.2 | 4.9 |
このデータにはいくつかのカテゴリカルデータが含まれているので今のままでは機械学習モデルで扱いづらいです。そこで、 カテゴリカルデータに対してget_dummies
関数を使いone hotベクトルに変換することができます。
ここではarea
、education
、position
についてone hotベクトル化を行います。 drop_first
を用いることで多重共線性を減らすことができます。
train_data_df = pd.get_dummies(train_data_df, columns=['area', 'education', 'position'], drop_first=True)
test_data_df = pd.get_dummies(test_data_df, columns=['area', 'education', 'position'], drop_first=True)
訓練データにおける給与がどのような分布になっているか見てみましょう。各収入階級ごとの度数をヒストグラムを用いてプロットするのが以下のコードです。
import matplotlib.pyplot as plt
%matplotlib inline
plt.hist(train_target_df['salary'], bins=20)
中間層にピークのある、 格差の少ない会社だということがわかります。
ここでは試しに、 ランダムフォレスト回帰を作成してみましょう。 sklearn
はは多くの機械学習モデルが実装されたライブラリであり、これを使って実装してみます。
from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor(n_jobs=-1, random_state=2525)
model.fit(train_data_df,train_target_df)
# RandomForestRegressor(bootstrap=True, criterion='mse', max_depth=None,
# max_features='auto', max_leaf_nodes=None,
# min_impurity_decrease=0.0, min_impurity_split=None,
# min_samples_leaf=1, min_samples_split=2,
# min_weight_fraction_leaf=0.0, n_estimators=10, n_jobs=-1,
# oob_score=False, random_state=2525, verbose=0,
# warm_start=False)
sklearn
の識別モデルには、.predict()
メソッドが定義されており、これを使うと与えられたデータに対して、給与の予測額を出力してくれます。
from sklearn.metrics import mean_absolute_error
predicted = model.predict(train_data_df)
print(mean_absolute_error(predicted, train_target_df))
# 9.381901130006629
また、予測結果と実際の結果がどの程度異なるかを評価する関数がsklearn.metrics
に定義されています。ここではmean_absolute_error
を確認してみましょう。
与えられているテストデータに対して予測を行い、 提出ファイルを作成します。
test_predicted = model.predict(test_data_df)
submit_df = pd.DataFrame({'y': test_predicted})
submit_df.index.name = 'id'
submit_df.to_csv('submission.csv')
これをベースにして、モデルのパラメータを変える、 モデルを変える、 有用な特徴量を探るなど試行錯誤して、モデルの性能を上げていきましょう。
import numpy as np
plt.hist(np.abs(predicted - train_target_df['salary'].values), log=True)
まずは誤差の分布をプロットしてみましょう。
もっとも誤差の大きなデータはこちらになります。
worst_index = np.argmax(predicted - train_target_df['salary'])
train_df.iloc[worst_index, :]
# position 2
# age 49
# area 大阪府
# sex 1
# partner 0
# num_child 0
# education 4
# service_length 22
# study_time 3
# commute 1.5
# overtime 12
# salary 421.522
# Name: 5986, dtype: object
print(predicted[worst_index], train_target_df['salary'].iloc[worst_index])
# 669.5488881368135 421.52210195900886