AWSでAIサービスを使ってみる〜第3回polly編〜

## Amazon Pollyとは
AIのテキスト読み上げのサービスです。テキストから音声を合成することができるAWSのサービスです。また、他言語にも対応指定たりニューラル音声といったより流暢にテキスト読み上げる機能(現状一部言語のみ)もあります。

##テキストから音声ファイルを作成してみる

エディタでpythonファイルを作成し、pollyサービスクライアントを利用してテキストの音声合成を行います。

```warabimochi.py
import boto3
import contextlib
import os

#pollyサービスクライアントを作成
polly = boto3.client('polly')
#音声合成のテキスト
text='Nさんは次のミーティングまでにSさんにわらび餅を買う予定です。'

#テキストから音声を合成
result = polly.synthesize_speech(
  Text=text, OutputFormat='mp3',VoiceId='Mizuki')

#出力ファイルのpath
path = 'warabimochi.mp3'
#音声のストリームを開く
with contextlib.closing(result['AudioStream']) as stream:
  #出力ファイルを開く
  with open(path, 'wb') as file:
    #音声ファイルを読み込んで出力ファイルに書き込む
    file.write(stream.read())

```

上記ファイルをターミナルで実行

```
python warabimochi.py
```

実行したディレクトリ上にmp3ファイルが作成されます。
(今回で言うと"warabimochi.mp3"が該当します)
そちらのmp3ファイルを再生しみると、作成したテキストが読み上げられます。

今回はpolly.synthesize_speechの引数のVoiceIdを'Mizuki'と言う女性の声に指定しましたが
VoiceIdを'Takumi'に変更すると男性の声に変更もできます。
VoiceIdは言語ごとに複数あり非常に多くの言語に対応しています。

[AmazonPollyの声](https://docs.aws.amazon.com/ja_jp/polly/latest/dg/voicelist.html)

また、ニューラル音声を指定すると標準音声よりもより高音質で流暢に読み上げます。
(日本語がまだニューラル音声に対応していないのが残念ですが、、、)
ニューラル音声を指定はsynthesize_speechメソッドにEngine='neural'を追加します。

```warabimochi.py
result = polly.synthesize_speech(
  Text=text, OutputFormat='mp3',VoiceId='Ivy',
  Engine='neural')
```

##Lexicon(レキシコン)で略語を読み上げる
先ほどのwarabimochi.pyのテキストの"ミーティング"の部分を"MTG"に変更してみましょう。

```warabimochi.py
#音声合成のテキスト
text='Nさんは次のMTGまでにSさんにわらび餅を買う予定です。'
```

ターミナルでwarabimochi.pyを実行し、作成された音声ファイルを再生してみてください。
先ほどの"ミーティング"と読み上げていた部分が"エムティージー"と読み上げます。

Lexiconを登録するとこのような略語も事前に登録をかけて、読みたいように読み上げることが可能です。
以下のようなLexiconファイル作成しましょう。まずLexiconファイルは.plsという形式で記述します。
(※この時文字エンコードはUTF-8に指定してください)

```my_lexicon.pls
<?xml version="1.0" encoding="UTF-8"?>
<lexicon version="1.0"
  xmlns="http://www.w3.org/2005/01/pronunciation-lexicon"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://www.w3.org/2005/01/pronunciation-lexicon 
    http://www.w3.org/TR/2007/CR-pronunciation-lexicon-20071212/pls.xsd"
  alphabet="ipa" xml:lang="ja">
  <lexeme>
    <grapheme>MTG</grapheme>
    <alias>ミーティング</alias>
  </lexeme>
 <lexeme>
    <grapheme>...</grapheme>
    <alias>...</alias>
 </lexeme>
 </lexicon>

```

graphemeは語彙素(登録を行う略語)
aliasは別名(読みたい読み方)
また略語ごとにgraphemeとaliasをlexemeタグ付けしてください。

次にLexicon(my_lexicon.pls)を登録する実行ファイルを作成します。
Lexiconの登録にはput_lexiconメソッドを呼び出します。

```lexicon_put.py
import boto3
polly = boto3.client('polly')
#Lexiconファイルを開く
with open('my_lexicon.pls', 'r', encoding='utf-8') as file:
  #Lexiconの登録(Lexiconの名前は任意)
  polly.put_lexicon(Name='Lexicon', Content=file.read())
```

lexicon_put.pyを実行

```
python lexicon_put.py
```

エラーがなければターミナル上でlexiconの確認
list-lexiconsでlexiconのリストを確認可能

```
aws polly list-lexicons
```

実行結果
lexiconが登録されている。

```
"Lexicons": [
        {
            "Name": "Lexicon",
            "Attributes": {
                "Alphabet": "ipa",
                "LanguageCode": "ja",
                "LastModified": 000000000000000,
                "LexiconArn": "0000000000000000",
                "LexemesCount": 1,
                "Size": 443
            }
        }
    ]
```

Lexiconの登録が済んだため。合成ファイルwarabimochi.pyを
Lexiconを使って合成するよう追記します。
synthesize_speechメソッドにLexiconNamesの引数を追加します。

```warabimochi.py
result = polly.synthesize_speech(
  Text=text, OutputFormat='mp3',VoiceId='Mizuki',
  LexiconNames=['Lexicon'])
```

これでwarabimochi.pyを実行

```
python warabimochi.py
```

ディレクトリに保存されたwarabimochi.mp3は
"エムティージー"を"ミーティング"と読みます。

##Lexiconの削除
最後に登録したLexiconの削除についても記述します。
下記のlexicon_delete.pyを作成

```lexicon_delete.py
import boto3
polly = boto3.client('polly')
#lexiconを削除
polly.delete_lexicon(Name='Lexicon')
```

lexicon_delete.pyを実行

```
python lexicon_delete.py
```

完了したらlist-lexiconsで確認


```
aws polly list-lexicons
```

実行結果で'Lexicon'が削除されていればOK

```
{
    "Lexicons": []
}
```

以上！

##まとめ
AWSでテキストの読み上げや複数言語の読み上げができるようになっています。
Lexiconを活用すれば難しいそうなテキストの読み上げも可能になるでしょう。
また、webページの閲覧の際に音声での文章の閲覧の補助をすることが可能となりますね。
次回もAIサービスを紹介します。


##参考文献

この記事は以下の情報を参考にして執筆しました

[AWSでつくるAIプログラミング入門](https://www.amazon.co.jp/AWS%E3%81%A7%E3%81%A4%E3%81%8F%E3%82%8B-AI%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%85%A5%E9%96%80-%E6%9D%BE%E6%B5%A6-%E5%81%A5%E4%B8%80%E9%83%8E/dp/4798059056)