データサイエンティストにはなれなかった

システム屋さんの中でひっそりデータ活用について考えていくブログ

統計検定2級を受けてきました

梅雨らしい雨が降りそうな天気の中、統計検定2級を受けてきました。

1週間前から「やばいやばい」と言いながら勉強し始めて
まぁ落ちずに済んだのではないか、というところです。
解答は2日程度で発表されるみたいなので、楽しみです。
(すでに2問も間違っていることが判明しているが、、)

モチベーション

統計検定の存在は前から知っていたのですが
レベル感がよく分からず、世の中にどの様に認められているものなのかも
不明だったのでスルーしていました。

そんな感じだったのですが、今年に入って
某分析力をコアとするほにゃららな企業の求人情報の欄に
「理論的な知識(統計検定2級程度以上)」と記載されているのをみつけました。
上位の職種を見ても2級程度以上と記載されていたので、安直ではありますが
「まぁ2級受かっていれば実務で分析してる人間として恥ずかしくはないのかなー」
なんて思ったのがきっかけです。

それで試験内容を確認してみると、
「データを扱うための初歩的なリテラシーの問題」と
「仮説検定などの推測と呼ばれる問題」の
大きく2つに分けられそうなことが分かりました。
http://www.toukei-kentei.jp/about/pdf/grade2_hani_140901.pdf

前者に関しては改めて勉強する必要はなさそうでしたが、
後者に関しては普段使わないのでいくらか勉強する必要(勉強する価値)がありそうでした。
今回から始まる準1級を受けてみようかなという気持ちもありましたが、
受験料が高かったのに加えて、1級に比べてだいぶ範囲が広く、
勉強する時間が確保できるか怪しかったので今回は手堅く2級を受けてみることにしました。
(我ながらナイス判断だったと思います)

勉強方法

まずは、過去問を解いてみようと思い公式問題集を買いました。

日本統計学会公式認定 統計検定 2級 公式問題集[2012〜2014年]

日本統計学会公式認定 統計検定 2級 公式問題集[2012〜2014年]

「過去問も買ったし余裕で受かるわー」なんて思ってたら
いつの間にか試験の1週間前になっていて、
いざ2012年の問題を解いてみると、6割程度の正答率で焦りました。
間違える問題の多くは信頼区間の計算だったり検定統計量に関わるもので、
「推測」の問題がやはり弱いということが確認できました。

間違った問題については解説をじっくり読んで理解を深める様にしました。
ただ、公式問題集の解説では各問題の「解き方」についてしか分からないため、
体系的に解き方を理解するのは難しかったです。当然と言えば当然ですが。

ですので、時折Wikipediaを見て頭を整理しつつ
足りない部分については別途ググって知識を補っていくという感じになりました。

これを何度か繰り返していくと、
直近2回の過去問では9割弱合う様になり、
落ちることはないかなーという感じで試験に臨みました。

所感

試験までの時間が残り少ないという状況で、
理論の本質的な理解よりも計算方法の暗記に走ってしまったことは若干後悔しています。
各検定統計量でなぜ検定ができるのかとかそういうことは全く分かっていません。
仮説検定が使われるケース自体が減少していきそうな世の流れに逆行して勉強する
機会を逃してしまったという喪失感がややあります。
(試験が終わった今となっては仮説検定について全く勉強する気が起きません)

また、逆に考えると大して理解していなくても
2級は取れそうなレベルであることが分かったので
2級を受かること自体にそれほど意味はないなーとも思いました。

さらに余談ですが、問題の中にはRを使えば一瞬で分かるような問題もちらほらあり、
「こんなのの計算の仕方を覚えるの?」って感じで辛かったです。
例えば、確率分布の上側確率の表を使って確率を求める方法とかです。
(紙と鉛筆(と電卓)があれば計算できることは凄いなとは思いますけど、、)

今後の話

今回2級に受かったとして次に準1級や1級を受けるかという話ですが、
多分受けないと思います。
「データ分析する人は博士号か統計検定1級持ってないとダメ」
なんて世の中になったら考えますが(笑)

試験合格を目標にすると合格することに最適化し
中身の本質的な理解は軽視してしまうことを今回改めて実感したので、
わざわざ高いお金を払ってそんな目標設定をする必要はないかなあと
私は思いましたという感じです。

追記

結果が出ていました。
統計検定:正解発表
自己採点してみると4問ミスでした。まぁこんなもんですか。

追記2

最優秀成績賞というのをもらいました。
嬉しいのは間違いないのですが
4問ミスで最優秀ってどうなの、、

分析のレベル

5日は長いなーと思っていたGWも残すところあと1日になりました。
このGW今のところ進捗ゼロなので
ブログぐらい更新するかという気持ちで書いています。

最近「データサイエンティストブーム」が下火になってきた関係か、
ポジショントークっぽいツイートやブログを目にすることが増えてきたなぁと感じています。

例えば「クロス集計だけでは気付けないことがある」とか
「時系列データを眺めてるだけではうんぬんかんぬん」とかですね。
どれも分析者の視点からは正しいことだと思うのですが、
ビジネス全体の動きにおいて常にこれらの指摘が正しいかと言うと
そうではないケースも多々あるのではないかと思っています。

一般的に「正しい分析」を行うためには
リテラシーの高い分析者に業務を依頼し、依頼された分析者は、
専門外の方からすると「どうしてそんな面倒なことするの?」と言われる様な
高度で複雑な手法を駆使してリアルデータに立ち向かうことが必要になったりします。

その結果「正しい分析」が出来たとして、
現場担当者が表計算ソフトで作ったクロス集計表や時系列グラフなどの
「現場の分析」と比べてどうなのかが、ポイントになるのではないでしょうか。

一般的には、「正しい分析」の方が精度や信頼性に関しては高い一方で、
現場からすると外部に流出するコストが発生したり、
高度で複雑な手法を駆使した分析は作業自体に時間がかかるのはもちろん、
結果に対して上司や関係者などから理解を得ることに手間取ったりして、
次のアクションに繋げにくかったりします。

次のアクションの決定に莫大な費用がかかる場合や
ビジネスの将来性に大きく影響する様な場面では
いくらか時間や費用をかけてでも「正しい分析」を実施すべきでしょう。
一方で、ある程度現場の裁量で動けて、
短期間でPDCAを回すことが是とされている様な状況ならば
「現場の分析」の方が適していると私は考えます。

両極端な例を挙げましたが、
実際は現場に求められる分析のレベルはもっと曖昧だと思います。

単なる「集計・可視化」で十分なのか、
数式1本で表現できる様な「モデル化」で十分なのか、
状態空間モデルや構造方程式モデルなどのもっと「複雑で精緻なモデル化」が必要なのか、
(細かい話をすれば変数選択や正則化、モデルの検証などをどこまでやるかなんて話もある)
これを現場の方が判断するのは非常に難しいことだと思います。

この様な状況に対し、常に「複雑で精緻なモデル化」を押し付けるのではなくて、
ちょうど良いレベルを探り当ててそちらに導くというのが
分析者に求められる役割だと思います。骨が折れることは承知ですが、、

長くなってしまった。。

グリッドサーチ結果の可視化

春がもう少しで来そうでなかなか来ないもどかしい季節ですね。こんばんは。
最近Rのパッケージの関数を見るのが面白いなと感じる様になりました。
私はあまりコーディングをしないので得意ではないのですが、
下手なりに色々書き換えたりして、自分の欲求を満たすものに作り変えていくのは
なかなか悪くない趣味だなと思っています。

というところで、以前id:hoxo_mさんのブログ
SVM のチューニングのしかた(2) - ほくそ笑む
を読んでtune.plotカッコいいなあ、
もっと汎用的に使えたら嬉しいなぁと思ったのを思い出し、
勉強がてら色々書き換えてみました。

本当は元のe1071で行っている様にfilled.contourを使いたかったのですが、
私の力不足で図の配置が上手くコントロールできなかったため断念しました。
そのためカッコよさは激減しています。
グラフィックパラメータ周り難しい。。

library(e1071)
plot.tune.mat <- function(data,#scoreを指定しない場合最も右の列を評価値
                          score = NULL,
                          error = TRUE,#評価値が小さいほど良い場合はTRUE
                          main = NULL,
                          xlab = NULL,
                          ylab = NULL,
                          transform = NULL,#パラメータ全体を変換する関数
                          color.palette = hsv_palette(),
                          nlevels = 20,
                          ...){
  param <- as.data.frame(data)
  k <- ncol(param)
  
  if(is.null(score)){
    score <- param[,k]
    param <- param[,-k]
    k <- ncol(param)
  }
  
  if (!is.null(transform))
    param <- transform(param)
  
  if(!error){
    col <- rev(color.palette(n =nlevels))
  }
  else{
    col <- (color.palette(n =nlevels))
  }
  
  #グラフィックパラメータ設定
  plot.new()
  par(mfcol=c(k,k))  
  par(mar=par("mar")/sqrt(k-1))
  par(mgp=c(1.5,0.5,0))
  
  #描画
  lapply(1:ncol(param),function(i){
    lapply(1:ncol(param),function(j){
      
      paramtab <- tapply(score,param[,c(i,j)],mean)
      
      if (is.null(xlab)) xl <- colnames(param)[i]
      if (is.null(ylab)) yl <- colnames(param)[j]
      
      image(x=as.double(rownames(paramtab)),
            y=as.double(colnames(paramtab)),
            z=paramtab,
            xlab=xl,ylab=yl,
            col = col)
    })})
  
  #グラフィックパラメータを初期化
  on.exit(par(mfcol=c(1,1)))
  on.exit(par(mgp=c(3,1,0)))
  on.exit(par(mar=c(5.1,4.1,4.1,2.1)))
}

使い方としてはこんな感じです。

plot.tune.mat(data,error=T,transform=log2,nlevels=10)

結果
f:id:fqz7c3:20150215222456p:plain
濃いところが良いところです。
濃さのスケールは全プロットで共通です。

表示したデータ

> data
     p1 p2  p3 error_rate
1   100  5 100 0.06585525
2   100  5 100 0.06455118
3   100  5 100 0.06302978
4   100  5 200 0.05520539
5   100  5 200 0.05498805
6   100  5 200 0.05629211
7   100  5 400 0.04694632
8   100  5 400 0.04803304
9   100  5 400 0.04542491
10  100  5 800 0.04629428
11  100  5 800 0.04759835
12  100  5 800 0.04520756
13  100 10 100 0.06020430
14  100 10 100 0.06346446
15  100 10 100 0.06042165
16  100 10 200 0.05390133
17  100 10 200 0.05107585
18  100 10 200 0.05455336
19  100 10 400 0.04629428
20  100 10 400 0.04694632
21  100 10 400 0.04303412
22  100 10 800 0.04868507
23  100 10 800 0.04542491
24  100 10 800 0.04846772
25  100 20 100 0.05824821
26  100 20 100 0.05933493
27  100 20 100 0.06259509
28  100 20 200 0.05129320
29  100 20 200 0.05107585
30  100 20 200 0.05346664
31  100 20 400 0.04998913
32  100 20 400 0.04694632
33  100 20 400 0.04955444
34  100 20 800 0.04998913
35  100 20 800 0.04694632
36  100 20 800 0.04672897
37  100 40 100 0.06216040
38  100 40 100 0.05824821
39  100 40 100 0.05976962
40  100 40 200 0.05346664
41  100 40 200 0.05085851
42  100 40 200 0.05346664
43  100 40 400 0.05107585
44  100 40 400 0.05433601
45  100 40 400 0.05368398
46  100 40 800 0.05020648
47  100 40 800 0.05194523
48  100 40 800 0.05107585
49  200  5 100 0.06476853
50  200  5 100 0.06302978
51  200  5 100 0.06433384
52  200  5 200 0.05737883
53  200  5 200 0.05585742
54  200  5 200 0.05629211
55  200  5 400 0.04781569
56  200  5 400 0.04651163
57  200  5 400 0.04607694
58  200  5 800 0.04607694
59  200  5 800 0.04499022
60  200  5 800 0.04585960
61  200 10 100 0.06107368
62  200 10 100 0.05998696
63  200 10 100 0.06129102
64  200 10 200 0.05194523
65  200 10 200 0.05129320
66  200 10 200 0.05172789
67  200 10 400 0.04694632
68  200 10 400 0.04672897
69  200 10 400 0.04738100
70  200 10 800 0.04651163
71  200 10 800 0.04716366
72  200 10 800 0.04672897
73  200 20 100 0.05911758
74  200 20 100 0.05890024
75  200 20 100 0.05911758
76  200 20 200 0.04977179
77  200 20 200 0.05107585
78  200 20 200 0.05151054
79  200 20 400 0.04977179
80  200 20 400 0.04651163
81  200 20 400 0.04803304
82  200 20 800 0.04759835
83  200 20 800 0.04716366
84  200 20 800 0.04781569
85  200 40 100 0.06107368
86  200 40 100 0.06042165
87  200 40 100 0.06063899
88  200 40 200 0.05129320
89  200 40 200 0.05064116
90  200 40 200 0.05281461
91  200 40 400 0.05042382
92  200 40 400 0.05020648
93  200 40 400 0.04846772
94  200 40 800 0.04977179
95  200 40 800 0.05129320
96  200 40 800 0.05107585
97  400  5 100 0.06324712
98  400  5 100 0.06324712
99  400  5 100 0.06324712
100 400  5 200 0.05585742
101 400  5 200 0.05303195
102 400  5 200 0.05390133
103 400  5 400 0.04520756
104 400  5 400 0.04651163
105 400  5 400 0.04455553
106 400  5 800 0.04716366
107 400  5 800 0.04651163
108 400  5 800 0.04672897
109 400 10 100 0.05955227
110 400 10 100 0.05976962
111 400 10 100 0.06129102
112 400 10 200 0.05237992
113 400 10 200 0.05172789
114 400 10 200 0.05303195
115 400 10 400 0.04542491
116 400 10 400 0.04651163
117 400 10 400 0.04651163
118 400 10 800 0.04564225
119 400 10 800 0.04694632
120 400 10 800 0.04585960
121 400 20 100 0.05803086
122 400 20 100 0.06042165
123 400 20 100 0.05868290
124 400 20 200 0.05151054
125 400 20 200 0.05020648
126 400 20 200 0.04933710
127 400 20 400 0.04846772
128 400 20 400 0.04694632
129 400 20 400 0.04781569
130 400 20 800 0.04803304
131 400 20 800 0.04629428
132 400 20 800 0.04716366
133 400 40 100 0.06042165
134 400 40 100 0.06107368
135 400 40 100 0.05998696
136 400 40 200 0.05216257
137 400 40 200 0.05151054
138 400 40 200 0.05194523
139 400 40 400 0.04977179
140 400 40 400 0.04933710
141 400 40 400 0.05107585
142 400 40 800 0.05085851
143 400 40 800 0.05129320
144 400 40 800 0.05172789
145 800  5 100 0.06433384
146 800  5 100 0.06216040
147 800  5 100 0.06129102
148 800  5 200 0.05455336
149 800  5 200 0.05433601
150 800  5 200 0.05411867
151 800  5 400 0.04672897
152 800  5 400 0.04433819
153 800  5 400 0.04629428
154 800  5 800 0.04455553
155 800  5 800 0.04629428
156 800  5 800 0.04477288
157 800 10 100 0.06020430
158 800 10 100 0.05998696
159 800 10 100 0.06129102
160 800 10 200 0.05346664
161 800 10 200 0.05216257
162 800 10 200 0.05324929
163 800 10 400 0.04520756
164 800 10 400 0.04607694
165 800 10 400 0.04607694
166 800 10 800 0.04542491
167 800 10 800 0.04672897
168 800 10 800 0.04651163
169 800 20 100 0.05998696
170 800 20 100 0.05737883
171 800 20 100 0.05976962
172 800 20 200 0.05042382
173 800 20 200 0.05085851
174 800 20 200 0.04977179
175 800 20 400 0.04672897
176 800 20 400 0.04672897
177 800 20 400 0.04629428
178 800 20 800 0.04672897
179 800 20 800 0.04738100
180 800 20 800 0.04759835
181 800 40 100 0.05868290
182 800 40 100 0.05955227
183 800 40 100 0.06063899
184 800 40 200 0.05107585
185 800 40 200 0.05151054
186 800 40 200 0.05129320
187 800 40 400 0.04998913
188 800 40 400 0.04933710
189 800 40 400 0.05172789
190 800 40 800 0.04955444
191 800 40 800 0.05064116
192 800 40 800 0.04998913

現時点ではテストもほとんどしていないので
色々不具合あると思います。
(lapplyの2重ループもなんか気持ち悪いので書き換えたいし)
そのうち修正していくと思います。

そもそもこんな関数caretとかにありそうな気がするがどうなのでしょうか。



今回のブログを書くにあたってこの辺りを参考にしました。
http://cse.naro.affrc.go.jp/takezawa/r-tips/r/52.html
http://cse.naro.affrc.go.jp/takezawa/r-tips/r/53.html
http://cse.naro.affrc.go.jp/takezawa/r-tips/r/55.html

ブログのタイトルを変えました。

どうも明けましておめでとうございます。
昨年末は少々やらかしてしまって散々な目にあいましたが
この流れを断ち切って2015年は健康で安心に過ごせると良いなと思っています。
皆様今年もどうぞよろしくお願いします。

で、本題。当ブログのタイトルを変更しました。
以前は「SE採用の新入社員がデータサイエンティストになるまで」というタイトルでした。
4月を迎えれば入社4年目ですし、そろそろ新入社員という言葉にも違和感があるなと感じていました。また、2014年様々な社外の活動に参加して、
私は「データサイエンティスト」になりたかったのではないという認識が強まりました。

私は現職(データ分析コンサルの様なもの)で、「ビジネスとしての価値を出す」ことが最重要であると考えて取り組んでいます。
その中で行う分析は事実に基づいてビジネスや課題を理解するということが
目的であることが多く、クロス集計や単純な可視化といったものが基本となります。
お客様に見せるかどうかは別にして主成分分析や一般化線形モデルなども使ったりしますが、精々その程度のことしかしません。
高度な統計学機械学習アルゴリズムの知識などは業務ではほとんど使っていない様に思います。
案外その様な知識よりも、私のバックグラウンドでもある実験心理学の様な
データ取得に関するバイアスに気付いたり、それを生じさせない様にする工夫などの方が役立っている様な気さえします。

この様に複雑なアルゴリズムや手法を使わず、また、ディープラーニングなど最新の研究成果にも疎い私は
とても「データサイエンティスト」であるとは思えないし、これからもきっとなれないのだろうと感じています。

一方で、私は今の仕事や働き方に対してある程度満足しています。
上でも述べましたが、私は「ビジネスとしての価値を出す」ということが最重要であると考えています。
「データサイエンティスト」でなければ出せない価値はもちろんありますが、
そうでなくてもデータをしっかり見て理解することで生み出せる価値もあると考えています。

私の当面の目標としては、データ活用によって価値が生まれるという体験を
草の根的に広げていける人間になりたいと考えています。
そのためには、予め多くの業界や業種に対する理解を深めていたり
海外のビジネスやソリューションの知識を得て持ち球を増やしたりということが
狭義の分析力を高めるよりも必要なことだと感じています。
もはや、データにこだわる必要ももしかしたらないのかもしれませんが、
私個人としては事実(データはこの一部)に基づいて理解を深めていくというプロセスを重視したいのでこれからもデータにこだわっていきたいと思います。

kNN関連パッケージの紹介

皆様こんばんは。
今回、R Advent Calendar 2014 : ATND 13日目の記事を担当することになったので
久しぶりのブログを書いています。

本記事でご紹介するのはRでkNN(k最近傍法)を実行するためのパッケージです。
kNNについて知らない方はwikipediak近傍法 - Wikipediaに簡単にまとまっているので見てもらうと良いと思います。
要は、入力データに似ているものを訓練データの中からk個探してきて、
それらの多数決で出力を決めるアルゴリズムです。

個人的な印象としては、クラスタリングというよりは検索のイメージが強く、
例えば、訓練データの中から似ているレコード(商品やユーザー、事例など)を引っ張ってくるときに使ったりしています。

それでは早速パッケージの紹介に入ります。

{class}パッケージ

RでkNNをやろうとすると最初に見つかるのがこのパッケージだと思います。
とりあえずクラスタリングをやってみるという意味ではこのパッケージで十分です。

本記事では{kernlab}パッケージのspamデータセットを使って実行してみます。
因みにこのデータセットは約5000件のe-mailに対してスパムかどうかを判定したものです。
各レコードは各ワードや記号などの出現回数から作った特徴量(1~54列目)と
大文字に関する単語の長さなどから作った特徴量(55~57列目)と
スパムかどうかのクラス(58列目)から成っており、
今回は話を単純にするために1~54列目と58列目を対象としています。

library(kernlab)
data(spam)
data <- spam[,-(55:57)] #55列目がクラスになる

library(class)
i <- 1
classres <- class::knn(train=data[-i,-55],test=data[i,-55],cl=data[-i,55],k=100,prob=T) 

実行結果:

> classres
[1] spam
attr(,"prob")
[1] 0.74
Levels: nonspam spam

trianとtestをセットし、求めるクラスを決めてあげると実行できます。
probで確率値を出力する様に設定でき、設定すると
勝ったクラスの割合がどのくらいだったかが分かります。
ただ、今回の場合の様に2クラスの場合は良いのですが、
3クラス以上のクラスタリングで2位以下の確率値が分からないのは残念です。

上記は1レコードに対してknnを実行する方法でしたが
全レコードに対してknnを実行する(leave-one-out)する場合は以下の様にします。

classrescv <- class::knn.cv(train=data[,-55],cl=data[,55],k=100,prob=T) 

実行結果:

> head(classrescv)
[1] spam    spam    spam    nonspam nonspam spam   
Levels: nonspam spam
> head(attr(classrescv,"prob"))
[1] 0.74 0.90 0.93 0.58 0.58 0.50

{class}パッケージのknnは各レコードごとに全探索を行っている様で、
spamデータぐらいではなんとも感じませんが、
データ量が大きくなってくるとパフォーマンスは辛くなってきます。
そこで、{FNN}パッケージです。

{FNN}パッケージ

FNNのFはFastのFなのですが、探索アルゴリズムを選択できる様になっており
全レコードに対してknnを実行する場合はこちらが速いです。
デフォルトのアルゴリズムであるkd_treeで実施した場合の計算時間は
理論的にはO(NlogN)となるそうです。

#classパッケージで実行
system.time(classrescv <- class::knn.cv(train=data[,-55],cl=data[,55],k=1,prob=T))
#FNNパッケージ"kd_tree"で実行
system.time(FNNrescv <- FNN::knn.cv(train=data[,-55],cl=data[,55],k=1,prob=T,algorithm="kd_tree"))

実行結果:

> system.time(classrescv <- class::knn.cv(train=data[,-55],cl=data[,55],k=1,prob=T))
   user  system elapsed 
   3.40    0.00    3.43 
> system.time(FNNrescv <- FNN::knn.cv(train=data[,-55],cl=data[,55],k=1,prob=T,algorithm="kd_tree"))
   user  system elapsed 
   2.69    0.00    2.70 

spamデータぐらいの規模では大きな差はでませんが、数十万件を超える様なデータですと明確な差がでてきます。

補足:この記事を書いていて気付きましたが、kの数を大きくするとそれほど計算時間の差は出なくなってくるみたいです。
アルゴリズムと実装について理解が追い付いていないので原因は不明です。
{FNN}パッケージはkd_treeを設定した場合、Approximate Near Neighbor(ANN)というC++のライブラリを呼んでいますが、
このパッケージにおいては近似していないとマニュアルに書いてあるので、
その辺り調整できればkの数が増えても差が保てるのかもしれません。
この調整を行うには{RANN}のnn2や{yaImpute}のannを使わないと難しそうです。私はまだ試していません。。


{FNN}を使う利点はもう1つあります。(他にもありそうですが)
FNNのknn.cvは最近傍k個のレコードのインデックスを返してくれるので、
本記事冒頭で述べた様に似ているレコードを引っ張ってくることができます。
また、引っ張ってきたレコードのクラスを集計すれば2位以下のクラスの確率値を知ることも可能です。

FNNrescv <- FNN::knn.cv(train=data[,-55],cl=data[,55],k=3,prob=T,algorithm="kd_tree")
i <- 1
data[c(i,attr(FNNrescv,"nn.index")[i,]),]

実行結果:

> data[c(i,attr(FNNrescv,"nn.index")[i,]),]
    make address  all num3d  our over remove internet order mail receive will people report addresses
1      0    0.64 0.64     0 0.32    0      0        0     0    0       0 0.64      0      0         0
13     0    0.69 0.34     0 0.34    0      0        0     0    0       0 0.69      0      0         0
312    0    0.68 0.34     0 0.34    0      0        0     0    0       0 0.68      0      0         0
168    0    0.71 0.35     0 0.35    0      0        0     0    0       0 0.71      0      0         0
    free business email  you credit your font num000 money hp hpl george num650 lab labs telnet num857
1   0.32        0  1.29 1.93      0 0.96    0      0     0  0   0      0      0   0    0      0      0
13  0.34        0  1.39 2.09      0 1.04    0      0     0  0   0      0      0   0    0      0      0
312 0.34        0  1.37 1.72      0 1.03    0      0     0  0   0      0      0   0    0      0      0
168 0.35        0  1.42 1.77      0 1.06    0      0     0  0   0      0      0   0    0      0      0
    data num415 num85 technology num1999 parts pm direct cs meeting original project re edu table
1      0      0     0          0       0     0  0      0  0       0        0       0  0   0     0
13     0      0     0          0       0     0  0      0  0       0        0       0  0   0     0
312    0      0     0          0       0     0  0      0  0       0        0       0  0   0     0
168    0      0     0          0       0     0  0      0  0       0        0       0  0   0     0
    conference charSemicolon charRoundbracket charSquarebracket charExclamation charDollar charHash type
1            0             0            0.000                 0           0.778          0        0 spam
13           0             0            0.056                 0           0.786          0        0 spam
312          0             0            0.055                 0           0.718          0        0 spam
168          0             0            0.058                 0           0.700          0        0 spam

上記、knn.cvを利用しましたが、インデックスが欲しいだけならば、
同パッケージ内のget.knnを使った方が速いです。

system.time(FNNrescv <- FNN::knn.cv(train=data[,-55],cl=data[,55],k=3,prob=F,algorithm="kd_tree"))
system.time(FNNresget <- FNN::get.knn(data=data[,-55],k=3,algorithm="kd_tree"))
> system.time(FNNrescv <- FNN::knn.cv(train=data[,-55],cl=data[,55],k=3,prob=F,algorithm="kd_tree"))
   user  system elapsed 
   3.07    0.00    3.12 
> system.time(FNNresget <- FNN::get.knn(data=data[,-55],k=3,algorithm="kd_tree"))
   user  system elapsed 
   0.76    0.00    0.76 

因みにget.knnの方はattrではなく、リストで値を返してくるのでご注意を。

{kknn}パッケージ

そして、最後に{kknn}パッケージの紹介をしようと思っていましたが、
長くなってしまったので省略します。
多数決を行う時に最近傍k個の重みを調整できたり
クロスバリデーションの機能が充実していたりするのですが、
実務的にはややオーバースペックな印象で、私は使ったことがないです。

本記事では割愛しましたが、多数決の重みやkの数の調整よりも
特徴量自体の正規化や重み付けの方が効くことが多いのかなと思っています。


それでは皆様、来年も宜しくお願い致します。

※間違い等ありましたらご指摘いただけますと幸いです。

TokyoR(第43回)でLTしてきました

半年以上空いての更新となってしまいました。
文章としてアウトプットする習慣がなかなかつかないです。

本題。昨日TokyoRでLTをしてきました。

内容はRのrandomForestの説明と、

使えるメモリに制限がある場合の工夫の仕方についてです。

今回の発表の準備を通して、randomForestが返すオブジェクトの

中の見方が分かったりしたので個人的には非常に有意義でした。

 

ご指摘もありましたが、さっさとOSを64bitにするというのが私もベストだと思います。(プライベートで使うPCへの投資はなかなか億劫。。)

ですが、ちょっとした工夫で省メモリになったり、高速になったりすることに喜びを感じる私の様な方も少なくないと思いますので、この資料がその様な方々のお役に立てば幸いです。

 

丸一年経ちました

また久しぶりの更新となってしまいました。

最近は、webサイトのクローリングをちょこちょこ行っています。

これについてはまた改めて書くかも、しれません。

 

データサイエンティストという言葉を知り、目指し始めたのが去年のこの頃だったと思うので、一年間の振り返りと今年の抱負などを書いてみたいと思います。

 

■データ整形

当時はまだ、ほとんどperlも触ったことがなくデータ整形を行うのにも非常に時間を費やしていましたが、現在はサクサクと手が動く様になりました。

ただ、複雑なデータ構造を扱うときに、稀にハマるのでまだまだスピード向上の余地があると思っています。

また、モジュールについての知識が全然ないので、今年は便利そうなモジュールはどんどん使ってみる様にしたいです。

 

■分析

学生の頃行っていた分析はExcelSPSSだったのですが、SPSSは会社で使っていないのでKnimeとRを主に使うことになりました。

最初は、集計や可視化を行うのも一苦労でしたが、現在は一先ず自分で確認する分には十分になりました。今年は、クライアントさんにそのままお見せできる様な綺麗な可視化、カッコいい可視化ができる様になりたいです。

また、モデリングに関してはlogistic regressionやrandom forestを中心として色々行ってきたので、一応なんとか使えるレベルにはなったと思っています。ただ、変数の作り方やチューニングの仕方についてはまだまだなので、今年はもっと上手くできる様に勉強したいと思います。

 

■理論

機械学習

 最初は全然理解できないことばかりでしたが、繰り返し繰り返し同じことについて説明している多数の資料を見ることで概念についてはなんとなく理解できる様になってきたと思っています。(数式アレルギーも徐々に克服中)

今年は概念だけでなく、情報理論や確率過程など基礎となる理論についても少しずつ理解を深めていきたいと考えています。

 

統計学

 統計学は学生時代から使っていたので、他部署の方に仮説検定などについて説明する機会があり、少しは役立てたのではないかと考えています。しかし、基礎的な検定であるχ2乗検定を行うことがあり、その時にすぐ計算ができなくて困ったことがありました。基礎的なものこそ当たり前の様に計算できなければならないと思うので、時間を作って一度振り返りたいものです。

 

以上、1年間の振り返りと今年の抱負でした。

組織的な色々な問題もあるのですが、環境に振り回されず着実にレベルアップしていきたいと思います。