機械翻訳を試してみました(その2)

最近、とても寒くなっていますね。明日からはもっと寒くなるそうで…
家の中でもコートを着てしまいたくなってしまったmi2yo4です。

さて、前回(と言っても少し前になりますが)の記事まででMicrosoft Translatorを使う準備が出来ていますので、今日は早速サンプルのソースコードを作成して試してみましょう!

今回の参照先

と、その前に今回サンプルソースコードを作成するにあたって参考にした情報元を列記させておきます。

Obtaining an Access Token
Microsoft Translatorの提供元、Microsoftにサンプルコードがありましたので、PHPのソースコードを参考にして、後半部分だけちょこっと変更しました。

json形式でファイルを読み書きする
個人的に最近、JSON形式のファイルに慣れ親しむようになったので、読み書きできるライブラリを参考にしました。
今回はClient IDとClient Secretの読み込みに使用していますが、試すだけであればAccessToTranslateクラスのコンストラクタに直接書き込んでおけばいいかと思います。

今回使用したサンプルソースコード

それでは今回作成したソースコードです

mstranslatorwrapper.php

<?php
/**
 * refer to 'http://msdn.microsoft.com/en-us/library/hh454950.aspx'
 */
class AccessTokenAuthentication {
    /*
     * Get the access token.
     *
     * @param string $grantType    Grant type.
     * @param string $scopeUrl     Application Scope URL.
     * @param string $clientID     Application client ID.
     * @param string $clientSecret Application client ID.
     * @param string $authUrl      Oauth Url.
     *
     * @return string.
    */
    function getTokens($grantType, $scopeUrl, $clientID, $clientSecret, $authUrl) {
        try {
            //Initialize the Curl Session.
            $ch = curl_init();
            //Create the request Array.
            $paramArr = array(
                'grant_type' => $grantType,
                'scope' => $scopeUrl,
                'client_id' => $clientID,
                'client_secret' => $clientSecret
            );
            //Create an Http Query.//
            $paramArr = http_build_query($paramArr);
            //Set the Curl URL.
            curl_setopt($ch, CURLOPT_URL, $authUrl);
            //Set HTTP POST Request.
            curl_setopt($ch, CURLOPT_POST, TRUE);
            //Set data to POST in HTTP "POST" Operation.
            curl_setopt($ch, CURLOPT_POSTFIELDS, $paramArr);
            //CURLOPT_RETURNTRANSFER- TRUE to return the transfer as a string of the return value of curl_exec().
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
            //CURLOPT_SSL_VERIFYPEER- Set FALSE to stop cURL from verifying the peer's certificate.
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            //Execute the  cURL session.
            $strResponse = curl_exec($ch);
            //Get the Error Code returned by Curl.
            $curlErrno = curl_errno($ch);
            if ($curlErrno) {
                $curlError = curl_error($ch);
                throw new Exception($curlError);
            }
            //Close the Curl Session.
            curl_close($ch);
            //Decode the returned JSON string.
            $objResponse = json_decode($strResponse);
            // if ($objResponse->error) {
            if (!isset($objResponse)) {
                throw new Exception($objResponse->error_description);
            }
            
            return $objResponse->access_token;
        }
        catch(Exception $e) {
            echo "Exception-" . $e->getMessage();
        }
    }
}
/*
 * Class:HTTPTranslator
 *
 * Processing the translator request.
*/

Class HTTPTranslator {
    /*
     * Create and execute the HTTP CURL request.
     *
     * @param string $url        HTTP Url.
     * @param string $authHeader Authorization Header string.
     * @param string $postData   Data to post.
     *
     * @return string.
     *
    */
    function curlRequest($url, $authHeader, $postData = '') {
        //Initialize the Curl Session.
        $ch = curl_init();
        //Set the Curl url.
        curl_setopt($ch, CURLOPT_URL, $url);
        //Set the HTTP HEADER Fields.
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            $authHeader,
            "Content-Type: text/xml"
        ));
        //CURLOPT_RETURNTRANSFER- TRUE to return the transfer as a string of the return value of curl_exec().
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //CURLOPT_SSL_VERIFYPEER- Set FALSE to stop cURL from verifying the peer's certificate.
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, False);
        if ($postData) {
            //Set HTTP POST Request.
            curl_setopt($ch, CURLOPT_POST, TRUE);
            //Set data to POST in HTTP "POST" Operation.
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        }
        //Execute the  cURL session.
        $curlResponse = curl_exec($ch);
        //Get the Error Code returned by Curl.
        $curlErrno = curl_errno($ch);
        if ($curlErrno) {
            $curlError = curl_error($ch);
            throw new Exception($curlError);
        }
        //Close a cURL session.
        curl_close($ch);
        
        return $curlResponse;
    }
    /*
     * Create Request XML Format.
     *
     * @param string $languageCode  Language code
     *
     * @return string.
    */
    function createReqXML($languageCode) {
        //Create the Request XML.
        $requestXml = '<ArrayOfstring xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">';
        if ($languageCode) {
            $requestXml.= "<string>$languageCode</string>";
        } else {
            throw new Exception('Language Code is empty.');
        }
        $requestXml.= '</ArrayOfstring>';
        
        return $requestXml;
    }
}

translateconf.json

{"clientID":"your_client_id","clientSecret":"your_client_secret"}

translator.php

<?php
/**
 *
 * AccessTokenAuthenticationクラスとHttpTranslatorクラスの
 * オリジナルは以下の場所のコードとなります
 * http://msdn.microsoft.com/en-us/library/hh454950.aspx
 * 
 * try句以降のコードについてはITKOBO-Zオリジナルのものとなります。
 * 
 * 使い方:
 * php translator.php -i [inputtext] -c [en] -o [ja/kr/cn]
 */
require_once 'mstranslatorwrapper.php';

/**
 * JSON形式のファイルをやりとりするクラス
 * 以下のページを参照して作成しています
 * 
 * http://d.hatena.ne.jp/tek_koc+programing/20101123/1290483417
 * 
 */
class Json {
    public $data;
    private $filename;
    private $path = "./";
    /**
     * [__construct description]
     * @param [type] $name [description]
     */
    public function __construct($name) {
        $this->filename = $this->path . $name;
        if (file_exists($this->filename)) {
            $this->data = json_decode(file_get_contents($this->filename), true);
        } else {
            $this->data = array();
        }
    }
    /**
     * [save description]
     * @return [type] [description]
     */
    public function save() {
        file_put_contents($this->filename, json_encode($this->data));
    }
}

/**
 * 
 */
class AccessToTranslate {
    private $clientID;
    private $clientSecret;
    /**
     * コンストラクタ
     * jsonファイルからクライアントIDとクライアントシークレットの
     * 設定を読み込む
     * @param [type] $jsonfile [description]
     */
    public function __construct($jsonfile) {
        $json = new Json($jsonfile);
        $this->clientID = $json->data['clientID'];
        $this->clientSecret = $json->data['clientSecret'];
    }
    /**
     * 翻訳実行メソッド
     * Microsoftのサーバに翻訳文章を送信、翻訳後の文章を受け取る
     * @param  string $from   翻訳元文章の種類(en/ja/kr/cn ...)
     * @param  string $to     翻訳先文章の種類(同上)
     * @param  string $script 翻訳対象の文章
     * @return string         翻訳後文章(XML)
     */
    public function translate($from, $to, $script) {
        //OAuth Url.
        $authUrl = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13/";
        $scopeUrl = "http://api.microsofttranslator.com";
        $grantType = "client_credentials";
        //Create the AccessTokenAuthentication object.
        $authObj = new AccessTokenAuthentication();
        //Get the Access token.
        $accessToken = $authObj->getTokens($grantType, $scopeUrl, $this->clientID, $this->clientSecret, $authUrl);
        //Create the authorization Header string.
        $authHeader = "Authorization: Bearer " . $accessToken;
        //Create the Translator Object.
        $translatorObj = new HTTPTranslator();
        $translateMethodUrl = "http://api.microsofttranslator.com/V2/Http.svc/Translate?text=" . urlencode($script) . "&from=" . $from . "&to=" . $to;
        //Call the curlRequest.
        $strResponse = $translatorObj->curlRequest($translateMethodUrl, $authHeader);

        return $strResponse;
    }

}
/**
 * ここから単独実行用のシェルスクリプト
 */
try {
    $tEngine = new AccessToTranslate("translateconf.json");
    $strResponse = $tEngine->translate("en", "ja", "English to Japanese Text");

    $xmlObj = simplexml_load_string($strResponse);
    
    foreach ((array)$xmlObj[0] as $val) {
        $languageCode = $val;
        // for debug(windows)
        echo (mb_convert_encoding($languageCode, 'SJIS', 'UTF-8'));
        //

    }
}
catch(Exception $e) {
    echo "Exception: " . $e->getMessage() . PHP_EOL;
}

それでは翻訳実行してみますか

それでは一番使いそうな機能の和訳(英語→日本語)を使ってみましょう。
上記translator.phpの”English to Japanese Text”の部分を英文に書き換えて実行すれば英日変換が可能となります。

さて、どうなるでしょうか…
と、ここで適当なサンプルとなる英語文が思いつきません。

最近英語学習で使っているDUO 3.0からちょっとだけ文章を拝借しましょう。

Bringing flammable items into the cabin is prohibited.
機内への可燃物の持ち込みは禁止されています。

おお、完璧です。エクセレント!
では次はこの文章

The government did not take appropriate measures to prevent the infection from spreading.
政府は感染症のまん延を防止する適切な措置を取らなかった。

これまたいい線いっています!
Duo3.0には下記のように書いていますが、言っていることは同じなので正解でしょう。

政府は感染の拡大を未然に防ぐための適切な措置を取らなかった。

しかし、これなら一生懸命英語学習しなくても機械翻訳に任せてしまえば済むかもしれません…フフフ
では今度はコレ!

It dawned on me that I had been taken in by Jennifer all along.
How naive! Didn't you see through her?
それは私が撮影されていたジェニファーすべてに沿って私に夜が明けた。
どのように素朴な!彼女を参照してくださいですか?

…うーん、やはり会話文は難しいのでしょうね。
ちなみに日本語訳は以下となります。

ジェニファーにずっとだまされていたのがわかってきたよ。
なんてウブなの。彼女の本性が見抜けなかったの?

あと、give,take,get等の基本的な動詞と組み合わせる熟語関連は弱いかもしれませんね。

When her patience gave out, she grabbed his collar and swore at him.
彼女の忍耐力与えた、彼女は彼の襟をつかんでし、彼をののしった。

日本語訳は以下となります。

彼女は我慢しきれなくなり、襟首をつかんで彼をののしった。

まとめ

とまあ、色々と英日翻訳だけですが色々と試す事が出来たかと思います。
定型文チックなものについては、問題なく翻訳できますね!

逆に会話文になるとアレアレっ?という翻訳結果になってしまいましたが、やはりこれは仕方の無い事なんでしょう。生きている英語だと、時代時代によって意味合いがどんどん変わって行きますからね!

という訳で前回、今回と機械翻訳について試してみました。いかがだったでしょうか?
この記事に関するコメントは下のコメント欄に、自分の書き込みを見られたくない!という方は画面右下の「この記事に関してコメント」をクリックして書き込んでくださいね。

コメントを残す

メールアドレスが公開されることはありません。