こんにちは、入社して半年経ちました新米エンジニア、takoです。
地元は海ではなく山の中に住んでました。
学生時代はコンピュータ言語ではなく韓国語の勉強をしていました。
そこで今回のブログデビューは"外国語"に関するものを触ってみたいと思い、
Amazon Translateを触ってみることにしました。
何を翻訳するかというと、Amazon LexのBotを翻訳していこうと思います。
現在Amazon Lexは日本語対応されていないため全て英語です。(2020/10 時点)
そのため、我々日本人が何を言っているか分かるようにするため
Amazon Translateを使って日本語に翻訳していこうというのが今回の試みです。
Amazon Translateとは
Amazon Translate は、高速で高品質な言語翻訳を手ごろな価格で提供する
ニューラル機械翻訳サービスです。
Amazon Translate を使用すると、世界中の言語のユーザー向けにウェブサイトやアプリケーションなどのコンテンツをローカライズし、大量のテキストを効率的に簡単に翻訳できます。
特徴1:幅広い言語への対応
アラビア語、中国語(簡体字・繁体字)、英語、フランス語、ドイツ語、インドネシア語、イタリア語、日本語、韓国語、ポルトガル語、ロシア語、スロベニア語、スペイン語、タガログ語、タイ語、ベトナム語、など55 の言語の翻訳に対応しています。
また、英語から日本語、日本語から英語など相互変換が可能です。
特徴2:正確かつ自然な翻訳
ディープラーニング手法を使用し、より正確で流暢な翻訳を生成します。
そのおかげでユーザーがAmazon Translateを使えば使うほど、システムが言葉や文章のニュアンスを学習して使いやすくなっていきます。
特徴3:カスタム設定
特定の組織、分野、業界における独自の用語や名称をカスタムで設定することができるため誤訳が減り自然な翻訳になります。
ブランド名、製品名などの固有名詞を登録することができます。
Amazon Lexとは
Amazon Lex は、音声やテキストを使用して、任意のアプリケーションに
特徴1:高品質の音声認識と自然言語理解
デベロッパーが入力する発話例に基づいて、話者が意図を表現するさまざまな方法を学習できます。
音声言語理解システムでは、自然言語の音声とテキストによる入力を受け取り、
その背景にある意図を理解し、適切な応答を呼び出すことによってユーザーの意図を実行します。
特徴2:複数回にわたる対話
Amazon Lex ボットでは、対話内容を保持してステートフルに対話を行うことができます。
インテントが特定されると、ユーザーは、そのインテントを実行するために必要な情報の入力を求められます。
(例えば、インテントが "ホテルの予約" である場合、ユーザーは場所、チェックインの日付、宿泊日数などの入力を求められます)
特徴3:AWS Lambda との統合
AWS Lambda との統合がネイティブでサポートされており、データ取得、更新、およびビジネスロジックの実行に活用できます。
サーバーレスのコンピューティング性能を生かして、ボットの開発に注力しながら、大規模なビジネスロジックを簡単に実行できます。
Amazon LexのBotを翻訳してみた
さて、本題に移っていきます。
以下のような流れで進めていきます。
1.ユーザーが日本語で入力した文章をAmazon Translateが英語に翻訳
2.Amazon Lex Botが英語で返答
3.Amazon Lex Botの返答をAmazon Translateが日本語に翻訳
4.日本語に翻訳したものをユーザーに返す
ということで、Amazon LexのBotを作成しLambda関数を作成していきます。
手順① Amazon LexのBotを作成
Amazon Lexコンソールを開きます。
(https://ap-northeast-1.console.aws.amazon.com/lex/)
Createを押下すると、「Custom Bot(カスタムボット)」またはサンプルのボットを選択することができます。
今回はお手軽にサンプルのBotにあったBook Car(レンタルカー予約)を選択してみました。
中身の文章は特に変えずに翻訳ができるかどうかを試していきます。
(Botの文章を変えてみたり、Botをカスタムで作成してちゃんと翻訳されるのかも試してみたいですね…)
手順② Lambda関数の作成
Lambda関数を作成してみました。
const Aws = require('aws-sdk'); const Translate = new Aws.Translate({region: 'us-east-1'}); const lexruntime = new Aws.LexRuntime(); let lex_response = "" // メイン exports.handler = async (event) => { console.log('event :' + JSON.stringify(event)); let js = JSON.stringify(event); let body = JSON.parse(js); let js_body_text = body.body; //日本語→英語 let rs = await getAwsTranslate(js_body_text,'ja','en'); // lexに情報を渡す await postLex(rs.TranslatedText); console.log(lex_response); // 英語→日本語 let rs2 = await getAwsTranslate(lex_response,'en','ja'); return {statusCode: 200,message:rs2.TranslatedText}; }; // textを送信してlexからresponseを受け取るメソッド async function postLex(inputText){ var params = { botAlias:"initial", botName: "translate_bot", inputText: inputText, userId: "userId" // sessionAttributes: "sessionAttributes" }; await lexruntime.postText(params,function(err,data){ if(err){ console.log(err); }else{ console.log(data.message); lex_response = data.message; } }); } // 翻訳するメソッド function getAwsTranslate(js_text,in_Language,out_Language) { return new Promise(((resolve, reject) => { let params = { Text: js_text, SourceLanguageCode: in_Language, TargetLanguageCode: out_Language } Translate.translateText(params, function(err,data){ if (err) { console.log(err); reject(); } else { console.log(JSON.stringify(data)); resolve(data); } }); })); };
テストデータはこちらです。
これが上記のユーザーがAmazon Lexに対して話す内容になります。
START RequestId: 8b5cc7f8-c58d-4aa5-9e57-06b5c13a4b2d Version: $LATEST 2020-10-12T05:58:31.001Z 8b5cc7f8-c58d-4aa5-9e57-06b5c13a4b2d INFO event :{"body":"車を予約したいです。"} 2020-10-12T05:58:32.069Z 8b5cc7f8-c58d-4aa5-9e57-06b5c13a4b2d INFO {"TranslatedText":"I want to book a car.","SourceLanguageCode":"ja","TargetLanguageCode":"en"} 2020-10-12T05:58:32.149Z 8b5cc7f8-c58d-4aa5-9e57-06b5c13a4b2d INFO Sorry, what can I help you with? 2020-10-12T05:58:32.515Z 8b5cc7f8-c58d-4aa5-9e57-06b5c13a4b2d INFO Sorry, I am not able to assist at this time 2020-10-12T05:58:32.976Z 8b5cc7f8-c58d-4aa5-9e57-06b5c13a4b2d INFO {"TranslatedText":"申し訳ありませんが、私はあなたを助けることができますか?","SourceLanguageCode":"en","TargetLanguageCode":"ja"} END RequestId: 8b5cc7f8-c58d-4aa5-9e57-06b5c13a4b2d REPORT RequestId: 8b5cc7f8-c58d-4aa5-9e57-06b5c13a4b2d Duration: 1975.99 ms Billed Duration: 2000 ms Memory Size: 128 MB Max Memory Used: 89 MB
このようにユーザーの入力した内容に対して、Amazon Lexの返答が日本語で返ってきました!
困ったところ
async/awaitがうまく使えずに
値が空白のまま次の処理に行ってしまったためエラーが出ました。
↓もともと書いたasync/awaitのないコード
ログからも分かるように値が0だよというエラーが出ています
// textを送信してlexからresponseを受け取るメソッド function postLex(inputText){ var params = { botAlias:"initial", botName: "translate_bot", inputText: inputText, userId: "userId" // sessionAttributes: "sessionAttributes" }; lexruntime.postText(params,function(err,data){ if(err){ console.log(err); }else{ console.log(data.message); lex_response = data.message; } }); }
START RequestId: 8aeccf8a-269a-453b-a141-74d72e0f2cac Version: $LATEST 2020-10-12T06:16:30.653Z 8aeccf8a-269a-453b-a141-74d72e0f2cac INFO event :{"body":"車を予約したいです。"} 2020-10-12T06:16:32.170Z 8aeccf8a-269a-453b-a141-74d72e0f2cac INFO {"TranslatedText":"I want to book a car.","SourceLanguageCode":"ja","TargetLanguageCode":"en"} 2020-10-12T06:16:32.231Z 8aeccf8a-269a-453b-a141-74d72e0f2cac INFO 2020-10-12T06:16:32.603Z 8aeccf8a-269a-453b-a141-74d72e0f2cac INFO Sorry, what can I help you with? 2020-10-12T06:16:33.059Z 8aeccf8a-269a-453b-a141-74d72e0f2cac INFO ValidationException: Text size cannot be zero. at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:51:27) at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20) at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10) at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14) at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10) at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12) at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10 at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9) at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12) at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18) { code: 'ValidationException', time: 2020-10-12T06:16:33.056Z, requestId: '044b2cb1-d12e-4c8c-bf97-acd27dfdeeac', statusCode: 400, retryable: false, retryDelay: 99.02595880869502 } 2020-10-12T06:16:33.109Z 8aeccf8a-269a-453b-a141-74d72e0f2cac ERROR Invoke Error {"errorType":"Error","errorMessage":"handled","stack":["Error: handled"," at _homogeneousError (/var/runtime/CallbackContext.js:12:12)"," at postError (/var/runtime/CallbackContext.js:29:54)"," at done (/var/runtime/CallbackContext.js:56:7)"," at fail (/var/runtime/CallbackContext.js:66:7)"," at /var/runtime/CallbackContext.js:104:16"," at processTicksAndRejections (internal/process/task_queues.js:97:5)"]} END RequestId: 8aeccf8a-269a-453b-a141-74d72e0f2cac REPORT RequestId: 8aeccf8a-269a-453b-a141-74d72e0f2cac Duration: 2477.05 ms Billed Duration: 2500 ms Memory Size: 128 MB Max Memory Used: 87 MB Init Duration: 522.07 ms
まとめ
上述しましたが、Botの文章を変えてみたり、Botをカスタムで作成してちゃんと翻訳されるのかも試してみたいと思いました。また、Amazon Translateは多言語に対応しているため、英語以外の言語で試してみるのも面白いかもしれません。
是非皆さんもAmazon Translateを試してみてください!
参考サイト:Amazon Translate→(https://aws.amazon.com/jp/translate/)
Amazon Lex→(https://aws.amazon.com/jp/lex/)