Rubyで形態素解析
最初はMeCab+nattoで試したのですが、MeCabのサイトで公開されているライブラリは64bit Rubyでは動作しませんでした。他はないのかと検索したところ、こちらでRubyによる形態要素エンジンokura(注:ocraではない)が公開されていましたので早速インストール。
公開サイトでは、ruby1.9専用と書かれていますが、こちらの動作環境(Windows 10 64bit / ruby 2.2.3p173 (2015-08-18 revision 51636) [x64-mingw32])でも問題は無い様です。
公開サイトおよび入手先
- Rubyによる形態素解析エンジンokura 0.0.1をリリースしました - <s>gnarl,</s>技術メモ”’<marquee><textarea>¥
- NAIST Japanese Dictionary
導入
- okuraのインストール
gem install okura
okura compile mecab-naist-jdic-0.6.3b-20111013/ okura-dic
公開サイトのサンプルプログラムの実行
okuraは文字コードutf-8を使用するので、入出力でcp932(Windows-31J)とのエンコードが必要
#coding: cp932 require 'okura/serializer' dict_dir='./okura-dic' # コンパイルした辞書フォルダの置き場所 tagger=Okura::Serializer::FormatInfo.create_tagger dict_dir str='すもももももももものうち'.encode('utf-8') # 文字列から単語候補を計算 nodes=tagger.parse(str) # 単語候補の中で、一番最もらしい組み合わせを選択 nodes.mincost_path.each{|node| word=node.word s = (' ' + word.surface.encode('cp932'))[-5..-1] # 空白は全角スペース s << ' ' s << word.left.text.encode('cp932') puts s # word.surface # : 単語の表記 # puts word.left.text # : 品詞 # 品詞はword.leftとword.rightがありますが、一般的に使われる辞書(IPA辞書やNAIST辞書)では # 両方同じデータが入ってます }
実行結果
C:\okura>ruby test.rb 1589586 S/EOS BOS/EOS すもも 名詞,一般,*,*,*,*,* も 助詞,係助詞,*,*,*,*,も もも 名詞,一般,*,*,*,*,* も 助詞,係助詞,*,*,*,*,も もも 名詞,一般,*,*,*,*,* の 助詞,連体化,*,*,*,*,の うち 名詞,非自立,副詞可能,*,*,*,* S/EOS BOS/EOS
RubyGemsが使用できない
RubyGemsを使用しようとして、ここ数日使用できなくなっていることに気が付きました。
発生を確認したのはRubyInstallerのruby2.1.4とRumix2のruby2.0.0です。
C:\>gem search rails *** REMOTE GEMS *** (結果が表示されない) C:\>gem update --system ERROR: While executing gem ... (Gem::RemoteFetcher::FetchError) SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (https://api.rubygems.org/specs.4.8.gz)
軽く検索したら12月の頭頃にサーバが落ちたみたいな記録がみつかったので、それが継続しているのかと思いましたが、どうもそうではないらしい。
エラーメッセージで検索したらSSLのアップデートに関する変更があったらしいです。とりあえずここの記述に従って、new trust certificateファイルを入手して指定のディレクトリにコピーしたら使用できるようになりました。
MinGW環境としてRumix2のDevKitを使用する。
Ruby/Tkの勉強環境としてインストールしたRumix2は、(選択すると)同時にDevKitがインストールされます。これはrubygemsでruby関連のツールをインストールするときにコンパイルが必要な場合に使用される環境です。DevKit中を覗くとMinGWで使用するツール類がかなり揃っているようで、自分がCやC++の勉強に使用する分には充分のようです。
というわけでオリジナルのMinGW+MSYSの環境は削除してこちらを使用することにしました。以前MinGWの環境構築時に作成したstart.batを以下の様に書き換えました。C:\Rumix2は、Rumix2のインストール先になります。
start.bat
@echo off rem use MinGW on rumix2's devkit set PATH=C:\rumix2\ruby\devkit-mingw64-32\bin;C:\rumix2\ruby\devkit-mingw64-32\mingw\bin;%PATH% set C_INCLUDE_PATH=C:\rumix2\ruby\devkit-mingw64-32\include;C:\rumix2\ruby\devkit-mingw64-32\mingw\include set CPLUS_INCLUDE_PATH=C:\rumix2\ruby\devkit-mingw64-32\include;C:\rumix2\ruby\devkit-mingw64-32\mingw\include set LIBRARY_PATH=C:\rumix2\ruby\devkit-mingw64-32\lib;C:\rumix2\ruby\devkit-mingw64-32\mingw\lib set MINGW_DIR=C:\rumix2\ruby\devkit-mingw64-32\mingw bash -rcfile bash_profile
Ruby/Tk サブウィンドウの作成
サブウィンドウ用のメソッドopen_sub_windowを作成して、このメソッド内でサブウィンドウのウィジェットを配置して作成します。
ルートウィンドウ側との情報のやり取りについて、最初はメソッドの引数と返り値で行おうとしましたが、メソッド自体は直ぐに終了してしまうため不可でした。この為グローバル変数$swによって行う様にします。
サブウィンドウのベースはTkToplevelを使用します。またサブウィンドウを開いている間にルートウィンドウへの操作を不可にするために、TkToplevel#grab_setを実行します。サブウィンドウ閉じるときは、TkToplevel#destroyを実行。
続きを読むRuby/Tk TkVariableの使用
ウィジェットで変化する値を使用する場合にはTkVariabeを使用する。TkVariableの値が変化すると、その変数を参照しているウィジェット上の表示が即時変化する。
TkVariable#new_hashとするとHashとして使用できる。この場合にはウィジェット内で使用する場合には、TkVariable#ref(key)とする。
#coding: Windows-31J require "tk" root = TkRoot.new do title 'TkVariable Test' geometry '300x150+100+100' # 親ウィンドウのサイズと位置 end d0 = TkLabel.new(root, text:'下段の入力文字が上段に即時反映される') d0.pack v1 = TkVariable.new('Label1') d1 = TkLabel.new(root) do textvariable v1 pack(anchor: :w) # 表示を左寄せにする(w: west) end e1 = TkEntry.new(root) do textvariable v1 pack(fill: :x) end TkLabel.new.pack # TkVariableをHashとして使用 v2 = TkVariable.new_hash(str: 'Label2') # HashへのアクセスはTkVariable#ref(key)を使用する d2 = TkLabel.new(root) do textvariable v2.ref(:str) pack(anchor: :w) end e2 = TkEntry.new(root) do textvariable v2.ref(:str) pack(fill: :x) end Tk.mainloop
Ruby/Tk ウィジェットへのパラメータ指定方法
サンプルをみると書き方がいろいろあって混乱するのでメモ
#coding: windows-31J require 'tk' # Widjetのパラメータの指定方法 # newの引数として指定する方法 # 第1引数は親ウィジェット # 第2引数以降はHashのキーと値 # キーはStringでもSymbolでもOK # 値も定数はSymbolでOK TkButton.new(nil, text:'ボタン1', command:proc{puts 'Button 1 Pushed'}).pack(fill: :x) #TkButton.new(nil, 'text'=>'ボタン1', 'command'=>proc{puts 'Button 1 Pushed'}).pack('fill'=>'x') # blockとして指定する方法 TkButton.new(nil) do text( 'ボタン2' ) # 丸カッコは省略可 command( proc{puts 'Button 2 Pushed'} ) pack(fill: :x) end # インスタンスのメソッドとして指定する方法 b3 = TkButton.new(nil) # 値を代入 b3.text = 'ボタン3' b3.command = proc{puts 'Button 3 Pushed'} # 値を引数としても渡せる #b3.text( 'ボタン3' ) # 丸カッコは省略可 #b3.command( proc{puts 'Button 3 Pushed'} ) b3.pack(fill: :x) Tk.mainloop
Ruby/Tkプログラムのexe化
Rumix2環境でのocraを使用したexe化は以下の要領で。
VisualuRubyに比べてファイルサイズが大きくなって、起動が遅くなるのがちょっと残念です。
$ ocra xx.rb C:/rumix2/ruby/2.0.0/i386-mingw32/lib/tcltk --windows --no-autoload --add-all-core