2014年10月19日日曜日

Rのsvd(特異値分解)で次元の圧縮

Rではsvdを使って次元の圧縮が可能
svdでは任意の行列を3つの行列に分解します。

> #適当な行列を作る。(2次元の特徴量が3個あるイメージ)
> x=matrix(1:6, nrow=2, ncol=3)
> 
> #中身はこんな感じ
> x
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
> 
> #特異値分解
> svd=svd(x)
> 
> #次の3つの行列に分解される。
> A=diag(svd$d)
> U=svd$u
> V=svd$v
> 
> #上記の3つの行列の積は元の行列と一致する。
> U %*% A %*% t(V)
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
次元の圧縮をしたいときはこんな感じ
> #次元圧縮はこんな関数にしておくと便利
> reduce <- function(x,svd,reduced_dimension) {
+     result=t(svd$u[,1:reduced_dimension]) %*% x 
+     return(result)
+ }
> 
> x=matrix(1:6, nrow=2, ncol=3)
> svd=svd(x)
> 
> #2次元だったものを1次元に圧縮
> reduce(x,svd,1)
          [,1]      [,2]      [,3]
[1,] -2.189418 -4.998466 -7.807514


詳しい原理は下記参照
http://en.wikibooks.org/wiki/Data_Mining_Algorithms_In_R/Dimensionality_Reduction/Singular_Value_Decomposition

2014年10月15日水曜日

rubyでBag-of-Wordsの計算

Mecabという日本語の形態素解析機があります。

Mecab公式

Bag-of-Wordsをつかっていろいろやってみたかったので、いろいろライブラリを探していました。
Mecabを使ったBag-of-Wordsの計算はRでRmecabというライブラリが提供されていますが、Rでは大きなテキストに対応できないそうで、私の環境では数十M程度のテキストファイルでメモリ関連のエラーが頻発しました。公式サイトでも大きなファイルには対応できないと書いてあります。

RMecab公式

そこで、rubyでBag-of-Wordsを計算してみました。
(Mecabを使って作ったのでTororoっていう名前にしました。)

Tororo

今はまだBag-of-Wordsの計算ぐらいにしか使えませんが、将来的にはMecabのラッパーとして、rubyからの日本語構文解析全般に使えるようにしたいです。 (あとgemの形にしたい) そのうち、READMEをもっとまともに書いて使える用にします。

githubのOVERVIEWに書かれている以下の文言は、これからこうしたい!という意気込みです。
Parse Japanese text with Mecab.
Simple ruby interface.

2014年10月4日土曜日

PostgreSQLでのレコードを返す関数の実行

PostgreSQLで関数は普通こんな形でselect以下に書いて実行します。
postgres=# select sqrt(144);
 sqrt 
------
   12
(1 row)
普通の関数は上のでOK
しかし、record型を返す関数の場合はこの形で指定するとレコードがすべて1カラムに入って帰ってくるのでみずらい
postgres=# select pg_get_keywords();
                         pg_get_keywords                          
------------------------------------------------------------------
 (abort,U,unreserved)
 (absolute,U,unreserved)
 (access,U,unreserved)
 (action,U,unreserved)
 (add,U,unreserved)
 (admin,U,unreserved)
 (after,U,unreserved)
 (aggregate,U,unreserved)
 (all,R,reserved)
 (also,U,unreserved)
where句に入れるとレコードで帰ってくるよ
みやすい!
postgres=# select * from pg_get_keywords();
       word        | catcode |                   catdesc                    
-------------------+---------+----------------------------------------------
 abort             | U       | unreserved
 absolute          | U       | unreserved
 access            | U       | unreserved
 action            | U       | unreserved
 add               | U       | unreserved
 admin             | U       | unreserved
 after             | U       | unreserved
 aggregate         | U       | unreserved
 all               | R       | reserved
 also              | U       | unreserved

rubyは文字列のインクリメントができる!

rubyは文字列のインクリメントができます。
こういう細かいところに配慮されているっていうところが素晴らしい
こういった動作はCであれば'x'を格納するアドレスをずらしていって実装するしかなかった。
str='x'
4.times{
   puts str
  str=str.next
}

実行結果

x
y
z
aa

ちゃんと桁上げまでされます。