統計処理の勉強メモ(3)

以下の本を読みました。

読み物として非常におもしろいです。ビッグデータ系の本の中では一番かな?最近は、どこもかしこもビッグデータビッグデータでみんなおなかいっぱいになっている感じがしますが、よく考えるとマシンログこそビッグデータです。ビッグデータという言葉自体に意味はあまりないですが、データ蓄積、分析、活用、フィードバックの流れはもう止められません。間違いなく、あと10年は主流です。

ビッグデータ系の本はいろいろあります。マーケティング系、統計学系、事例紹介系などさまざまな分野に影響を与えています。その中にあって、著者は、自身が関わってきた研究を中心に話しているので説得力があります。特に今までわかっているようでわかっていなかったことをデータを使って明らかにする説明はとてもおもしろいです。もう、「ビジネス的なビッグデータにあきちゃったよ。なんで常に金儲けなんだよ。おもしろそうだなって発想でやっちゃいけないのかよ。」って人には最適です。

さて、自分自身について悩んでたこともあり、しばらくブログを休んでましたが、大きな外的要因があり、ふっきれました。初心に戻って、承認欲求を満たしながら、いろんなことを学んでいこうと思います。

当面は、ElasticSearchかなぁ。

統計処理の勉強メモ(2)

以下の本を読みました。

1億人のための統計解析 エクセルを最強の武器にする

1億人のための統計解析 エクセルを最強の武器にする

Amazonの評価はとても低いですが、私自身は良いなと思う部分もけっこうありました。というのも、まず、ビジネス的な価値を意識している点です。やっぱり、この視点ってけっこう重要だと思うんですよ。企業とかでやろうと思うと、ある程度お金が発生しているんで、どうしたって最終的には誰かに説明しないといけないタイミングって来るはずで、そういう時に、ビジネス的な価値を意識していないと困ると思うんです。そういったビジネス的な価値と統計処理をどう結ぶかってことが最初の40ページぐらいに書かれていて、ここだけでも読む価値があるかなと。私みたいに統計素人には、統計処理の厳密さよりも、とりあえず何か結果だせるメソッドやフレームワークを提示してくれるってのは、けっこうありがたい。その後、興味があれば、より詳細に学べればいいかなって思います。

あとは、もう、そこらのExcelの解説書より丁寧じゃね?ってぐらいExcelでの統計処理に特化して説明してくれているところですね。エンジニア系の人と付き合っているとExcelの話題なんてあまり出ないですけど、ふつうの人ってやっぱりExcelなんですよね。そういった人たちに、統計処理の効果を伝えようと思ったら、Excelでできるっていうのは大きいと思うんですよ。

なので、この本は、ガチの人にはウケないと思いますが、会社で急に統計処理に取り組むことになった企画部門の人とかにはオススメです。とりあえず、Excelでなんかできますし、フレームワークでどんな分析をするか?まで明確にできれば、プロの人にアウトソースできますしね。著者が「一億人の」って言っているのはこのあたりかなって気もします。全員が全員、Rとかその他もろもろの専用ツールの使い方を知る必要ってない気がしますし。うまく分業できるのが良いような気がします。

ただ、私は、もう少し詳細な部分に興味が出てきたので、Twitterで情報を調べて、ガチっぽい統計の教科書とかも読むようにしているんですが、こちらはどうしたって時間がかかりますね。まぁ、もともと数学をよく勉強している人にとってはそうでもないんでしょうが。まだまだ先は長いと思います。ただ、簡潔データ構造を勉強し始めた時よりは情報が揃っているんでやりやすいですけど。

サーチアプリケーション

Solrは、3.Xの頃に調査したことがあったのですが、4.Xになってからは触れることがほとんどなく、なんか良くなったらしいということだけ聞こえてきていました。また、最近の世の中の事情もあって、構造化データと非構造化データを効率的に扱うことを考えるとサーチアプリケーションという選択肢もアリになっていると思います。専用のDWHを用意するという発想ももちろんアリだと思います。ただ、データの格納が必要なく、すでに稼働しているさまざまなデータを取出し、サーチアプリケーションのインデックスとしてだけ保持しておいて利用するというのもコストがあまりかからないので良いと思います。弱点としては、サーチアプリケーションごとに、機能の違いがあることと、元のデータソースとの同期を適切に行わないといけないというところでしょう。

全文検索というとテキストだけを対象としているように考えてしまいがちですが、ビッグデータブームもあり、Solrコミュニティは、構造化データと非構造化データを結合したアナリティクスを提供するという方向を意識しているように思います。例えば、IBMの方の以下の記事がわかりやすいと思います。

http://www.ibm.com/developerworks/jp/java/library/j-solr-lucene/

検索とアナリティクスの融合は、Splunkが先行していますが、Elasticsearchは、Kibanaなどを利用して、同様のことをより低価格で目指しているように見えます。

http://www.elasticsearch.org/overview/kibana/

このような状況でもあり、真面目に調査しようと思い、改訂版のSolr本とElasticsearch本を購入しました。

[改訂新版] Apache Solr入門 ~オープンソース全文検索エンジン (Software Design plus)

[改訂新版] Apache Solr入門 ~オープンソース全文検索エンジン (Software Design plus)

高速スケーラブル検索エンジン ElasticSearch Server

高速スケーラブル検索エンジン ElasticSearch Server

私は、関係者でもないですが、ステマしておきます。改訂版のSolr本は、前作のSolr本を踏襲しつつ、新しい内容が加筆されているので、前作を読んだことがある人は読みやすいと思います。Elasticsearch本は、まだ眺めただけですが、アプリケーションを利用する人にとっては、十分な情報が書かれているように思います。

サーチアプリケーションというのは、情報系の勉強をするのにもってこいだと思います。検索のUIは多くの人が慣れ親しんでいるのでとっつきやすいですし、結果も見慣れたものなので、苦痛ではないでしょう。Solrのサンプルを動かすだけだと簡単にできるでしょうし、楽しいと思います。さらにそこから深堀りできます。例えば、

  • 高速な検索をどう実現しているのだろうか?という疑問を持ち、高速な検索アルゴリズムを調べる。
  • より良い検索結果とは何だろうか?という疑問を持ち、情報検索の世界を調べる。
  • 世界には多くの言語があるが、それを柔軟に扱うにはどうしたら良いだろうか?という疑問を持ち、自然言語処理の世界を調べる。
  • 関連するものをいろいろ出してくれるレコメンドというのはどう実現されているのだろうか?という疑問を持ち、機械学習の世界を調べる。
  • 多くのユーザに安定的にサーチというサービスを提供するために、システムはどう構成されて、動いているのだろうか?という疑問を持ち、インフラ技術を調べる。

など、さまざまなことをサーチアプリケーションを入り口にして学ぶことができます。私も勉強中です。特に、分散検索などは、昔は試すのが難しかった(作るのが大変だった)ですが、Solrの登場でだいぶ敷居が下がりました。学生実験などでも十分にできると思います。私は、社会人になって、サーチアプリケーションから、検索アルゴリズムの世界に興味を持ち、簡潔データ構造を調べるようになり、いろいろ作ってみたりしました。Suffix ArrayやFM-Indexという技術ももちろんおもしろいですが、アプリケーションとしてのサーチもやはりおもしろいです。また、Luceneのコアは、転置索引やN-gramですが、なぜ、逐次探索(grep系)やSuffix Array系ではないのか?、Suffix Array系にしようと思うとどういった課題を解決しないといけないのか?というのを考えるのもおもしろいです。

私も、まだ、SolrやElasticsearchをあまり触っていないので、これから知識を深めていこうと思います。

文法圧縮(6)

仕事上での悩みもあり、なかなかエンジンがかからない状態が続いており、新年からずっとダラダラしている。いまいちモチベーションが上がらないが、ずっとダラダラしていてもしょうがないので、簡単なことからいろいろとやり始めることとした。「遅くともやらないよりはマシ」だと思うので。

今回、特に内容はないが、文法圧縮の入門に良い記事を見つけたので紹介しておく。九工大の坂本先生の記事である。*1

「圧縮情報処理ノススメ」
http://www.donald.ai.kyutech.ac.jp/~hiroshi/sakamoto_tutorial_2013_7.pdf

私の知る限り、文法圧縮をわかりやすく解説した日本語の解説はないので、大変貴重だと思う。*2私は、関東に住んでいないので、DSIRNLPには参加できなかったが、文法圧縮の話題も出ていたようなので、「文法圧縮」って何?という場合は、この記事を読むと良いと思います。文法圧縮の圧縮全文索引が出てくると、ストリーム処理向きの検索エンジンが作れるので、かなりおもしろいと思います。

ちなみに、文法圧縮には関係ないが、「百科事典棒」は、「なるほど!」とうなってしまった。おもしろい。

*1:私は、我流で学んだので、専門の方のこういう解説記事は知識が整理できるので大変ありがたい。

*2:あれば教えてください。

文法圧縮(5)

文法圧縮(Re-Pair)の構築部分については、線形時間で構築できるようになったが、文法圧縮部分の辞書をどう簡潔に保持するか?という問題が残っている。

例えば、

abcabcabb

という文字列に対して、Re-Pairを適用して、以下のような辞書(R)と圧縮文字列(C)が得られたとする。

辞書(R):
s ---> ab
t ---> sc
u ---> ts

圧縮文字列(C):
tub

このとき、辞書(R)を単純にハッシュで保持することもできるが、簡潔に保持することもできる。図に示す。

f:id:ryokkie:20140101174858p:plain

詳しい作り方は、後で述べるので、まずは、簡単に説明する。辞書(R)を2分木を使って表現し、その構造をRbというビットベクトルで表現する。ビットベクトルの1は、ノードであり、0が葉である。木を行きがけ順(pre-order)で探索して、Rbを表現する。また、葉の文字を行きがけ順に並べたのがRsである。このとき、uの中にsが出てくるが、すでに部分木として表現されているので、Rbでの部分木の位置をRsに表現する。なので、実際には、木というよりもDAGと表現した方が良い気がする。

例として、このデータ構造を使って、「t」を展開してみる。「t」が表現されているのは、Rbで1の位置である(位置は0からとする)。このとき、

rank_0(Rb, 1) = 0

なので、Rsの開始位置を0に設定する。つまり、Rbの開始位置を1とし、Rsの開始位置を0とする。ここからは、Rbを順番に探索して、0の数が1の数より大きくなった時点で探索を終了する。また、Rbが0の時は、Rsから文字を一つ取り出す。実際に探索してみる。Rbの1の位置と2の位置には、1があるので、1の数を2とする。Rbが3の位置から0が連続しているので、1の数が2だったので、0が2を超えるまで、Rsから順に文字を取り出すと、「abc」を取り出すことができる。これは、「t」を展開したことと等しい。

次にこのような簡潔表現を構築する方法について説明する。まず、辞書の各定義が別の定義から使われている数を数える。例の場合、以下のような回数となる。

s : 2
t : 1
u : 0

つまり、uはどの定義からも参照されていないことがわかる。このとき、どの定義からも参照されていないuを頂点として、再帰的に展開していく。Rbの0の位置に1を設定し、「u ---> ts」であるため、「t」を展開する。「t」は、展開可能であるため、Rbの1の位置に1を設定し、「t ---> sc」であるため、「s」を展開する。「s」は展開可能であるため、Rbの2の位置に1を設定する。「s ---> ab」の「a」と「b」はこれ以上展開できないため、Rbの3と4の位置に0を設定し、Rsの0と1の位置に「a」と「b」を設定する。次に、「t ---> sc」の「c」もこれ以上展開できないので、Rbの5の位置に0を設定し、Rsの2の位置に「c」を設定する。最後に、「u ---> ts」の「s」は、展開可能であるが、すでに表現されているので、Rbの6の位置に0を設定し、Rsには、その部分木の開始位置として、Rbの位置である2を設定する。圧縮文字列であるCについては、Rbの位置を使って表現する。

このように表現することで、辞書(R)の構造をRbを利用して、簡潔に表現できる。また、辞書(R)の「s t u」の展開後の文字列である「ab sc ts」の6文字は、冗長性を排除することで、Rsにおいて、4文字で表現することができる。Cは変わらない。また、Rbを完備辞書で表現すれば、ランダムアクセスも可能である。

ただし、辞書の簡潔表現は、一旦、Re-Pairの圧縮を行ってから辞書を圧縮する必要があると思うので、中間メモリは、簡潔にはならない。

次は、今回紹介した辞書の簡潔表現を使って、Re-Pairを利用した完備辞書についてまとめてみる。

Splunkを利用したテキストマイニングもどき

さて、前回の記事で、PerlからLTSV形式のフォーマットを扱う方法を書いた。

http://rn.hatenablog.com/entry/2013/12/07/012621

そのとき、自然言語処理の分野での適用をぼんやり考えていて、単語とか品詞とか簡単に集計できる仕組みがあると役立つかなと思った。現状、こういったことを簡単にやろうと思っても、それっぽい専用ソフトが必要なので、やりにくいかなと思う。

そこで、Jumanで抽出した形態素解析情報をLTSV形式で表現し、Splunkでビジュアルに扱う方法について書いてみたいと思う。現状、かなり試行錯誤だし、ベストプラクティスを発見できていないが、せっかく試したので書いてみる。というのも、Splunkをテキストマイニングっぽく使うというのは、あまり聞いたことがないからだ。

さて、Splunkというソフトを知っているだろうか?私も最近知ったが、主にログを解析するためのソフトである。日本だと、大手SIerが積極的に扱っている。ただし、大規模なデータを扱うのでなければ、フリーでも利用することができる。

例えば、日本語のホームページは以下にある。

http://ja.splunk.com/

右上にあるダウンロードボタンからダウンロードすることができる。プラットフォームは、WindowsとLinuxとMacなどがある。今回は、Cent OSを利用したので、32bitのLinux版をダウンロードした。ソースからでもrpmからでもどちらでもインストールすることができる。

データとしては、日本語のWikipediaの情報を利用した。Wikipediaからのテキストの抽出については、以下を参照してください。

http://rn.hatenablog.com/entry/2012/09/09/003001

まず、結論からすると、結果の画面は以下のようになった。

f:id:ryokkie:20131209022210p:plain

形態素をテキストごとに表示している。任意のキーワードで検索できるし、その形態素解析結果も見やすいのではないだろうか。

また、以下ののように、もう少し視覚的に、どの品詞がどのぐらい使われているか?ということも見ることができる。

f:id:ryokkie:20131209022223p:plain

さらに、上位10件を表示するコマンドを利用すると、グラフも一発で作成できる。

f:id:ryokkie:20131209022235p:plain

次に、どうやってこんな処理をSplunkで行うか?について説明しておく。私は、Jumanがけっこう好きなので、Jumanを利用したが、別にMeCabでもKyTeaでも問題ない。Splunk自体は、DWHと可視化がセットになっているだけなので、解析器自体はなんでも良い。

まず、Jumanを使って、解析結果を以下のようなLTSV形式にしておく。

base_file_name:txt/00027.txt    title:自然言語  line_no:3       str:「自然言語」という語は特に数式やプログラミング言語など人工的に定義された形式言語・人工言語に対比させる必要がある場合にこ う呼ばれる。    mrph_000_midasi:「      mrph_000_yomi:「        mrph_000_genkei:「      mrph_000_hinsi:特殊     mrph_000_hinsi_id:1     mrph_000_bunrui:括弧始  mrph_000_bunrui_id:3    mrph_000_katuyou1:*  mrph_000_katuyou1_id:0  mrph_000_katuyou2:*     mrph_000_katuyou2_id:0  mrph_000_imis:NIL       mrph_001_midasi:自然    mrph_001_yomi:しぜん    mrph_001_genkei:自然    mrph_001_hinsi:副詞  mrph_001_hinsi_id:8     mrph_001_bunrui:*       mrph_001_bunrui_id:0    mrph_001_katuyou1:*     mrph_001_katuyou1_id:0  mrph_001_katuyou2:*     mrph_001_katuyou2_id:0  mrph_001_imis:"代表表記:自然/しぜん 修飾(ト格)"    mrph_002_midasi:言語    mrph_002_yomi:げんご    mrph_002_genkei:言語    mrph_002_hinsi:名詞     mrph_002_hinsi_id:6     mrph_002_bunrui:普通 名詞    mrph_002_bunrui_id:1    mrph_002_katuyou1:*     mrph_002_katuyou1_id:0  mrph_002_katuyou2:*     mrph_002_katuyou2_id:0  mrph_002_imis:"代表表記:言語/げんご カテゴリ:抽象物"    mrph_003_midasi:」   mrph_003_yomi:」        mrph_003_genkei:」      mrph_003_hinsi:特殊     mrph_003_hinsi_id:1     mrph_003_bunrui:括弧終  mrph_003_bunrui_id:4    mrph_003_katuyou1:*     mrph_003_katuyou1_id:0       mrph_003_katuyou2:*     mrph_003_katuyou2_id:0  mrph_003_imis:NIL       mrph_004_midasi:と      mrph_004_yomi:と        mrph_004_genkei:と      mrph_004_hinsi:助詞  mrph_004_hinsi_id:9     mrph_004_bunrui:格助詞  mrph_004_bunrui_id:1    mrph_004_katuyou1:*     mrph_004_katuyou1_id:0  mrph_004_katuyou2:*     mrph_004_katuyou2_id:0  mrph_004_imis:NIL    mrph_005_midasi:いう    mrph_005_yomi:いう      mrph_005_genkei:いう    mrph_005_hinsi:動詞     mrph_005_hinsi_id:2     mrph_005_bunrui:*       mrph_005_bunrui_id:0    mrph_005_katuyou1:子 音動詞ワ行      mrph_005_katuyou1_id:12 mrph_005_katuyou2:基本形        mrph_005_katuyou2_id:2  mrph_005_imis:"代表表記:言う/いう 補文ト"       mrph_006_midasi:語      mrph_006_yomi:ご     mrph_006_genkei:語      mrph_006_hinsi:名詞     mrph_006_hinsi_id:6     mrph_006_bunrui:普通名詞        mrph_006_bunrui_id:1    mrph_006_katuyou1:*     mrph_006_katuyou1_id:0  mrph_006_katuyou2:*  mrph_006_katuyou2_id:0  mrph_006_imis:"代表表記:語/ご 漢字読み:音 カテゴリ:抽象物"      mrph_007_midasi:は      mrph_007_yomi:は        mrph_007_genkei:は      mrph_007_hinsi:助詞  mrph_007_hinsi_id:9     mrph_007_bunrui:副助詞  mrph_007_bunrui_id:2    mrph_007_katuyou1:*     mrph_007_katuyou1_id:0  mrph_007_katuyou2:*     mrph_007_katuyou2_id:0  mrph_007_imis:NIL    mrph_008_midasi:特に    mrph_008_yomi:とくに    mrph_008_genkei:特に    mrph_008_hinsi:副詞     mrph_008_hinsi_id:8     mrph_008_bunrui:*       mrph_008_bunrui_id:0    mrph_008_katuyou1:*  mrph_008_katuyou1_id:0  mrph_008_katuyou2:*     mrph_008_katuyou2_id:0  mrph_008_imis:"代表表記:特に/とくに 用言弱修飾" mrph_009_midasi:数式    mrph_009_yomi:すうしき  mrph_009_genkei:数式 mrph_009_hinsi:名詞     mrph_009_hinsi_id:6     mrph_009_bunrui:普通名詞        mrph_009_bunrui_id:1    mrph_009_katuyou1:*     mrph_009_katuyou1_id:0  mrph_009_katuyou2:*     mrph_009_katuyou2_id:0       mrph_009_imis:"代表表記:数式/すうしき カテゴリ:抽象物 ドメイン:教育・学習"      mrph_010_midasi:や      mrph_010_yomi:や        mrph_010_genkei:や      mrph_010_hinsi:助詞  mrph_010_hinsi_id:9     mrph_010_bunrui:接続助詞        mrph_010_bunrui_id:3    mrph_010_katuyou1:*     mrph_010_katuyou1_id:0  mrph_010_katuyou2:*     mrph_010_katuyou2_id:0  mrph_010_imis:NIL    mrph_011_midasi:プログラミング  mrph_011_yomi:ぷろぐらみんぐ    mrph_011_genkei:プログラミング  mrph_011_hinsi:名詞     mrph_011_hinsi_id:6     mrph_011_bunrui:サ変名詞        mrph_011_bunrui_id:2 mrph_011_katuyou1:*     mrph_011_katuyou1_id:0  mrph_011_katuyou2:*     mrph_011_katuyou2_id:0  mrph_011_imis:"代表表記:プログラミング/ぷろぐらみんぐ カテゴリ:抽象物 ドメイ ン:科学・技術"  mrph_012_midasi:言語    mrph_012_yomi:げんご    mrph_012_genkei:言語    mrph_012_hinsi:名詞     mrph_012_hinsi_id:6     mrph_012_bunrui:普通名詞        mrph_012_bunrui_id:1 mrph_012_katuyou1:*     mrph_012_katuyou1_id:0  mrph_012_katuyou2:*     mrph_012_katuyou2_id:0  mrph_012_imis:"代表表記:言語/げんご カテゴリ:抽象物"    mrph_013_midasi:など    mrph_013_yomi:など   mrph_013_genkei:など    mrph_013_hinsi:助詞     mrph_013_hinsi_id:9     mrph_013_bunrui:副助詞  mrph_013_bunrui_id:2    mrph_013_katuyou1:*     mrph_013_katuyou1_id:0  mrph_013_katuyou2:*  mrph_013_katuyou2_id:0  mrph_013_imis:NIL       mrph_014_midasi:人工    mrph_014_yomi:じんこう  mrph_014_genkei:人工    mrph_014_hinsi:名詞     mrph_014_hinsi_id:6     mrph_014_bunrui:普通名詞     mrph_014_bunrui_id:1    mrph_014_katuyou1:*     mrph_014_katuyou1_id:0  mrph_014_katuyou2:*     mrph_014_katuyou2_id:0  mrph_014_imis:"代表表記:人工/じんこう カテゴリ:抽象物"       mrph_015_midasi:的に    mrph_015_yomi:てきに    mrph_015_genkei:的だ    mrph_015_hinsi:接尾辞   mrph_015_hinsi_id:14    mrph_015_bunrui:形容詞性名詞接尾辞      mrph_015_bunrui_id:6 mrph_015_katuyou1:ナ形容詞      mrph_015_katuyou1_id:21 mrph_015_katuyou2:ダ列基本連用形        mrph_015_katuyou2_id:7  mrph_015_imis:"代表表記:的だ/てきだ 準内容語 カテゴリ:抽象物"   mrph_016_midasi:定義 mrph_016_yomi:ていぎ    mrph_016_genkei:定義    mrph_016_hinsi:名詞     mrph_016_hinsi_id:6     mrph_016_bunrui:サ変名詞        mrph_016_bunrui_id:2    mrph_016_katuyou1:*  mrph_016_katuyou1_id:0  mrph_016_katuyou2:*     mrph_016_katuyou2_id:0  mrph_016_imis:"代表表記:定義/ていぎ カテゴリ:抽象物 ドメイン:科学・技術"        mrph_017_midasi:さ      mrph_017_yomi:さ     mrph_017_genkei:する    mrph_017_hinsi:動詞     mrph_017_hinsi_id:2     mrph_017_bunrui:*       mrph_017_bunrui_id:0    mrph_017_katuyou1:サ変動詞      mrph_017_katuyou1_id:16 mrph_017_katuyou2:未然形     mrph_017_katuyou2_id:3  mrph_017_imis:"代表表記:する/する 付属動詞候補(基本) 自他動詞:自:成る/なる"   mrph_018_midasi:れた    mrph_018_yomi:れた      mrph_018_genkei:れる mrph_018_hinsi:接尾辞   mrph_018_hinsi_id:14    mrph_018_bunrui:動詞性接尾辞    mrph_018_bunrui_id:7    mrph_018_katuyou1:母音動詞      mrph_018_katuyou1_id:1  mrph_018_katuyou2:タ 形      mrph_018_katuyou2_id:10 mrph_018_imis:"代表表記:れる/れる"      mrph_019_midasi:形式    mrph_019_yomi:けいしき  mrph_019_genkei:形式    mrph_019_hinsi:名詞     mrph_019_hinsi_id:6  mrph_019_bunrui:普通名詞        mrph_019_bunrui_id:1    mrph_019_katuyou1:*     mrph_019_katuyou1_id:0  mrph_019_katuyou2:*     mrph_019_katuyou2_id:0  mrph_019_imis:"代表表記:形式/けいしき カテゴリ:抽象物"       mrph_020_midasi:言語    mrph_020_yomi:げんご    mrph_020_genkei:言語    mrph_020_hinsi:名詞     mrph_020_hinsi_id:6     mrph_020_bunrui:普通名詞        mrph_020_bunrui_id:1 mrph_020_katuyou1:*     mrph_020_katuyou1_id:0  mrph_020_katuyou2:*     mrph_020_katuyou2_id:0  mrph_020_imis:"代表表記:言語/げんご カテゴリ:抽象物"    mrph_021_midasi:・      mrph_021_yomi:・     mrph_021_genkei:・      mrph_021_hinsi:特殊     mrph_021_hinsi_id:1     mrph_021_bunrui:記号    mrph_021_bunrui_id:5    mrph_021_katuyou1:*     mrph_021_katuyou1_id:0  mrph_021_katuyou2:*  mrph_021_katuyou2_id:0  mrph_021_imis:NIL       mrph_022_midasi:人工    mrph_022_yomi:じんこう  mrph_022_genkei:人工    mrph_022_hinsi:名詞     mrph_022_hinsi_id:6     mrph_022_bunrui:普通名詞     mrph_022_bunrui_id:1    mrph_022_katuyou1:*     mrph_022_katuyou1_id:0  mrph_022_katuyou2:*     mrph_022_katuyou2_id:0  mrph_022_imis:"代表表記:人工/じんこう カテゴ リ:抽象物"      mrph_023_midasi:言語    mrph_023_yomi:げんご    mrph_023_genkei:言語    mrph_023_hinsi:名詞     mrph_023_hinsi_id:6     mrph_023_bunrui:普通名詞        mrph_023_bunrui_id:1 mrph_023_katuyou1:*     mrph_023_katuyou1_id:0  mrph_023_katuyou2:*     mrph_023_katuyou2_id:0  mrph_023_imis:"代表表記:言語/げんご カテゴリ:抽象物"    mrph_024_midasi:に      mrph_024_yomi:に     mrph_024_genkei:に      mrph_024_hinsi:助詞     mrph_024_hinsi_id:9     mrph_024_bunrui:格助詞  mrph_024_bunrui_id:1    mrph_024_katuyou1:*     mrph_024_katuyou1_id:0  mrph_024_katuyou2:*  mrph_024_katuyou2_id:0  mrph_024_imis:NIL       mrph_025_midasi:対比    mrph_025_yomi:たいひ    mrph_025_genkei:対比    mrph_025_hinsi:名詞     mrph_025_hinsi_id:6     mrph_025_bunrui:サ変名詞     mrph_025_bunrui_id:2    mrph_025_katuyou1:*     mrph_025_katuyou1_id:0  mrph_025_katuyou2:*     mrph_025_katuyou2_id:0  mrph_025_imis:"代表表記:対比/たいひ カテゴリ:抽象物" mrph_026_midasi:さ      mrph_026_yomi:さ        mrph_026_genkei:する    mrph_026_hinsi:動詞     mrph_026_hinsi_id:2     mrph_026_bunrui:*       mrph_026_bunrui_id:0    mrph_026_katuyou1:サ 変動詞  mrph_026_katuyou1_id:16 mrph_026_katuyou2:未然形        mrph_026_katuyou2_id:3  mrph_026_imis:"代表表記:する/する 付属動詞候補(基本) 自他動詞:自:成る/なる"   mrph_027_midasi:せる mrph_027_yomi:せる      mrph_027_genkei:せる    mrph_027_hinsi:接尾辞   mrph_027_hinsi_id:14    mrph_027_bunrui:動詞性接尾辞    mrph_027_bunrui_id:7    mrph_027_katuyou1:母音動詞      mrph_027_katuyou1_id:1       mrph_027_katuyou2:基本形        mrph_027_katuyou2_id:2  mrph_027_imis:"代表表記:せる/せる"      mrph_028_midasi:必要    mrph_028_yomi:ひつよう  mrph_028_genkei:必要 だ      mrph_028_hinsi:形容詞   mrph_028_hinsi_id:3     mrph_028_bunrui:*       mrph_028_bunrui_id:0    mrph_028_katuyou1:ナノ形容詞    mrph_028_katuyou1_id:22 mrph_028_katuyou2:語幹  mrph_028_katuyou2_id:1       mrph_028_imis:"代表表記:必要だ/ひつようだ 反義:形容詞:不要だ/ふようだ"  mrph_029_midasi:が      mrph_029_yomi:が        mrph_029_genkei:が      mrph_029_hinsi:助詞  mrph_029_hinsi_id:9     mrph_029_bunrui:格助詞  mrph_029_bunrui_id:1    mrph_029_katuyou1:*     mrph_029_katuyou1_id:0  mrph_029_katuyou2:*     mrph_029_katuyou2_id:0  mrph_029_imis:NIL    mrph_030_midasi:ある    mrph_030_yomi:ある      mrph_030_genkei:ある    mrph_030_hinsi:動詞     mrph_030_hinsi_id:2     mrph_030_bunrui:*       mrph_030_bunrui_id:0    mrph_030_katuyou1:子 音動詞ラ行      mrph_030_katuyou1_id:10 mrph_030_katuyou2:基本形        mrph_030_katuyou2_id:2  mrph_030_imis:"代表表記:有る/ある 補文ト 反義:形容詞:無い/ない" mrph_031_midasi:場合    mrph_031_yomi:ばあい mrph_031_genkei:場合    mrph_031_hinsi:名詞     mrph_031_hinsi_id:6     mrph_031_bunrui:副詞的名詞      mrph_031_bunrui_id:9    mrph_031_katuyou1:*     mrph_031_katuyou1_id:0       mrph_031_katuyou2:*     mrph_031_katuyou2_id:0  mrph_031_imis:"代表表記:場合/ばあい"    mrph_032_midasi:に      mrph_032_yomi:に        mrph_032_genkei:に      mrph_032_hinsi:助詞  mrph_032_hinsi_id:9     mrph_032_bunrui:格助詞  mrph_032_bunrui_id:1    mrph_032_katuyou1:*     mrph_032_katuyou1_id:0  mrph_032_katuyou2:*     mrph_032_katuyou2_id:0  mrph_032_imis:NIL    mrph_033_midasi:こう    mrph_033_yomi:こう      mrph_033_genkei:こう    mrph_033_hinsi:指示詞   mrph_033_hinsi_id:7     mrph_033_bunrui:副詞形態指示詞  mrph_033_bunrui_id:3    mrph_033_katuyou1:*  mrph_033_katuyou1_id:0  mrph_033_katuyou2:*     mrph_033_katuyou2_id:0  mrph_033_imis:NIL       mrph_034_midasi:呼ば    mrph_034_yomi:よば      mrph_034_genkei:呼ぶ    mrph_034_hinsi:動詞  mrph_034_hinsi_id:2     mrph_034_bunrui:*       mrph_034_bunrui_id:0    mrph_034_katuyou1:子音動詞バ行  mrph_034_katuyou1_id:8  mrph_034_katuyou2:未然形        mrph_034_katuyou2_id:3       mrph_034_imis:"代表表記:呼ぶ/よぶ"      mrph_035_midasi:れる    mrph_035_yomi:れる      mrph_035_genkei:れる    mrph_035_hinsi:接尾辞   mrph_035_hinsi_id:14    mrph_035_bunrui:動詞 性接尾辞        mrph_035_bunrui_id:7    mrph_035_katuyou1:母音動詞      mrph_035_katuyou1_id:1  mrph_035_katuyou2:基本形        mrph_035_katuyou2_id:2  mrph_035_imis:"代表表記:れる/れる"   mrph_036_midasi:。      mrph_036_yomi:。        mrph_036_genkei:。      mrph_036_hinsi:特殊     mrph_036_hinsi_id:1     mrph_036_bunrui:句点    mrph_036_bunrui_id:1    mrph_036_katuyou1:*  mrph_036_katuyou1_id:0  mrph_036_katuyou2:*     mrph_036_katuyou2_id:0  mrph_036_imis:NIL

ちなみに、PerlからJumanを利用する場合は、Juman.pmを利用するのが便利である。それについては、別の記事で書く。

さて、こんな感じでLTSV形式のフォーマットを用意したら、Splunkで読み込むだけである。ただし、Splunkは、LTSV形式のファイルを読み込むことができないので、自分で解析フォーマットを用意する。解析フォーマットは、以下を参考にした。

https://gist.github.com/takscape/4736182

ただし、このままだと、genkeiとかがすべて分かれたものしかできないので、マージしたファセット項目を作成した方が良い。結局、以下のようにする。

# props.conf
[ltsv]
NO_BINARY_CHECK = 1
REPORT-ltsv = ltsv-extractions
REPORT-genkei = jgenkei-extractions
REPORT-hinsi = jhinsi-extractions
REPORT-bunrui = jbunrui-extractions
SHOULD_LINEMERGE = false
TIME_FORMAT = %d/%b/%Y:%H:%M:%S %z
TIME_PREFIX = time:
pulldown_type = 1

# transforms.conf
[ltsv-extractions]
REGEX = (?:^|\t)([0-9A-Za-z_.-]+):([^\t]*)(?:\t|$)
FORMAT = $1::$2
KEEP_EMPTY_VALS = true
CLEAN_KEYS = 0

[jgenkei-extractions]
REGEX = (?:^|\t)(mrph_[0-9]+_genkei):([^\t]*)(?:\t|$)
FORMAT = genkei::$2
REPEAT_MATCH = true
KEEP_EMPTY_VALS = true
CLEAN_KEYS = 0
MV_ADD = 1

[jhinsi-extractions]
REGEX = (?:^|\t)(mrph_[0-9]+_hinsi):([^\t]*)(?:\t|$)
FORMAT = hinsi::$2
REPEAT_MATCH = true
KEEP_EMPTY_VALS = true
CLEAN_KEYS = 0
MV_ADD = 1

[jbunrui-extractions]
REGEX = (?:^|\t)(mrph_[0-9]+_bunrui):([^\t]*)(?:\t|$)
FORMAT = bunrui::$2
REPEAT_MATCH = true
KEEP_EMPTY_VALS = true
CLEAN_KEYS = 0
MV_ADD = 1

これを、以下のフォルダの2つのファイル追加する。なければ、ファイルを作成する。

/opt/splunk/etc/system/local/props.conf
/opt/splunk/etc/system/local/transforms.conf

これで、あとは、LTSV形式にしたWikipediaのデータを読み込むとSplunkの機能で検索したり、集計したり、グラフ作ったりできるようになる。ちなみに、Splunkは、UnixコマンドとSQLを足して2で割ったような操作性であり、そこにstatsコマンドという統計処理用のコマンドで機能を強化している。コマンドリファレンスは、以下にあるので、参考にしてみてください。

http://docs.splunk.com/images/7/78/SearchReference_JA_502.pdf

Splunkの本来の用途であるログ解析から離れて、テキストマイニングもどきに強引に適用してみるということをやってみた。今回は、Wikipediaのデータでやってみたが、時系列が重要なデータだとより良いと思う。というのも、Splunk自体は、時刻を自動でキーにして、時系列の変化を自動でグラフ化してくれるからだ。それを考えると、Twitterなどのデータの方がもっと有益かもしれない。

Perlメモ(2)

Perlを触りだすと、自分のネイティブプログラミング言語は、Perlだなと実感します。ただ、Perlに限らず、プログラムは好きなので、9時~17時の労働で、プログラムだけ書いて適当に過ごせないものかと思うが、日本では難しいようだ。がんばるしかない。

さて、自分は、学生の時から入力ファイルと出力ファイルを残しながらプログラムを作っていくということをやっている。どういうことかというと、

cat input1.txt | ./1.pl > output1.txt
cat output1.txt | ./2.pl > output2.txt
cat output2.txt | ./3.pl > output3.txt

みたいな感じで、中間結果を残しつつ加工している。もちろん、業務で必要とされているプログラムでこんなことはしない。ただ、研究の時のように、結果を見ながら試行錯誤が必要なプログラムでは、このようなやり方の方が、中間結果をいつでも確認できて、都合が良い。

しかし、このスタイルの問題点として、中間結果のフォーマットを決めるのがめんどうだということがある。例えば、CSVだと、地味にParser書くのがめんどうだし、tsvだと、フォーマットの間に値を格納したくなった場合に、後のプログラムを全部直さなくてはならなくてなかなかめんどうである。

そんな時に、LTSV形式というフォーマットに出会いました。

http://ltsv.org/

このフォーマットがなかなか便利である。良い点は、以下の記事にまとまっている。

http://d.hatena.ne.jp/naoya/20130209/1360381374

さて、Perlで扱う場合は、Text::LTSVというcpanモジュールを利用するのが便利である。

http://search.cpan.org/~naoya/Text-LTSV-0.07/lib/Text/LTSV.pm

では、この形式を自然言語処理に応用するとどうなるか?というのを明日やってみよう。うん。眠い。