scala による自然言語処理

29
Scala による自然言語処理 2013-09-01 Hiroyoshi Komatsu @torotoki 1

Upload: hiroyoshi-komatsu

Post on 28-May-2015

5.808 views

Category:

Technology


1 download

DESCRIPTION

DSIRNLP 4 の資料です。 http://partake.in/events/76854228-ba38-4f6e-87b9-f79e30add75c

TRANSCRIPT

Page 1: Scala による自然言語処理

Scala による自然言語処理2013-09-01

Hiroyoshi Komatsu@torotoki

1

Page 2: Scala による自然言語処理

プロフィール• @torotoki

• 興味• 質問応答

• トピックモデル

• 言語• Scala 歴は半年くらい

• NTCIR RITE という含意関係認識のワークショップで触れた

• 他の関数型言語をやったことはない

• 高2

2

Page 3: Scala による自然言語処理

前置き

3

Page 4: Scala による自然言語処理

なぜ Scala なのか• Scala の利点• 一般的な書き方をしつつも、面倒な部分は関数型言語らしく簡

潔に書ける

• スクリプト言語と比べて早い

• 静的型付けなのでコンパイル時にエラーが分かる

• 型推論が強力で動的型付け言語並みに型を省略できる

• JVM で動く

• Java の力を借りられる

4

Page 5: Scala による自然言語処理

今回の議題

• 自然言語処理/機械学習をする人に Scala を知ってもらう

• なぜ Scala を使うのか• 関数型言語のおかげでデータ構造が比較的簡単に扱える

• グラフとかツリーとか扱うので便利

• 好きなところだけ関数型な構文でかける

• 言語処理/機械学習のライブラリが充実”しつつ”ある

5

Page 6: Scala による自然言語処理

Scala の構文

• セミコロンや型名などごちゃごちゃせずに奇麗に書ける

var capital = Map("US" -> "Washington", "France" -> "Paris")capital += ("Japan" -> "Tokyo")println(capital("France"))

6

Page 7: Scala による自然言語処理

タイプ推論

val list = List(1, 3, 4)

var list2 = listlist2 = List(4,5,6) // OKlist2 = List(“Test!”) // error

7

Page 8: Scala による自然言語処理

マップ処理

val list = List(1,2,3)

def plus1(x: Int) = x + 1

val increaseList = list.map(plus1)

8

Page 9: Scala による自然言語処理

マップ処理(別バージョン)

val list = List(1,2,3)

val increaseList = list.map(_ + 1)

9

Page 10: Scala による自然言語処理

Scala のデータ構造

10

Page 11: Scala による自然言語処理

データ構造• “関数型的な”データ構造とは• 全ての変数をイミュータブル(不変)にする• 望ましい構造• スケーラブルでも同等の性能を出す• 非破壊的• 更新の際は元のデータを書き換えるのではなく、新たなデー

タを生成する• イメージとして 関数型的 ≒ 非破壊的

11

Page 12: Scala による自然言語処理

Scala のリスト構造

List(a, b, c, d)

A B C D

要素と次の要素のリンクを持つ簡素なもの

12

Page 13: Scala による自然言語処理

Scala のリストの関数

• 頑張ってなるべく O(1) の操作を使う

O(1) O(log n) O(n)

最初の値先頭に追加

最後に追加連結挿入

最後の値n番目の値

13

Page 14: Scala による自然言語処理

キュー• キュー(Queue)は enqueue と dequeue という2つの

操作ができるデータ構造• enqueue: 一番後ろにデータを入れる• dequeue: 一番前にデータを取り出す

http://en.wikipedia.org/wiki/Queue_(abstract_data_type)

14

Page 15: Scala による自然言語処理

単純な非破壊的なキュー• 単純にやると全コピー: 計算量: O(n)

1 2 3 4 ・・追加

1 2 3 4 ・・

コピー コピー コピー

15

Page 16: Scala による自然言語処理

非破壊的なキュー• ちょっと工夫• 後ろのほうは逆順で持つ• 単純な順番しかないリストなので先頭への追加は O(1)

1 2 3 ・

5 4 ・

16

Page 17: Scala による自然言語処理

キューの Scala 実装

case class Queue[T](leading: List[T], trailing: List[T]) { private def mirror = if (leading.isEmpty) new Queue(trailing.reverse, Nil) else this def head = mirror.leading.head def tail = { val q = mirror new Queue(q.leading.tail, q.trailing) }

def enqueue(x: T) = new Queue(leading, x :: trailing) def dequeue = this.tail}

17

Page 18: Scala による自然言語処理

関数型言語だけど…• Scala は関数型言語だが、for文やwhile文など「普通の書

き方」ができる

• 変数も可能

var a = 0while (a != 100) { println(a) a += 1} for (i <- 1 to 100) { println(a)}

val a = 3 // 定数var b = 15 // 変数

18

Page 19: Scala による自然言語処理

ライブラリ

19

Page 20: Scala による自然言語処理

NLP/MLのライブラリ

• 「ScalaNLP」という5つのライブラリがある

http://www.scalanlp.org

20

Page 21: Scala による自然言語処理

ScalaNLP• ScalaNLP の5つのライブラリ• Breeze: 線形代数, 数値計算, 可視化• Nak: 機械学習• Chalk: テキスト処理• Epic: パーサー• Junto: ラベル伝搬

• 依存関係• Breeze -> 他の全て• Nak -> Chalk• Epic -> Chalk• Junto は独立したライブラリ

Breeze のロゴ

21

Page 22: Scala による自然言語処理

Breezescala> val m = DenseMatrix.zeros[Int](5,5)

m: breeze.linalg.DenseMatrix[Int] = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

scala> (m.rows, m.cols)res10: (Int, Int) = (5,5)

scala> m(::,1)res7: breeze.linalg.DenseVector[Int] = DenseVector(0, 0, 0, 0, 0)

scala> m(4,::) := DenseVector(1,2,3,4,5).t // 転置res8: breeze.linalg.DenseMatrix[Int] = 1 2 3 4 5

scala> mres9: breeze.linalg.DenseMatrix[Int] = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5

22

Page 23: Scala による自然言語処理

Python vs Scala

• 公式サイトのスライドから引用• http://www.scalanlp.org/documentation/

• 詳しい条件があまり書いてないが…

23

Page 24: Scala による自然言語処理

ScalaNLP 所感• Breeze 以外はドキュメント不足• 現状 README とサンプルが手がかり• サイトには Breeze 以外のプロジェクトについてあまり記述が

ないため、今後作成予定だと思われる

• 開発は進行中• それぞれを見るとまだ超大規模なプロジェクトではないので、

今なら色々貢献できる?

24

Page 25: Scala による自然言語処理

おまけ

25

Page 26: Scala による自然言語処理

Scala で XML 処理• 個人的には XML 処理がもっとも Scala の拡張性がよく

現れていると思う• 前提• XML を構文としてサポートしている

• Scala では記号は関数として扱われるため、ユーザーも簡単に記号を定義できる

• これを生かして XML では XPath が埋め込める

val p = <a> This is some XML. Here is a tag: <atag/> </a>

X + X, X * 3, X ??? “aaa” //=> X.+(X) X.*(3) X.???(“aaa”)

26

Page 27: Scala による自然言語処理

MeCab の XML の処理val sentence =

<sentence> <chunk id="0" link="6" rel="D" score="2.909358" head="0" func="1"> <tok id="0" feature="名詞,固有名詞,人名,名,*,*,太郎,タロウ,タロー" ne="B-PERSON">太郎</tok> <tok id="1" feature="助詞,係助詞,*,*,*,*,は,ハ,ワ" ne="O">は</tok> </chunk> <chunk id="1" link="2" rel="D" score="1.257926" head="2" func="2"> <tok id="2" feature="連体詞,*,*,*,*,*,この,コノ,コノ" ne="O">この</tok> </chunk> <!-- 省略... --> </sentence>

for (tok <- sentence \\ "tok") { val feature = tok \ "@feature" println(feature + ": " + tok.text)})

27

Page 28: Scala による自然言語処理

実際の処理で感じたこと• メリット

• 構文解析の木構造、グラフ構造に関するデータ処理がやりやすい

• 小規模~大規模なプログラムまで耐えられる

• Java との互換性があるおかげで、特に英語圏のライブラリがけっこう使える

• 並列化が楽

• デメリット

• コンパイル速度が Java よりかなり遅い

• 実行速度も Java に比べると遅いらしい

28

Page 29: Scala による自然言語処理

実際の処理で感じたこと• メリット

• 構文解析の木構造、グラフ構造に関するデータ処理がやりやすい

• 小規模~大規模なプログラムまで耐えられる

• Java との互換性があるおかげで、特に英語圏のライブラリがけっこう使える

• 並列化が楽

• デメリット

• コンパイル速度が Java よりかなり遅い

• 実行速度も Java に比べると遅いらしい

(1 to 10000).par.sum

29