データサイエンティスト上がりのDX参謀・起業家

データサイエンティスト上がりのDX参謀・起業家のブログ。データ分析や事業について。自身はアーティスト、経営者、事業家。

【CodeIQ】Rで解くデータサイエンティスト問題の解説(R Advent Calendar2012)

先日より、リクルート様のITエンジニアのための実務スキル評価サービス「CodeIQ」で、データサイエンティストに関する問題を出題させて頂いております(問題集はこちら)。先日12/12のおしゃスタ@リクルートでも少し解説しましたが、Rでの解答例をお見せする時間がなかったので、この機会にブログで公開します(おしゃスタに関するCodeIQ様のブログはこちら)。去年に引き続き勢いだけで参加したR Advent Calendar 2012でしたが、ちゃんとネタが見つかって良かった!!!でも無計画に参加したらクリスマスイブの日に当たってしまったので、、、日付が変わるくらいにさっさと書いてしまいたいと思います!!!爆


【データサイエンティスト初級問題】

【前提】
とある転職サイトから、「とりあえずデータがあるんだけど、、、」と言われてデータを受け取りました。先方は何をして欲しいかまだはっきりと決まってない様子。


受け取ったデータは、
「応募した人の属性データ(oubo_zokusei.csv)」
「応募した時間の記録データ(oubo_kiroku.csv)」
の2種のCSVファイルです。



【課題】
幸いにもデータサイズはあまり大きくなく、Rで読み込める程度。まずはRで読み込んでどんなデータか把握してください。
解答はテキストファイル(.txt)で、


1. Rコード
2. データの概要:どんなデータかまとめた文章
3. 分析提案:もし応募数の予測モデルを作るとしたらあった方がよさそうな変数とその理由


の3つを、この順番で書いて下さい。

データサイエンティストによくある状況なんですが、「データがあるからとりあえず何かやってよ」と言われているパターンです。「仮説がはっきりしてないと分析できませんよ」と言いたくなる気持ちを抑えつつも、何か結果を出す必要があります。受け取ったときはデータの定義ファイルなんかもありません。データを読み込んで始めて分かる状況です。解答例としては、例えば以下のようになります。


【解答例】

1. Rコード

# データチェック
setwd("......")

ID   <- read.csv(file("oubo_zokusei.csv", encoding="cp932"), as.is=T, header=F)
oubo <- read.csv("oubo_kiroku.csv", as.is=T, header=F)

head(ID)
head(oubo)

dim(ID)
dim(oubo)

names(ID)   <- c("ID", "join_time", "age", "gakureki", "shokureki")
names(oubo) <- c("ID", "time")
oubo$month  <- months(as.Date(oubo$time))

hist(ID$age)
summary(ID$age)
table(ID$gakureki, useNA="always")
table(ID$shokureki, useNA="always")

table(oubo$month)


# 全期間での応募数
ouboNum  <- aggregate(oubo$ID, list(oubo$ID), length)
names(ouboNum) <- c("ID", "oubo_num")

# 各月の応募数
ouboNumMonth <- aggregate(oubo$ID, list(oubo$ID, oubo$month), length)
names(ouboNumMonth) <- c("ID", "month", "oubo_num")
ouboNumMonth$month <- ifelse(ouboNumMonth$month == "5月", "mon5", 
                      ifelse(ouboNumMonth$month == "6月", "mon6", "mon7"))

library(reshape)
ouboNumMonth1 <- cast(ouboNumMonth, ID~month, value="oubo_num")
ouboNumMonth1 <- as.data.frame(ouboNumMonth1)
ouboNumMonth1[is.na(ouboNumMonth1)] <- 0

# 入会データとマージ
ouboID <- merge(ID, ouboNum, by="ID", all.x=T)
ouboID <- merge(ouboID, ouboNumMonth1, by="ID", all.x=T)
ouboID[is.na(ouboID)] <- 0

# 可視化
cor(ouboID[, 7:9])
plot(ouboID[, 7:9])

# モデル
ouboLM <- lm(mon7~age+gakureki+shokureki+mon5+mon6, data=ouboID)
summary(ouboLM)

cor(predict(ouboLM), ouboID$mon7)
plot(predict(ouboLM), ouboID$mon7, xlim=c(0, 100), ylim=c(0, 100))
abline(a=0, b=1)


library(randomForest)
ouboRF <- randomForest(mon7~mon5+mon6, data=ouboID)
summary(ouboRF)

cor(predict(ouboRF), ouboID$mon7)
plot(predict(ouboRF), ouboID$mon7, xlim=c(0, 100), ylim=c(0, 100))
abline(a=0, b=1)


2. データの概要レポート

zokuseiデータ:恐らくID・登録日・年齢・学歴・勤務状況が記録されている
ouboデータ:恐らく誰が・いつ応募したのか記録されている
20代〜30代、大卒が中心に利用。離職中が在職中の約半分。

とりいそぎ過去の応募数から次月の応募数を予測するモデルを作ってみたところ、単純な線形回帰モデルでR二乗が約0.33であった。ランダムフォレストも同じくらいの精度であった。次月の応募数のうち約3割が説明可能という解釈ができるが、プロットを確認すると応募数が多い外れ値に引きずられているようにも見える。


3. 分析提案

詳細な分析を行うためには、属性データの詳細が必要。またサイトのアクセス履歴も分析することで、ユーザーの行動特性が見つかるかもしれない(ただ、アクセス解析はRではなく専用ソフトが向いているかも)。
将来の応募数を予測することで、営業支援や売上予測につなけることも可能である。そのためには現在のモデルより精度を上げなければならないため、新たな変数が必要であるし、モデルも吟味する必要がある。


【解説】

だいたいここまで分析時間と文章に起こす時間で、1〜2時間といったところです(エラーが出たりしたらもっとかかりますが)。むしろここまでは割とさくっとできるのですが、ここから先が大変です。仮説をヒアリングしたり、この結果を丁寧に説明したり。丁寧に説明しなくても分かる人が増えてくれれば良いんですがね。マッキンゼーが「データサイエンティストをマネジメントする人材が150万人足りなくなる」って言っているのはこのことだと感じてます(詳しくはこの記事など)。あと実務でこういう事をやろうとすると、データを作るまでに結構な時間がかかってしまったりします。分析に慣れている方がDBを操作していると、簡単に作ってくれたりすることもあります。

しかし、出題した後に、結構レベルが高かったかな〜と思ったり。。まだみなさんの回答を見れてないのですが、むしろこんな出題の仕方で回答してもらえて恐縮でした。。。初級の次に中級・上級を予定してたのですが、それは断念しました。


その反省点を活かして、次の問題からは課題をはっきりとさせました。データサイエンティストで必要な学問知識のうち重要な「統計学」と「機械学習」に分けて出題しています。Codingして結果を出せるように、Rを使って回答してもらう、という形式にしています。以下問題と、私の解答例を紹介します。



データサイエンティスト〜統計学編1〜


【問題】
問1. Rを使い、5人分の身長に関し、下記の6つの統計量を求めてください。


 # 5人分の身長データ
 height1 <- c(168, 173, 152, 181, 175)


 (1) 5人分の身長データの平均値
 (2) 5人分の身長データの中央値
 (3) 5人分の身長データの標本分散
 (4) 5人分の身長データの不偏分散
 (5) 5人分の身長データの標準偏差(不偏分散を使う)
 (6) 5人分の身長データの標準誤差(不偏分散を使う)


問2. 下記のrnorm関数を使うと5人分の身長のデータを擬似生成できます。擬似生成データを使った以下の質問に答えてください。


 # 5人分の身長を擬似生成するコード
 height2 <- 170 + 10*rnorm(5)


 (1) 擬似生成した5人分の身長データを使って
   - 標本分散
   - 不偏分散
   - 標準偏差(不偏分散を使う)
   - 標準誤差(不偏分散を使う)
  の4つの統計量を計算してください。
  計算に使ったRのコードと計算結果を提出してください。

 (2) 「100人分の身長データ」、「1,000人分の身長データ」を擬似生成し、上記4つの統計量(標本分散、不偏分散、標準偏差、標準誤差)を計算してみてください。人数(データ件数)が増えたとき、この4つの関係性はどうなるか議論してください。


【解答例】

# --1.
height1 <- c(168, 173, 152, 181, 175)
mean(height1)
median(height1)
sum( (height1 - mean(height1)) ** 2)/length(height1)
var(height1)
sd(height1)
sd(height1)/sqrt(length(height1))

# --2.
stat <- function(vec){
  a <- sum( (vec - mean(vec))**2)/length(vec)
  b <- var(vec)
  c <- sd(vec)
  d <- sd(vec)/sqrt(length(vec))
  c(a, b, c, d)
}

height2 <- 170 + 10*rnorm(5)
stat(height2)

height3 <- 170 + 10*rnorm(100)
stat(height3)

height4 <- 170 + 10*rnorm(1000)
stat(height4)

# 標本分散と不偏分散はほとんど等しくなっていく
# 標準偏差は10付近をばらついている
# 標準誤差はゼロに近づいていく


データサイエンティスト〜統計学編2〜


【問題】
問1. DataScience_stat2.csvのデータは100万人分の身長を模擬的に作成したものです。
この100万人分の身長データから、1000人分のデータをRを使ってサンプリングしてください。



問2. 問1でランダムサンプリングしたデータを使って以下の値を求めてください。
   2-1. 平均値
   2-2. 標準誤差(不偏分散を使う)
   2-3. 平均値の95%信頼区間



問3. 問2-3の信頼区間は、もとの100万人の集団の平均身長(真値)を推測するものです。サンプリングを無限に繰り返すと、理論的には95%の割合で信頼区間の範囲に真値が含まれます。ランダムサンプリングを10000回繰り返し、この事を確認してください。計算に使ったRのコードと簡単な説明を提出してください。



※DataScience_stat2.csvは以下のRプログラムによって作成しています。
set.seed(1)
height <- 170 + 10*rnorm(1000000)


【解答例】

# --1.
height <- read.csv("DataScience_stat2.csv", as.is=T)

mean(height$x)
sd(height$x)
sd(height$x)/sqrt(length(height$x))


# --2.
set.seed(1)
height_sample <- sample(height$x, 1000)

MEAN <- mean(height_sample)
SE   <- sd(height_sample)/sqrt(length(height_sample))
LCL  <- MEAN - 1.96*SE
UCL  <- MEAN + 1.96*SE


# --3.
CI <- data.frame(LCL=NULL, UCL=NULL)
for(i in 1:10000){
  set.seed(i)
  height_sample <- sample(height$x, 1000)
  
  MEAN <- mean(height_sample)
  SE   <- sd(height_sample)/sqrt(length(height_sample))
  LCL  <- MEAN - 1.96*SE
  UCL  <- MEAN + 1.96*SE
  
  CI <- rbind(CI, c(LCL, UCL))
  print(i)
}
names(CI) <- c("LCL", "UCL")

# ----真値が信頼区間に含まれている割合
CI$BetweenCI <- ifelse(CI$LCL <= mean(height$x) & mean(height$x) <= CI$UCL, 1, 0)
table(CI$BetweenCI)
prop.table(table(CI$BetweenCI))

# ----グラフでチェックする
plot(c(168, 172), c(1, 100), type="n")
for(i in 1:100){
  lines(c(CI$LCL[i], CI$UCL[i]), c(i, i), col=2-CI$BetweenCI[i])
}
abline(v=mean(height$x), lty=2)

データサイエンティスト〜機械学習編1〜


【問題】
問1. Rを使い、DataScience_ML1.csvを読み込み以下の線形回帰モデルを作成してください。
   y=x1+x2



問2. Rを使い、問1で作ったモデルに対して以下の回帰診断を行なってください。

  (1) ローデータの散布図
  (2) 調整済みR二乗
  (3) 残差プロット
  (4) キャリブレーションプロット



※DataScience_ML1.csvは以下のRプログラムによって作成しています。
set.seed(1)
x1 <- rnorm(10000)
set.seed(2)
x2 <- rnorm(10000)
set.seed(3)
y <- 2*x1 + x2**2 + rnorm(10000)
Data <- data.frame(x1 = x1, x2 = x2, y = y)


【解答例】

# --1.
Data <- read.csv(DataScience_ML1.csv, as.is=T)
LM1  <- lm(y ~ x1 + x2, data=Data)

# --2.
plot(Data)
summary(LM1)
plot(LM1)
plot(predict(LM1), Data$y)

# --3.
Data2 <- data.frame(Data, x3 = Data$x2**2)
LM2   <- lm(y ~ x1 + x2 + x3, data=Data2)
summary(LM2)
plot(predict(LM2), Data2$y)

データサイエンティスト〜機械学習編2〜



【問題】
問1. Rを使い、DataScience_ML1.csvを読み込み、以下のモデルを作成してください。結果変数はyとします。

・線形カーネルSVRモデル
・3次多項式カーネルSVRモデル
・ガウシアンカーネルSVRモデル(radial basis)
・シグモイドカーネルSVRモデル



問2. 作ったモデルに対して予測診断を行うために、各モデルのキャリブレーションプロットとR二乗をチェックしてください。


【解答例】

# --1.
library(e1071)
Data <- read.csv(DataScience_ML1.csv, as.is=T)
SVR1 <- svm(y~., data=Data, type="eps-regression", kernel="linear")
SVR2 <- svm(y~., data=Data, type="eps-regression", kernel="polynomial", degree=3)
SVR3 <- svm(y~., data=Data, type="eps-regression", kernel="radial")
SVR4 <- svm(y~., data=Data, type="eps-regression", kernel="sigmoid")


# --2.
plot(predict(SVR1), Data$y)
plot(predict(SVR2), Data$y)
plot(predict(SVR3), Data$y)
plot(predict(SVR4), Data$y)

cor(predict(SVR1), Data$y) ** 2
cor(predict(SVR2), Data$y) ** 2
cor(predict(SVR3), Data$y) ** 2
cor(predict(SVR4), Data$y) ** 2

以上が解答例になります。解説はまた今度の機会に行おうと思っています。CodeIQのサイトからデータのダウンロードはできなくなっていますが、統計学編と機械学習編は各自の環境でデータを作成できます。ぜひやってみて下さい。今回紹介した5問は分析では入り口ですが、これらができるだけでも実務ではとても役に立ちます。これくらい出来ていれば、他の手法も理解しやすくなると思います。おしゃスタでの発表資料でも問題の解説を少ししていますので、補助的に見て下さい。


今後も分析力を身に着けてレベルアップしていけるように、問題をステップアップできればと思っています。最終的には私の修士論文とか博士論文のネタに辿り着ければな〜と思ったり(ここに置いてます)。


それでは、今回の記事はこのへんで失礼致します。

みなさまよいクリスマスと年末年始をお過ごし下さい!!!!!!!!!!

データマイニングに関する8つの誤解

「意思決定のためのデータマイニング」という以下の本から、データマイニングに関する8つの誤解についての抜粋です。

Data Mining and Statistics for Decision Making (Wiley Series in Computational Statistics)

Data Mining and Statistics for Decision Making (Wiley Series in Computational Statistics)

よく質問されることも含まれてます。”誤解”なので、そうではないですよ、ということがタイトルになってます。



1. 事前の知識は必要ない⇒事前知識は必要

データマイニングする際には分析対象のデータに関する事前知識は必要です。特に変数が表す意味や、どういう経緯でデータが入手されているかなど、業務知識は重要です。


2. 専門的なスタッフは必要ない⇒専門スタッフが必要

分析の専門家だけでなく、データに関する当該業務の専門家も必要です。例えば、経済的なリスクを評価する分析を行うときには、リスクを何に設定するのか、専門家が決定しなくてはなりません。


3. 統計学者は必要ない⇒統計家が必要

データマイニングで一番時間がかかるのはデータプロセシングです。変数の信頼性や相関のチェックなどは統計家が行うべきですし、他にも確認することがたくさんあります。欠測、過適合、多重共線性、アルゴリズムのパラメータ、変数の型など。ソフトのボタンを押すだけでは良い分析はできません。


4. データマイニングは思いもよらないことを発見する⇒(特に分析し始めは)当たり前の事が発見されることが多い

データマイニングで利用される変数は、(業務の)専門家に決めれられたものであることが多いです。そのためデータマイニングによって生成されたモデルは、思いもよらない、ということは少ないです。データマイニングでできることは、数千の変数の組み合わせから最も良い組み合わせを抜き出したり、それによってターゲティングルールを少し変更することで反応率が良くなる事もあります。


5. データマイニングは全く新しい技術⇒昔ながらの技術も多い

データマイニングは古典的な分析も含みます。これまでの分析と違うのは、データサイズが大きい、性能が少し落ちても解釈しやすいモデルを使うなどの点ですが、データマイニングが全く新しいわけではありません。


6. 手に入る全てのデータを利用しなくてはならない⇒データを絞ることも重要

データマイニングの結果は、変数が沢山あるほど改善すると思うかもしれないが、そう言う訳ではない。良いモデルができたとき、さらに改善させようとして変数を加えると、モデルの質や頑健性が悪くなることもあります。


7. いつもサンプリングしなくてはならない⇒全数データを使うこともある

サンプリングするときは、元の集団のことを良く知っておかなくてはなりません。顧客特性が良く変わる分野ではサンプリングは控えるべきです。サンプリングデータの分布は、もとのデータの分布と一致している必要があるので、サンプリングによって稀なデータ(稀な現象や小さいセグメントの顧客)が無くなってはいけません。


8. 絶対にサンプリングしてはいけない⇒サンプリングすることもある

予測モデルを作るとき、学習と検証のためにサンプリングが必要です。またデータが大きいときに、サンプリングすることで早くモデルを作ることができます。サンプリングデータで深い計算をすることで、良いモデルができることもあります。



データマイニングのことを過度に期待せず、正しく効果的に利用しましょう、ということですね。”ビッグデータ”にも同じ事が言えるかと思います。

メモ:データハンドリング系で良く使う関数

特に1人多レコードのデータを加工するときに良く使う関数のメモ。

  • 過去の記事のExtractData:1人多レコードあるときに、各人で一番上の行を抜き出す
  • data[order(data$var),]:dataをdata$varで昇順に並べ替える
  • aggregate(data$var1, list(data$var2, ...), function):var1に対して、var2,...の層ごとにfunctionを適用する
  • library(reshape)のcast(data, var1+...~var2, value="var3"):var1,...がキー、var2が変数ラベル、var3が値
  • a <- 1:100; b <- ifelse(regexpr("1", a) != -1 , 1, 0):特定文字列があればフラグを付ける
  • あとはplyrとか

MapReduceできる10個のアルゴリズム

HadoopとMahoutにより、ビッグデータでも機械学習を行うことができます。Mahoutで実装されている手法は、全て分散処理できるアルゴリズムということになります。Mahoutで実装されているアルゴリズムは、ここに列挙されています。論文としても、2006年に「Map-Reduce for Machine Learning on Multicore」としていくつかのアルゴリズムが紹介されています。

そこで今回は、(何番煎じか分かりませんが自分の理解のためにも)この論文で紹介されているアルゴリズムと、どうやって分散処理するのかを簡単にメモしておきたいと思います。計算するべき統計量が、summation form(足し算で表現できる形)になっているかどうかが、重要なポイントです。なってない場合は、”うまく”MapReduceの形にバラす必要があります。

※例によって、間違いがあった場合は随時修正致しますのでご指摘下さい。


1. 局所重み付け線形回帰(Locally Weighted Linear Regression, LWLR)

  • mapperでサブデータの重み付き平方和(xxとxy)を計算しreducerで足す。(以前の記事を参考
  • 重みが1の場合は通常の線形回帰になる。


2. ナイーブベイズ

  • ナイーブベイズには条件付き確率が必要なので、mapperではそれぞれの条件付き”頻度”を計算しreducerで足す。
    • #(x=k|y=1), #(x=k|y=0), #(y=1), #(y=0)(#は頻度)


3. ガウシアン判別分析(Gaussian Discriminative Analysis, GDA)

  • GDAに必要な4つのパラメータを分散計算する。
    • P(y), μ0, μ1, Σ


4. k-means

  • mapperで中心に割り付け&中心までの距離の合計とサンプル数を計算、reducerで中心の更新を行う。
  • これを繰り返す。


5. ロジスティック回帰

  • ニュートンラフソン法で尤度を最大化する。
  • 更新に必要な部分をmapperで加法できるように計算し、reducerで合計して更新する。


6. ニューラルネットワーク

  • バックプロバゲーションをmapperで行い、部分的な傾きを計算する。
  • reducerでそれぞれの傾きを足し合わせ、重みを更新する。


7. 主成分分析(Principal Components Analysis, PCA)

  • 共分散行列が求まれば良く、共分散行列はsummation formになっている。


8. 独立成分分析(Independent Component Analysis, ICA)


9. EMアルゴリズム(Expectation Maximization, EM)

  • Eステップ、Mステップで推定するそれぞれのパラメータをうまくmapperとreducerにバラす
  • EステップのMapReduce、MステップのMapReduceを繰り返す


10. サポートベクターマシンSupport Vector Machine, SVM

  • 線形SVMの2次損失関数の場合、ある方程式を解くことで最適化ができる
    • 部分的な傾きをmapperで計算しreducerで足す。これによって重みのwを更新する。


以上です。こうやって見るとsummation formになっていない場合は最尤法を使い、(傾きによる)尤度の更新を1回のMapReduceで行なっているようです。またEMアルゴリズムというとても汎用的な手法がMapReduceできるということで、多くの手法が分散処理できるということが分かります。しかし実際にはそれぞれのEMをMapReduceに分解しなくてはならないので、実装はかなり大変そうです。また毎回のパラメータ更新をMapReduceしなくてはならないので、結構な時間もかかりそうです。

Pythonで分析や機械学習メモ

私はRからプログラミングに入って分析もRでやってるわけですが、ちょっと大きめのデータになるとRでは扱うのが難しくなります。そこで前々からPythonに手を出そうとしていたのですが、なかなかインストールがうまく行きませんでした。しかし、ようやくPython環境を整えることが出来たので、メモしておきます(@teikawさんにいろいろ教えてもらいました)。

Pythonのインストールは良く使われるパッケージが入っている、enthoughtpythonxyで行うのが良いです。自分は前者のアカデミック版をインストールしました。インストールした後、環境変数の設定が必要かもしれません(以前にPython単体でインストールしたときに環境変数は設定していました)。

機械学習を実行するにあたって、今一番アツそうなのがscikits.learnというライブラリです。これはGoogle summer codeがきっかけで立ち上がったプロジェクトで、10人を超えるエンジニアが作っているようです。トップのUser Guideの中身をひと通り目を通しましたが、主な手法はほとんど入っています!欲を言えば、アンサンブル系がもっとあって欲しいですが。上記のパッケージでPythonをインストールしていれば、追加でパッケージを入れることなく、コンソール上でコードをコピペすれば結果を再現できます。Exampleにある画像も、ほとんどコピペで作成できます!(一部、改行やコメントの影響でエラーが出ました。)R使いな私としては、こういう手軽さがとても嬉しいですね。実際にRとどう住み分けるかは、引き続き考えなきゃいけないですが。

また、自学習用にscipyのチュートリアルもメモしておきます。

因果推論のススメ

2012年3月12日、計算機科学分野の権威ある賞、チューリング賞wikiはこちら)をJudea Pearl先生が受賞されました(米記事はこちら日本記事はこちら)。Pearl先生は「因果推論」分野の権威です。因果推論はベイジアンネットワークや構造方程式モデリングSEM、パス解析)などの基本理論になります。チューリング賞が出たこともあって因果推論が注目されそうですが、難易度が高い分野でもあります。そこで、私が読んで理解が進んだ本を紹介致します。

まずは、このエッセイ本を読むと「因果関係とは何か?」「効果とは何か?」といった事をとてもイメージしやすくなります。これは医療統計分野の本なので、「ランダム化試験」という用語で因果関係を説明していますが、web業界の方はA/Bテストと言った方が分かりやすいかもしれません。A/Bテストをすることでレイアウトの良し悪しが判明するのも、基礎には因果推論の考え方があります。

宇宙怪人しまりす医療統計を学ぶ (岩波科学ライブラリー (114))

宇宙怪人しまりす医療統計を学ぶ (岩波科学ライブラリー (114))


次に、理論的な内容のこれらの本があります。1つ目の星野先生の本は疫学や公衆衛生学寄りで、Rubin先生やModern Epidemiologyの説明に近いと思います。2つ目の宮川先生の本はグラフ理論やDAG(非循環有向グラフ)に基づいていて、Pearl先生の説明に近いです。傾向スコアや操作変数に関する解説があります。

統計的因果推論―回帰分析の新しい枠組み (シリーズ・予測と発見の科学)

統計的因果推論―回帰分析の新しい枠組み (シリーズ・予測と発見の科学)


上記の本で因果推論が分かってくると、Pearl先生の教科書が読みやすくなります。次のように、日本語訳もあります。ベイジアンネットワーク、SEMなどの説明があります。

統計的因果推論 -モデル・推論・推測-

統計的因果推論 -モデル・推論・推測-



また、DAGには3つ重要な基準があります(DAGであれば必ずこれらを満たすわけではないのでご注意下さい)。この特性は慣れないと理解が難しいので、自分の理解をメモしておきます(正確な定義は教科書をご覧下さい)。表現に間違いがあれば、後ほど修正致します。


1. 有向分離基準(d-separate)

有向分離基準を満たせば、集合Sによってaとbは独立となる。aとbの間の道上で、すべての合流点(collider)で条件付けると擬似相関が生まれる。また、aとbの共通因子や中間因子で条件付けると独立になる。


2. バックドア基準

バックドア基準を満たすSが存在すれば、xのyへの介入効果はSによって表現可能となる。このとき、xのyへの介入効果は識別可能という。このようなSの条件は、xがSの原因因子になっておらず、かつ、xからの矢線をとりのぞいたときにSがxとyを有効分離することである。


3. フロントドア基準

Sがフロントドア基準を満たせば、Sによってxのyへの介入効果は表現可能である。このときの条件は、Sの要素でxyの道を全てブロックしている、xからSへのバックドアパスは空集合でブロックされる、Sからyへのバックドアパスをxがブロックしている、の3つを満たすことである。未測定の交絡因子があるときの対処法の1つである「媒介変数法」を拡張したアイディアになっている。他の対処法としては、操作変数法や条件付き操作変数法がある。


また、過去にPearl先生の訳本を読みながら資料に起こしたものがありますので、紹介しておきます。

一年で身に付ける!Rと統計学・機械学習の4ステップ

久しぶりの投稿です。この一年間、Rの勉強会などに参加したり主催したりしてきて、後輩や勉強会の方々の話をいろいろ聞くとこができました。そんな中、一年間でRと統計学機械学習を身に付けれるようなフローを作れるかも?と思ったので、ここで記録しておきます。統計学機械学習は理論を勉強するだけでなく、Rで実際に解析してみることで、より理解が深まります。


ステップ1. 分布・検定

理論

統計学入門 (基礎統計学?)

統計学入門 (基礎統計学?)

R本

Rによるやさしい統計学

Rによるやさしい統計学


ステップ2. 尤度・回帰

理論

自然科学の統計学 (基礎統計学)

自然科学の統計学 (基礎統計学)

R本

統計学:Rを用いた入門書

統計学:Rを用いた入門書


ステップ3. 多変量解析

理論

多変量解析入門――線形から非線形へ

多変量解析入門――線形から非線形へ

R本

RとS-PLUSによる多変量解析

RとS-PLUSによる多変量解析


ステップ4. 機械学習

理論(Hastie本、PDF

The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition (Springer Series in Statistics)

The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition (Springer Series in Statistics)

R本

Rによるデータサイエンス データ解析の基礎から最新手法まで

Rによるデータサイエンス データ解析の基礎から最新手法まで



本の内容的に重複もあって、完全に上記のように分けれるわけではないですが、この順で学ぶことで理解が進むかと思います。また、それぞれのステップで代役になる本は他にもあります。例えば、ステップ2の理論本は、『現代数理統計学』でも同じくらいの難度だと思います。また、PRML本では、Hastie本とは違った見方で機械学習を学べます。それぞれのステップを3ヶ月くらいでこなせれれば、一年で統計学機械学習の全体感を取得し、Rも使えるようになりますね。(最後のHastie本を3ヶ月は大変ですが笑)

実践から入りたい!!といった方は、ステップ3や4から入るのも良いと思います。もともと統計学は実データから生まれた学問なので、むしろそういうモチベーションは大事です。実際、私は「とりあえず分析して結果を見たい」派なので、R本が少なかった数年前は金先生のページの資料にある例を実行したりしていました。以前書いた「ぼくのかんがえたとうけいがくぶかりきゅらむ」も、実践を先に勉強しましょう、という趣旨で学習順序を構成しました。

この後は、「Rで学ぶデータサイエンス」シリーズで各論を学んだりすると、より高スキルが身につきます。また、ビッグデータを扱うためにHadoop+Mahoutを習得したり、切り出したデータを加工するためにRubyPythonPerlなどのスクリプト言語を勉強したり、一度DBに格納してデータ操作をするためにMySQLSQLiteなどのデータベースを扱えるようになれれば、データサイエンティストへより近づけますね。実際に、Facebookが求人しているデータサイエンティストは、以上のようなスキルを持った人です。

明後日からちょうど4月です。ぜひこの一年で、1人でも多くの人が統計学やデータ分析を取得して頂きたいものです。そしてデータ分析を社会に役立てて欲しいですね!


※なお、紹介している本や、ステップは随時変更するかもしれませんのでご了承下さい。