January 24, 2012

CotEditorで拡張子に関連付けられた実行ファイルを起動するスクリプトとか




CotEditor http://sourceforge.jp/projects/coteditor/ のためのスクリプトをまとめておきます.スクリプトを使うためには,メニューバーから Open Scripts Folder で ~/Library/Application Support/CotEditor/ScriptMenu/ を開いて,スクリプトファイルを置いて,Update Script Menu します.ファイル名を変えることでショートカットを変更することもできます.

今のところ
  • 関連付け実行
  • テンプレートロード
  • Finder 開く
  • Terminal 開く
  • 実体参照置換
  • C, C++, C#, Javaソース整形
のためのスクリプトがあります.


ダウンロード
https://github.com/satomacoto/CotEditor-ScriptMenu


  • Run.@r.applescript (command + r)
    • ファイルの拡張子に関連付けられたスクリプトを実行します.スクリプトは"Run.d"ディレクトリに置いておきます.スクリプトのファイル名は"拡張子.applescript"です.
      • foo.py ってファイルを編集してる時に実行するとターミナルで python foo.py と実行してくれるとか
      • bar.html ってファイルを編集しているときに実行すると Safari で開いてくれるとか 
    • 基本ターミナル経由
    • 自分がよく使うもの以外動作確認してない
    • 一応関連付けたスクリプトを確認してから使ったほうがいいかも
    • 拡張子一覧
      • applescript
      • c
      • cc
      • cp
      • cpp
      • cron
      • crontab
      • cxx
      • f
      • f90
      • go
      • html : Safari
      • java
      • mp
      • php
      • pl
      • py
      • rb
      • tex : UpTeX.app
      • texi
    • 参考
  • Hello.^@l.applescript (ctrl + command + l)
    • ファイルの拡張子に基づいてテンプレートをロードします.テンプレートは"Hello.d"ディレクトリに置いておきます.スクリプトのファイル名は"hello.拡張子"です.
    • Hello Worldって出力するテンプレ
    • 拡張子一覧
      • applescript
      • c
      • cpp
      • f
      • f90
      • go
      • html
      • java
      • php
      • pl
      • py
      • rb
      • tex
    • 参考
  • Open Finder.^@o.applescript (ctrl + command + o)
    • ファイルの場所でファインダーを開きます.
  • Open Terminal.^@t.applescript (ctrl + command + t)
    • ファイルの場所でターミナルを開きます.
  • Predefined entity reference.py
    • 選択範囲の実体参照を置換します.スクリプトファイルはターミナルで"chmod 755"で実行できるようにしておく必要があります.
  • Artistic Style.sh
    • 選択範囲のC, C++, C#, Javaのソースを整形します.スクリプトファイルはターミナルで"chmod 755"で実行できるようにしておく必要があります.Artistic Style http://astyle.sourceforge.net/ が(デフォルトでは/usr/local/binに)インストールされている必要があります.Artistic Styleはhomebrewでインストールしました.
      brew install astyle 

vim/emacs/coteditor/etc.で1/4くらいずつつかってるきがする.どれもおぼえらんない.

January 13, 2012

PythonでMapReduceっぽいものを実装してみる

satomacoto: 青空文庫のルビのマイニングをやり直した

MapReduceっぽいものを触ってみたかったのでPythonで実装.参考にしたのは

Writing An Hadoop MapReduce Program In Python @ Michael G. Noll
http://www.michael-noll.com/tutorials/writing-an-hadoop-mapreduce-program-in-python/

あんま意味ないけどdefaultdictを使ったものと比較.

コード

以下mapper.pyとreducer.pyのコード.ほぼコピペ.




以下defaultdictのコード.



実行結果

https://github.com/downloads/satomacoto/Playground/count.zip

% head count.txt
 obscene house ナンバー・ナイン 1
A l'odeur du soleil sur les lavandes douces. もうむらさきにうれているげな 1
Abaisse'〕 アベッセ 4
Autant de pluie autant de tristesse, Paris qui m'oppresse! くさくさするほどあめがふる 1
Aux figuiers qui 〔mu^riront〕, au vent qui passera, みなみのくにではいちじくが 1
Belle-vue de Tombeau ベル・ビュウ・ド・トンボウ 2
Bonjour Monsieur ボンジュール・ムッシュウ 1
But this fold flow'ret climbs the hill この花こそは山にも攀ぢよ 1
Cafe' カフエ 1
Cafe' カツフエ 1
% wc count.txt
  260652  834471 6590672 count.txt


速度比較

% time cat ruby_rev.txt | python mapper.py | sort -k1,1 | python reducer.py > count_mapreduce.txt
cat ruby_rev.txt  0.00s user 0.07s system 0% cpu 59.480 total
python mapper.py  7.74s user 0.06s system 13% cpu 59.485 total
sort -k1,1  79.92s user 0.43s system 86% cpu 1:33.18 total
python reducer.py > count_mapreduce.txt  10.48s user 0.12s system 11% cpu 1:33.17 total

% time cat ruby_rev.txt | python count_defaultdict.py | sort -k1,1 > count_defaultdict.txt 
cat ruby_rev.txt  0.00s user 0.07s system 1% cpu 6.228 total
python count_defaultdict.py  6.90s user 0.12s system 98% cpu 7.131 total
sort -k1,1 > count_defaultdict.txt  6.21s user 0.06s system 46% cpu 13.438 total

Hadoopではやってない.つーか入れてない.やってみるか…

青空文庫のルビのマイニングをやり直した

################

「ヶケ」を漢字として扱っていなかったため,下のファイルでも取り切れていないようです.(bunさんにご指摘頂きました.ありがとうございます.)

################

ついカッとなって青空文庫からルビをマイニングしてみたものの

上のエントリでマイニングしたデータを少しちゃんと見たら,恥ずかしながらちゃんとルビが取れていないところがあったのでやり直しました.ごめんなさい.今度はあってるといいけど.ついでに"ファイル名\t文字\tルビ\n"だと後々使いにくいそうなので,
作品ID\t人物ID\t文字\tルビ\n
って形式にしました.

https://github.com/downloads/satomacoto/Playground/ruby_rev.zip

UTF-8.凡例含む出てきた順.被りあり.

################

「々仝〆〇ヶ」と「ケ」を漢字扱いにしてルビを抜き出しました.「ヶ原 はら」のような余計なものまで入っているので後処理が必要.

https://github.com/downloads/satomacoto/Playground/ruby_rev3.zip

################


% head ruby_rev.txt
046658 001257 倦怠 けんたい
046658 001257 玩味 がんみ
046658 001257 倦怠 けんたい
046658 001257 窪地 くぼち
046658 001257 鶉 うずら
046658 001257 啄木鳥 きつつき
046658 001257 叩 たた
046658 001257 漲 みな
046658 001257 栗鼠射 りすう
046658 001257 胡桃 くるみ
% wc ruby_rev.txt
 2212232 9099124 66071554 ruby_rev.txt

どうも
  • 青空文庫では漢字扱いの「々」が抜けてた
  • 注釈つきの文字(「※[#「火+稲のつくり」、第4水準2-79-87]みたいなの)」が取れてなかった
っぽいので,ルビを抜き出す正規表現を
((※[[^]]+?]|[一-龠々])+?|(?<=|)([^|]+?))《([^》]+?)》
としました.

どうなんだろうまだ微妙なのかな…正規表現ェ…

January 7, 2012

ついカッとなって青空文庫からルビをマイニングしてみたものの

################

下のzipは上手いことルビが取れてないので以下を参照.
satomacoto: 青空文庫のルビのマイニングをやり直した

################

ついカッとなってWikipediaからカッコ表現をマイニングしてみた - nokunoの日記

を参考にさせていただき青空文庫のルビを抜き出してみました.なーんも使い道考えてないけど.MLやらNLPやらIMEやらの研究でもサーベイしてみて色々ゴニョゴニョしてみたい.まーでもとりあえずなんか適当に処理して辞書に登録してみて近代の文学者のごとく認《したた》めるかな.

https://github.com/downloads/satomacoto/Playground/ruby.zip

データは
ファイル名\t語\tルビ\n
って具合に出てきた順にタブ区切りで出力しました.語のカウントとかしてません.被りあります.凡例の分も出力しちゃってます.

% head ruby.txt
1000_ruby_2956.zip 小焦 こじ
1000_ruby_2956.zip 尾 ぴき
1000_ruby_2956.zip 小焦 こじ
1000_ruby_2956.zip 強請 ねだ
1000_ruby_2956.zip 葛飾 かつしか
1000_ruby_2956.zip 堤 どて
1000_ruby_2956.zip 雪洞 ぼんぼり
1000_ruby_2956.zip 堰 せ
1000_ruby_2956.zip 御留川 おとめがわ
1000_ruby_2956.zip 殺生 せっしょう
% wc ruby.txt
 1847315 5750935 65440323 ruby.txt

ルビ表記は 青空文庫 - Wikipedia にあるルールに従って抜き出しました.
ルビの表記は |と《》によって表現される。ルビを《》で囲んだり|でルビのかかる文字列を特定するのは、視覚障碍者読書支援協会(BBA)の原文入力ルールに合わせたものである。
青空|文庫《ぶんこ》
とあれば、「ぶんこ」というルビが「文庫」についていることを示す。
本日は晴天《せいてん》なり。
のように、仮名と漢字の間に|が入る場合は|を省略することも出来る。
|ブルースカイ《青空》
のように、仮名にルビを強制的に振る時に使用することもある。

ちなみに「漢字《かんじ》」というパターン以外には
1029_ruby_20617.zip 接吻 ベエゼ
1040_ruby_20510.zip 然 きん/\ぜん
1182_ruby_20549.zip 盡 こと/″\
1067_ruby_1929.zip Esteros de Patino エステロス・デ・パチニョ
1317_ruby_22263.zip 三たび魔女の呪詛に萎れ毒気に染みぬる ウイズ・ヘキッツ・バン・スライス・プラステッド・スライス・インフェクテッド
1490_ruby.zip 願掛 がんがけ[#底本では「け」が脱落]
15971_ruby_28461.zip 並木道 ブリ※[#濁点付き片仮名ワ、1-7-82]ール
なんてパターンがあります.ほかにもパターンあると思う.漢字側に注があるのもあった.あとでなんとかするか.


以下抽出した手順のメモ.Lion.要wget(←brew install wget).

手順メモ
  1. 青空文庫リストCSVのダウンロード

    青空文庫のこのページの"「公開中 作家別作品一覧拡充版:全て(CSV形式、zip圧縮)」をダウンロード"からリストをダウンロードして解凍するとCSVファイルが.Shift_JISなのでUTF-8に変換しておく(別に変換しなくても大丈夫だけど).適当にディレクトリ掘ってから.
    wget http://www.aozora.gr.jp/index_pages/list_person_all_extended.zip
    unzip list_person_all_extended.zip
    iconv -f Shift_JIS -t UTF-8 < list_person_all_extended.csv > list_person_all_extended_utf-8.csv
  2. テキストファイルURLの抽出

    ダウンロードするためにテキストファイルのURLの列だけ抜き出して保存.
    python urls.py list_person_all_extended_utf-8.csv > urls.txt
  3. テキストファイルのダウンロード

    "zip"フォルダをつくって,そこにテキストのzipファイルをwgetでダウンロード.
    mkdir zip
    wget -i urls.txt -P zip
  4. ルビの抽出

    上のルールに従いルビを抽出.エラー起こっちゃったときは無視してるので,すべてのテキストに対してルビを取り出せているわけじゃない.
    python ruby.py 'zip/*.zip' > ruby.txt
  5. (おまけ)ルビがひらがな(と'・'と'ー')だけのもの


わかんないこと

  • そもそもどうやって辞書に登録するんだろう?まとめてできんのかな?品詞どーすればいい?つーか既に辞書にある語もあるような.全部登録していいのかな?記号関連どうすんだろ?
  • 文語体⇔口語体,何とかできんのかな?音便やらの仮名遣パターンあるのかな?
  • 普通は「漢字《かんじ》」だけどそれ以外のも結構ある.おもしれーからむしろこっちをゴニョゴニョしてみるかな?


IME関連の研究おもしろそうだよなー

January 6, 2012

Pythonでカーネル主成分分析を実装してみる

カーネル主成分分析(Kernel principal component analysis; kernel PCA)はその名のとおりカーネルを使って主成分分析(PCA)を行う手法.カーネルっていうのは距離みたいなもん(→Kernel trick - Wikipedia).線形主成分分析はデータが元の変数のベクトルの線形結合で表されてるとしているけど,そうでもないときもあるよねってことで,非線形写像して主成分分析する.分散共分散行列の代わりに,各データ間のカーネルを要素とするカーネル行列の固有値固有ベクトルを求めるってこと.

Kernel pricipal component analysis - Wikipediaに載ってる画像っぽいのをつくってやってみた.つくったデータ→
kpca.data
"x1 x2 class\n".3つのクラス.各クラス100個ずつ.

元データの描画.


カーネルは2通り試してみた.固有値大きい方から2つ取り出して固有ベクトルの要素の値をプロット.

その1 多項式カーネル
$$k({\mathbf x},{\mathbf y}) = ({\mathbf x}'{\mathbf y} + 1)^2$$



その2 ガウシアンカーネル
$$k({\bf x},{\bf y}) = \exp \left( \frac{- ||{\bf x} - {\bf y}|| ^2}{2\sigma^2}\right)$$



以下実装.要numpy,matplotlib.



距離(非類似度)行列の固有値固有ベクトル求めて描画するのはMDSっぽい

January 5, 2012

Pythonで多次元尺度構成法を実装してみる

多次元尺度構成法(Multidimensional scaling; MDS)は多変量解析の手法です.よくデータ間の(非)類似度の情報可視化に用いられます.MDSは基本的には似ているものは近くに,似ていないものは遠くに配置するような座標を求めます.ここでは古典的(計量的; metric)MDSをPythonで実装してみます.

古典的MDSは以下の手順で可視化.実装に必要なところのみ.

  • 要素の値が距離の2乗と見なせる非類似度行列Sを用意する
  • Sにヤング・ハウスホルダー変換を施してPとする
  • Pをスペクトル分解する(固有値・固有ベクトルを求める)
  • 固有値の大きい方から2~3個選び,対応する固有ベクトルを取り出す
  • 各固有ベクトルの要素値をプロットする(2個の固有ベクトルの時は2次元,3個の固有ベクトルの時は3次元)

一応,下部に参考リンクを挙げましたが,詳しい説明は検索すれば山ほど….ヤング・ハウスホルダー変換は距離の2乗の行列に両側から中心化行列をかける演算のことらしいです.中心化行列は距離の基準の原点を重心に移動するための行列らしいです.

ヤング・ハウスホルダー変換:
SがN×N行列のとき
$$P = -\frac{1}{2}({\bf I}-\frac{1}{n}{\bf 11}')S({\bf I}-\frac{1}{n}{\bf 11}')$$
と計算します.1は要素がすべて1のN次ベクトル[1,...,1]'です.なので11'は要素がすべて1のN×N行列.

アメリカの空港間の距離が与えられているときMDSで可視化してみます.
atl   chi   den   hou    la    mi    ny    sf   sea    dc
atl     0
chi   587     0
den  1212   920     0
hou   701   940   879     0
 la  1936  1745   831  1374     0
 mi   604  1188  1726   968  2339     0
 ny   748   713  1631  1420  2451  1092     0
 sf  2139  1858   949  1645   347  2594  2571     0
sea  2182  1737  1021  1891   959  2734  2408   678     0
 dc   543   597  1494  1220  2300   923   205  2442  2329     0

以下コード.要numpy, matplotlib.



結果はこんなかんじ.ラベルは手作業で付けました.


ちなみに実際の位置はこんなかんじ.

View US 10 Airport in a larger map

結果を180度回転すればだいたいなんとなくあってるかな?

上の例では非類似度行列を実際の距離の行列としましたが,MDSはデータ間の非類似度を測ることができたらそれっぽく2次元(3次元)にマッピングできるよ,ってことなので色々使えるかも知れません.

ちなみにRだったらcmdscaleでMDSが実装されてて楽