shimo_tの日記

興味のあること:Python, 機械学習, kaggle, Cryptocurrency[NEW], Blockchain[NEW]

seabornの導入

以下の記事で話題になっていたので,自分も導入してみました.

seabornは,installして読みこむだけで,デフォルトでは少々野暮ったい感じのmatplotlibをいい感じにしてくれるライブラリです.

公式のドキュメント

基本的には,公式のギャラリーに行き,書きたいグラフを探して使うのがいいと思います.

install

pip install seaborn

サンプル

ipython notebook環境で行う場合は,以下のコードを打つことでインライン出力できます.

%matplotlib inline

import

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

関数

seabornをimportしただけで自動的にスタイルが適用されるようです.

fig = plt.figure(figsize=(16, 4))

ax = fig.add_subplot(1, 3, 1)
ax.set_title('y = x')
x = np.linspace(-5, 5, 100)
ax.plot(x, x)

ax = fig.add_subplot(1, 3, 2)
ax.set_title('y = x^2')
x = np.linspace(-5, 5, 100)
ax.plot(x, x**2)

ax = fig.add_subplot(1, 3, 3)
ax.set_title('y = sin(x)')
x = np.linspace(-10, 10, 100)
ax.plot(x, np.sin(x))

f:id:shimo_t:20151008225754p:plain

標準正規分布

ヒストグラムは,sns.distplot()で描けます.

x = np.random.randn(1000)
sns.distplot(x)

f:id:shimo_t:20151008220454p:plain

ランダムウォーク

n = 1000
x = np.linspace(0, n, n)
step = np.random.choice([1, -1], n)
pos = np.cumsum(step)
plt.plot(x, pos)

f:id:shimo_t:20151008221408p:plain

線形回帰

簡単な線形回帰の例です.

from sklearn.linear_model import LinearRegression

N = 100
x = np.linspace(0, 10, N)
noise = np.random.randn(N)
y = x + noise

X = [[i] for i in x]
lr = LinearRegression()
lr.fit(X, y)
y_predicted = lr.predict(X)

plt.scatter(X, y)
plt.title('Linear Regression')
plt.plot(X, X, label='actual: y = x')
plt.plot(X, y_predicted,
         label='predicted: y = %.4f + %.4fx' % (lr.intercept_, lr.coef_))
plt.legend(loc=2)

f:id:shimo_t:20151008222356p:plain

iris

sns.pairplot()を使うことで一度に散布図がプロットできます(かなり便利!!!).

pandasのDataFrameを使うことが前提らしいです.

from sklearn import datasets
import pandas as pd

iris = datasets.load_iris()

df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
df['target'] = iris.target
sns.pairplot(data=df, hue='target', vars=iris.feature_names)

f:id:shimo_t:20151008224535p:plain

Kaggle: Coupon Purchase Predictionに参加しました

初投稿です.よろしくお願いします.

KaggleのCoupon Purchase Predictionに参加したので,備忘録を兼ねて,その振り返りをしたいと思います.

自分は今回がKaggle初参加だったのですが,日本企業が主催している(Kaggle初)ということで,内容が把握しやすく,日本人が参加しやすいコンテストだったのかなと思います.

問題把握

今回のコンテストは,22,873人のユーザーの51週間分の購入履歴と閲覧履歴が与えられ,52週目に誰がどのクーポンを購入するかを予測し,購入する確率が高いものから10個選んで,以下のようなcsv形式で提出するというものでした.

USER_ID_hash,PURCHASED_COUPONS
ユーザーID, クーポン1 クーポン2 クーポン3
ユーザーID, クーポン4 クーポン1 クーポン3 クーポン5
ユーザーID, クーポン3 クーポン2 クーポン6
etc...

Forum, Scriptsを読む

Kaggleの特徴としてForum上で問題について議論されていたり,ときには使用したスクリプトが,Scripts上で公開されていたりします. 実際,今回のコンテストでもPublic Leaderboard上で,Score: 0.007600(=400/1000位相当)のスクリプトが公開されていました.

自分は,このスクリプトを理解することからはじめて,これを改良するという形で進めていきました.

実装

Scriptsを参考にレコメンデーションベースのモデルを作成しました.

参考にしたスクリプトでは,コンテンツベースのレコメンデーションに基づき,

  1. ユーザーの購入履歴 + 閲覧履歴に基づいたユーザープロフィール(=ユーザー数 x 特徴量数の行列)
  2. test用クーポンの特徴量(=クーポン数 x 特徴量数の行列)

の重み付きコサイン類似度(ユーザー数 x クーポン数の行列)を計算し,類似度の高い上位10クーポンを選んでいました.

このスクリプトを参考に以下の点を改良しました.

改良点

主な改善点は,以下の3つです.

  1. test用クーポンにユーザー属性(性別と年齢)の付加
  2. TF-IDF値の計算
  3. Cross Validation

1. test用クーポンにユーザー属性(性別と年齢)の付加

上記のスクリプトのtest用クーポンの特徴量には,ユーザーの属性(性別と年齢層)が含まれていなかったため,まず,どんな性別や年齢層ののユーザーがtest用クーポンを購入するかをアイテムベースのレコメンデーションに基づき予測しました.

具体的には,train用クーポンとtest用クーポンの重み付きコサイン類似度を求め,test用クーポンと類似度の高いtrain用クーポン上位100を購入したユーザーの属性(性別と年齢層)の平均をtest用クーポンの特徴量に追加しました.

2. TF-IDF値の計算

各特徴量のカテゴリ['SEX_ID', 'AGE_GROUP', 'GENRE_NAME', 'large_area_name', 'small_area_name']ごとにTF-IDF値を求め正規化してからコンテンツベースのレコメンデーションを行いました.

3. Cross Validation

コサイン類似度の重みは以下のサイトを参考にCross Validationを用いて決定しました.

nycdatascience.com

今回のコンペティションではMAP@10という評価関数を使ってスコアを算出していたので,Forumを参考にgithubに載っている計算式をそのままコピペして使用しました.(pipを使ってml_metricsをinstallすると正しく計算されなかったので,コピペしました.)

上位の人がやっていたこと

  • 負例の考慮(購入時,同時期に掲載されていたにもかかわらず購入に至らなかったクーポン)
  • xgboost?(kaggleで流行っている手法らしい)

最終結果

最終結果は62/1089位でした.

Kaggleには今回が初参加…というより,機械学習自体一ヶ月前にデータサイエンティスト養成読本を買って始めたので,まあよく出来たほうではないでしょうか.

得られたもの

  • pythonでのデータ処理(numpy, pandas)に関する知識
  • レコメンデーションシステムについての初歩的な理解
  • コサイン類似度(Cosine Similarity)
  • Cross Validation
  • TF-IDF

まとめ

  • Kaggle上で公開されているForumやScriptsを読むだけでもかなり勉強になる
  • Forum, Scriptsを読むには,それなりに英語力が必要
  • ただし,それ以上に機械学習についての知識が必要

かなり雑なまとめになりましたが,これからも勉強を続けていきたいと思います.