※2022/2/28、3/1,2にデータダウンロードされた皆さま
上記期間のstation_list.csvの情報に誤り、一部データの不足がございました。
正しいデータのカラムは、「station_name,longitude,latitude」の順であり、総データ件数は746件となります(大型の駅については、一部重複駅名あり)。
該当データをご使用されている方は、誠に恐れ入りますが、再ダウンロードいただけますと幸いです。
お手数おかけいたしますが、何卒よろしくお願いいたします。
課題背景
民泊サービスは、2016年に国内で解禁されて以降、わずか5年後の2020年3月には取扱件数12.9万件に達するほど大きな市場となりました。
物件の所有者であれば誰でも始められる手軽さが、新規参入者にとってのメリットではありますが、宿泊事業の専門化ではない多くの民泊オーナーにとって、料金設定は常に悩みの種となっています。
こうした中、大手民泊仲介事業者のAirbnbは、宿泊価格の決定方法として、機械学習アルゴリズムにより価格を決定する「ダイナミックプライシング*1」を採用したことで注目を集めました。
近年では、Beyond Pricing、メトロエンジン 等 価格設定の最適化を専門とする企業が登場するほど、ダイナミックプライシングへの機械学習技術の貢献度は大きなものとなっております。
課題内容
今回は、機械学習のテーマとしても王道とも呼べる、ダイナミックプライシングをテーマとしたコンペティションを設計いたしました。
皆さまには、国内2地区の宿泊施設を対象とした、最適な宿泊料金を算出するアルゴリズムの開発に取り組んでいただきます。
コンペを通して、民泊料金がどのように設定されているのか、裏側にある因子についても興味を持っていただければと存じます。
*1 ダイナミックプライシングとは?
ダイナミックプライシングは、需要・供給に応じて、利益を最大化させるよう商品・サービス価格を変動させる技術です。
民泊サービスにおいては、立地やサービス、季節、利用動向 等の情報により、宿泊価格の最適化が図られています。
他業界での適用範囲も広く、民泊サービスのほかにも、スーパーの商品価格、スポーツ観戦チケット、テーマパーク入園料 等様々な業界への導入が進んでおります。
コンペティションの特徴
初心者の方でも取り組みやすいテーブルデータコンペティション形式となります。
またやり込み要素として、駅の位置情報データを提供しております。上位入賞を目指される方は、ぜひ駅と宿泊施設の位置関係も特徴量に用いてみてください。
賞金
1位 100,000円
※ 対象者には、コンペティション終了後メールにて連絡いたします
締め切り
2022年5月8日 22:00 JST
LB公開 5月8日 24:00 JST
ダウンロード
データをダウンロードするにはログインまたはユーザー登録して下さい
概要
コンペに使用するデータは4つに分けられます。
- 訓練データ(train_data.csv)
- テストデータ(test_data.csv)
- 東京都23区内駅緯度経度データ(station_list.csv)
- サンプルサブミット用データ(submission.csv)
訓練データセットとテストデータセットには、それぞれ9,990レコードと4,996レコードのサンプルが含まれています。
また追加情報として、東京都23区内駅緯度経度データ(station_list.csv)をご利用もいただけます。
今回、提供している訓練データとテストデータは、2020年4月のある特定の日に取得したデータとなります。
テストデータセットに対して、同日における各宿泊施設の一泊あたりの宿泊料金を予測してください。
また、提出ファイルの例に関しては、評価方法のタグを参照してください。
データの形式
データセットのカラムは以下の通りです。
データ
カラム名 |
説明 |
例 |
name |
施設名称 |
Downtown next to Koji-Machi |
host_id |
施設の提供者の識別子(乱数化済) |
181893395 |
neighbourhood |
所在地(東京都の23の特別区のいずれか) |
Shinjuku Ku |
latitude |
緯度 |
3568185 |
longitude |
経度 |
139.68077 |
room_type |
部屋の形式 (Entire home/apt|Private room|Shared room|Hotel room) |
Entire home/apt |
minimum_nights |
最短宿泊日数 |
1 |
number_of_reviews |
評価件数 |
523 |
last_review |
最終評価日 |
2020-02-03 |
reviews_per_month |
月当たりの評価件数 |
1.67 |
availability_365 |
年間の宿泊可能日数 |
288 |
y |
1泊あたりの宿泊料金 |
9923 |
駅の緯度経度データ
カラム名 |
説明 |
例 |
station_name |
駅名 |
東京 |
longitude |
経度 |
139.766103 |
latitude |
緯度 |
35.681391 |
目標
目標は、テストデータセットの宿泊施設の情報にもとづき、宿泊料金を予測することです。y(宿泊料金)を予測してくだい。
評価指標
モデルの予測性能は評価関数RMSLE(Root Mean Squared Logarithmic Error)で評価されます。
(RMSLEの評価値)
$$
\sqrt{\frac{1}{n}{\sum_{i=1}^{n}{(\log (Pred_i+1)-\log (Act_i+1))^2}}}
$$
- 評価値は0以上の値をとり、精度が高いほど小さな値となります。
提出ファイルの形式
回答用のsubmission.csvを用意する(エントリーとヘッダー行を含む) 。
提出されたファイルに余分な行や列(idとy以外)が含まれていた場合はエラーとなります。
提出ファイルは以下の列のみを必ず含んでください:
- id(テストデータセットと同じ順序)
- y(予測された宿泊料金)
以下は提出ファイルの例です。
id,y
1, 9181
2, 14831
3, 34000
4, 1388
■Open Review Competition
本コンペでは、開催期間終了後 賞金対象者のコードを公開し、ユーザーの皆様からのチーティング有無のレビュー後に順位を確定させる、オープンレビュー方式のコンペティションを行います。
賞金対象ユーザー
コンペ終了後1週間以内:
トピックにて、学習過程の分かるコードの公開をお願いいたします。
(簡易解説までつけていただけると助かります。)
コード公開後1週間:
レビュアー(ユーザー)より、チーティングの疑いに関するコメントがある場合は、ご回答をお願いいたします。
※チーティングとは無関係のコメント(ノウハウに関する質疑 等)についてもご回答いただけると幸いですが、順位確定の判断材料とは致しません。
レビュアー(ユーザーの皆様)
コード公開後1週間:
公開コードを確認いただき、チーティングが疑われる場合は、トピックを通して質疑の投稿をお願いいたします。
レビュアーからの質疑と、回答状況をふまえて、最終的に運営側で順位確定を判断します。
■順位決定ロジック
- コンペ期間中はPublicリーダーボード(以下LB)により暫定評価を、最終結果についてはPrivate LBにより評価します。
※ Private LBはコンペ終了と同時に表示されます。
- Private スコア計算に使われるファイルについては、2つまで選択可能です。
※ 未選択の場合は、Public スコアの上位ファイルが提出上限まで自動選択されます。
- スコアが同値の場合は、早い日時に提出いただいたユーザーが上位となります。
- コンペ終了後であっても、不正が発覚の際は、対象ユーザーは失格となり、全体の順位が繰り上がります。
順位繰上げにより賞金対象者となられた場合は、繰上げ日より一週間以内に、トピックにてコードを公開いただき、「Open Review Competition」と同様のフローにて順位を確定させていただきます。
■タイムライン
開始 2022/2/28 15:00 JST
提出締切 2022/5/8 22:00 JST
終了日 2022/5/8 24:00 JST
エントリー締め切り なし
■システム利用
- 参加者ごとに1つのアカウントでご参加ください
- チーム参加の場合は、最大5名までエントリー可能です
- 1日あたり、最大5回までの提出が可能です
■禁止事項
- ユーザー間での情報共有
コンペティションに関連するコード・データを、チーム外のユーザーと共有することはできません。全参加者が利用できる場合に限り、共有可能です。
■外部データ/学習済みモデルの使用
- 本コンペティションの基本情報/データから取得できるデータのみを用いてチャレンジして下さい。コンペ外データを用いて学習されたモデルの使用も禁止とします。
- ただし、トピック上で、運営より承認された外部データのみ、使用を許可いたします。承認プロセスについては、「外部データ/学習済みモデルの使用申請について」をご確認ください。
※コンペ期間中であっても、不正が疑われる場合は、運営より確認のためメール連絡させていただくことがございます。一週間以内にご回答いただけない場合も、不正と判断させていただきます。
■外部データ/学習済みモデルの使用申請について
原則外部データ/学習済みモデルの使用は禁止としておりますが、正解データの入手につながらない場合は、下記承認プロセスにより使用できることといたします。
- トピックを作成し、取得元情報とデータ(格納先URLも可)を添付
- 運営にて判断・承認
注)ただし、コンペ終了まで7日をきってからの申請は禁止とします。
また、下記ホワイトリストについては、申請不要で使用いただくことが可能です。
・ホワイトリスト
https://docs.google.com/spreadsheets/d/1yciWoubQ_JtJSFcsGTjqemNDUL3KccL52dBfCzvVIZA/edit#gid=0
※注意事項
・上記をラップしたツールキットは申請不要で使用可能
・データを追加し再学習されたモデルについては使用不可(要申請)
■運営からのお願い
公平性の担保、チーティング等の不正防止のため、予告なくルールの追加・変更を行う場合がございます。
ご不便をおかけすることもあるかと思いますが、サービス向上のためご了承ください。
FAQ
このコンペティションでは賞金はでますか?
はい。
最も精度の高い学習モデルを作成した優勝者には、賞金10万円を贈呈します。
順位確定までのプロセスについては、ルール「Open Review Competition」を参照ください。
チームで参加できますか?
可能です。チームページから作成いただけます。
どこでアカウントをつくればいいですか?
こちらから作成いただけます。
コンペティション参加にはアカウント登録が必要となりますのでご注意ください。
外部データ/学習済みモデルを使うことは可能ですか?
申請を行うことによって利用可能です。
ルール「外部データ/学習済みモデルの使用申請について」を参照ください。
コードを提出するにあたって Seed を固定する必要はありますか?
Seed を固定することが推奨です。
ただし、Seed を固定しなくても提出用コードとしては認めています。
提出回数はいつリセットされますか?
ファイル提出後、23時間ごとにリセットとなります。
グローバル展開していくにあたり、居住国(時差)による有利・不利を最小化するため、一定時間でリセットする仕様としております。
概要
このチュートリアルでは、民泊の宿泊施設データに対して
- データの読み込み
- データの確認と前処理
- Scikit-Learnを用いて回帰モデルの作成、学習
- 提出用データの作成
を行います。
環境
import pandas as pd
import numpy as np
import sklearn
!python3 --version
print("Pandas", pd.__version__)
print("Numpy", np.__version__)
print("Scikit learn", sklearn.__version__)
import matplotlib
print("Matplotlib", matplotlib.__version__)
Python 3.9.8
Pandas 1.3.0
Numpy 1.20.3
Scikit learn 0.24.2
Matplotlib 3.4.2
データのロード
まずはデータを読み込んで見ましょう。csvデータの読み込みは複数のやり方がありえますが、pandas
のread_csv
関数はその中でも機能が豊富で、扱いやすいためこれを使います。
これを使うと、csvデータを読み込み、pandas.DataFrame
にして返してくれます。
import pandas as pd
train_data = pd.read_csv("../compe_data/train_data.csv", index_col='id')
print(train_data.shape)
(9990, 12)
また、DataFrame
には.head()
というメソッドが定義されており、これを呼び出すとDataFrame
の先頭の数行を確認できます。
train_data['room_type'].unique()
array(['Entire home/apt', 'Private room', 'Shared room', 'Hotel room'],
dtype=object)
train_data.head()
|
name |
host_id |
neighbourhood |
latitude |
longitude |
room_type |
minimum_nights |
number_of_reviews |
last_review |
reviews_per_month |
availability_365 |
y |
id |
|
|
|
|
|
|
|
|
|
|
|
|
1 |
KiyosumiShirakawa 3min|★SkyTree★|WIFI|Max4|Tre... |
242899459 |
Koto Ku |
35.68185 |
139.80310 |
Entire home/apt |
1 |
55 |
2020-04-25 |
2.21 |
173 |
12008 |
2 |
Downtown Tokyo Iriya next to Ueno |
308879948 |
Taito Ku |
35.72063 |
139.78536 |
Entire home/apt |
6 |
72 |
2020-03-25 |
2.11 |
9 |
6667 |
3 |
Japan Style,Private,Affordable,4min to Sta. |
300877823 |
Katsushika Ku |
35.74723 |
139.82349 |
Entire home/apt |
1 |
18 |
2020-03-23 |
3.46 |
288 |
9923 |
4 |
4 min to Shinjuku Sta. by train / 2 ppl / Wi-fi |
236935461 |
Shibuya Ku |
35.68456 |
139.68077 |
Entire home/apt |
1 |
2 |
2020-04-02 |
1.76 |
87 |
8109 |
5 |
LICENSED SHINJUKU HOUSE: Heart of the action! |
243408889 |
Shinjuku Ku |
35.69840 |
139.70467 |
Entire home/apt |
1 |
86 |
2020-01-30 |
2.00 |
156 |
100390 |
データの確認と前処理
訓練データにおける一日あたりの宿泊料の分布がどうなっているのか見てみましょう。
import matplotlib.pyplot as plt
%matplotlib inline
plt.hist(train_data['y'], log=True, bins=20)
(array([9.357e+03, 4.600e+02, 4.200e+01, 2.400e+01, 6.000e+00, 5.100e+01,
1.000e+00, 0.000e+00, 0.000e+00, 5.000e+00, 0.000e+00, 0.000e+00,
0.000e+00, 1.000e+00, 0.000e+00, 1.000e+00, 0.000e+00, 3.500e+01,
4.000e+00, 3.000e+00]),
array([9.210000e+02, 5.088010e+04, 1.008392e+05, 1.507983e+05,
2.007574e+05, 2.507165e+05, 3.006756e+05, 3.506347e+05,
4.005938e+05, 4.505529e+05, 5.005120e+05, 5.504711e+05,
6.004302e+05, 6.503893e+05, 7.003484e+05, 7.503075e+05,
8.002666e+05, 8.502257e+05, 9.001848e+05, 9.501439e+05,
1.000103e+06]),
<BarContainer object of 20 artists>)
10,000円以下に大きなピークがあり、90,000円程度のところにも小さな峰があることがわかります。
続いて、下記のコードを使用して使用するデータ全体の概観を確認します。
各項目について欠損値('null')の値がどの程度含まれているか把握できます。また、データの形式についてもここで判別可能です。
train_data.isnull().sum(axis=0)
name 0
host_id 0
neighbourhood 0
latitude 0
longitude 0
room_type 0
minimum_nights 0
number_of_reviews 0
last_review 1699
reviews_per_month 1699
availability_365 0
y 0
dtype: int64
(train_data['number_of_reviews'] == 0).sum()
1699
カラムのうち欠損値が含まれているのはlast_review
とreviews_per_month
のようです。この2つのカラムがnullとなっているのはreviews
数が0となっているデータのようです。これらのカラムは宿泊施設の人気度の尺度になりそうです。
予測モデルの作成,学習
モデルに投入する目的変数(y),説明変数(X)を作成します
train_columns = ['neighbourhood', 'room_type', 'minimum_nights', 'number_of_reviews']
target = 'y'
X = pd.get_dummies(train_data[train_columns], drop_first=True)
y = train_data[target] / 10000
いよいよ予測モデルの作成に入ります。
model.fit('説明変数','目的変数')
と記述することでモデルの学習が可能となります。目的変数を説明変数の組み合わせで説明可能な回帰モデルを作成できます。
import sklearn
from sklearn.ensemble import RandomForestRegressor as RFR
model = RFR()
result = model.fit(X, y)
予測モデルの評価
score
メソッドを用いてモデルの評価を行うことができます。
model.score(X, y)
0.46400404613856716
モデルの評価
テストデータに対する回帰モデルの当てはまりの良さの指標としては'決定係数'などの指標が用いられます。
決定係数の値は、.score
で確認が可能です。
1に近いほど回帰式で予測された値が実際のデータに当てはまることを表します。
また、コンペの評価指標となるRMSLE
についても出力が可能です。
今回は、sklearn.metrics
に含まれるmean_squared_log_error
メソッドとnp.sqrt
メソッドを使用します。
RMSLEは出力値と真値の差を表し、0に近いほど予測精度が高いことを表します。
モデルを元にした予測値は、model.predict('説明変数')
で表します。
from sklearn.metrics import mean_squared_log_error
y_true = y
y_pred = model.predict(X)
print(np.sqrt(mean_squared_log_error(y_true, y_pred)))
0.483417271534843
今回作成したモデルのRMSLEは0.483程度でした。
テストデータに対する出力
最後に、作成したモデルを使用してテストデータでの取引金額を予測します。
テストデータの説明変数については予め、上記でモデルに学習させたデータの説明変数と同様の前処理をする必要があります。
path_test = "../compe_data/test_data.csv"
test_data = pd.read_csv(path_test, index_col='id')
test_data.head()
|
name |
host_id |
neighbourhood |
latitude |
longitude |
room_type |
minimum_nights |
number_of_reviews |
last_review |
reviews_per_month |
availability_365 |
id |
|
|
|
|
|
|
|
|
|
|
|
1 |
5-minute walk from Akasaka Sta, Superior double |
184730720 |
Minato Ku |
35.67131 |
139.73285 |
Private room |
1 |
0 |
NaN |
NaN |
183 |
2 |
7 min Sta.-Center of IKEBUKURO Cozy Room#503 |
20993205 |
Toshima Ku |
35.73014 |
139.71739 |
Entire home/apt |
2 |
21 |
2020-04-16 |
1.94 |
337 |
3 |
Designer'sApt 1min sta☆Shinjuku 7min☆Shibuya 4min |
322521715 |
Setagaya Ku |
35.66193 |
139.66540 |
Entire home/apt |
1 |
14 |
2020-02-12 |
0.82 |
240 |
4 |
Komagome Station 2 minutes on foot |
234477095 |
Toshima Ku |
35.73603 |
139.74794 |
Entire home/apt |
1 |
16 |
2020-02-17 |
1.19 |
0 |
5 |
Monthly/Metro1min/JR5min/Ueno,Asakusa,Akihabara |
145453833 |
Taito Ku |
35.72126 |
139.78320 |
Entire home/apt |
30 |
2 |
2019-07-21 |
0.19 |
164 |
test_X = pd.get_dummies(test_data[train_columns], drop_first=True)
先ほど使用したmodel.predict('説明変数')
の'説明変数'にテストデータの値を代入することで、テストデータの予測値を算出することができます。
下記のようにして、提出用のsubmission.csv
を出力することが可能です。
test_predicted = model.predict(test_X)
submit_df = pd.DataFrame({'y': test_predicted})
submit_df.index.name = 'id'
submit_df.to_csv('submission.csv')
「民泊サービスの宿泊料金予測」コンペティション参加規約
コンペティションへの参加に際しては、ProbSpace利用規約(以下、「利用規約」といいます。)に加え、本ProbSpace参加規約(以下「本規約」といいます。)に同意いただく必要があります。利用規約にて定義された用語は、本規約においても同様の意味で用いられるものとします。
第1条(適用)
- 参加者(第2条に定義します。)は、コンペティションに参加した時点で、本規約、利用規約、その他ご同意いただいた規約のすべて、及びコンペティションサイトに掲載されているコンペティションに関するルールの一切に同意したものとみなされます。
- 本規約、利用規約、その他ご同意いただいた規約のすべて、及びコンペティションサイトに掲載されているコンペティションに関するルールは、コンペティションの終了後も参加者に適用されます。
第2条(定義)
本規約において次の各用語の定義は、それぞれ以下に定めるとおりとします。
- 「本コンペ」とは、当社ウェブサイト上で開催されるAI開発又はデータ分析等に関するコンペティションのうち、本規約に紐づく特定のコンペティションを意味します。
- 「主催者」とは、当社またはユーザーのうち、本コンペを主催する者を意味します。また、本コンペが、当社の顧客又は提携先の企業、学校その他の団体等がスポンサードするものである場合は、当該団体等も主催者の定義に含まれます。
- 「参加者」とは、ユーザーのうち、主催者側以外の立場で本コンペに参加する方を意味します。
- 「成果物」とは、本コンペにおいて参加者により開発される学習済みモデル、そのソースコード及び乱数シード等の設定値を意味します。
- 「入賞者」とは、当社より本コンペに入賞した旨の通知を受けた参加者を意味します。
- 「知的財産権」とは、著作権(著作権法第27条及び第28条に定める権利を含みます。)、特許権、実用新案権、商標権、意匠権、その他のノウハウ及び技術情報等の知的財産権(それらの権利を取得し、又はそれらの権利につき登録等を出願する権利を含みます。)を意味します。
第3条(権利の帰属)
- 本コンペで発生した成果物に関する知的財産権は、参加者に帰属します。
第4条(入賞者の義務)
- 入賞者は、本コンペで公開した成果物を、MITライセンスを適用し、商用利用の許諾条項及び著作権人格権の包括的不行使条項をライセンス条項に付与した形式で、オープンソースソフトウェアとして公開する義務を負うものとします。その前提として、入賞者は、成果物について本項に基づく方法でオープンソース化する権利を有していることを当社に対して表明保証するものとします。
※第三者が、授業・研修・セミナー等で活用できるようにするための規約となります。ご理解のほどよろしくお願いいたします。
- 当社は、以下の3点の確認が完了した時点で、本コンペの賞金または商品を、入賞者に対して授与するものとします。
- 入賞者が、前項に基づいて成果物のオープンソース化を実施したこと
- 入賞者が、本規約、利用規約、その他ご同意いただいた規約のすべて、及びコンペティションサイトに掲載されているコンペティションに関するルールの一切に違反していないこと
- 当社が定める方法による本人確認
- 当社は、入賞者が第1項に基づいてオープンソース化した成果物を、自由に商用利用することができます。
第5条(禁止事項)
- 参加者は、本コンペにおいて、以下の各号のいずれかに該当する行為を行ってはならないものとします。
- クラッキングやチート行為、なりすまし、盗用等の不正行為
- 第三者の知的財産権その他の権利を侵害する内容ないし態様で、参加者公開事項を公開する行為
- 主催者(当社以外の者に限ります。)に対する直接連絡、相談、依頼、勧誘、勧誘対応等の活動(但し、当社を介して当社が認めた方法により行うものは除きます。)
- 本コンペにおいて、当該コンペと直接関係のない成果物等を提出すること
- 本規約における参加者としての地位又は参加者としての権利義務について、譲渡、移転、担保設定、その他の処分をすること
- その他、本規約、参加ルール及び利用規約に違反する行為
- 参加者が前項に規定する禁止行為を行ったと当社が認める場合、当社は、当該参加者に事前に通知することなく、当該参加者の本コンペにおける失格処分、当社サービスの全部又は一部の利用停止、ユーザー登録の抹消、その他当社が必要と判断した措置をとることができるものとします。
第6条(本コンペの変更、中断、終了等)
- 当社は、参加者に事前の通知をすることなく本規約に基づく本コンペの開催内容の変更、本コンペの一時的な中断又は終了を行うことができます。
- 当社は、本条に基づき当社が行った措置により生じた結果及び損害について、一切の責任を負わないものとします。
第7条(損害賠償)
- 参加者は、本コンペに関連して、自らの責に帰すべき事由により、当社、主催者その他の第三者に損害を与えた場合には、その一切の損害(逸失利益、弁護士費用を含みます。)を賠償するものとします。
- 参加者が本規約の規定に違反したことにより主催者(当社を除きます。)その他の第三者が当社に対して何らかの訴え、異議、請求等がなされた場合において、当社から処理の要請がなされたときは、参加者は自己の責任と費用負担において、当社に代わって当該第三者との紛争を処理するとともに、当社がかかる訴え、異議、請求等により被った一切の損害(逸失利益、弁護士費用を含みます。)を賠償するものとします。
第8条(本規約の変更)
当社は、必要と判断した場合には、参加者に対して事前に通知する(本コンペにかかる当社ウェブサイト上での告知その他当社が適当と認める方法を含みます。)ことにより、いつでも本規約を変更することができるものとします。なお、変更内容の通知後、参加者が当社の定める期間内に本コンペへの参加を取り消す手続をとらなかった場合には、当該参加者は変更後の規約に同意したものとみなされます。当社は、本規約の変更により参加者に生じたすべての損害について一切の責任を負いません。
第9条(その他)
本契約の準拠法は日本法とし、本契約に起因し又は関連する一切の紛争については、当社の本店所在地を管轄する裁判所を第一審の専属的合意管轄裁判所とします。
(制定)2020年6月22日