データとは何か

第3回若手Webエンジニア交流会
      @suzu_v
自己紹介
• 2006.4 – 2012.3
  – Keio University
     • 人工知能、セマンティックWeb、オントロジー工学
• 2011.2 – 2012.3
  – CTO at Trippiece, Inc.
     • 旅行系のWebサービスを作っていました。
• 2012.4 –
  – Engineer at VOYAGE GROUP, Inc.
     • 主にデータ解析業務とオペレーションエンジニアリングを担
       当しています。
                                            twitter: @suzu_v
                                 http://blog.kentasuzuki.net
交流会ということで、酒の肴にな
 るネタを持って来ました。

   今日はJenkinsとHadoopの話はしません。
         解析の話もしません。
最近、こんな本を読んでいま
     す。
私の仕事は、
データと向き合うことです。

SICPを通して、
私はデータについて知らないというこ
とを知りました。
質問: データとは何でしょう?



      http://www.flickr.com/photos/wwworks/2959833537/sizes/l/in/photostream/
大きさ                                          花の色
              ユーザ行動
                                  ビールの銘柄
       CPM
                           転置インデックス
                                              確率
             株価
  お金                 アクションログ

                  音の高さ                  アクティブユーザ数

                                   重さ

                     宗教
 クリック数
                                    人口
                                            クロック数

             バイト数
                            降水量
                                           経常利益
 親子関係
                    座標位置           ツイート
         行
質問: 計算機にとってのデータとは
      何でしょう?



        http://www.flickr.com/photos/st3f4n/3708150348/sizes/l/in/photostream/
“一般に、データは選択肢と構成肢
と、これらの手続きを有効な表現
とするための満たすべき条件とで
定義されると思って良い。”


      「計算機プログラムの構造と解釈」第2版 p.45 より
(define (data what-we-hope-so))
_人人人人人人人_
> 突然のScheme <
 ̄Y^Y^Y^Y^Y^Y ̄
今から30秒で
Schemeの簡単な説明をします。
(cons 1 2)



             対(ペア)を示しています。
(car (cons 1 2))
-> 1



           carはconsの最初の部分を取り出します。
(cdr (cons 1 2))
-> 2



           cdrはconsの後ろの部分を取り出します。
(define x (cons 1 2))

(car x)
-> 1

(cdr x)
-> 2
           defineによって手続きを定義できます。
(define x (cons 1 2))
(define y (cons 3 4))
(define z (cons x y))

(car (car z))
-> 1        すなわち、(car (cons 1 2)) です。



(car (cdr z))
-> 3        すなわち、(car (cons 3 4)) です。
“一般に、データは選択肢と構成肢
と、これらの手続きを有効な表現
とするための満たすべき条件とで
定義されると思って良い。”


      「計算機プログラムの構造と解釈」第2版 p.45 より
“だからといって、
データとは「与えられた選択肢と
構成肢で実装されているもの」と
いうのでは不十分である。”


      「計算機プログラムの構造と解釈」第2版 p.51 より
(define x (cons 1 2))

(car x)
-> 1

(cdr x)
-> 2
cons, car, cdrは、他のデータ構造
を利用せずに定義することができ
ます。
(define (cons x y)
 (define (dispatch m)
  (cond ((= m 0) x)
      ((= m 1) y)
      (else (error "Argument not 0 or 1 --
CONS" m))))
 dispatch)

           (cons x y)は手続きdispatchを返します。
           この手続きdispatchは引数を1つとり、
           0が渡されるとx, 1が渡されるとyを返します。
carとcdrを定義しましょう。
(define (car z) (z 0))

(define (cdr z) (z 1))


                   これにより、
                   (car (cons x y)) はxを返し、
                   (cdr (cons x y)) はyを返します。
(define (cons x y)
 (define (dispatch m)
  (cond ((= m 0) x)
      ((= m 1) y)
      (else (error "Argument not 0 or 1 -- CONS"
m))))
 dispatch)
(define (car z) (z 0))
(define (cdr z) (z 1))


cons, car, cdrを、他のデータ構造を利用せ
ずに定義することができました。
大事なこと:

対の手続き実装が実際に普段利用して
いる言語でこうなっている、というわ
けではありません。

しかし、対が満たすべき条件は満たし
ています。そして、手続きをオブジェ
クトとして操作する能力が、自動的に
合成データを表現する能力を提供する
ことを示しています。
ここまでのあらすじ
•   計算機にとってデータとは何か
•   cons: 対の表現
•   car, cdr: 値の取り出し
•   cons, car, cdrを任意のデータ構造によらず
    に表現
並びの世界を見ていきます。



      http://www.flickr.com/photos/akash_k/125489887/sizes/l/in/photostream/
並びの表現を導入します。



   (list 1 2 3 4)
(cons 1
   (cons 2
        (cons 3
           (cons 4 nil))))

対の並びをリストとします。

(list 1 2 3 4)
listの演算
(define one-through-four (list 1 2 3 4))

(car one-through-four)
-> 1
                carは最初の項を取り出します。

(cdr one-through-four)
-> (2 3 4)
                cdrは先頭以外の項からなる部分リストを
                取り出します。
ここで「公認インターフェース」
  について説明します。
公認インターフェースとは、
データ構造を扱う上の強力な設計
原理です。
例を見ていきましょう。
引数として木を取り、奇数である
葉の二乗の和を計算する手続き
と、

偶数のフィボナッチ数Fib(k)のリス
トをつくる手続き
木
                ((2 3) 5 6)



    (2 3)



                     5        6



2           3




                                  葉
木
その要素自身が並びであるような並び

(define x (cons (list 1 2) (list 3 4)))
;-> ((1 2) 3 4)

(list x x)
;-> (((1 2) 3 4) ((1 2) 3 4))
引数として木を取り、奇数である
葉の二乗の和を計算する手続き
                    ((2 3) 5 6)



        (2 3)



                         5        6



    2           3




和: 3^2 + 5^2 = 34                     奇数の葉
引数として木を取り、奇数である
葉の二乗の和を計算する手続き

(define (sum-odd-squares tree)
 (cond ((null? tree) 0)
     ((not (pair? tree))
      (if (odd? tree) (square tree) 0))
     (else (+ (sum-odd-squares (car tree))
            (sum-odd-squares (cdr tree))))))
偶数のフィボナッチ数Fib(k)の
  リストをつくる手続き
(1 1 2 3 5 8 13 21 34 55 ...)



   (   2   8     34   ...)
偶数のフィボナッチ数Fib(k)の
リストをつくる手続き

(define (even-fibs n)
 (define (next k)
  (if (> k n)
    nil
    (let ((f (fib k)))
      (if (even? f)
        (cons f (next (+ k 1)))
        (next (+ k 1))))))
 (next 0))
引数として木を取り、奇数である葉の
     二乗の和を計算する手続き
 •   木の葉を数え上げる
 •   フィルタを通し、奇数のものを選ぶ
 •   選ばれたものをそれぞれ二乗する
 •   0の初期値に結果を + を使いアキュムレー
     トする

enumerate:    filter:    map:    accumulate:
tree leaves   odd?      square       +, 0
map
   filter
accumulate
map, filter
(map square (list 1 2 3 4 5))
-> (1 4 9 16 25)     listの各要素を2乗しています。



(filter odd? (list 1 2 3 4 5))
-> (1 3 5)
                        listから奇数の要素のみ取り出しています。
accumulate
(accumulate + 0 (list 1 2 3 4 5))
;-> 15                1 + 2 + 3 + 4 + 5です。


(accumulate * 1 (list 1 2 3 4 5))
;-> 120               1 * 2 * 3 * 4 * 5です。


(accumulate cons nil (list 1 2 3 4 5))
;-> (1 2 3 4 5)     listの各要素を初期値nilとしてconsします。
                          これは結局listになります。
偶数のフィボナッチ数Fib(k)の
           リストをつくる手続き
 • 整数を0からnまで数え上げる
 • 整数のそれぞれのフィボナッチ数を計算
   する
 • フィルタを通し、偶数のものを選ぶ
 • 空のリストの初期値に結果をconsを使い
   アキュムレートする

enumerate:   map:   map:    accumulate:
 integers     fib   even?     cons, ()
信号処理の形式のように
書きなおしてみましょう。
      http://www.flickr.com/photos/caveman_92223/3346906435/sizes/o/in/photostream/
引数として木を取り、奇数である葉の
     二乗の和を計算する手続き

 (define (sum-odd-squares tree)
  (accumulate +
          0
          (map square
             (filter odd?
                    (enumerate-tree tree)))))


enumerate:           filter:            map:    accumulate:
tree leaves          odd?              square       +, 0
偶数のフィボナッチ数Fib(k)の
           リストをつくる手続き

 (define (even-fibs n)
  (accumulate cons
          nil
          (filter even?
                 (map fib
                    (enumerate-interval 0 n)))))




enumerate:             map:                map:    accumulate:
 integers               fib                even?     cons, ()
共通の構造が明らかになりまし
         た。
(define (sum-odd-squares tree)
 (accumulate +
          0
          (map square
            (filter odd?
                   (enumerate-tree tree)))))

(define (even-fibs n)
 (accumulate cons
         nil
         (filter even?
                (map fib
                   (enumerate-interval 0 n)))))
“プログラムを並びの演算として表
す価値は、部品化されたプログラ
ム設計、つまり比較的独立な部品
を組み合わせてつくり上げる設計
を可能とすることだ。われわれ
は、標準部品のライブラリと、部
品を柔軟に接続するための公認イ
ンターフェースを用意すること
で、部品化された設計を奨励す
る。”
      「計算機プログラムの構造と解釈」第2版 p.67 より
改めて、
並びの世界を見ていきます。



      http://www.flickr.com/photos/akash_k/125489887/sizes/l/in/photostream/
これをベクトルとしましょう。



    (list 1 2 3)
リストによる行列の表現
(list (list 1 2 3 4)
     (list 5 6 7 8)
     (list 9 10 11 12))
これから定義するもの
  (dot-product v w)     総和    を返す(ベクトルの内積)




(matrix-*-vector m v)         であるようなベクトルtを返す




(matrix-*-matrix m n)           であるような行列pを返す




    (transpose m)            であるようなマトリックスnを返す
accumulateを拡張します
(print (accumulate-n + 0 (list (list 1 2 3) (list 4 5 6))))
;-> (5 7 9)

(print (accumulate-n + 0 (list (list 1 2 3) (list 4 5 6) (list 7 8
9))))
;-> (12 15 18)

(print (accumulate-n * 1 (list (list 1 2 3) (list 4 5 6))))
;-> (4 10 18)
(define (dot-product v w)
 (accumulate + 0 (map * v w)))

(define (matrix-*-vector m v)
 (map (??) m))

(define (transpose mat)
 (accumulate-n (??) (??) mat))

(define (matrix-*-matrix m n)
 (let ((cols (transpose n)))
   (map (??) m)))




                       「計算機プログラムの構造と解釈」第2版 p.70 問題2.37より
(define (dot-product v w)
 (accumulate + 0 (map * v w)))

(define (matrix-*-vector m v)
 (map (??) m))

(define (transpose mat)
 (accumulate-n (??) (??) mat))

(define (matrix-*-matrix m n)
 (let ((cols (transpose n)))
   (map (??) m)))




    あまりにも綺麗に書けてしまいました。
    (※アップロード用スライドでは伏字にしてあります。)
実行列の計算を行うまでの流れ
• consで最小限のデータ構造を定義した
• consの並びでlistを定義した
• 2重のlistで行列を表現した

たった2つの構成肢を組み合わせるところか
ら、listという合成データをつくり、listに対
する演算を合成手続きとして定義すること
で、実行列の演算を行うまでに表現力を高
めることができました。
発表のまとめ
質問: 計算機にとってのデータとは
      何でしょう?



        http://www.flickr.com/photos/st3f4n/3708150348/sizes/l/in/photostream/
“一般に、データは選択肢と構成肢
と、これらの手続きを有効な表現
とするための満たすべき条件とで
定義されると思って良い。”


      「計算機プログラムの構造と解釈」第2版 p.45 より
“だからといって、
データとは「与えられた選択肢と
構成肢で実装されているもの」と
いうのでは不十分である。”


      「計算機プログラムの構造と解釈」第2版 p.51 より
適切な抽象化を行うことで、私達
プログラマはデータを扱う手段を
得ています。
Webにデータにあふれているからこ
そ、




               http://linkeddata.org/
アプリエンジニアも
インフラエンジニアも
解析エンジニアも

同じエンジニアとして、

データとのふれあい方を考え、
良い仕事をしていけると
尐し幸せになれるのではないかと
思います。     一緒にSICP読みましょう!
参考資料
SICP
• Welcome to the SICP Web Site
  – http://mitpress.mit.edu/sicp/
  – 邦題: 「計算機プログラムの構造と解釈」
  – 今回は第2章の”データによる抽象の構築”の部
    分を俯瞰するような形でスライドを構成しま
    した。とても良い話です。
• Why <cite>Structure and Interpretation of
  Computer Programs</cite> matters
  – http://www.eecs.berkeley.edu/~bh/sicp.html
  – <blockquote>The invention of the MapReduce
    software for data parallelism at Google, based
    on functional programming ideas, has helped
    eliminate that ivory-tower
    reputation.</blockquote>
抽象モデルについて
• Structured programming: C.A.R. Hoareら
  (1972)
  – http://dl.acm.org/citation.cfm?id=1243380&dl=
    ACM&coll=DL&CFID=203717221&CFTOKEN
    =47398745
補足資料
cons, car, cdrの名前の由来
• cons
  – Construct
• car
  – Contents of the Address part of the Register.
• cdr
  – Contents of the Decrement part of the
    Register
accumulate
(define (accumulate op initial sequence)
 (if (null? sequence)
   initial
   (op (car sequence)
      (accumulate op initial (cdr sequence)))))
accumulate-n
(define (accumulate-n op init seqs)
 (if (null? (car seqs))
   nil
   (cons (accumulate op init (map car seqs))
       (accumulate-n op init (map cdr seqs)))))
map
(define (map proc items)
 (if (null? iterms)
   nil
   (cons (proc (car items))
       (map proc (cdr iterms)))))
filter
(define (filter predicate sequence)
 (cond ((null? sequence) nil)
     ((predicate (car sequence))
      (cons (car sequence)
           (filter predicate (cdr sequence))))
     (else (filter predicate (cdr sequence)))))

データとは何か