• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
普通のプログラミング言語R
 

普通のプログラミング言語R

on

  • 7,166 views

Tsukuba.R #7

Tsukuba.R #7

Statistics

Views

Total Views
7,166
Views on SlideShare
6,645
Embed Views
521

Actions

Likes
7
Downloads
27
Comments
0

8 Embeds 521

http://d.hatena.ne.jp 498
http://www.slideshare.net 12
http://www.hatenatunnel.appspot.com 4
http://webcache.googleusercontent.com 2
http://hatenatunnel.appspot.com 2
http://static.slidesharecdn.com 1
http://twitter.com 1
http://s.deeeki.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    普通のプログラミング言語R 普通のプログラミング言語R Presentation Transcript

    • 普通の プログラミング言語 R(仮) 2010/5/9 id:n_shuyo / @shuyo 中谷 秀洋@サイボウズ・ラボ
    • 最近
    • 機械学習
    • いろいろ 実装してみたくて
    • R始めました
    • そんなわけで
    • R歴
    • まもなく1年
    • Rって 便利ですね!
    • これが E-step: 2 1 (k = argminj n − j のとき) rnk = 0 (それ以外) M-step: n rnk n k = n rnk K-means クラスタリングの更新式
    • Rなら1行 mu<-t(sapply(1:K,function (k)colMeans(x[max.col( -sapply(1:K,function(i) colSums((t(x)-mu[i,])^2))) ==k,])));
    • Rって ほんと便利!!
    • でも……
    • Rって……
    • 変ですよね?
    • すごいことが 簡単にできるけど
    • 簡単なことが やたら難しかったり
    • 予想と違う動きで ハマったり
    • いままで結構いろんな言語を 触ってきたつもりだけれど── Ruby MSX-BASICX-BASIC COBOL C++ Perl ぺけBASI javascript ActionScript R PHP Excel VBA C XSLT Erlang PL/SQL JavaZ80 Brainf*ck 6502/680x Visual BASIC x86 MS-BASIC
    • 気持ち悪い と思った言語は R だけ
    • Rの一番良いところは 統計学者が 作っているところだ。 Rの一番悪いところは 統計学者が 作っているところだ。 [要出典]
    • [出典]
    • でも R だって
    • 普通の プログラミング言語に なりたいはず!
    • そのためには
    • 「普通のプログラミング言語」 の 「普通のプログラミング」 ができるようになれば!
    • もちろん
    • メタプログラミング のことですね!
    • Rで普通の メタプログラミング 2010/5/9 id:n_shuyo
    • R って意外と
    • インスペクトと 動的定義が 得意なんですよ!
    • というわけで クイズです
    • 次の文を実行したとき、 f は何になるでしょう? f <- function(x){x*2};
    • 関数?
    • 正解は「クロージャ」 > f <- function(x){x*2} > typeof(f) [1] "closure"
    • 「クロージャ」って
    • なんかあの 難しいやつ
    • Wikipedia「クロージャ」 クロージャ(クロージャー、closure、閉 包)はプログラミング言語における関 数の一種。引数以外の変数を実行時 の環境ではなく、自身が定義された環 境(静的スコープ)において解決する ことを特徴とする。関数とそれを評価 する環境のペアであるともいえる。
    • 「関数と それを評価する 環境のペア」
    • たしかにクロージャ > f <- function(x){ x*2 }; > body(f) # 関数本体 { x * 2 } > environment(f) # 環境 <environment: R_GlobalEnv>
    • グローバル環境 グローバル環境はワークスペースの ルートをなす .GlobalEnv がエイリアス > environment(f) <environment: R_GlobalEnv> > .GlobalEnv <environment: R_GlobalEnv>
    • 環境の中身を見る ls.str(環境) もしくは as.list(環境)で 見ることが出来る > a <- 1 > ls.str(.GlobalEnv) a : num 1 f : function(x) > as.list(.GlobalEnv) $a [1] 1 $f function(x){x*2}
    • 関数は子環境を作る > f <- function(x) { + print(environment()); + print(parent.env(environment())); + print(as.list(environment())); + } > f(3) <environment: 0x064bd8f0> # 子環境 <environment: R_GlobalEnv> # 親環境 $x # 子環境の中身 [1] 3 # ←3が出る仕組みは別の長い話
    • 子環境は毎回作られる 関数は呼び出されるごとに子環境を 作成する(スコープの話はしません) > f <- function() { + print(environment()); + } > f() <environment: 0x06dbdd54> # 子環境1 > f() <environment: 0x06ca9c28> # 子環境2
    • クロージャは環境とひもづく 定義されたときの環境を「閉包」 > f <- function() { + print(environment()); + function() {} + } > g <- f() <environment: 0x061d5cb4> # f の子環境 > environment(g) # || <environment: 0x061d5cb4> # g の環境
    • クロージャの環境の中身 > f <- function() { + x <- 3 + function(a){ a * x } # 環境を閉包 + } > g <- f() > g function(a){ a * x } # x って何? <environment: 0x06dbe0b8> # この中を見れば… > ls.str(environment(g)) x : num 3 # g の環境では x <- 3 > g(2) [1] 6 # つまり g は値を3倍する関数
    • 準備完了
    • クロージャを いじってみよう!
    • クロージャの環境は 外からいじれる > as.list(environment(g)) $x [1] 3 > environment(g)$x <- 4 # 書き換え! > ls.str(environment(g)) x : num 4 > g(2) [1] 8 # 値を4倍する関数に変わった!
    • 環境のまるごと差し替え new.env() で新しい環境を作成し、 クロージャの環境に差し替える > e <- new.env() # 環境の作成 > e$x <- 5 # 値をセット > environment(g) <- e # 差し替え > ls.str(environment(g)) # 環境を確認 x : num 5 > g(3) [1] 15 # 値を5倍する関数に!
    • 関数本体も差し替え! > g function(a){ a * x } # 掛け算する関数 <environment: 0x06dbe0b8> > body(g) <- expression({ a + x }) > g function (a) { a + x # 足し算する関数になった! } <environment: 0x06dbe0b8> > g(1) [1] 6 # 5を足す関数に変わった
    • 引数だっていじれる! > formals(g) $a # 引数 a を持つ。デフォルト値なし > formals(g)$a <- 2 > formals(g) $a [1] 2 # 引数 a のデフォルト値が 2 に > g() [1] 7 # 2 + 5
    • 結論
    • Rかわいいよ!
    • え?
    • 「それが なんの役に 立つの?」
    • ……
    • ……えーと、
    • こんな感じで 「R の中身」が わかってくると
    • R で「できること」と 「できないこと」が
    • わかるように なるかもね!(棒読み)
    • ま、
    • 役に立つか なんて
    • 一番つまんない 尺度ですよね!
    • [没ネタ集]
    • 「Rで変なコードを書こう!」とか 遅延評価ってわかりにくいよね。 > a [1] 0 > g <- f(a<-3) # f は「とある関数」 > a [1] 0 # a は 0 のまま > g() # でも g() を呼ぶと…… > a [1] 3 # 3 に変わる
    • 「なんでエラーなの?」とか なぜか plot できない! しかもエラーメッセージが意味不明 (わかる人にはわかるけど、 わかる人はこんなコード書かない) > plot(function(x) x+x^2); # 問題なし > f <- function(x) c(x,x^2); > plot(function(x) sum(f(x))) 以下にエラー xy.coords(x, y, xlabel, ylabel, log) : 'x' and 'y' lengths differ # 何このエラー?
    • 「なんでエラーじゃないの?」とか 「なんでそんな書き方出来るの? 文法どうなってんの?」って 思うことありません? > f(abc) # f は「よくある関数」 以下にエラー f(abc) : オブジェクト 'abc' がありません > g(abc) # g は「とある関数」 > # あれ? エラーにならない……
    • 「あるある~」小ネタとか plot() の重ね描きで、同じ引数を何 度も書かなくて済む方法ないの? plot(data1, xlim=c(-5,5), ylim=c(-5,5), ann=F); par(new=T); plot(data2, xlim=c(-5,5), ylim=c(-5,5), ann=F); par(new=T); plot(data3, xlim=c(-5,5), ylim=c(-5,5), ann=F);
    • などなど
    • ほかにも
    • いろいろ
    • なくもなかったん ですけど
    • 時間ないので またの機会(あるかな?)
    • ありがとう ございました。