2015/10/17
JapanesePhoneticAnalyzerを使ってPowerShellで形態素解析(前編)
はじめに
がりっち氏がWindows10 UWPに日本語解析のAPIが備わっていた件 | garicchi.com というエントリを上げていました。
実はWin10に限らず、Win8.1 / Server 2012R2以降であれば、Windows ランタイム(WinRT)のWindows.Globalization名前空間に含まれるJapanesePhoneticAnalyzerクラスを用いた形態素解析ができます。
形態素解析とは要するに文字列を単語(正確には形態素という、文字列の最小構成要素)ごとに分割し、それぞれの単語の品詞を判別する処理になります。(JapanesePhoneticAnalyzerクラスだと分割までで、品詞の情報は取得できない?ようですが…)
またJapanesePhoneticAnalyzerでは分割した単語の読み仮名を取得することができます。
WinRTならPowerShellからも使えるんじゃないかなーと思ってやったらできたので、紹介します。
WinRTのPowerShellからの利用法
WinRTについての説明は他サイト様に譲りますが、要はWindowsストアアプリやUWP(ユニバーサルWindowsプラットフォーム)アプリを動作させる実行環境とAPI群です。
じゃあデスクトップアプリであるPowerShellは関係ないのかというとそうではなくて、例えばストアアプリのサイドローディングを行うAppxモジュールというものがあります。
つまりWinRTは従来のデスクトップアプリからの相互運用もできるようになっています。(すべてのコンポーネントではない)
このあたりの話は、荒井さんの記事が参考になるかと思います。:特集:デスクトップでもWinRT活用:開発者が知っておくべき、ライブラリとしてのWindowsランタイム (1/5) - @IT
PowerShellからWinRTを利用するには.NET Frameworkに含まれるクラスを利用するのと基本は同じです。
ただし注意点としては、クラス名を指定する時は、クラスの「アセンブリ修飾名」を指定する必要があります。
今回の例ではJapanesePhoneticAnalyzerクラスを使いますが、アセンブリ修飾名はWindows.Globalization.JapanesePhoneticAnalyzer, Windows.Globalization, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime
となります。
このうち必須となるのは
Windows.Globalization.JapanesePhoneticAnalyzer:クラスの完全修飾名
Windows.Globalization:クラスの含まれる名前空間
ContentType=WindowsRuntime:WinRTのコンポーネントであること
の3つだけのようです。
つまり、PowerShellからは
[Windows.Globalization.JapanesePhoneticAnalyzer, Windows.Globalization, ContentType=WindowsRuntime]
とすればクラスを参照することができます。
ちなみに任意の型のアセンブリ修飾名を知るには、[型名].AssemblyQualifiedName のようにすればOKです。
なお、WinRTにはPowerShellからも利用価値の高いクラスが他にも色々あるようです。ぎたぱそ氏が認証系のクラスについて書かれていますので、参考にしてみてください。:PowerShell も Windows Store Apps 同様に Windows.Security.Credentials namespace を使って認証情報を管理できるようにしてみる - tech.guitarrapc.com
単語を分割する
早速、形態素解析をやってみましょう。具体的にはJapanesePhoneticAnalyzerのGetWordsメソッドを呼び出すだけです。
すべての基本になるので軽く関数としてラップしておきます。
function Get-JpWord { param( [parameter(ValueFromPipeline=$true)] [ValidateLength(1,99)] [string[]] $Text, [switch] $MonoRuby ) process { foreach($t in $Text) { [Windows.Globalization.JapanesePhoneticAnalyzer, Windows.Globalization, ContentType=WindowsRuntime]::GetWords($t, $MonoRuby) } } }
GetWordsメソッドはスタティックメソッドなので、::演算子で呼び出します。戻り値はIReadOnlyList<JapanesePhoneme>というコレクションです。
GetWordsメソッドの第2引数にTrueを指定すると、漢字の含まれた単語をルビの振れる最小単位にまで分割する、Mono Rubyモードが有効になります。
なお、GetWordsメソッドはどうも文字数制限があるようです。だいたい100文字を超えると何も出力しない感じです。この制限値はリファレンスに書いてないようなので詳細不明ですが、一応関数では99文字までという制限を入れておきました。
例えば、Get-JpWord "最近急に寒くなってきました。" のようにすると結果は以下のように表示されます。
DisplayText IsPhraseStart YomiText ----------- ------------- -------- 最近 True さいきん 急に True きゅうに 寒くな True さむくな って False って き True き ました False ました 。 True 。
出力されるJapanesePhonemeオブジェクトは3つのプロパティを持ちます。
DisplayText | 分割された単語 |
IsPhraseStart | 単語が文節の開始であるかどうか |
YomiText | 単語の読み仮名 |
このように、入力した文章を単語単位に分割し、それぞれの単語の読み仮名を取得することができます。ただこれだけだと、「で、どうしろと」という感じなので、この出力結果を利用する、より実用的な関数を書いていきましょう。
長くなったので次回に続く。
2011/05/05
stringを引数に取るメソッドに$nullを渡すと勝手にstring.Emptyに変換されてしまう
仕様みたいです。以下、検証コード。
$def = @" public static string TestMethod(string str) { if(str==null) { return "null"; } else if(str==string.Empty) { return "empty"; } else { return "other"; } } "@ $test = Add-Type -memberDefinition $def -name "TestClass" -passThru $test::TestMethod($null)
結果は「null」ではなく「empty」になってしまいます。
Windows Phone 7 エミュレーターをビルド後アクティブにする « LiveSpac.esのコメント欄でも書いたのですが、回避策はリフレクション経由でメソッドを呼ぶしかなさそうです。
$test.GetMethod("TestMethod").Invoke($null, @($null))
このように、Invokeメソッドの第一引数はスタティックメソッドの実行なのでインスタンスを指定しないので$null、第二引数はメソッドに与える引数の配列を指定します。ここでは引数は一つ、その値は$nullなので、@($null)を指定します。このようにすると結果は「null」となり意図した結果が得られます。
元記事:http://blogs.wankuma.com/mutaguchi/archive/2011/05/05/198785.aspx2011/04/26
PowerShellでJScript.NETのコードを実行する
PowerShell 2.0ではAdd-Typeコマンドレットを用いてC#など他言語のコードをコンパイルし実行することが可能です。(P/Invokeも可能です)
ほとんど使っている方はいないと思われますが、JScript.NETのコードもコンパイルして実行できます。以下、コード例です。
$code=@" static function writeHello() { System.Console.WriteLine("Hello JScript.NET World!"); } "@ $c = Add-Type -Language JScript -MemberDefinition $code -Name "JSTest" -PassThru $c[1]::writeHello()
JScript.NETのスタティックメソッドを用意してやると、Add-Typeコマンドレットによりそのメソッドを持ったクラス(ここではMicrosoft.PowerShell.Commands.AddType.AutoGeneratedTypes.JSTest)が生成されます。-passThruパラメータを指定することでその型情報が変数に代入できます。あとはJSTestクラスのスタティックメソッドを::演算子で呼び出すのですが、なぜかAdd-Typeが目的のクラスの型以外にJScript.NETのグローバルクラス?の型情報も一緒に出力するので、型情報が配列になっています。よってインデックスを指定してからスタティックメソッドを呼ぶようにします。
ここではスタティックメソッドを実行する例を挙げましたが、インスタンスメソッドも実行できるか試してみました。
$code=@" import System; public class JSTest { public function writeHello() { Console.WriteLine("Hello JScript.NET World!"); } } "@ Add-Type -Language JScript -TypeDefinition $code $o = new-object JSTest $o.writeHello()
ところがこれはNew-Objectのところで「New-Object : "0" 個の引数を指定して ".ctor" を呼び出し中に例外が発生しました: "アプリケーションでエラーが発生しました。"」というエラーになってしまいます。コンストラクタの実行でしくっているようですが…。ちなみに明示的にfunction JSTest()というコンストラクタを定義してやってもだめでした。なんででしょうね?
元記事:http://blogs.wankuma.com/mutaguchi/archive/2011/04/26/198645.aspx2008/03/17
[IronPython].Net Frameworkメソッド呼び出し urllibの代替
IronPythonもちょっとやろうと思いまして、荒井さんのIronPythonの世界などを読みつつ研究。 Python2.5ではファイルのダウンロードは組み込みライブラリのurllibを使うのが定番みたいです。
#!/usr/bin/python import urllib url = 'http://img.yahoo.co.jp/images/main7.gif' dest = 'D:\\script\\test.gif' file = urllib.urlopen(url).read() try : f=open(dest, "wb") f.write(file); f.close except : print "file error."
(20:35追記)このpyスクリプトの元ネタはhttp://www.geocities.jp/mirrorhenkan/python/getimg.py.txtです。作者さんに転載の了承を得ています。トップページhttp://www.geocities.jp/mirrorhenkan/からもいろいろ面白いコンテンツに飛べます。
IronPython 1.1.1ではurllibが含まれておらず、Python2.5.2に含まれているライブラリを使うのも互換性の問題で難しいようです。
import sys sys.path.append("C:\\Program Files\\Python25\\lib")
なんて頭につけてもエラーになります。
でもIronPythonは.NET Framework上で動作する言語なので、これらのライブラリに含まれるクラスが使えます。System.Net.WebClientを使いましょう。なお、System.Net名前空間に含まれるクラスはデフォルトでロードされているので、
import clr clr.AddReference("System.Net")
などとする必要はありません。これはPowerShellと同様です。
from System.Net import * url = 'http://img.yahoo.co.jp/images/main7.gif' dest = 'D:\\script\\test.gif' wc = WebClient() wc.DownloadFile(url, dest)
こんな感じ。最初、DownloadFileがスタティックメソッドと勘違いしていて、インスタンスを作る(wc = WebClient())のを忘れてうまく動かなかったですw
元記事:http://blogs.wankuma.com/mutaguchi/archive/2008/03/17/128160.aspx
Copyright © 2005-2018 Daisuke Mutaguchi All rights reserved
mailto: mutaguchi at roy.hi-ho.ne.jp
プライバシーポリシー