Shell – DECODE https://decode.red/blog data decode, decoder or decoded ... design of code Mon, 15 Dec 2025 06:15:00 +0000 ja hourly 1 https://wordpress.org/?v=4.7.29 Word To Vector ../../../20150823385/ Sun, 23 Aug 2015 09:05:35 +0000 ../../../?p=385 以前から気になっていたword2vecを動かしてみました。
これは単語間の類似性をベクトルとして計算します。

参考 : https://code.google.com/p/word2vec/

やはり実際に自分でやってみるといろんなことに気づきました。ファイルがとにかく大きくて処理に時間がかかること。マシンスペックもメモリ、CPUともできるかぎり高いレベルのものがあった方がいいということです。(VMはちょっときついかも)

環境: Ubuntu 14.04 / Virtual Box / Windows 8.1
セットアップ

svn checkout http://word2vec.googlecode.com/svn/trunk/
cd trunk
make
wget http://mattmahoney.net/dc/text8.zip -O text8.gz
gzip -d text8.gz -f
time ./word2vec -train text8 -output vectors.bin -cbow 1 -size 200 -window 8 -negative 25 -hs 0 -sample 1e-4 -threads 20 -binary 1 -iter 15

ここまでで下記ツールを使う準備ができました。

./distance vectors.bin
./word-analogy vectors.bin

./demo-word.sh
./demo-phrases.sh
の内容が参考になります。
demo-phrases.shは、word2vecに膨大な時間がかかるので、あきらめました。
w2v_00

どんなファイルかイメージするために、text8の冒頭部分です。
w2v_01

./word2vec -train text8 -output vectors.txt -cbow 1 -size 200 -window 8 -negative 25 -hs 0 -sample 1e-4 -threads 20 -iter 15

上のようにvectors.binをテキスト出力することもできます。以下がその内容で、
見やすくするためにExcelに表示しました。200次元のベクトルになっています。
w2v_02

ツールを使って、近い距離にある単語を出力してみます。vectors.binではあまり十分な結果が得られなかったので、word2vecのサイトにあった、GoogleNews-vectors-negative300.bin を使いました。
w2v_03

次は、前二つの単語の関係から、三つ目の単語から類推できる単語を出力してみます。
w2v_04

今回デフォルトで用意されたデータばかり使いましたが、自分で目的にあったデータを収集すれば、期待どおりの結果を出してくれそうだと思いました。

]]>
Signal Processing Toolkit ../../../20150708374/ Wed, 08 Jul 2015 14:16:48 +0000 ../../../?p=374 音声データをコマンドツールだけで処理できるSPTKを試してみました。
SPTK-3.8
http://sp-tk.sourceforge.net/

ただSPTKだけではカバーできない部分は、古くからあるsox、gnuplotを使いました。
sox-14.4.2
http://sox.sourceforge.net/

環境 : MacOSX 10.10.3

録音した音声をコンバートして、ピッチの抽出をします。
音声データは、ポータブルキーボードで、ドレミファソラシド、と適当に弾いたものを、Macの内臓マイクで録音しました。
tones1

tones_plot
ピッチの高低とグラフの高低は逆に表示されています。

元の録音データもプロットしてみました。
tones2

最近はあらゆるデータが解析の対象になります。このようなコマンドラインツールも使えるように備える意味でもテストしてみました。

参考 :
http://aidiary.hatenablog.com/entry/20120701/1341126474
http://linuxwebdev.blogspot.jp/2006/03/plot-wav-file-wav2png.html

]]>
Map Reduce ../../../20141102230/ Sun, 02 Nov 2014 06:10:43 +0000 ../../../?p=230 ビッグデータを分散処理する手法として、とても有名です。いまさら感は否めないのですが、この手法をとても身近なやり方でわかりやすく実装しているプログラムを見つけましたので、取り上げてみたいと思います。
その名は、bashreduce。文字通り、Linuxのシェルスクリプト(Bash)で、MapReduceを実現しています。

https://github.com/rcrowley/bashreduce

map/reduceができるという興味以上に、コードの中身がすごい。Unixのパイプ処理のすさまじさを体験できます。
ということで、注目する部分をピックアップして、コードリーディングをしてみたいと思います。

https://github.com/rcrowley/bashreduce/blob/master/br

mkfifo $jobpath/{in,out}/$host_idx
# Listen for work (remote)
ssh -n $host "mkdir -p $nodepath/"
pid=$(ssh -n $host "nc -l -p $port_out >$nodepath/$host_idx \
2>>$tmp/br_stderr </dev/null & jobs -l" \
| awk {'print $2'})

# Do work (remote)
ssh -n $host "tail -s0.1 -f --pid=$pid $nodepath/$host_idx \
2>>$tmp/br_stderr </dev/null \
| LC_ALL='$LC_ALL' sort -S$sort_mem -T$tmp -k$column,$column \
2>>$tmp/br_stderr \
$map $reduce \
| nc -q0 -l -p $port_in >>$tmp/br_stderr &"

# Send work (local)
nc $host $port_in >$jobpath/in/$host_idx &

# Receive results (local)
nc -q0 $host $port_out <$jobpath/out/$host_idx &
out_files="$out_files $jobpath/out/$host_idx"

# ++i
port_in=$(($port_in + 2))
port_out=$(($port_in + 1))
host_idx=$(($host_idx + 1))

このプログラムの前準備の部分です。(ループ内部)
リモートホスト$hostは何台でも増設ができるようになっており、リモートホストにはSSHでパスワードなしでログインできるようにしておくこと以外、何も準備する必要はありません。

ssh-keygen

これで、生成される.ssh/id_rsa.pubをリモードの.ssh/authorized_keysに追加します。

・名前付きパイプ
・netcat(nc)によるバックドア

この二つを駆使して、リモートへの接続、リモートでのコマンド実行、結果の取得をしています。ローカル・リモートホスト間は、ホストの数だけそれぞれ送受信二つずつコネクションをはります。
(tail –pidで、プロセスが死んだときに終了する部分、こうやって使うのか・・フムフム)
ローカル > リモート > ローカル とパイプ接続がされた状態にして、データ入力を待ちます。

次は、データを分散して書き込むところです。(mapに相当)

https://github.com/rcrowley/bashreduce/blob/master/brutils/brp.c

fputs(line.buf, pouts[fnv_hash(line.col_beg, line.col_end) % pouts_len]); // write it to the correct file

https://github.com/rcrowley/bashreduce/blob/master/brutils/brutils.h

unsigned int fnv_hash(const char *p, const char *end) {
    unsigned int h = 2166136261UL;
    for (; p != end; ++p)
        h = (h * 16777619) ^ *p;
    return h;
}

fnv_hash関数でデータ内容からハッシュ値を生成して、それを出力ファイル数pouts_len分に振り分けます。この出力ファイルというのは名前付きパイプです。ここにデータを流し込むと、リモードに送られるしくみです。ちなみにfnvというのは、
Fowler-Noll-Vo hash function
という意味で、簡単なアルゴリズムでハッシュをつくるしくみのようです。

http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
http://wowdev.jp/?p=873

これにより、同じデータが違うサーバに振り分けられることがなくなり、独立性がたもたれ、処理効率があがります。ここが肝なのでしょう。

最後はデータをまとめるところです。(reduceに相当)

eval "$BRM - $(($column - 1)) $(find $jobpath/in/ -type p | xargs) \
${output:+| pv >$output}"

$outputに使われている、コロン演算子が標準出力かファイルかの切り替えをシンプルにしています。

bashreduceはオリジナルや他のバージョンもあるのですが、このバージョンがわかりやすかったので、使いました。実行は、Ubuntuがよさそうです。
Cのプログラムがない場合もLinuxコマンドで代替えしています。

とても勉強になるコードでした。(ほとんど個人メモ)

]]>