Data Science by R and Python

統計学を、広く、深く、わかりやすく。

pythonでデータ分析(1)

f:id:tomoshige_n:20140907233155j:plain

R -> python

さて、pythonでRと同程度以上のデータ解析をできるようになろうと決意して、はや1週間が経ちました。まだ、1週間かよ!という突っ込みはやめてください笑。ここ数日は、全力でpythonによるデータ分析入門を読み込んでいます。というか、写経して、基本的なデータ分析の操作を覚えています。
O'Reilly Japan - Pythonによるデータ分析入門

本の内容に沿って、やってみたこと。

まず、Movielensの映画評価データを使います。Movielensは映画評価システムの1つで、ミネソタ大学のコンピュータ理工学研究科のグループレンズが運営しています。映画評価データは1990年代後半から、2000年代前半に書けて、Movielensユーザーを対象に収集されてきました。各データは、その映画への評価値、映画の属性(ジャンル・公開年度)、評価者の属性(年齢・郵便番号・性別・職業)から構成されています。

このデータは、データ数は100万件あります。4000本の映画に対する、6000人の評価をまとめたものになっています(つまり、それぞれが全ての映画にレビューを書くわけではないということです)。データは3つの表(評価・ユーザー情報・映画情報)から構成されています。

These files contain 1,000,209 anonymous ratings of approximately 3,900 movies
made by 6,040 MovieLens users who joined MovieLens in 2000.


MovieLens | GroupLens

それぞれのデータを確認すると、まずは「ユーザー」情報は。

In [52]: users
Out[52]: 
      user_id gender  age  occupation    zip
0           1      F    1          10  48067
1           2      M   56          16  70072
2           3      M   25          15  55117
3           4      M   45           7  02460
4           5      M   25          20  55455
5           6      F   50           9  55117
6           7      M   35           1  06810
7           8      M   25          12  11413
8           9      M   25          17  61614
9          10      F   35           1  95370

となっていて、評価結果はこのようになっています。これらのデータはuseridでひもづいています。

In [53]: ratings[:10]
Out[53]: 
   user_id  movie_id  rating  timestamp
0        1      1193       5  978300760
1        1       661       3  978302109
2        1       914       3  978301968
3        1      3408       4  978300275
4        1      2355       5  978824291
5        1      1197       3  978302268
6        1      1287       5  978302039
7        1      2804       5  978300719
8        1       594       4  978302268
9        1       919       4  978301368

そして、映画情報はこんな感じ。これは評価データとmovie_idでひもづいているデータです。

In [54]: movies[:10]
Out[54]: 
   movie_id                               title                        genres
0         1                    Toy Story (1995)   Animation|Children's|Comedy
1         2                      Jumanji (1995)  Adventure|Children's|Fantasy
2         3             Grumpier Old Men (1995)                Comedy|Romance
3         4            Waiting to Exhale (1995)                  Comedy|Drama
4         5  Father of the Bride Part II (1995)                        Comedy
5         6                         Heat (1995)         Action|Crime|Thriller
6         7                      Sabrina (1995)                Comedy|Romance
7         8                 Tom and Huck (1995)          Adventure|Children's
8         9                 Sudden Death (1995)                        Action
9        10                    GoldenEye (1995)     Action|Adventure|Thriller

このデータをまずは、pandasにあるmerge関数で統合する必要があります。これはRでもmerge関数があって、どこを引数にするのかを指定すれば、マージしてくれます。このあと、性別毎の平均などを導出して、性別で評価が変わる映画は何かなどを出していきます。コードはこんな感じ。

#data merge
data = pd.merge(pd.merge(ratings,users),movies)

#1行目を参照する
data.ix[0]

#男女/タイトルで結果を出力する
mean_ratings = data.pivot_table('rating',rows='title',cols='gender',aggfunc='mean')

#分析対象を250件以上のレビューのある映画に限る
#titleでグループ分けして、sizeを調べる
rating_by_title = data.groupby('title').size()

#250件以上に絞り込む
active_title = rating_by_title.index[rating_by_title>=250]

#mean_ratingsの中でactive titleのみを抜き出す
mean_ratings = mean_ratings.ix[active_title]

#女性の中で評価が高かった映画の抽出
top_female_ratings = mean_ratings.sort_index(by="F",ascending=False)



#評価の分かれた映画の抽出
mean_ratings['diff'] = mean_ratings['M'] - mean_ratings['F']

#sort by diff
sort_by_diff = mean_ratings.sort_index(by='diff')

1週間経ってみて。

Rで関数を書くよりもpythonで書いてる方が、まずなんというか「楽しい」ということがわかりました。もちろん、不便だなと感じることもあります。記述量が多いです。ただ、Rで処理をすると遅いことも、pythonならやっぱり体感値ですが、速いなぁと感じます。
あとは、プログラム書ける周りの人と話してても、Rは取っ付きにくいし、学習コストが大きいなんて言われたりもします(Rになれると、その感覚はわからないんですけど、そういう感覚もあるようですから)。なので、僕がpythonでデータ処理ができるようになれば、そういう人達にも伝えるお手伝いができるようになるかなとも思うので・・・引き続き、がんばります。

codeacademyでpythonを勉強してみたよという話

codeacademyとは?

今日はこれを紹介:Learn to code | Codecademy
codeacademyはオンラインでプログラミング言語を学べるサービスです。昔、一度だけ使ったことがあったんですけど、そのときは、ありがたみがわかりませんでしたが、全力で勉強する気になるとなかなかいいサービスだなと思います。とりあえず僕はデータ解析で使うためにpythonをやってみました。
f:id:tomoshige_n:20140906202456p:plain

実際の勉強は?

勉強は実際に書きながら学んでいきます。一つ一つ解説すると、

  • 一番左が今から何をするのかを解説+その下に問題が書かれています。
  • 真ん中のグレー〜黒の画面に自分でプログラムを書くことで勉強します。
  • そして、右上の黒のところに「実行結果」がでるという風になっています。

f:id:tomoshige_n:20140906203115p:plain

ちなみに、問題を解いてわからないところは、大抵左下のQ&Aで誰かが質問をしてくれているのでそれを参照するだけで、理解も深まりますし、勉強にもなります。もちろんこれだけで、何かアプリケーション創れるようになるとは思いませんが、プログラミングを始めるキッカケとしては、とてもいいツールだなと思いました。

ちなみに、今はcodeacademyで「interactive web」の勉強中です。その他、PHP, js, HTML&CSS, jQuery, Rubyなどが学べるようになっています。それから、APIの叩き方も講座で載っています。勉強したい人にとっては最高のプラットフォームだと思いました。

プログラムを勉強してみたいけど、授業にないよ!とか、どこで学べばいいの?と思っている方は本当にこれで始めてみてはどうでしょうか?※)ただ、唯一の難点は「英語」であるということです。

ちなみに、日本語だとドットインストールというものがありますが、こちらは動画を見ながら手元で自習するという側面があり、活用することはありますが、プログラミングを始めるという意味では、codeacademyの方がオススメかなーと思いました。

プログラムをオンラインで学ぶのが普通になりつつある(気がする!)

実際に、今回codeacademyで勉強をしてみて気づいたのは、オンライン学習プラットフォームの質がぐんぐん向上しているということです。3年前とは本当に全然違います。断然、快適な環境が、無料で使えるというところまで来ています。興味がある!という人は是非やってみてください。

統計言語Rの使い方を学ぶには?

ちなみに、統計言語Rを勉強するには、codeacademyにはそのコースはありませんが、、、見つけました!コードスクールにO'ReillyがスポンサーになってRのコースを開設しています。使ってみましたが、こちらも快適ですので、興味があればやってみてください!

Code School - Try R

ふと思えば

8月終わりまで、僕はRが大好きでした。
でも、最近pythonいいなと思って心変わりしつつあります。
なんたって、データの加工や処理力の高さが...
Rで使ってるライブラリもpythonから使えますしね。
ggplotも実はpython用のライブラリがあります。


ggplot 0.6.5 : Python Package Index


そんなこんなで、2014年秋1本目のブログでした。

集中講義の感想 -3日間ブログ書けなかった言い訳など-

f:id:tomoshige_n:20140830025847p:plain
from: Multiple Imputation in Stata: Imputing

3日間の集中講義を受けてきました。

8/27~8/29の3日間朝9:00〜17:00の時間帯をぶっとうしで講義を受ける「集中講義」を受講していました。その疲れで、3日間ブログを書けませんでした...(←言い訳。今回の集中講義は、「調査観察データの統計科学―因果推論・選択バイアス・データ融合」を著された、星野先生がお越し下さって3日間講義をしてくださいました。このブログで、お話しいただいたことや、欠測データ解析のことなどを9月に入ってからになるかもしれませんが扱ってみようと追います。僕は傾向スコアしかほとんどわからないのですが、今回たくさんの手法が話題にあがったので、しっかりと勉強して使えるようにしようと思います。

※)ただ、集中講義は先生にとっても、受講する学生にもかなりハードでした(笑

そうえいば、統計の興味分野が増え過ぎて、手に負えない件...

最近、SVMを本格的に勉強するためにカーネル法を理論からやり直したり、MCMCマルコフ連鎖から理解し直したりと、一応「数理科学」専攻なので基礎的なことからやり直さないと気が済まないのですが、とにかく追いつかないということで困っております。研究(空間統計)もそろそろ始めないとヤバそうですし(時間的に笑)。ちょっとオーバータスク状態ですが、、、めげずにブログも更新していこうと思います。あと、状態空間モデル勉強すると決意したのに、まだほとんど触れてない...うああ...

明日は...

明日(今日)は初めてTokyoRに参加してきます。
ずっと行きたかったので楽しみです。
明日のブログはそれについて書きます!wkwk...

集中講義の疲れを取るために、そろそろ寝ます。
おやすみなさい。

plotlyパッケージでグラフをシェアしよう! -Rによるグラフィックス-

Plotlyパッケージを紹介します。

PlotlyはRのグラフィックのライブラリで、グラフの作成や共有をインタラクティブに行えて、かつかなりハイレベルな図をブラウザーで表示できるという特徴を持っています。
実際、書いたものをアップロードして、URLでブログなどに張り込むということができるという点でとても実用的です。今回は、このplotlyを用いて、グラフを3つほどDemo的に作成します。

plotlyのインストール

まずは、インストールですが、Rのコンソールから次のようにdevtoolsを読み込みます。libraryで使ってない人は、installをしてください。

install.packages("devtools")
library("devtools")

次に、githubからplotlyをダウンロードします。plotlyには様々なapiが用意されており、今回はR版を使います。Python, Matlabなども対応しているようです。

devtools::install_github("plotly/R-api")

これで、インストールすることができました。ただしplotlyを使うためにはこれだけではダメで、https://plot.ly/のページからアカウントを作成してください。そして、アカウントを作成したら右上のsettingsからusernameとpassをコピーして、次の形でログインをします。

library(plotly)
p <- plotly(username="#ユーザーの名前", key="#APIキー")


これで、plotlyを使えるようになりました。

グラフの作成

さて、ここからはグラフの作成を行います。手始めに、次の用にコマンドを打ってください。それぞれの説明は、#で記述しています。

#データの作成
x0 = rnorm(500)
x1 = rnorm(500)+1

#データを表示方法を一緒に記述
data0 = list(x=x0,type='histogramx',opacity=0.8)
data1 = list(x=x1,type='histogramx',opacity=0.8)
layout = list(barmode='overlay')  
#
response = p$plotly(data0, data1, kwargs=list(layout=layout)) 
#ブラウザーの表示
browseURL(response$url)


すると、こんな感じのグラフを書くことができます。ちなみにオンライン上(https://plot.ly/~tomoshige_n/0)でも見ることができるのですが、iframeで張り込むこともできます。そして何より素晴らしいのは「インタラクティブ」であることです。見ていただくとわかるように、図の上にマウスをのせると、その箇所の数字がみれます!

ggplot2との連携

このplotlyはggplot2とも連携しています。実際ggplot2で描く図はとても奇麗なのでそれをオンライン上でパブリッシングして、さらにインタラクティブにできたら嬉しいですよね。そのためにggplotlyというコマンドが用意されています。実際に以下のようにコマンドを打ち込んでください。コマンドの説明は中に書いてあります。irisのデータを使っています。

library(ggplot2)
#ggplotでirisデータを可視化したもの
ggiris <- qplot(Petal.Width, Sepal.Length, data = iris, color = Species)
print(ggiris)

#plotlyでonline publishing
library(plotly)
py <- plotly("tomoshige_n", "APIキー")
res = py$ggplotly(ggiris)
#ブラウザを開く
browseURL(res$url)

この結果は次のようになります。これもオンラインでも確認できますが、iframeで張り込むことができます。つまり、ggplot2で作成した図もpublishingすることができます。

注)ただ、まだ対応していない部分もあるかもしれません...僕は、図を作成してpublishしたら図がおかしなことになったので...

MAPを書くことだってできます!

オンラインで、インタラクティブな図を作成する場合に、よく例に出されるのが「市町村と人口」を表示する図です。今回は「カナダ」の都市の人口を可視化してみます。

library(maps)
data(canada.cities)
#まずカナダの図(listで作成するところに注意してください)
trace1 <- list(x=map(regions="canada")$x,y=map(regions="canada")$y)
#カナダの都市の位置をx,yで指定して、その箇所につける「名称」をtextで指定。さらに各位置に対して、markerを付けて、マーカーの大きさはsizeで指定。opacityは透過性です。
trace2 <- list(x= canada.cities$long,y=canada.cities$lat,
	text=canada.cities$name,type="scatter",mode="markers",
	marker=list(
    	"size"=sqrt(canada.cities$pop/max(canada.cities$pop))*100,
    	"opacity"=0.5)
    )
response <- py$plotly(trace1,trace2)

url <- response$url
filename <- response$filename
browseURL(response$url)

すると、次のような図が作成できます。マウスオーバーでその都市の人口が見られるようになりました!

とにかく、データの可視化は大事!

先日のTokyoRの資料で「The R User Conference 2014 @ UCLA」という資料(The R User Conference 2014 @ UCLA )が公開されているのを拝見して、データを可視化するということにとても注目が集まっていることを再確認しました。
このブログでも少し前にshinyというRで作成するアプリケーションの話をしましたがそれもこの資料で取り上げられていることをみると、みんな可視化するにはどうすればいいのかといろいろと試行錯誤しているんだと思います。
実際、どんな場所でデータを解析した結果をみせても「図でみたい」と言われることは多いですし、図があれば統計を学んでいない人にも少なからず伝えることができる。そういった利点があるのだと思います。可視化周りは今後、もっと勉強していこうと思いました。

p.s.

最近、もっぱらカーネル法と、マルコフ連鎖の勉強をしていますが、、、とにかく数学をきちんとやってこなかったつけを今まさに払っています。これから統計を始める皆さんは、ぜひ数学を大事にして欲しいと思います...。

正規表現の勉強をしたのでメモ(自分用).

//メタ文字

//[abc] :aかbかcのどれか一文字にマッチさせる
//[]と一緒に使えるメタ文字
//[a-z]:a-zのうちのどれか
//[^abc]:^(キャレット):これの中の文字以外の1文字
	var s = '@tomoshige_n,@temoshige';
	var rs = s.match(/t[^ao]moshige/);
	if(rs){
		alert('マッチしました');
	}
	
// . :任意の一文字
	var s = '@tomoshige_n,@temoshige,@testtest';
	var rs = s.match(/to...hige$/);
	if(rs){
		alert('マッチしました');
	}


// ^ :行頭, 行の一番最初にあるか?
// $ :行末, 行の一番最後にあるか?

//{} :直前の文字の繰り返し回数
//0{2} : 00にマッチする
//0{2,}:2以上の00にマッチ.00,000000など
//0{2,4}:00,000,0000

//[a-z]{5}:小文字5つにマッチする
//[a-z]{3,6}:小文字3~6文字にマッチする


//繰り返しに関するメタ文字
//a? :0文字か1文字の繰り返し, 文字がないか、aか
//a* :0文字以上の繰り返し, 文字がない, a, aaaaa
//a+ :1文字以上の繰り返し, aaaa,aaaaaaaa

//(abc)*, 0文字以上なので、なし、abc, abcabc
//(abc|def), abcもしくはdef


// \n : 改行
// \t : tab
// \d : 数字[0-9]としてもOK
// \w : 英数字と_, [A-Za-z0-9_]
// \s : スペース,タブ
// \メタ文字 : メタ文字


//フラグ,言語によって異なる
// i : 大文字小文字を区別しない, s.match(/to...hige/);でTOMOSHIGEもtomoshigeにもマッチする
// g : すべてのマッチした要素を返す.
// m : 複数行に対応させる  : ^$



// * + のあとの?について(最小マッチ)
// *+?:最初のものだけをマッチさせる

//(), RegExp:マッチしたものの抽出

//	var s = 'tomoshige.nakamura@gmail.com';
//	var rs = s.match(/(.+?)@gmail.com/);
//	console.log(RegExp.$1);

//TwitterIDをマッチさせる
//TwitterIDを引っ掛ける

//var s ="@tomoshige_n";
//var rs = s.match(/@[A-Za-z0-9_]{1,15}/);
//console.log(RegExp.$1);


//タグの中身の抽出
//タイトルタグ

//var s = '<title>ドットインストール</title>';
//var rs = s.match(/<title>([^<]+)<\/title>/);
//console.log(RegExp.$1);


//日付を日本語表記に直す
var s = '2012-03-24';
var rs = s.match(/(\d{4})[-\/](\d{2})[-\/](\d{2})/);
console.log(RegExp.$1+'年'+RegExp.$2+'月'+RegExp.$3+'日')

ShinyをCSSで拡張しようぜ!(その2) - Rでつくるウェブアプリケーション -

ShinyのCSSでの拡張第2弾

今日は、昨日書いた記事の続きを書きます。昨日の記事では、wwwフォルダーの中にCSSファイルを入れて拡張しようということを行ったわけですけど、別の方法もあります。それが、紹介することです。HTMLをご存知の方は知っていると思いますが、HTMLファイルの中にCSSをstyleタグをつけて書くことができます。これは、shinyでも同じようにできます。書き方は、簡単です。

CSSをHTMLのヘッダーに入れる方法

CSSをHTMLのヘッダーに入れるためには、tagsの関数とHTML関数を用います。shinyの公式ブログによれば、HTML()という関数は、ShinyがHTMLであると認識しないようにするための関数だそうです。次のように書くと、CSSを読み込めます。

library(shiny)
#define UI
shinyUI(fluidPage(
		tags$head(
			tags$style(HTML("
				@import url('http://fonts.googleapis.com/css?family=Lobster|Cabin:400,700');
				h1{
					font-family:'Lobster',cursive;
					font-family:500;
					line-height:1.1;
					color:#48ca3b;
				}
				"
				))
		),
		headerPanel("New Application"),
		sidebarPanel(
			sliderInput("obs", "Number of observations:",min = 1, max = 1000, value = 500)
		),
		mainPanel(plotOutput("distPlot"))
	)
)

CSSを外部にファイルを置いて、読み込むこともできます。

その場合の方が幾分簡単です。CSSファイルを以下のように作成します。このCSSファイルの置き場は昨日の記事のように「www」フォルダーの中には入れません。ui.Rと同じディレクトリにおく、または
なんらかのサブディレクトリを作成して、その中に入れて、link指定を変更するようにします。

@import url("http://fonts.googleapis.com/css?family=Lobster|Cabin:400,700");

h1 {
  font-family: 'Lobster', cursive;
  font-weight: 500;
  line-height: 1.1;
  color: #ad1d28;
}

body {
  background-color: #fff;
}

そして、ui.Rの方を以下のように変更します。

shinyUI(fluidPage(

  includeCSS("styles.css"),
    
  headerPanel("New Application"),
  
  sidebarPanel(
    sliderInput("obs", "Number of observations:", 
                min = 1, max = 1000, value = 500)
  ),
  
  mainPanel(plotOutput("distPlot"))
))

これで完成です。一応ウェブアプリケーションということですから、外部にファイルを置いた方がいい気がしますけども。。。こんな感じで、比較的簡単にCSSを自作して使うこともできます。wwwフォルダーを使うよりも、僕個人としてはこちらの方が慣れているし、いいかなと思ってしまいますね...

ShinyをCSSで拡張しようぜ! - Rでつくるウェブアプリケーション -

Shiny

先日、記事で「Shiny」というパッケージを用いたウェブアプリケーションの作成方法についてお話ししました。今回は、そんなウェブアプリケーションをCSScascading style sheets)で拡張しようじゃないか!というお話です。こちらの記事により詳しく書かれています(Shiny - Style your apps with CSS)が、自分の勉強用に作成しています。


CSSはご存知の通り、HTMLで書かれた構造をデザインするためのものです。ShinyのインターフェースがHTMLで書かれているため、オリジナルのCSSを作成することによって、Shinyの見栄えを奇麗にすることができます。CSSについて勉強したい人はコードアカデミーなどで調べればコースはいっぱいありますので、ここでは割愛。

ShinyのアプリケーションでCSSを取り込む方法は3つあります。

  • wwwというディレクトリーの中にスタイルシートを入れる方法
  • HTMLのヘッダーにCSSへのリンクを張る方法(これが一番自然?)
  • styleをHTMLタグの中に直接書き込む(これは、ウェブだとあまり推奨されない)

これをそれぞれ解説していきます(今日は、時間の都合で最初の1つだけです)。まずは、一番最初のwwwのディレクトリーにいれる方法について。

wwwというディレクトリーの中にスタイルシートを入れる方法

まずは、イメージをみせるために、スタイルシートを用いない場合のデザインを示します。かなり簡素なデザインで、、、一面真っ白です。
f:id:tomoshige_n:20140821235418p:plain

それをスタイルシートを導入するだけで、こんな感じで変わります。

f:id:tomoshige_n:20140821235428p:plain


このようなウェブアプリケーションを作成するために必要なものを書いてきます。先日の記事でも書いたようにshiny appは、2つの要素からなります。アプリケーションを実際に動かすサーバー側と、表示するインターフェースです。これらのファイルは、次のようにつくりました。

#ui.R
library(shiny)
#define UI
shinyUI(
	fluidPage(
		theme = "bootstrap.min.css", #wwwフォルダーの中のcssファイルを指定
		headerPanel("New Application"),
		sidebarPanel(
			sliderInput("obs", "Number of observations:",min = 1, max = 1000, value = 500)
		),
		mainPanel(plotOutput("distPlot"))
	)
)
#server.R
library(shiny)

#define server logic required to plot various variables against mpg

shinyServer(function(input, output){
	output$distPlot <- renderPlot(function(){
		dist <- rnorm(input$obs)
		lim_x=c(min(dist),max(dist))
		lim_y=c(0,0.5)
		hist(dist,xlim=lim_x,ylim=lim_y,probability=T)
		par(new=T)
		plot(density(dist),xlim=lim_x,ylim=lim_y,xlab="",ylab="",main="")
	})
})

そして、次にスタイルシートです。今回はブートストラップのCSSを利用しましょう。こちらからダウンロードすることができます。Bootswatch: Free themes for Bootstrap。ここから好きなテーマを選んで、ダウンロードします。そして、次のようにディレクトリーを構成します。ここでwwwフォルダーの中に入っているのが上のページからダウンロードしたbootstrap.min.cssです。

f:id:tomoshige_n:20140821235922p:plain

あとは、ターミナルから、このフォルダーのあるdirectryに移動して、以下のコマンドを実行すると、先ほどのようなCSSの反映されたshiny appが完成します!

R -e shiny::runApp('shiny_css')

ui.Rに書き込む方法

ちなみに、今回はthemeという関数でcssを参照しましたが、別の方法もあります。ui.Rの中に書き込むというものです。bootstrap.min.cssのファイルはwwwのフォルダーの中に入れっぱなしでOKです。で、ui.Rだけ以下のように書き換えてください。ここで、以下のコードを見ていただければわかるように、hrefのパスの中に"./www"のような記述は必要ありません。shinyではwwwというサブディレクトリは特別な意味を持つようです。

#ui.R
library(shiny)
#define UI
shinyUI(
	fluidPage(
		tags$head(
			tags$link(rel="stylesheet",type="text/css",href="bootstrap.min.css")
		),
		headerPanel("New Application"),
		sidebarPanel(
			sliderInput("obs", "Number of observations:",min = 1, max = 10000, value = 500)
		),
		mainPanel(plotOutput("distPlot"))
	)
)

同様に、ターミナルからappを動かせば同じ結果が得られるはずです。