Statistical Programming

reduceとfold…

例えばこんなコレクションがあったとして

List(1,2,3,4,5)

このコレクションの各要素に10を足したものを掛け合わしたいとする。
そんなとき便利なのかreduce系もしくはfold系メソッド。
例えばreduceLeft(f)メソッドは,リスト x1, x2, …, xn に対して

f(f(…f(f(x1, x2), x3), …), xn) 
n=4 の場合は,f(f(f(x1, x2), x3), x4)

となる。
逆にreduceRight(f)は,リスト x1, x2, …, xn に対して

f(x1, f(x2, … f(xn-1, xn)…)) 
n=4 の場合は,f(x1, f(x2, f(x3, x4)))

翻ってfoldLeft(e)(f)は,リスト x1, x2, …, xn に対して

f(f(…f(f(f(e, x1), x2), x3), …), xn) 
n=4 の場合は,f(f(f(f(e, x1), x2), x3), x4)

まあ再帰を使ってもいいけど。

def mul(in:List[Int]):Int=in match{
    case Nil=>0
       case List(x)=>x+10
       case x::tail=>(x+10)*mul(tail)
     }

でも早くて簡潔な方がいいよね!

reduce((a,b)=>(a+10)*(b+10))
fold(10)((a,b)=>(a+b)

foldとreduceの違いは最初の要素に対する処理が違うのかな…
reduceの場合強制的に最初の要素とその次の要素が処理されるのに対してfoldはその前にひと呼吸置けるというか最初の要素とその次の要素が処理される前に自分が追加した引数と最初の要素をまず処理してからその後の処理にいくってかんじか。
だからfoldの場合その最初の処理の片割れ(もう一方はコレクションの最初の要素)追加してあげなきゃいかんのね。

Scalaでフロントサイドが書ける!scala-js!!

scala-jsとはjavascriptに嫌気がさした僕のような人のためにscalaでサーバーからクライアントまで書けるようにしてくれる優れもの!!と言いたいところですがまだ開発途中なこともありドキュメントの整備や機能においても完成されたものではありません。それでももしscalaでクライアントサイドが書けるかと思うと心が躍ります^^

こちらがscala-jsのサイト、ドキュメントへのリンクです。

http://www.scala-js.org/doc/

見ていただければわかりますがドキュメント???というレベルです。笑

とりあえず俺をフォークしてみろよ!とのことなのでまあクローンしてみました。

んでターミナルを開きクローンしたフォルダへ行き、sbtコマンドを打ち込みます。

その後 packageJSと入力するとscalaで書かれたコードがjavascriptのコードへ変換されるということらしいです。このサンプルプログラムの例ではindex-dev.htmlの中身が変更されたらうまくいっているとのこと。このHTMLファイルが参照しているexample.jsというファイルの中身がpackageJSの前後で変わってくるということなのかな?というよりもpackgeJSコマンドによってtargetフォルダ自体が作成されてますね。。。これjQueryみたいな使い方できんのかな…

index-dev.html
<!DOCTYPE html>
<html>
<head>
  <title>Example Scala.js application</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>

<h1>Example Scala.js application - development version</h1>

<p>After having compiled and packaged properly the code for the application
(using `sbt packageJS`), you should see "It works" herebelow.
See README.md for detailed explanations.</p>

<div id="playground">
</div>

<script type="text/javascript" src="./target/scala-2.10/example-extdeps.js"></script>
<script type="text/javascript" src="./target/scala-2.10/example-intdeps.js"></script>
<script type="text/javascript" src="./target/scala-2.10/example.js"></script>

</body>
</html>

scala-js-example-app/src/main/scala/example以下にあるscalaJSExample.scalaがjsへと変換される具体的なコードです。

scalaJSExample.scala
package example

import scala.scalajs.js
import js.Dynamic.{ global => g }

object ScalaJSExample {
  def main(): Unit = {
    val paragraph = g.document.createElement("p")
    paragraph.innerHTML = "<ul><li>1</li><li>2</li>"
    g.document.getElementById("playground").appendChild(paragraph)
  }
}

そしてこちらが変換後のコードの一部だと思われます…
たぶん!笑

example.js
/** @constructor */
ScalaJS.c.example_ScalaJSExample$ = (function() {
  ScalaJS.c.java_lang_Object.call(this)
});
ScalaJS.c.example_ScalaJSExample$.prototype = new ScalaJS.inheritable.java_lang_Object();
ScalaJS.c.example_ScalaJSExample$.prototype.constructor = ScalaJS.c.example_ScalaJSExample$;
ScalaJS.c.example_ScalaJSExample$.prototype.main__V = (function() {
  var paragraph = ScalaJS.g["document"]["createElement"]("p");
  paragraph["innerHTML"] = "<ul><li>1</li><li>2</li>";
  ScalaJS.g["document"]["getElementById"]("playground")["appendChild"](paragraph)
});
ScalaJS.c.example_ScalaJSExample$.prototype.main = (function() {
  return this.main__V()
});
/** @constructor */
ScalaJS.inheritable.example_ScalaJSExample$ = (function() {
  /*<skip>*/

Play FrameworkのAdvent Calendar!!

最近というか一昨日くらいからQiitaというプログラミングに関する知識を共有するサービスに登録したんですがそこでPlay Framework (2.0系)のAdvent Calendar なるものを発見したので早速なんで登録してみました。正確にはAdventarというサービスなのかな…

※Advent Calendarとはプログラミングに関する記事を12月1日〜25日にかけてみんなで投稿するイベントです。

まだまだ人数が足りないので興味ある人いましたらどしどしです!!

プログラミング歴が短い自分にとってはPlayのDocumentationはなかなか理解が難しいものも多いのでこの手の投稿が増えてくれればいいなとかおもっとります。

Play framework 2.x Scala Advent Calendar 2013

 

scalaのIDEについてーeclipse&IntelliJ

今までscala IDE for eclipseを利用してきて特に問題ないどころか非常に満足していたのですが、どうやらscala使いの方々はIntelliJを好むのか!?という不安にかられIntelliJを試してみました。印象としては、、、eclipseの方がいいなあ(慣れてるからですよね、すいません)かなり細かくどのライブラリを利用するのか指定しなきゃだめだしそこんとこよくわかってなかった自分がわるいっちゃ悪いんですけどなんだかなあという思いなり。Homebrewにインストールされているscalaライブラリを使う時のパスは

/usr/local/Cellar/scala/2.10.3/libexec 

ここ、テストにでるよ!!!

あと、worksheetの使い勝手がすごい悪いなあとも。極めつけに、おっっそおおおい!!おそいよーー!eclipseの方が断然はやい!?(少なくともworksheetはめさおそい)てっきり逆かとおもてたけどIntelliJが多機能だからかeclipse開発陣が優秀だからか。。。worksheetを重宝してるからこれは耐えられない…というわけでやっぱり本家が開発しているeclipseにしときます…まあIDEのデザインはIntelliJの方が好きなんだけどね。ロゴはecliseの方が好きだけど。さらに、現在無償版であるCommunity Editionの方ではPlayがサポートされていないなんて話も…実際Playのプラグインが見つからなかったし…もしそうだとしたらIntelliJは学生には敷居が高いなー有償版は2万くらいするし!高い!しかも毎年更新せねばならんとかもーやだわー更新は半額らしいけどね。

少し話が変わるけどbrowserベースのIDE、Typesafe activatorは結構好きです。デザインがシンプルで良いし色んなプロジェクトのテンプレートが既にあってそれを利用して開発をスタートできるから手っ取り早い。現在41個ほどテンプレートがある。テンプレートはplay,slick,akkaなど代表的なやつもあればPlayAkkaWebsocketAngularJSみたいなやつもあったりとなかなか嬉しい。

というわけでこれからもeclipse+sbt+typesafe activatorで行こうと思います。

jarを作りたいならsbt-assembly!!

とあるライブラリ、もしくは単なるプログラムがあるとしてそのjarファイルを作りたい時に登場するのがsbt-assemblyです。その名の通りjarファイルを生成してくれるすぐれもの!準備は簡単で、まずはsbtのフォルダ構成に乗っ取ったフォルダを生成し、その中に含まれる(含まれなかったら自作する)build.sbt , plugin.sbtをいじれば良いだけ!

 

build.sbt には以下を追加。ただしimportの部分はファイルの先頭に追加。

import AssemblyKeys._ // put this at the top of the file
assemblySettings

 

次にplugin.sbtには以下を追加。

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.10.1")

 

これで完了!それではフォルダのルートディレクトリへ行きsbtを実行。

>   assembly

と打ち込むと     /target/scala-2.10/~~~.jar

が出来てる。

試しにそのjarファイルをeclipseから使ってみる。

libフォルダを適当につくってその中に先ほど作ったjarを入れる。ビルドパスを通す。

適当なmainプログラムを作りそのjarに含まれているクラスを使う。

このとき、どういった名前でどこのパッケージにそのクラスが入っているかはeclipseのビルドパスをよくみたらすぐにわかる。今回はscalaパッケージの中のクラスを使う。

import scala.Data

object DataActor extends App{

val d=new Data

 

}

以下、コンソールにちゃあんと表示される。

Coffees query=> name: French supID: 101 price:  450.0

Coffees query=> name: Espreso supID: 34 price:  333.0

Coffees query=> name: American supID: 45 price:  590.0

Suppliers query=> id: 11 name: doku country:  Africa

Suppliers query=> id: 101 name: DoraCof country:  India

Suppliers query=> id: 34 name: Starbar country:  America

Suppliers query=> id: 45 name: mandolecoff country:  SouthAfrica 

 

テキストマイニング入門が簡単な時代になったのですなあ〜

kuromojiという形態素解析ライブラリを利用してテキストマイニングしてみる。やってみたけど超簡単。やばい、これ。しかもScalaから利用するからJavaと比べてさらにすっきりするしいいね。以下からjarファイルをダウンロード。

Downloads · atilika/kuromoji · GitHub

ビルドパスを通すだけでおっけ。プロジェクトにビルドパスを通したらあとは org.atilika.kuromoji.Tokenizer をimportしてついでにJavaのリストをScalaに変換できるよう scala.collection.JavaConversionsもimport。importするのはこれで終わり。
まずはTokenizerのインスタンスをゲットしてからtokenize()の中に解析したい文字列をいれ、それをもとにTokenの入ったListをげっと!最後にそれらをjavaからscalaのListに変換してforeachでまわせばおけ!

kuro.scala
package textmining
import org.atilika.kuromoji.Tokenizer
import scala.collection.JavaConversions._
object  Kuromoji extends App{
val tokenizer=Tokenizer.builder().build()
val tokens=tokenizer.tokenize("明日ははやいよーー!!ねむた!ねむた!")
val stokens=tokens.foreach(x=>println(x.getAllFeatures()))
} 

名詞,副詞可能,*,*,*,*,明日,アシタ,アシタ
助詞,係助詞,*,*,*,*,は,ハ,ワ
形容詞,自立,*,*,形容詞・アウオ段,基本形,はやい,ハヤイ,ハヤイ
助詞,終助詞,*,*,*,*,よ,ヨ,ヨ
名詞,一般,*,*,*,*,*
記号,一般,*,*,*,*,!,!,!
記号,一般,*,*,*,*,!,!,!
形容詞,自立,*,*,形容詞・アウオ段,ガル接続,ねむたい,ネムタ,ネムタ
記号,一般,*,*,*,*,!,!,!
形容詞,自立,*,*,形容詞・アウオ段,ガル接続,ねむたい,ネムタ,ネムタ
記号,一般,*,*,*,*,!,!,!

ちなみにこんな感じで1行でも書ける。見づらいけど笑

Tokenizer.builder().build().tokenize("やっはろー!?元気してる?").foreach(x=>println(x.getAllFeatures()))

ちょっとだけ手を加えてファイルから読み取る感じに。

kuro.scala
package textmining
import org.atilika.kuromoji.Tokenizer
import scala.collection.JavaConversions._
import scala.io.Source
object  Kuromoji extends App{

def analyze(file:String)={
val files=Source.fromFile(file)
  val tokenizer=Tokenizer.builder().build()
    for(lines <- files.getLines){
      val tokens=tokenizer.tokenize(lines)
      val stokens=tokens.foreach(x=>println(x.getAllFeatures()))
    }
    files.close()
}
analyze("/Users/kyu/Documents/assignment/Exercise/
src/textmining/shayo.txt")
} 

こんな感じでカウント数でソートも!        
 

tokens.groupBy(x=>x.getBaseForm)
  .values
  .toList
  .sortWith( (a,b)=>a.length>b.length)
  .foreach(x=>println("count: " +x.length+" "+x(0).getBaseForm))

でもこのままだと”た”とか”て”とかあまり意味のない助詞とかが上の方にでてきてしまた(よく考えれば当たり前)。それを防ぐには多分どの品詞だけ適用みたいなことを指定する必要があるのかな。というわけでfilterを途中に挟み込む。 というわけで名詞だけにしぼってみた。最終的なコードは以下っす。

kuro.scala
package textmining
import org.atilika.kuromoji._
import scala.collection.JavaConversions._
import scala.io.Source
object  Kuromoji extends App{
def analyze(file:String)={
val files=Source.fromFile(file)
val content=files.getLines.mkString
  val tokenizer=Tokenizer.builder().build()
  valtokenlist=tokenizer.tokenize(content)
  val sorted=
    tokenlist
  .filter(x=>x.getPartOfSpeech().startsWith("名詞"))
  .groupBy(x=>x.getBaseForm)
  .values
  .toList
  .sortWith( _.length>_.length)
  sorted.foreach(x=>println("count: " +x.length+" "+x(0).getBaseForm()))  
}
analyze("/Users/kyu/Documents/fruits
/Exercise/src/textmining/shayo.txt")
} 

<各変数の値、メソッドの返り値はこんな感じ>
tokenlist ; List(Token(),Token()......)

→filter ; List(Token(~),Token(~),....) 
※名詞のみを取り出す

→groupBy ; Map("~"->List(),"~"->List(),....) 
※原型が同じ単語をまとめる。"~"がその原型、List()にはその単語が入っている。例えばもし文中に2回”世界”という単語が出現していれば "世界"->List(Token(),Token()) となる

→values ; MapLike(List(),List(),...)
※先ほどのMapのListの部分だけを抽出

→toList ; List(List(),List(),....)

→sortWith ; List(List(),List(),...)
※各リストの要素が多い順、つまり単語の出現頻度順にソートする

→foreach以下 ; それらを出力

効率をもっと良くしたいですね…コレクションの使い方をべんきょうせねば。