前回までの記事はこちらです。
前回は Translation Glossary を辞書代わりに使用して、英語版の Group Policy Settings Reference for Windows and Windows Server を日本語に変換してみました。Translatiion Glossary で使用されている文章および用語と、Group Policy Settings Reference で使用されているものが微妙に異なる場合があり、以下に示すように残念ながら完全ではありませんでした。
そこで、変換できなかった英語部分をどうしたらよいか...機械翻訳で補足してしまおう!というのが今回の趣旨です。
実は、BING を使用した機械翻訳 API については、1年近く前に田辺さんが紹介してくださっています。せっかくですので、以下で紹介されているスクリプトをベースに作りましょう~。(田辺さん、ありがとう!)
Windows PowerShell でのスクリプティング - スクリプトセンター Microsoft Translator の API を使ってみよう - Shigeya Tanabe's blog - Site Home - TechNet Blogs
【準備】
BING の翻訳 API を使用するには、事前に AppID と呼ばれるアプリケーションのIDが必要です。これが発行されていないとAPIからの要求が拒否されてしまいます。 AppID を要求するには、以下のサイトから必要事項を入力してください。 http://www.bing.com/developers/createapp.aspx 一番下のボタン[Agree] をクリックすると、以下のようにAppIDが発行されます。
BING の翻訳 API を使用するには、事前に AppID と呼ばれるアプリケーションのIDが必要です。これが発行されていないとAPIからの要求が拒否されてしまいます。
AppID を要求するには、以下のサイトから必要事項を入力してください。
http://www.bing.com/developers/createapp.aspx
一番下のボタン[Agree] をクリックすると、以下のようにAppIDが発行されます。
【スクリプトを作成する】
今回作成するスクリプトの方針は、「Translation Glossary」とマッチしなかった英文/用語に対して BING 翻訳 するようにします。ですので、前回同様、以下の3つのファイルを用意しておいてください。 Translationg Glossary で提供されている Windows 7 の Glossary jpn-jpn-csv-Windows 7 (1).csv Group Policy Settings Reference for Windows and Windows Serverの「Administrative Template」タブをCSVで保存したファイル WindowsServer2008R2andWindows7GroupPolicySettings_AdministrativeTemplate.csv Group Policy Settings Reference for Windows and Windows Serverの「Security」タブをCSVで保存したファイル WindowsServer2008R2andWindows7GroupPolicySettings_security.csv 田辺さんのスクリプトと前回作成したスクリプトを合体させて、すこしアレンジしたものが以下です。 # Get-Transaction という機械翻訳用のFunctionを定義しています。 # Function の中では、"http://api.microsofttranslator.com/V2/Http.svc/Translate" というメソッドを使用して、 # この Function に引数として渡されたテキスト文字列を翻訳しています function Get-Translation { param([parameter(ValueFromPipeline=$true)] [String] $text = "Group Policy") $w = new-object system.net.webclient $enc = [Text.Encoding]::GetEncoding("utf-8") # AppID を指定 $appid = "CExxxxxxxxxxxxxxxxxxxxxxxxxxxx0B19" # 翻訳もとは英語 $from = "en" # 翻訳先は日本語 $to = "ja" $contentType = "text/plain" $category = "general" # BING翻訳 Translate メソッドの uri $api = "http://api.microsofttranslator.com/V2/Http.svc/Translate" $url = "{0}?appID={1}&from={2}&to={3}&text={4}&contentType={5}&category={6}" -f $api, $appid, $from, $to, $text, $contentType, $category $h = $enc.GetString($w.DownloadData($url)) Write-Host "----" if ($h -ne $null) { ([xml]$h).string.get_Innertext() } else { # もし翻訳に失敗したら元の英文を返す $text } } cls $japaneseFile = '.\jpn-jpn-csv-Windows 7 (1).csv' $englishFile_Security = '.\WindowsServer2008R2andWindows7GroupPolicySettings_security.csv' $englishFile_adm = '.\WindowsServer2008R2andWindows7GroupPolicySettings_AdministrativeTemplate.csv' #日本語ファイルをCSVファイルとして読み込む。各列は a~k とする。 $jpnfile = Import-Csv $japaneseFile -Header "a","b","c","d","e","f","g","h","i","j","k" #ハッシュテーブルを作成し、a列をキーとして、c列を格納 $jpnfile_hash = @{} $jpnfile |foreach-object { if ($jpnfile_hash.ContainsKey($_.a) -eq $false ){ $jpnfile_hash.add($_.a,$_.c) } } # セキュリティポリシー一覧ファイルをCSVとして読み込む。各列は a~g とする。 $enfile = Import-Csv $englishfile_Security -Header "a","b","c","d","e","f","g" # 読み込んだファイルから1行ずつ取り出し、日本語化したい列をハッシュテーブルのキーをベースに置換する # $japaneseFile とのマッチングに失敗した場合に Get-Translation を呼び出しています。以降も同様です。 # なお、あとから完成したCSVを見たときにカラムが機械翻訳を通ったことがわかるよう、[T] を頭に付けています。 ForEach($item in $enfile) { if ($jpnfile_hash.ContainsKey($item.b.replace("`n","\r\n")) ) { $item.b = $jpnfile_hash.Get_Item($item.b.replace("`n","\r\n")).Replace("\r\n"," ") } else { $item.b = Get-Translation ($item.b.replace("`n"," ")).toString() $item.b = "[T]" + $item.b } if ($jpnfile_hash.ContainsKey($item.e.replace("`n","\r\n")) ) { $item.e = $jpnfile_hash.Get_Item($item.e.replace("`n","\r\n")).Replace("\r\n"," ") } else { $item.e = Get-Translation ($item.e.replace("`n"," ")).ToString() $item.e = "[T]" + $item.e } if ($item.g -ne "") { if ($jpnfile_hash.ContainsKey($item.g.replace("`n","\r\n")) ) { $item.g = $jpnfile_hash.Get_Item($item.g.replace("`n","\r\n")).Replace("\r\n"," ") } else { $item.g = Get-Translation ($item.g.replace("`n"," ")).ToString() $item.g = "[T]" + $item.g } } } # 置換後のデータをCSVファイルに保存 $enfile | Export-Csv gplistjp_security.csv -encoding Default # # 管理ポリシーファイルも同様の処理 # $enfileadm = Import-Csv $englishfile_adm -Header "a","b","c","d","e","f","g","h","i","j" ForEach($item in $enfileadm) { if ($jpnfile_hash.ContainsKey($item.b.replace("`n","\r\n"))) { $item.b = $jpnfile_hash.Get_Item($item.b.replace("`n",".")) } else { $item.b = Get-Translation ($item.b.replace("`n",".")).ToString() $item.b = "[T]" + $item.b } if ($jpnfile_hash.ContainsKey($item.g.replace("`n","\r\n")) ) { $item.g = $jpnfile_hash.Get_Item($item.g.replace("`n",".")) } else { $item.g = Get-Translation ($item.g.replace("`n",".")).ToString() $item.g = "[T]" + $item.g } } $enfileadm | Export-Csv gplistjp_adm.csv -encoding Default どうでしょう? 「翻訳」などという高度な処理をしているのに、かなりシンプルですよねぇ。 結果は以下の通りです。いい感じです。ところどころ、「うむむ」という翻訳はあるものの、まぁいけている気がします。 実物を添付したいのですが、Tanslation Glossary の縛りがあり、できません...すみません...是非とも皆さん自身でスクリプトを実行してみてください。 ちなみに、Administrative Template と Security の両方を変換するのに、私の環境で約40分かかりました。
今回作成するスクリプトの方針は、「Translation Glossary」とマッチしなかった英文/用語に対して BING 翻訳 するようにします。ですので、前回同様、以下の3つのファイルを用意しておいてください。
田辺さんのスクリプトと前回作成したスクリプトを合体させて、すこしアレンジしたものが以下です。
# Get-Transaction という機械翻訳用のFunctionを定義しています。 # Function の中では、"http://api.microsofttranslator.com/V2/Http.svc/Translate" というメソッドを使用して、 # この Function に引数として渡されたテキスト文字列を翻訳しています
function Get-Translation { param([parameter(ValueFromPipeline=$true)] [String] $text = "Group Policy")
$w = new-object system.net.webclient $enc = [Text.Encoding]::GetEncoding("utf-8")
# AppID を指定 $appid = "CExxxxxxxxxxxxxxxxxxxxxxxxxxxx0B19" # 翻訳もとは英語 $from = "en" # 翻訳先は日本語 $to = "ja" $contentType = "text/plain" $category = "general" # BING翻訳 Translate メソッドの uri $api = "http://api.microsofttranslator.com/V2/Http.svc/Translate" $url = "{0}?appID={1}&from={2}&to={3}&text={4}&contentType={5}&category={6}" -f $api, $appid, $from, $to, $text, $contentType, $category $h = $enc.GetString($w.DownloadData($url)) Write-Host "----" if ($h -ne $null) { ([xml]$h).string.get_Innertext() } else { # もし翻訳に失敗したら元の英文を返す $text } }
cls
$japaneseFile = '.\jpn-jpn-csv-Windows 7 (1).csv' $englishFile_Security = '.\WindowsServer2008R2andWindows7GroupPolicySettings_security.csv' $englishFile_adm = '.\WindowsServer2008R2andWindows7GroupPolicySettings_AdministrativeTemplate.csv'
#日本語ファイルをCSVファイルとして読み込む。各列は a~k とする。
$jpnfile = Import-Csv $japaneseFile -Header "a","b","c","d","e","f","g","h","i","j","k"
#ハッシュテーブルを作成し、a列をキーとして、c列を格納 $jpnfile_hash = @{} $jpnfile |foreach-object { if ($jpnfile_hash.ContainsKey($_.a) -eq $false ){ $jpnfile_hash.add($_.a,$_.c) } }
# セキュリティポリシー一覧ファイルをCSVとして読み込む。各列は a~g とする。 $enfile = Import-Csv $englishfile_Security -Header "a","b","c","d","e","f","g"
# 読み込んだファイルから1行ずつ取り出し、日本語化したい列をハッシュテーブルのキーをベースに置換する # $japaneseFile とのマッチングに失敗した場合に Get-Translation を呼び出しています。以降も同様です。 # なお、あとから完成したCSVを見たときにカラムが機械翻訳を通ったことがわかるよう、[T] を頭に付けています。
ForEach($item in $enfile) { if ($jpnfile_hash.ContainsKey($item.b.replace("`n","\r\n")) ) { $item.b = $jpnfile_hash.Get_Item($item.b.replace("`n","\r\n")).Replace("\r\n"," ") } else { $item.b = Get-Translation ($item.b.replace("`n"," ")).toString() $item.b = "[T]" + $item.b }
if ($jpnfile_hash.ContainsKey($item.e.replace("`n","\r\n")) ) { $item.e = $jpnfile_hash.Get_Item($item.e.replace("`n","\r\n")).Replace("\r\n"," ") } else { $item.e = Get-Translation ($item.e.replace("`n"," ")).ToString() $item.e = "[T]" + $item.e } if ($item.g -ne "") { if ($jpnfile_hash.ContainsKey($item.g.replace("`n","\r\n")) ) { $item.g = $jpnfile_hash.Get_Item($item.g.replace("`n","\r\n")).Replace("\r\n"," ") } else { $item.g = Get-Translation ($item.g.replace("`n"," ")).ToString() $item.g = "[T]" + $item.g } } }
# 置換後のデータをCSVファイルに保存 $enfile | Export-Csv gplistjp_security.csv -encoding Default
# # 管理ポリシーファイルも同様の処理 #
$enfileadm = Import-Csv $englishfile_adm -Header "a","b","c","d","e","f","g","h","i","j" ForEach($item in $enfileadm) { if ($jpnfile_hash.ContainsKey($item.b.replace("`n","\r\n"))) { $item.b = $jpnfile_hash.Get_Item($item.b.replace("`n",".")) } else { $item.b = Get-Translation ($item.b.replace("`n",".")).ToString() $item.b = "[T]" + $item.b }
if ($jpnfile_hash.ContainsKey($item.g.replace("`n","\r\n")) ) { $item.g = $jpnfile_hash.Get_Item($item.g.replace("`n",".")) } else { $item.g = Get-Translation ($item.g.replace("`n",".")).ToString() $item.g = "[T]" + $item.g } }
$enfileadm | Export-Csv gplistjp_adm.csv -encoding Default
どうでしょう?
「翻訳」などという高度な処理をしているのに、かなりシンプルですよねぇ。
結果は以下の通りです。いい感じです。ところどころ、「うむむ」という翻訳はあるものの、まぁいけている気がします。
実物を添付したいのですが、Tanslation Glossary の縛りがあり、できません...すみません...是非とも皆さん自身でスクリプトを実行してみてください。
ちなみに、Administrative Template と Security の両方を変換するのに、私の環境で約40分かかりました。
機械翻訳に対してかなりネガティブなイメージを持っていましたが、BING の翻訳機能 を使ってみたところ、マイクロソフト製品で使用されている用語やメッセージについては、割とよさげなことがわかりました。
ただですねぇ...問題が無いわけではなのんです。BING翻訳のAPIに高頻度でアクセスしていると、途中からアクセスを拒否されてしまうことがあります。
まぁ、そりゃそうなんですけど...。今回も、何回かそんなことがありました。処理の間にSleep でも入れれば違うのでしょうけど...
じゃ、今回のように大量の個別データを翻訳したい場合にはどうするかといえば、TranslateArray というメソッドを使うようです。XMLファイルで複数のテキストを一度に渡すことができるみたいです。これについてはまた今度ということで。
それにしても、BING翻訳、やってみると結構面白いですね。翻訳結果をスピーチしてくれたりとかもあるので、スマートフォンのアプリに実装すれば、リアル「ほんやくこんにゃく」らしきものができてしまいそうです。きっと、Phone 7 担当のT氏が企画してくれるでしょう~。
BING 翻訳が大きいサービス変更があって、AppID から AppToken など仕様も大きく変わってしまいました・・・
なんとか捏ね繰り回して、使えるようにすることはできないでしょうかね・・・
MYUさん
おっと、まじですか!
なんてことでしょう。ちょっと時間を見つけて確認してみますね~
すみません。本ページなんどもみています。
本当にありがとうございます。
でも MYUと同様でappidが取得できません。
自分でも調べていますが、どうしていいかというところです・・・
でも MYUさんと同様でappidが取得できません。