Amazon自然言語サービスの力を借りて外国語音声を翻訳する

2018.11.19

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

旅行中や生活の中で、外国語の音声を理解しなければいけないときがあります。 例えば、自動音声ガイダンスです。 カジュアルに一度限りの翻訳したいときは、Google 翻訳に音声を流すのが一番お手軽です。

それとは別に、システマティックに多くの音声を翻訳・分析したいときがあります。

そのようなユースケースのために、Amazonの自然言語(NLP)系サービスを活用し

  1. Amazon Transcribe で外国語音声を文字起こし
  2. Amazon Translate で別の言語に翻訳
  3. Amazon Comprehend でテキストを特徴づけるキーワードを抽出

してみます。

利用音声

題材となる音声には、カナダ首相の Justin Trudeau がフランスの国会議会で行ったカナダ系フランス語の演説を利用します。

前提

操作について

SDK に移植しやすいように、操作には AWS CLI を利用します。

利用リージョン

言語系サービスは利用可能なリージョンが限られています。

今回は全音声系サービスを利用可能な North Virginia(us-east-1) リージョンを利用します。

CLI/SDK のリージョンを変更します。

$ export AWS_DEFAULT_REGION=us-east-1

1. Amazon Transcribe で外国語音声を文字起こし

Amazon Transcribe は S3 にある音源(wav/mp3/mp4 など)を 非同期 に文字起こしするサービスです。

対応言語

以下の言語に対応しています。

  • 英語(アメリカ)
  • 英語(イギリス) ※ 2018/11/15 から
  • 英語(オーストラリア) ※ 2018/11/15 から
  • スペイン語
  • フランス語(カナダ)※ 2018/11/15 から

また、2018/11/16 より 以下の言語のプレビュー対応が始まっています。

  • フランス語(汎用)
  • ドイツ語
  • ポルトガル語(ブラジル)

日本語対応は気長に待ちましょう。

文字起こしジョブを登録

文字起こしジョブを登録します。

ジョブ実行結果の取得方法は

  • AWS 管理の S3 バケットに出力して、presigned URL 経由で取得
  • 自アカウントの S3 バケットに出力し、通常の S3 API で取得

の2通りがあります。今回は後者を採用します。

$ aws transcribe start-transcription-job \
  --transcription-job-name canadian-french-test \
  --media-format mp4 \ # 入力ファイルのフォーマット
  --language-code fr-CA \ # 入力言語
  --media MediaFileUri=https://s3.amazonaws.com/BUCKET-NAME/filename.mp4 \ # 入力ファイルパス
  --output-bucket-name OUTPUT-BUCKET-NAME # 出力先バケット名
{
    "TranscriptionJob": {
        "TranscriptionJobName": "canadian-french-test",
        "TranscriptionJobStatus": "IN_PROGRESS",
        "LanguageCode": "fr-CA",
        "MediaFormat": "mp4",
        "Media": {
            "MediaFileUri": "https://s3.amazonaws.com/BUCKET-NAME/filename.mp4"
        },
        "CreationTime": 1542489915.174
    }
}

文字起こしテキストを取得

文字起こしジョブは非同期に実行されます。

ジョブが完了すると、ジョブステータスが COMPLETED になります。

$ aws transcribe get-transcription-job \
  --transcription-job-name canadian-french-test
{
    "TranscriptionJob": {
        "TranscriptionJobName": "canadian-french-test",
        "TranscriptionJobStatus": "COMPLETED",
        "LanguageCode": "fr-CA",
        "MediaSampleRateHertz": 44100,
        "MediaFormat": "mp4",
        "Media": {
            "MediaFileUri": "https://s3.amazonaws.com/BUCKET-NAME/filename.mp4"
        },
        "Transcript": {
            "TranscriptFileUri": "https://s3.amazonaws.com/OUTPUT-BUCKET-NAME/filename.json"
        },
        "CreationTime": 1542489915.174,
        "CompletionTime": 1542490296.877,
        "Settings": {
            "ChannelIdentification": false
        }
    }
}

ジョブ結果ファイルのパスは レスポンスの TranscriptFileUri にあります。

$ aws s3 cp s3://OUTPUT-BUCKET-NAME/filename.json .
download: s3://OUTPUT-BUCKET-NAME/filename.json to ./filename.json

この JSON ファイルをちら見します。

canadian-french-test.json

{
  "jobName": "canadian-french-test",
  "accountId": "205974338614",
  "results": {
    "transcripts": [
      {
        "transcript": "La france et le canada ont réalisé des progrès importants à ce chapitre nous avons tous deux marqué ... SNIP"
      }
    ],
    "items": [
      {
        "start_time": "15.6",
        "end_time": "15.84",
        "alternatives": [
          {
            "confidence": "1.0000",
            "content": "La"
          }
        ],
        "type": "pronunciation"
      },
      {
        "start_time": "15.84",
        "end_time": "16.36",
        "alternatives": [
          {
            "confidence": "0.9993",
            "content": "france"
          }
        ],
        "type": "pronunciation"
      },
      ...
}

上記 JSON ファイルの transcript 要素だけを jq で抽出し、変数 TRANSCRIPT に代入します。

$ jq '.results.transcripts[0].transcript' canadian-french-test.json
"La france et le canada ont réalisé des progrès importants à ce chapitre nous avons tous deux marqué l'histoire en choisissant un conseil des ministres paritaire je note également que cette assemblée approche la parité et là-dessus. Je remercie les hommes qui sont se sont levés pour ça aussi mais là-dessus je dois avouer que au parlement canadien nous avons encore beaucoup de chemin à faire et c'est à nous devraient tous les jours pour la véritable égalité des sexes à tous les niveaux dans tous les domaines ni la france ni le canada ni les cinq autres économies les plus avancées du monde qui forment le g sept ne peuvent prétendre avoir comblé ces inégalités aillant l'audace de bâtir ensemble un monde plus progressiste plus diversifié plus vert plus inclusif plus ouvert plus démocratique un monde plus libre plus égal et plus fraternelle un monde à notre imad merci."

$ TRANSCRIPT=$(jq -r '.results.transcripts[0].transcript' canadian-french-test.json)

2. Amazon Translate で別の言語に翻訳

Amazon Translate はリアルタイムなニューラル機械翻訳サービスです。

対応言語

以下の各言語間の翻訳をサポートしています。

  • アラビア語
  • 中国語 (簡体字)
  • 中国語 (繁体字)
  • チェコ語
  • 英語
  • フランス語
  • ドイツ語
  • イタリア語
  • 日本語
  • ポルトガル語
  • ロシア語
  • スペイン語
  • トルコ語

サポートされる言語ペアの詳細な一覧は、このドキュメントページをご覧ください。

日本語関連では、以下のペアが未対応です。

  • 日本語 - 中国語 (繁体字)
  • 日本語 - ロシア語

別言語に翻訳

フランス語の文章だと何が書かれているのかわからないため(個人差があります)、英語に翻訳します。

$ aws translate translate-text \
  --source-language-code fr \ # 翻訳元の言語
  --target-language-code en \ # 翻訳先の言語
  --text $TRANSCRIPT
{
    "TranslatedText": "France and canada have made significant progress in this regard, we have both marked history by choosing a joint cabinet of ministers. I also note that this assembly is approaching parity and on that. I thank the men who have stood up for this too, but on this I must confess that in the Canadian parliament we still have a long way to go and it is up to us every day for true gender equality at all levels in all fields neither france nor canada nor the five other most advanced economies in the world who make up the g seven cannot claim to have filled these inequalities with the boldness of building together a more progressive, more diverse, green, more inclusive, more democratic, a freer, more equal and more fraternal world a world to our imad thank you.",
    "SourceLanguageCode": "fr",
    "TargetLanguageCode": "en"
}

source の言語指定を省略すると、Amazon Comprehend を利用して推定した言語が利用されます。

レスポンスの TranslatedText が英語へ翻訳された文章です。

それっぽく翻訳されています。

3. Amazon Comprehend でテキストを特徴づけるキーワードを抽出

Amazon Comprehend は、機械学習を使用してテキスト内でインサイトや関係性を検出する自然言語処理 (NLP) サービスです

  • キーフレーズ
  • エンティティ
  • 感情

を抽出できます。

これらを活用することで

  • 分析に関するお客様の声
  • セマンティック検索
  • ナレッジマネジメントおよび検出

などに応用できます。

キーワード

音声を全部確認したり、書き起こされた文章を読まなくても、何について話されているかわかるように、キーワードを抽出してみます。

$ aws comprehend detect-key-phrases \
  --language-code en \ # 入力言語
  --text $ENGLISH_TRANSCRIPT # 入力クテキスト
{
    "KeyPhrases": [
        {
            "Score": 0.9593480825424194,
            "Text": "France and canada",
            "BeginOffset": 0,
            "EndOffset": 17
        },
        {
            "Score": 0.9989510774612427,
            "Text": "significant progress",
            "BeginOffset": 28,
            "EndOffset": 48
        },
    ...
}

レスポンスにはキーワード(Text)と確度のスコア(Score)などが含まれます。

スコアを無視して、キーワードだけを抜粋します。

$ aws comprehend detect-key-phrases \
  --text $ENGLISH_TRANSCRIPT \
  --language-code en |
  jq '.KeyPhrases[].Text'
"France and canada"
"significant progress"
"this regard"
"both marked history"
"a joint cabinet"
"ministers"
"this assembly"
"parity"
"the men"
"the Canadian parliament"
"a long way"
"every day"
"true gender equality"
"all levels"
"all fields"
"neither france"
"canada"
"the five other most advanced economies"
"the world"
"the g seven"
"these inequalities"
"the boldness"
"a more progressive"
"a freer, more equal and more fraternal world"
"a world"
"our imad"

翻訳された文章全体を読まなくても、キーワードを眺めるだけで gender inequalities を無くす社会を目指す演説であることがわかるかと思います。

さらなる改善

パイプライン対応

今回はステップごとに AWS CLI で操作しました。 パイプライン化する際には

  • S3 の更新イベント
  • Amazon Transcribe ジョブの CloudWatch Events へのイベント通知

をトリガーに Lambda で次の処理につなげると、素直なパイプラインを作成できます。

また Step Functions を使うと、パイプライン全体の状態の遷移の見通しが良くなります。

前処理を追加

今回はレスポンスデータを加工せずに次の処理に利用しました。

例えば、Transcribe -> Translate のフェーズでは、翻訳しやすいように句読点を補完すると、全体の精度がぐっと上がります。

最後に

Amazon が提供する自然言語系サービスの高レベル API を使って、外国語の音声を多言語に翻訳し、簡単な分析を行いました。

高レベル API のため、細かい制御はできませんが、自然言語処理の知識がなくても利用可能です。ある程度割り切ってしまえば、いろいろ遊べます。

Transcribe/Comprehend の対応言語が増えたり、Transcribe がリアルタイム処理に対応すると、活用の幅がより広まるのではないでしょうか。

参考