ChaPASを使って何か遊べないかなーと思い立ったので、てきとうに出力をparseするスクリプトを書いてみました。大したことはしてないです。

ChaPAS

ChaPASは日本語の述語項構造解析器です。述語項構造解析は文中の「誰が何をどうした」という意味的な役割を同定する自然言語処理のタスクです。

使い方は至って簡単で

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ echo "私は課題に鉛筆を使う" | java -jar chapas.jar -I RAW

* 0 3D 0/1 -1.656864
私  名詞,代名詞,一般,*,*,*,私,ワタシ,ワタシ O   ID="1"
は  助詞,係助詞,*,*,*,*,は,ハ,ワ    O
* 1 3D 0/1 -1.656864
課題    名詞,一般,*,*,*,*,課題,カダイ,カダイ    O   ID="2"
に  助詞,格助詞,一般,*,*,*,に,ニ,ニ O
* 2 3D 0/1 -1.656864
鉛筆    名詞,一般,*,*,*,*,鉛筆,エンピツ,エンピツ    O   ID="3"
を  助詞,格助詞,一般,*,*,*,を,ヲ,ヲ O
* 3 -1D 0/0 0.000000
使う    動詞,自立,*,*,五段・ワ行促音便,基本形,使う,ツカウ,ツカウ    O   type="pred" ga="1" ni="2" o="3"
EOS

お手軽ですね。

この例文の場合、名詞「私」、「課題」、「鉛筆」に対してIDが振られており、述語「使う」のガ格が「私」、二格が「課題」、ヲ格が「鉛筆」となっています。

今回

ChaPASを使って遊ぶためにはこの出力をparseする必要があります(実際のところは良く分からない)。なので、簡単にこの出力をparseするスクリプトを作ってみました。

asahima/ChapasWrapper

今のところ、超お手軽スクリプトなので、もう少しどうにかしたいと思っていますが何時になるやら。。。

機械学習を勉強している過程で色々なアルゴリズムを実装して理解を深めようと取り組んできていますが、今回はNeural Networkを実装したいなーと思っております。実装したいと思っているのは、シンプルなフィードフォワード型のNeural Networkです。

Neural Network

フィードフォワード型のNeural Networkは入力層から出力層に向けて順伝搬を行う(逆方向へは伝搬しない)モデルです。逆方向へ伝搬するモデルとしてはRecurrent Neural Networkなどがあります。Recurrent Neural Networkについてはまだ良くわかっていないので記述しません。

実装

実装としては、[2]を参考にさせて頂いたこともあって、ほとんど同じになっています。違いとしてはあちらの記事ではPython・Numpyでの実装ですが、私の方ではScala・breezeで実装しているというものです。

ソースコードはこちら

まとめ

実装するにあたって、PRMLに記述されているNeural Networkの数式の写経を繰り返していたのですが、ようやく理解できたような気がします。一番初めにNeural Networkの数式を見た時は、こんなもの私には理解できないと思っていたのですが、一つ一つ解読していくと意外となんとかなるんだなーと思っています。

今後の方針としては色々ありますが、現状でいうなら

  • 活性化関数をクラスの外から指定できるようにする
  • mini-batch AdaGradを実装する

参考

  1. 多層パーセプトロンによる関数近似
  2. 多層パーセプトロンで手書き数字認識
  3. Scalaで機械学習
  4. breeze scaladoc
  5. ゼロから始めるDeepLearningその1ニューラルネットとは

昨日はbreeze-vizを導入してQuickStartに乗っているソースを動かしてみるということをやりました。今日は与えられた点と最小二乗法で求めた回帰直線をplotしてみようということをやってみます。

ソースはこんな感じ。breeze-vizのplotの第一引数は描画する点のx座標、第二引数はy座標になっています。第三引数は描画するものを示しているようで、”.“を指定すると点がプロットされます。ここで何も指定しないと直線が描画されることになります。Documentが見れれば細かいことが分かりそうですが、breeze.plotに関してはapi documentの方にも記述がないので実際にソースを読むしかなさそうです(私が探しきれていないだけで実はあったりするのかな)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import breeze.linalg._
import breeze.plot._

case class Data(x: Double, y: Double)

object Main {
  def main(args: Array[String]): Unit = {
    val datas = Array[Data](Data(4.0, 7.0), Data(8.0, 10.0), Data(13.0, 11.0), Data(17.0, 14.0))
    val value = leastSquares(datas)
    println(s"a:${value._1} b:${value._2}")

    val x = datas.map { data => data.x }
    val y = datas.map { data => data.y }
    val oy = datas.map { data => value._1 * data.x + value._2}

    // plot
    val f = Figure()
    val p = f.subplot(0)

    p += plot(x, y, '.')
    p += plot(x, oy)
    p.xlabel = "x"
    p.ylabel = "y"
  }

  def leastSquares(datas: Array[Data]): (Double, Double) = {
    val x_sum = datas.map { data => data.x }.sum
    val x_square_sum = datas.map { data => data.x * data.x }.sum
    val y_sum = datas.map { data => data.y }.sum
    val x_y_sum = datas.map { data => data.x * data.y }.sum

    val a = (((x_sum * y_sum) - (datas.length * x_y_sum)) / ((x_sum * x_sum) - (datas.length * x_square_sum)))
    val b = (((x_sum * x_y_sum) - (x_square_sum * y_sum)) / ((x_sum * x_sum) - (datas.length * x_square_sum)))

    (a, b)
  }
}

追記

plotに関して、描画するstyleを記述するのはmatplotlibにもあるようです。ですが、matplotlibの場合、指定できる文字の種類がbreeze-vizに比べて多いようです。

breeze-vizで使用できる文字は

  • ‘-’
  • ‘.’
  • ‘+’

の3つだけのようです。これはplotに適当な文字を入れてみると出力されるエラーに記述されていました。

java.lang.IllegalArgumentException: Expected style to be one of - . or +

ちなみにplotで指定できるオプションとして

  • style
  • colorcode
  • name
  • lines
  • shapes
  • labels
  • tips

以下がソースに記述されていたコメントになります

/* * Plots the given y versus the given x with the given style. * @param x X-coordinates, co-indexed with y (and indexed by keys of type K). * @param y Y-coordinates, co-indexed with x (and indexed by keys of type K). * @param style Matlab-like style spec of the series to plot. * @param name Name of the series to show in the legend. * @param labels Optional in-graph labels for some points. * @param tips Optional mouse-over tooltips for some points. /

まとめ

breeze-vizを使い始めて、予想以上にDocumentがなくて驚いています。まぁ、”This API is very experimentable”とソースコードにも記述されているので、まだ作る段階ではないということなのでしょうが。とりあえず自分のメモ代わりということで、今後使い方などをまとめていきたいなと思っていて、matplotlib入門のような形で見やすくまとめられたらなと考えています。

これ私もやっていきたいなーと思った記事があったので軽く紹介。

詳細は以下の記事を参照してください。 - 緑化活動、しませんか

内容を私的に一文でまとめると「アウトプットの習慣をつけよう」だと思っています。もう少し詳しく説明するとgithubではユーザ画面で contributions calender というものを提供しています。これはそのユーザがgithubに対してどれだけcontributionしているかを評価するためのものになっていて、contributionの回数が多いほど白から濃い緑色になるというものです。ここで上記のスライドの作者の方はgithubにcontributionする行為を「緑化活動」として、これを継続的にやっていこうという話をしています(世間でも緑化活動と言ってるかはよく知らない)。

この「緑化活動」の利点として、実際の作業が可視化されることです。contributionの回数が具体的に色として表示されますし、継続できているかどうかが一目で分かります。ちなみに私は真っ白です。

上記の記事を見て、今まである程度まで完成しないとgithubには上げていなかったことに気づきました。そこそこ動く状態じゃないと上げづらかったというのが理由です。その程度の理由なので、これからは積極的に上げていきたいと思います。でも、まぁ適度に商い程度に続けていければと思いつつですが。。。

今作りたいなーと思っているものが幾つかあるので、それを作りつつ、またこのブログを書きつつでやっていきたいと思います。

はじめに

今現在、機械学習・Scalaの勉強がてらに機械学習 はじめようで解説されているものをScalaで実装するということを行なっています。元の記事ではアルゴリズムをPythonで実装しており、線形代数のようなものを扱うためのライブラリであるnumpyやグラフ描画用のmatplotlibを利用しています。

私はScalaで実装するのですが、PythonにnumpyやmatplotlibがあるようにScalaにも同じようなものが存在していて、numpyはbreeze、matplotlibはbreeze-vizといったライブラリと置き換えることができます(たぶん)

breezeとは

breezeとはScalaNLPというscalaで自然言語処理・機械学習などを扱うためのプロジェクトで開発されている機械学習・数的計算用のライブラリです。ScalaNLP自体はbreeze以外にもEpicやPuckというようなものが提供されています。Epicはよくわからないですが、PuckはBerkeley NLP Groupで開発されているBerkeleyParserをGPU上で動作させるために実装したものみたいです。 breeze-vizはbreezeを構成するモジュールの一つでグラフ描画用のライブラリになっています。

今回やったこと

breezeが用意しているQuickStartのうちのbreeze-vizの部分を試したというものです。

環境

  • MacOSX
    • 10.9.5
  • Scala
    • 2.11.2
  • sbt
    • 0.13.6

ソースコード自体はQuickStartとまったく一緒ですが、一応乗っけておきます。関数の使い方などどこかmatplotlibを彷彿とさせます(公式にはmatlab likeと書いているのでmatlabもこんな感じなんですかね)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import breeze.linalg._
import breeze.plot._

object Main extends App {
  val f = Figure()
  val p = f.subplot(0)
  val x = linspace(0.0, 1.0)

  p += plot(x ,x :^ 2.0)
  p += plot(x ,x :^ 3.0, '.')

  p.xlabel = "x axis"
  p.ylabel = "y axis"

  f.saveas("lines.png")
}

ここで私が何に詰まったかというと、sbtでbreezeを導入したにも関わらず、breeze.plotが存在しないという事態でした。breeze-viz自体はbreezeとは別のリポジトリで開発されていますが、最近、大本のbreezeのリポジトリに移動したという記述があったため、breezeのみでやったのですが動かなかったということです。

解決方法としては単純でbuild.sbtのlibraryDependenciesにbreeze-vizを記述してsbtを動かすだけです。簡単ですね。

まとめ

breezeもbreeze-vizもメジャーリリースされていないということもあって、いざ使ってみるとちょいちょいバグと遭遇します。ですが、使ってみるとpythonでnumpyやmatplotlibを使う感覚と使えるので興味のある方は使ってみるといいんじゃないでしょうか。

幾つか統計に関する書籍を読んできましたが、いまいちピンと来なかったので実際に入力などして感覚が掴みやすそうなものを読んでみることにしました。

Rによるやさしい統計学はRと統計学の入門書でRを使いながら統計学に触れてみようという感じの本です。

1~4章を読んだので重要そうな所を簡単にまとめたいと思います。

相関

抽出方法

  • 今回用いられているのは単純無作為抽出
    • 単純無作為抽出が行われる理由としては、抽出方法における分布が関係する
    • 単純無作為抽出の場合、標本の分布は母集団の分布に従うが、他の抽出方法の場合だと、抽出方法によっては母集団の分布と等しくないことが考えられる

不偏性

  • 一般に標本の分散などを取り扱う場合の方法として標本分散と不偏分散がある
  • 標本分散はよくある式の分散の式で求められるもので、不偏分散は割る値が-1になっているものである
  • この不偏性は一般に対象としている標本が母集団全体である場合は標本分散を、一部分である場合は不偏分散が用いられる
  • ここで不偏性をもつ推定量とは、ある標本分布の平均が母集団の平均と一定している場合の推定量のことをいう

標本分布

  • 簡単に言えば標本統計量の分布

    1. 母集団から標本を取ってきて、母数を点推定する場合、その推定値(標本統計量)が本当に母集団を表現することができているかどうかが分からない
    2. なので母集団から繰り返し標本を取ってきて、母数の点推定を行い、その分布を使って標本誤差を判定する
      • 標本統計量の分布が標本分布になる
  • 標本平均の場合、一般にサンプルサイズを大きくすれば、標本平均の標本分布は正規分布に従うと過程することができる

    • 中心極限定理っていうらしい
  • 一般に正規分布に従う母集団から得られる標本平均の標本分布は分散をサンプルサイズで割った正規分布に等しくなる

現在、knockoffを使って、markdownからhtmlに変換したものをdbに保存する際にstringnにしています。それをscala templateに渡す際には、play.api.templates.Htmlを使うとstringをhtmlとして使えるみたいです。

しかし、使ってみるとplay.api.templates.Htmlがdeprecatedになっていました。

色々見てみると、play.twirl.api.Htmlに変わっていました。使うときは注意が必要ですね。

PlayでDBを使うときのライブラリでplay-slickというものがあって、今回はそれを試してみたというものです。

play-slickとは

play-slickはScalaのORマッパーライブラリであるSlickをplayで使いやすい形にするというライブラリです。slick自体がとても使いやすいORマッパーであるため、それがPlayで使えると非常に便利です。

play-slickの使い方

自分がとりえあず使ってみようという形でやってみたものを簡単にまとめようと思います。

手順1 sbtでplay-slickをインストールする

以下が自分が使っていたbuild.sbtの一部です。私は手元にインストールしているmysqlを使いたかったので、そのためのライブラリも記述しています。

1
2
3
4
5
libraryDependencies ++= Seq(
    "org.slf4j" % "slf4j-nop" % "1.6.4",
    "mysql" % "mysql-connector-java" % "5.1.28",
    "com.typesafe.play" %% "play-slick" % "0.8.1"
)

手順2 application.confを修正する

application.confにslickを使うための設定を記述していきます。この中で大事なのがslick.defaultの部分です。slickはmodelsにtableの定義を書くとtableが生成されるのですが、これを記述しないと生成されないみたいです。この辺の設定についてはまだ良くわかってないので、時間があるときに調べられればと思います。

1
2
3
4
5
db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://localhost/tododb"
db.default.user=""
db.default.password=""
slick.default="models.\*

手順3 動かす

あとはrunをすればいいです。初回のrunでtableを生成するかどうか聞いてくるので、生成してください alert

感想

ホントはtableの定義の書き方もまとめたいんですが、自分でもよくわかってない部分が多いので、その辺が理解できたら書こうと思います。

1
2
3
4
5
6
7
scalaVersion := "2.11.5"

// slickのscalaのversionを自動で補完する
"com.typesafe.slick" %% "slick" % "2.1.0

// '' のscalaのversionを自動で補完しない
"com.typesafe.slick" % "slick\_2.11" % "2.1.0

の二種類があるみたいです。まぁ、細かくいうと後に何か付け足したりできるみたいですけど。

sbtでknockoffを入れてみようと思った時に起きた話。

ライブラリが入らない。。。

knockoffはScalaのmarkdownパーサーのライブラリで、色々遊んでみようと思い、今回入れることに。しかし、色々やって見れども出力されるのは。。。

1
[error] (*:update) sbt.ResolveException: unresolved dependency: com.tristanhunt#knockoff_2.11;0.8.0-16: not found)]

そりゃ、downloadすら出来てないんだからunresolved dependencyってでるよね。

解決

原因はsbtで探しに行くmavenのリポジトリの中にscalaのversionの2.10以降に対応するものが登録されていないためでした。githubの方のリポジトリには2.11に対応と書いてあったので不覚でした。mavenにあるのは2.9.2まで対応しているものでした。

こんな感じで修正してみて、sbtを動かしたら無事knockoffを導入することができました。

1
2
- scalaVersion := "2.11.5"
+ scalaVersion := "2.9.2"

感想

mavenのリポジトリ経由ではなくsbtで直接githubを指定する方法ってないんかなーと。

追記

普通にgithub上のライブラリを指定する方法があるみたいですね。これで入れてみて動かしてみますかね。 Github 上のライブラリや sbt plugin を使う (sbt 0.13 以降用)