2014年7月24日木曜日

留学終了。そして、次のステップへ

6月末で授業が終わり、帰国しました。

語学留学も含めると1年2ヶ月、あっという間でした。
そして、TOEFLやGMATなど留学準備にかなり長い時間かかったので、感慨深いです。

留学して、技術的なことはもちろん、コミュニケーションの面でも多くのことを学んだと思います。
そして何より、日本とは違う生活スタイルや社会インフラを受け入れて、その中で生活することで、日本の良いところを感じたり、一方、アメリカ、サンフランシスコの良さを感じたりすることができました。言葉にすると陳腐ですが、世界が身近になったと思います。

サンフランシスコではデータサイエンティストの需要が引き続き大きく、インターネット系のスタートアップだけでなく、大企業も採用を始めています。そして、シリコンバレーのスタートアップの人たちと話をすると、今後もデータサイエンスのマーケットは大きくなると考えているようです。この流れに乗って、データサイエンスをいろいろなところで活かせる仕事をしていきたいと思っています。

留学が終わったので、このブログの更新も止めたいと思います。
読んでくださった方、ありがとうございました。

2014年6月19日木曜日

(備忘) Amazon AWSを使ってのMapReduce -第1章

Elastic Map Reduce(EMR)を使って簡単な集計をしたときのメモ。
使用データは、wikipediaのtraffic を集めたwikistatsデータ。公になっているデータでサイズは150GBです。
(http://aws.amazon.com/datasets/6025882142118545)

結構調べながらやったこともあり、週末かかりました。もう一度はできないので、メモします。


第一章: データの準備


参考URL
http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-public-data-sets.html


1) Amazon EBS Snapshotのコピー

正直なんのこっちゃって感じでしたが、どうやらデータは、Amazon Elastic Block Store(EBS)でサポートされており、EBCとは仮想の外付けHDDのようなものだと理解しています。そして、Amazonが公開しているフリーのデータの多くは、EBCに格納されているようです。

1. まず初めにAWSのマネジメントコンソールから、EC2のページに行きます。

2. 右にあるツールバーから「Snapshots」を選び、 wikistatsのsnapshots ID (US Snapshot ID (Linux/Unix):snap-f57dec9a) を表示させます。EBSはRegion(Virgnia、N. Carifornia, Oregon, Tokyoなどなど)によって分かれており、wikistatsデータは、Virgniaにありました。なので、表示されなかったら、RegionがVirgniaになっているか確認します。

3. N.Virgniaから自分の最寄りのRegionにコピーします(「Actions」から「Copy」を選択すると、ポップアップでどこにコピーするか聞いてきます)。

4. コピーし終わったら、Create Volumeします。

5. 続いて、EC2のインスタンスを起動します。EBSは”外付けHDD"なので、バーチャルマシンであるEC2インスタンスからアクセスすることになります。EC2を立ち上げるときに、コピーで作ったSnap ShotのIDを入力すると、インスタンスが起動したときに、認識してくれます。


6. EC2が起動したら、Snapshotをマウントします。SSHでEC2のインスタンスにログインして、以下を実行します(ec2-userでログインしているが、rootで作業したいのでsudo suします)

$sudo su
#mkdir /mnt/wikidata
#mount /dev/xvdf1/ /mnt/wikidata

ここまで準備の準備・・・・続いて、マウントしたデータをS3にデータを移します。


2) EC2からS3へデータの転送


1) EC2にSSHログインして、sudo suしたら、便利ツール「s3cmd」をインストールします。そして、s3cmd --configure でセッティング。 Access Key、Secret Keyを聞かれますので、AWSのマネジメントコンソール右上のログイン名をクリックし、Security Credentialから確認できます。
$sudo su
#yum --enablerepo=epel install s3cmd
#s3cmd --configure
2) そして、S3でバケット(フォルダ)を用意します。作ったバケットにデータをコピーしていきます。というのも、EMRはS3からデータを読み込むので、ここにインプットするデータを置いておきたいわけです。


3)さて、いよいよデータをEC2からS3に転送します。以下のコマンドでいけるはずです。
#cd /your path to wikistats data/
#s3cmd put --recursive /mnt/wikidata/wikistats/ s3://<your bucket>/wikidata/

それにしても、150GB、約2000のgzipファイルをコピーするので、めちゃ時間かかる・・・

これ以外のs3cmdの用法は、こちら(http://s3tools.org/usage)


(おまけ)

転送中にまさか!!・・・途中でエラーが出てファイルの一括アップロードが止まりました。残り961ファイル・・・そこで、残りのファイルのリストを作り、Perlでs3cmd putを呼び出すone linerコードを準備しました。遠い昔にやった、Perl one linerの記憶を便りに検索しまくりました。。。

#まず、残ったファイルのリストをテキストファイルで保存
ls /mnt/wikidata/wikistats/ | cat | tail -n 961 > filelist.txt

#そして、Perl one-linerで残ったファイルを転送
perl -nle '$from = "s3cmd put /mnt/wikidata/wikistats/".$_; $to = " s3://<your bucket>/wikidata/wikistats/".$_; $cmd = $from.$to; system($cmd);' filelist.txt

ちょっとつかれたので、続きは次回!

2014年5月29日木曜日

いよいよ最終モジュール!

いよいよ5月中旬から最終モジュールが始まりました。私の留学生活も残すところ1ヶ月です。
あっという間だったような、長かったような、不思議な感じです。しかし、多くのことを勉強しましたし、何より旅行ではなく、実際に住んで、サンフランシスコのライフスタイルに触れて、アメリカのことや、日本のことについて考えるようになりました。そのことが大きな収穫だと思っています。

さて、最終モジュールのラインナップについて書きたいと思います。

Application of Analytics
シミュレーションのクラスです。モンテカルロシミュレーションに始まり、MCMCなどをやります。わりと数学重視のクラスです。最終モジュールで疲れてきている身体には応えますが、トピックは実用的かつ重要なので、頑張ってついていきます。


Marketing Analytics
マーケティングに纏わる分析手法を勉強します。コンジョイント分析、LTVの求め方など。先生は元ニールセンの方で、統計学的にどうこうというよりは、統計分析の結果をどうビジネスクライアントに説明するかに力点が置かれています。そして、このクラスの特徴は、SASを使用すること。クラス内では、賛否両論ありますが、私個人としては、SASはRと違って有償ですし、まだまだ大手企業で使っているメジャーなソフトウェアで覚えておいて損はないと思っています。

Web Analytics
これが本モジュール一番期待している授業です。自分でウェブサイトを作って、それにGoogle Analytics等の分析ソフトを導入して、実際に分析していくという流れです。先生は、元Googleのエンジニアの方でこれらのツールを熟知しているのはもちろん、とてもナイスガイなので、多くを学びたいと思います。

Practicum
インターンですね。いよいよ最後!!


最終モジュールで、気が抜けそうですが、なかなかのラインナップだと思います。最後まで楽しんで勉強できそうです。



2014年5月1日木曜日

備忘) Hadoop Streaming PythonでJOIN

もう少し調べておりましたら、Hadoop Streaming + Pythonで2つのファイルをJOINする方法を見つけました。参考にしたのは、こちらのブログ。忘れないようにメモしておきます。

  • http://allthingshadoop.com/2011/12/16/simple-hadoop-streaming-tutorial-using-joins-and-keys-with-python/

1. まずはお試し用データを用意

今回は、あるカスタマーデータがあるとして(customerData.csv)、その中にある県のID(Pref_id) を、県の名前テーブル(pref.csv)を参照して、実際の県の名前(pref_name)をカスタマーデータにくっつける、ということを考えています。


customerData.csv
#ID, Name, Pref_id, good or bad id
1, Taro, 1, 0
2, Jiro, 2, 1
3, Saburo, 3, 0
4, Hanako, 1, 0
5, Ken, 3, 1
6, Nick, 2, 1
pref.csv
#Pref_id, Pref_name
1, Tokyo
2, Osaka
3, Hokaido

2. Hadoop hdfsにアップ

そんでもって、この2つのファイルをcustomerというフォルダにアップします。
$hadoop fs -put pref.csv /user/<your username>/customer/customerData.csv
$hadoop fs -put pref.csv /user/<your username>/customer/pref.csv



3. MapperとReducerを用意

参考にしたブログにもあるように、1つのフォルダに格納されている2つのファイルを出力します。

問題は、ある出力があったときに、それが、どちらのファイルから来たものなのかを判別することが必要になります。ここでは、カンマで区切って配列にしたときの長さで判別しています。

また、Mapperから出力される文字列ですが、すべての要素(この例では、共通項目のPref_id、customerData.csvにあるID, Name, good or bad idの3つ + pref.csvにあるPref_nameの合計5つ)、をくっつけて出力します。

その際、該当する要素がない場合は、NAを意味するフラグを立てて出力させるのがポイントのようです。

Mapper.py
#!/usr/bin/python

import sys

# input comes from STDIN (standard input)
for line in sys.stdin:
    line = line.strip()
    line = line.split(",")

    id = "-1"
    name = "-1"
    pref = "-1"
    pref_name = "-1"
    good = "-1"


    #If length of the line is four, the data comes from customerData
    if len(line) ==4:
        id = line[0]
        name = line[1]
        pref = line[2]
        good = line[3]

    else:
        pref = line[0]
        pref_name = line[1]


    print '%s\t%s\t%s\t%s\t%s' % (id, name, pref, pref_name, good)

Reducerですが、ここでは、県名を入れておく辞書と、カスタマー情報を入れておく辞書を用意して、mapperから出てくる文字列を見て、各行を格納しておきます。

reducer.py
#!/usr/bin/python

import sys

pref_dict ={}
customer_dict={}
for line in sys.stdin:
    line = line.strip()
    id, name, pref, pref_name, good = line.split('\t')

    id = int(id)
    pref = int(pref)
    good = int(good)

    #if id ==-1, it means the data comes from Pref data
    if id ==-1:
        pref_dict[pref] = pref_name
    
    #Oterwise, the data comes from customer data
    else:
        customer_dict[id] = [name,pref,good]

for id in customer_dict.keys():
    pref_name = pref_dict[customer_dict[id][1]]
    name = customer_dict[id][0]
    good = customer_dict[id][2]

    print '%s\t%s\t%s\t%s'% (id, name, pref_name, good)


4. テスト

ターミナルでテストしておきます。
$cat customerData.csv pref.csv | python mapper.py | python reducer.py
1  Taro  Tokyo 0
2  Jiro  Osaka 1
3  Saburo  Hokaido 0
4  Hanako  Tokyo 0
5  Ken  Hokaido 1
6  Nick  Osaka 1


5. 権限を変更して、hadoop jarを実行

chmod でmapper.pyとreducer.pyに実行権限を与えておきます(コマンドは、chmod +x mapper.pyもしくはreducer.py)。最後に、hadoop jar streamingです。
$hadoop jar /usr/lib/hadoop-mapreduce/hadoop-streaming.jar -mapper mapper.py -reducer reducer.py -input /user/<your username>/customer/*.csv -output custoer_pref -file mapper.py -file reducer.py

6. 実行結果の確認
$ hadoop fs -cat /user/ykatada/customer_pref/part-00000
1  Taro  Tokyo 0
2  Jiro  Osaka 1
3  Saburo  Hokaido 0
4  Hanako  Tokyo 0
5  Ken  Hokaido 1
6  Nick  Osaka 1



2014年4月30日水曜日

備忘) Pythonで書くMap Reduce on Hadoop


ここ最近の授業でもPythonのMulti processingのモジュールを使って、Mapper, Partitioner, Reducerを組み合わせて、いろいろ集計したり、回帰分析のプログラムを書いたりしています。 徐々にですが、Map Reduceがどういうもので、どこをパラレルに計算させて、集計とるかみたいな勘がわかってきました。


で、今日は、1ヶ月くらい前にHadoopのセットアップをやりましたが、その後ほったらかしていたので、授業で勉強したことを活かすべく(?)、Hadoopの擬似分散モード上で動くPythonのM/Rのプログラムを書いてみようと思います。

参考にしたブログはこちら。


  • http://www.michael-noll.com/tutorials/writing-an-hadoop-mapreduce-program-in-python/
  • http://blog.matthewrathbone.com/2013/11/17/python-map-reduce-on-hadoop---a-beginners-tutorial.html


まず下準備です。


1. 使用するデータを用意する


こちらのデータは、1行目から順に、ID, 性別, 年齢, 身長(インチ), 体重(ポンド), 自分の体重をどう思うか?(1=太っている、2=痩せている、3=普通), 体重を変えようとしているか?(1=太ろうとしている, 2=痩せようとしている, 3 = 維持しようとしている) というデータです(元データはこちら
:ftp://ftp.cdc.gov/pub/Health_Statistics/NCHS/nhanes/nhanes3/1A/adult.dat)。

このデータを、adult_data.csvと呼びます。
'00003', 1, 21, 72, 180, 3, 1
'00004', 2, 32, 63, 135, 1, 2
'00009', 2, 48, 61, 147, 1, 2
'00010', 1, 35, 70, 205, 1, 2
'00011', 1, 48, 67, 170, 3, 3
'00019', 1, 44, 70, 187, 3, 3
'00034', 2, 42, 63, 128, 1, 2
'00040', 2, 17, 60, 100, 3, 3
'00044', 2, 24, 66, 125, 3, 2
'00045', 2, 67, 64, 147, 3, 3
'00048', 2, 56, 68, 231, 1, 2
'00049', 2, 82, 73, 97, 2, 1
'00051', 1, 44, 71, 300, 1, 2


2. 使用するデータをローカルからHDFS上にアップする

#まずは、testフォルダを作ります
$ hadoop fs -mkdir /user/<your username>/test
#そんでもって、putでデータをローカルからHDFS上にコピーします
$ hadoop fs -put adult_data.csv /user/<your username>/test/adult_data.csv

3. PythonでMapperとReducerを書きます

今回は、性別ごとの平均年齢を出してみます。
まずは、Mapperから。

どうやら、Hadoopのstreaming-jarというもので、データを一行ずつPythonのプログラムに標準入力できるようです。なので、テキストとして読み込んだ一行ずつのデータをstripとsplit(",")でパースしています。例えば、最初の行は、以下のような配列になります。

"'00003', 1, 21, 72, 180, 3, 1" ->['00003', "1", "21", "72", "180", "3", "1"]

そして、1つめの要素(性別)と2つめの要素をピックして、標準出力していきます。 Key Valueのペアは、ただのタブ区切りのテキストとして出力されるというわけです。

Mapper.py
#!/usr/bin/python

import sys

# input comes from STDIN (standard input)
for line in sys.stdin:
    line = line.strip()
    line = line.split(",")

    if len(line) >=2:
        sex = line[1]
        age = line[2]

        print '%s\t%s' % (sex, age)

続いて、Reducerです。 Reducer.pyには、PartitionerとReducerがセットになっています。 Mapperから吐き出されるKey Valueペアのテキストをパースして、辞書にValueを格納、最後に集計というのが大雑把な流れです。

Reducer.py
#!/usr/bin/python
#Reducer.py
import sys

sex_age = {}

#Partitoner
for line in sys.stdin:
    line = line.strip()
    sex, age = line.split('\t')

    if sex in sex_age:
        sex_age[sex].append(int(age))
    else:
        sex_age[sex] = []
        sex_age[sex].append(int(age))

#Reducer
for sex in sex_age.keys():
    ave_age = sum(sex_age[sex])*1.0 / len(sex_age[sex])
    print '%s\t%s'% (sex, ave_age)

3. Pythonのプログラムの権限変更

作ったプログラムに実行権限を追加します。
$ chmod +x mapper.py
$ chmod +x reducer.py

4. テストしてみる

これって、ただのテキストを吐き出して、Mapperで読み込んで、また吐き出して、Reducerでも読み込んで吐き出しているだけなので、ターミナル上でテストできます。例えば、こんな感じで。
$ cat adult_data.csv | python mapper.py | python reducer.py
1 47.597301855
2 47.2906009245


5. 最後にMap Reduce on Hadoop!

ここで、hadoop-streaming.jarというJavaのプログラムをhadoop jarで実行します(参考にしたブログに書いてあった、hadoop-streaming.jarがあるディレクトリと私のディレクトリが違ったので、cdhのバージョ等ンに寄って違うのかもしれませんので、検索して確認したほうが良いかもしれません)。

mapper.pyとreducer.pyのあるディレクトリで以下を実行すると、Map Reduceが始まります(見やすくするために、複数行で書いていますが、実際にやるときは一行で書いてください)。
$hadoop jar /usr/lib/hadoop-mapreduce/hadoop-streaming.jar 
 -mapper mapper.py 
 -reducer reducer.py 
 -input /user/<your username>/test/adult_data.csv 
 -output ave_age 
 -file mapper.py 
 -file reducer.py


6. めでたく結果をゲット

(よくわからないんですが)outputで指定したフォルダに、part-00000というテキストファイルが作られていて、そこに結果が入っています。
$hadoop fs -cat /user/<your username>/ave_age/part-00000 
1 47.597301855
2 47.2906009245

2014年3月24日月曜日

CDH4を使ってのHadoop + HIVE インストール備忘録(Ubuntu 12.10)

新しいモジュールでDistributed Computingの授業があるので、UbuntuにHadoopとHiveを入れておこうと思って始めたのですが、不慣れでかなり手間取ってしまい、丸一日潰してしまいました。。。こういうインフラ系のことって本当に難しいんですね・・・

また同じことはできないと思うので、忘れないように残しておきます。

参考にしたブログや記事です。本当に助かりました。ありがとうございます。


  • https://gist.github.com/YoshihitoAso/9444292
  • http://kakakikikeke.blogspot.jp/search?q=hive



上記を見ながら、「動かない!!なぜだ!??」と試行錯誤しながら、ようやく動くまでに至った経緯です。正直、Hadoopがどうやって動いているのか、hiveがどうして動いているのかわかっていませんが、自分がやったことは以下のとおりです。


まず、インストールするOSですが、Ubuntu12.10の64bitです。

Javaのインストール
$ sudo add-apt-repository ppa:webupd8team/java
$ sudo apt-get update
$ sudo apt-get install oracle-java7-installer
インストールが済んだら、以下のコマンドを叩いてバージョンを確認します。
$ java -version
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
続いて、JAVA_HOMEを設定します。homeにある隠しファイル「.bashrc」を開いて、以下をファイルの末尾に入力し保存します。
export JAVA_HOME=/usr/lib/jvm/java-7-oracle
export PATH=$PATH:$JAVA_HOME/bin
これをやったら、一度ログアウトして、JAVA_HOMEの変更を反映させるのを忘れないように!(それをやらずに、この後のCDHをインストールしたところ、エラー!って怒られました・・・)

CDH4をインストールします。
$ sudo dpkg -i cdh4-repository_1.0_all.deb
$ curl -s http://archive.cloudera.com/cdh4/ubuntu/precise/amd64/cdh/archive.key | sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get install hadoop-conf-pseudo
どうやら、インストールしたときに、hdfsユーザーというものが作られているようです。そこで、ここからはhdfsユーザーで作業をします。
$ sudo su hdfs
コマンドラインが、「hdfs@」で始まるようになります。
そして、以下のコマンドを叩いて、Namenodeをフォーマットします。
$hdfs namenode -format
そしたら、コマンドラインに「exit」と入力してhdfsユーザーから抜けます。
続いて、以下のコマンドをターミナルに入力して、HDFSを起動します。ちなみに止めるときはstartの代わりにstopです。
for service in /etc/init.d/hadoop-hdfs-*
do
sudo $service start (止めるときは、ここのstartをstopに変える)
done
startingほにゃららみたいなメッセージが何回か現れると思います。 それを見届けてから、何も考えずに以下を打ち込みます。
$ sudo su - hdfs
$ hadoop fs -mkdir /tmp 
$ hadoop fs -chmod -R 1777 /tmp
$ hadoop fs -mkdir /var/log/hadoop-yarn
$ hadoop fs -chown yarn:mapred /var/log/hadoop-yarn
$ hadoop fs -mkdir /tmp/hadoop-yarn/staging
$ hadoop fs -chmod -R 1777 /tmp/hadoop-yarn/staging
$ hadoop fs -mkdir /tmp/hadoop-yarn/staging/history/done_intermediate
$ hadoop fs -chmod -R 1777 /tmp/hadoop-yarn/staging/history/done_intermediate
$ hadoop fs -mkdir /user/$USER
$ hadoop fs -chown hdfs /user/$USER
そして、HIVEを使うために、/userの権限を変更します。(これをやらなかったために、HIVEを起動して、テーブル作ったときに、Permission Deniedのエラーが出てハマりました。。。。)
$sudo -u hdfs hadoop dfs -chmod 777 /user
上記がうまくの権限変更がうまく行っているか、確認します。
$sudo su hdfs (改めてhdfsでログイン)
$ hadoop fs -ls /
Found 3 items
drwxrwxrwt   - hdfs supergroup          0 2014-03-23 22:13 /tmp
drwxrwxrwx   - hdfs supergroup          0 2014-03-23 22:02 /user
drwxr-xr-x   - hdfs supergroup          0 2014-03-23 18:26 /var
続いて、YARNを起動してみます。
sudo service hadoop-yarn-resourcemanager start
sudo service hadoop-yarn-nodemanager start
sudo service hadoop-mapreduce-historyserver start

そして、HIVEをインストールします。
※これはhdfsユーザーではなくrootユーザーでやります。
$ wget http://mirror.tcpdiag.net/apache/hive/stable/hive-0.11.0.tar.gz
$ tar xzf hive-0.11.0.tar.gz
$ mkdir /usr/local/hive
そしたら、hive-0.11.0の中身を新しく作った/usr/local/hiveに移します。
次に、環境変数を設定します。また、homeにある隠しファイル「.bashrc」を開いて以下をファイルの末尾に追加して保存します。
export HIVE_HOME=/usr/local/hive
export PATH=$HIVE_HOME/bin:$PATH
また、一度ログアウトし、再度ログイン。ターミナルで、$echo $HIVE_HOMEを叩いて、ちゃんと反映されているか確認。続いて、/hive/confに入っている各種テンプレートを本番用に変更します。
$cd $HIVE_HOME
$mkdir logs
$cd /usr/local/hive/conf
$mv hive-log4j.properties.template log4j.properties
$mv hive-env.sh.template hive-env.sh
$chmod 755 hive-env.sh
$mv hive-exec-log4j.properties.template hive-exec-log4j.properties
$mv hive-default.xml.template hive-site.xml
これで、最後にhiveが動くかどうか・・・・
$hive (これはrootユーザーです)
それで、hive>となったら、まずはshow databases;を叩いてみます。

hive> show databases;
OK
default
test
Time taken: 3.108 seconds, Fetched: 2 row(s)
で、create tableなど試してみて、きちんと動いているようであれば、無事インストール終了です。

2014年3月23日日曜日

サンフランシスコの花粉症

花粉症って日本だけだと思っていたら、アメリカにもあるんですね・・・。ゴールデンゲートパークの近くに住んでいるか、くしゃみが止まらない・・・

日本にいるときは、必ずマスクをして外出していたのですが、サンフランシスコではマスクをしている人を見かけないので、ちょっとマスクして出かけにくいなぁと。結構、バス乗っていても、くしゃみしたり、鼻すすっている人多いんですが、マスクはしていないんですよね。。。友達にこのこと言ったら、「怪しまれるからマスクはしない方がいい」って言われたので、しばらく我慢します。

うーん、早く花粉症の季節が終わらないかなぁ。

第4モジュール開始!

1週間の春休みも終了し、新しいモジュールが始まりました。本モジュールは、ソフトな授業が多かった先モジュールとは大きく異なり、統計&プログラミングのお祭りです。

Data and Information Visualization
字のごとく、Rのggplot2を使って、ひたすらグラフを書きまくるクラスの模様です。データの可視化は重要なテーマです。ただ、データの可視化ってかなり個人の嗜好が影響するので、どう教えるんだろうって気もしてします。ただ、先生はデータの可視化を研究している方なので、盗めるところは盗んでいきたいですね。

ただ、そもそも、これまでのビジネスの現場経験からすると、複雑なデータをどうやって折れ線と棒グラフに持ち込むかを考えるほうが重要だと個人的には思っています。

Multivariate Statistical Analysis
多変量解析の授業です。主成分分析、因子分析などなどやるようです。回帰分析、時系列分析から引き続き先生は同じで、数学をかっちりやりつつ、Rで動かすっていう感じになりそうです。

Distributed Computing
おまちかねのMapReduceです。先生は実際に働いている方なので、実務でどうやっているかを学べます。また、学生はAWSのクーポンを持っているので、AWS上でHadoopを動かします。が、AWSで遊んでいるとすぐクーポンがなくなってしまうので、好きな人は、自分のマシンにHadoop入れて遊んだりしています。

Practicum
引き続き、インターンですね!


上記の他に、Kaggleの生みの親でありデータサイエンティストのJeremy Howardのレクチャーがあります(来年はどうかわかりませんが・・・)。彼が実際にKaggleでどんなテクニックを使ってきたのかについて、説明してくれています。彼は本当にすごいです・・・。

とても楽しいモジュールになりそうです!

2014年3月17日月曜日

KAGGLE 備忘録

ここ最近、KaggleのLoan Predictionのコンペに参加していました。結果はTop25%入りでした。(コンペの詳細は、http://www.kaggle.com/c/loan-default-prediction)

このコンペの目的は、名前のとおり債権のデフォルト予測なのですが、多くのデフォルト予測は「デフォルトする・しない」のクラス分類問題です。しかし、このコンペは、デフォルトする・しないの分類だけではなく、デフォルト後の回収率を予測するという数値予測の要素も入っています。

実は、開始当初の数週間は、全てデフォルトしないと予測する「ゼロベンチマーク」を超えられず、かなり苦戦しました。しかし、いくつかブレークスルーがあり、最終的にはTop25%で着地しました。最後の1週間、時間がなくてモデルをアップデートできなかったのが悔やまれますが、まぁ、いろいろと学びがあったので、良しとしましょう!

このコンペの最大の難関は、説明変数約700個の内容が隠されていることです。もし、「利子率」とか「満期までの時間」などがわかればもっと簡単なのでしょうが、データセットの変数のラベルは、f201やf355と付けられているので、どの列が何を意味しているのかわかりません。つまり、Feature Engineeringができないことになります。

また、コンペは、Mean Absolute Error(MAE)で競われることになります。この点も非常に重要なところです。

そして、私がとったアプローチは以下2段階です。

① デフォルトした、しないのフラグを作り、クラス分類のモデルを作る。
② デフォルトしたサブセットのみを対象に、回収率の予測モデルを作る。

①の問題は「どのアルゴリズムを使うか」ということよりも、変数選択です。また、データセット中、デフォルトした債権の本数は約10%なので、かなりアンバランスなデータセットです。

そこで、フォーワードステップワイズ式のロジスティック回帰で、説明変数の絞り込みを行いました。ここで意識したのは、「何」を最大化(最小化)させるようにステップワイズを組むかです。通常のステップワイズでは、新たな変数を加えた時にAICが改善、Devianceが改善するかどうかで行いますが、今回のコンペの目的はクラス分類の精度が重要なわけです。そこで、F1スコア(PrecisonとRecallの調和平均)が最大になる変数を選択するように関数を組みました。この結果、5つの説明変数が選ばれ、F1スコアが約0.85でした。

次に、選ばれた変数を実際にグラフで見てみて、傾向を探り、ある変数と別の変数の差が予測に貢献していそうなことがわかったので、それら2つの変数の差を取ったものを、新たな変数として加えました(元の2変数は削除)。

このうえで、アルゴリズムを変えることでF1スコアが上がるかどうかを試しました。直観的には、ロジスティック回帰で0.85いくのであれば、ランダムフォレスト、ニューラルネットワークでも同等かそれ以上になるだろうということで、この2つを試しました。最終的にはニューラルネットで、F1が0.91にまで上昇しました。これで、①のクラス分類モデルの作成は終了です。

②は、①のモデルを使って、デフォルトする「だろう」と予測されたサブセットを作ります。ここで注意したのは、元データのうち本当にデフォルトしたものだけを抽出するか、①の予測モデルで、デフォルトと予測されるものを抽出するかですが、私は後者を選んでいます。賛否両論あるかと思いますが、①のモデルには誤差があるので、その誤差も含めて、②のステージで予測しようというのが考え方です。

②では、回帰分析で予測モデルを考えました。問題は残差の仮定ですが、最終的にはポアソンで落ち着きました。単純な回帰分析の場合は、被説明変数が0~100と限定されているのに対し、予測値は0以下も100以上も出ますので、予測値を得た後で、丸めなくてはなりません。今回のデータは0~100の整数で、かつ0側に歪んでいる分布だったので、ポアソンにして、残差もチェックしたら悪くない感じでした。ただ、単純に全変数を突っ込んで予測していても、順位が上がらなくなっていたので、2変数の交互作用の全組み合わせを入れて、ステップワイズでMAEを最小化するモデルを選ぶようにしました。

②はえいやー!でやった感は否めず、もう少し時間があれば変数選択をちゃんとできたかもしれませんが、まぁ、結果は悪くないと思っています。

次回も頑張りたいと思います!

2014年1月23日木曜日

春学期 第3モジュールスタート!

今週から新学期!第3モジュールが始まりました。

このモジュールのラインナップはこんな感じです。

Business Strategies for Big Data(週2コマ)
先生は、あるゲーム会社のディレクターで元UCLA Andersonの先生だそうです。主にミクロ・マクロ経済の基礎、アカウンティング、ファイナンス、マーケティングをざーっとやるような感じのようです。このクラスは、MBAのビジネスマネージャーの話を理解できる(馬鹿にされない!)というのがゴールです。

Interview Skills(週1コマ)
Googleでデータサイエンスをやっていた先生が受け持ちます。サンフランシスコもしくはシリコンバレーにある会社に就職するとき、Tech interviewが最初のハードルです。Tech Interviewというのは、例えば「P値って何?」とか「Boostingの疑似コード書いてみて」みたいな質問です。いきなりはできないので、それに対応するための練習をする必要があります。このクラスは、その練習をひたすらやる!というのがゴールです。ちなみに、毎週、Mock Interviewをやります。

Text Mining(週2コマ)
Text Miningといいながら、前モジュールの機械学習の続きのような感じです。ひたすらPythonとRで機械学習のライブラリを呼び続ける!という感じでしょうか。ただ先生は代わって、元々応用数学の人なので、授業は結構数学オリエンテッドです。おそらくこの授業が本モジュールで最もハードになると思われます。

もちろん引き続き週2日のPracticum(企業実習、インターン)がありますので、このモジュールも寝る時間は相当削られそうですが、後半戦も元気にやっていきたいと思います。

2014年1月7日火曜日

Intersession SAS Programming スタート!

さて本日よりIntersession programのSAS Programming のコースが始まりました。このコースは、2週間後のSAS Base programmerの試験の合格を目指します(落ちると何度も受けなおさせられます・・・)。Rに慣れているので、SASは最初わかりにくかったですが、慣れるとふつう(失礼!)ですね。おそらく、R使いの方で、はじめてSASを扱う方は同じような印象を持つのではないでしょうか。

一番とっつきにくいのは、データの操作だと思いますが、その辺はSASのオンラインチュートリアルはわかりやすいと思います。
http://web.utk.edu/sas/OnlineTutor/1.2/en/60476/paths.htm

2014年1月5日日曜日

第2モジュールの振り返り

新年の初投稿です。あけましておめでとうございます。冬休みは一時帰国していましたが、元旦にサンフランシスコに戻ってきました。新年早々、第2モジュールの成績が明らかになってきています。ここらでいちど、第2モジュールの振り返りをしておきたいと思います。


Time Series Analysis for Business and Finance
以前にも書きましたが、第1モジュールでやった回帰分析の続きという位置づけです。自己回帰プロセス(AR process)、移動平均プロセス(MA process)に始まり、GARCHまでがカバー範囲です。授業が数学ヘビーでやりつつも、結構わかりやすく、ここまでのベストレクチャーでした。ただ、あくまで単変量のモデルでやるので、時系列分析入門といったところでしょうか。多変量のモデルも実務では必要となるときがあるでしょうから、そこは自習する必要があります。使用したソフトウェアは、RとSASです。

Machine Learning
カバーした機械学習のアルゴリズムは、
1. 決定木
2. ナイーブベイズ
3. KNN
4. サポートベクターマシーン
5. クラスター分析
6. アンサンブル学習(Random Forest, Bagging, Boosting)
7. アソシエーションルール
8. ニューラルネットワーク
とです。最後まで理論よりでした。アルゴリズムの中で何が起きているのかを理解することが主眼に置かれていたように思います。しかし、今思えば、そういう勉強の仕方は時間がないとできないので、良かったかもと思っています。また、ゲストスピーカーで、Jeremy Howord(KaggleのPresident兼チーフサイエンティストで数々のコンペで優勝)が彼の普段やるデータ分析のやり方などを聞く機会があったのはありがたかったです(この授業だけでなく、以前も来ています)。

Distributed Databases
MySQLのおさらいから、MongoDBでMapReduceの概念を勉強し、最後はAWSでHadoopの使い方、Hiveの使い方を学ぶというものでした。週1の授業でしたので、ざーっと流した感じです。しかし、私はWIndowsになんとかHadoop + Hiveをインストールしようとして一番時間かかったかも。。。

Practicum 1 
会社でインターンをするというもので、週2回出社、週20時間以上の時間と先生からは言われていましたが、もっと時間を使っていたような気がします。なにせデータの量も半端じゃないので処理するのに時間かかります。インターンで感じることは、データ分析で一番大事なことはやっぱり分析結果を使ってもらうことだということです。なので、データ利用者にどうやってわかりやすく説明するか、「お客さんはこんな感じではなからろうか?」とストーリーで話すことの重要性を改めて感じました。また、Take Awayをクリアにしてあげることも重要です。「棒グラフや表などでさえも読みたくない」というのがデータ利用者の本音なのだと感じます。まぁ、私にとっては、実際にアメリカで働いてみたかったので、この授業はありがたいです。

とこんな感じで第2モジュールは終わりました。結構勉強したなぁと思います。そして、週明けからはSAS集中講義があり、2週間後にSAS Base Programmerの試験を受けることになっています。これに受からないと受かるまでやらされる模様なので、一発で合格したいです。

残りは半年!後半戦もがんばらないと!