2022年4月26日火曜日

SpeechSynthesis のテスト用に TTS Demo を作った

Web ブラウザで Text-to-speech の簡易的なテストをしたい時が結構あります。 しかし巷で公開されている Text-to-speech のデモはだいたいバグっているので、うまくテストできません。 毎回自分でデモを作って確認せざるを得ず、地味に手間となっていました。 そこでまともな SpeechSynthesis のデモとして、TTS Demo を公開することにしました。



声はあえて手動で選択せずランダムに選択するようにしたのですが、 これは英語のテキストを日本語で Text-to-speech したい時などに、 声を選ぶのが大変なように思えたからです。 完全に自分用に作ったのですが、割と便利だと思います。

2022年4月22日金曜日

Ubuntu デスクトップ比較: 22.04 も Lubuntu で決まり

Ubuntu 22.04 がリリースされたので、いつも通り Ubuntuデスクトップ比較をしてみました。 比較条件は 20.04 のときと一緒で、以下。
  • VirtualBox でクリーン環境を比較
  • 検証時の最大メモリサイズは 2GB
  • 起動→安定後のメモリ使用量を free --mega で比較

結果はこちら。
  • Ubuntu: 738MB → 712〜727MB (最重量)
  • Lubuntu: 316MB → 351〜355MB (最軽量)
  • Xubuntu: 415MB → 467〜483MB
  • Kubuntu: 409MB → 489〜537MB
  • Ubuntu MATE: 523MB → 507〜534MB
  • Ubuntu Budgie: 632MB → 674〜684MB

素の Ubuntu と MATE がすこし軽くなった一方で、その他はメモリ使用量が増えました。 メモリ使用量が増えた理由はわかりませんが、 Lubuntu 以外はフレーバー間のメモリ使用量の差はほとんどなくなっています。 1回測っただけだと少し怪しい感じだったので 2回測定してみましたが、 Xubuntu が少し軽いかなというくらいです。 どのフレーバーも頑張った結果とも言えそうですが、Lubuntu 以外は UI で選べば良いような気がします。

メニューを表示したときのスクリーンショットをまとめると、こんな感じ。 どれも良い感じに思うけど、Lubuntu かっこいい。

Ubuntu
Lubuntu
Kubuntu
Xubuntu
Ubuntu MATE
Ubuntu Budgie


しょぼマシンをたくさん使ってる身としては、私は今後も Lubuntu で決まりです。 Xubuntu と Kubuntu のメモリ使用量がだいぶ増えたので、メモリ使用量を削減したくても Lubuntu が動かないような場合、 他のディストリビューションを検討してみても良いのかも知れません。

Web N-gram を用いた英語の共起コーパス wncc-en を作った

Web N-gram を用いた英語の共起コーパス wncc-en を作りました。 名前は Web N-gram based Collocation Corpus の略です。 検証用に作ったものなのですが、まあまあの出来には見えます。 日本語版がうまくできたのでノリで作りましたが、日本語ほど使いやすくないかな?



英語では Google N-gram を使って共起関係を抽出します。 Google N-gram は大きすぎるので、事前に軽量な N-gram データ (google-ngram-small-en) を作って、そちらから作っています。 Google N-gram には 単語_品詞 の形で品詞情報が付いているので色々と活用もしやすいです。 ちなみに 4gram はデータ量がヤバイので解析していません。

品詞情報は DB を生成してみたところ微妙だったので無視しました。 他にも過去形を正規化するべきかどうか迷いましたが、日本語より正規化が面倒なので、正規化せず処理することにしました。 少しデータサイズが大きくなりますが、気にするほどではないかも。

抽出できると嬉しそうな基本ルールは以下ですが、英語は割と雑に順序を入れ替えても何とかなります。 実のところ何も考えずにすべての N-gram を登録してみました。

2gram

  • S [verb]
  • [verb] [adverb]
  • [adverb] [verb]
  • [adjective] [adverb]
  • [adverb] [adjective]
  • [noun] [noun]

3gram

  • S [verb] [adverb]
  • S be [adjective]
  • S be [noun]

今回作ったデータをもとに、また何か作れそうです。 ただ最初に書いたように、あまり使い勝手は良くなさそう。 サジェストにでも使えるかな、というくらい。

2022年4月15日金曜日

Web N-gram を用いた日本語の共起コーパス wncc-ja を作った

Web N-gram を用いた日本語の共起コーパス wncc-ja を作りました。 名前は Web N-gram based Collocation Corpus の略です。 精度と網羅性の高い例文や用例、共起データが欲しかったので開発しました。 検証用に作ったのですが、まあまあの出来には見えます。



共起辞書は昔 NICT がやってたみたいですが今は存在不明、 例文や用例データとしてすぐに使えるコーパスとして WordNet、 単語ベクトルを算出する Word2Vec がありますが、後述するように難点はあります。 他にも例文や用例は検索サイトならいくつかあるのですが、 再利用可能なデータがなく精度や実用性にも少し疑問があります。

既存の例文生成の問題

例文や用例は課題がわかりやすいので取り上げてみます。 生成手段としては青空文庫や Project Gutenberg から全文検索で作る方法が有名です。 しかし (1) 文章が長すぎ、(2) 文調が古すぎます。 上記の問題を解決するには頻度を考慮した適切な文章を生成する必要があります。 そのためには言葉の意味、最低でも共起関係をきちんと見ることが重要となります。 例文や用例は、文章が長くなっても言葉のイメージが掴めない問題があるので、 語彙の意味や利用シーンがわかることが重要となります。 一番わかりやすい例は「真理の追究」と「責任の追及」です。 同音異義語の「ついきゅう」はたった一つの周辺語さえ提示すれば、 利用用途が完璧にわかります。これは地味に凄いことです。

Word2Vec や WordNet の問題

共起コーパスとは異なりますが、語彙の関係を抽出する試みとして有名なものに Word2Vec があります。 Word2Vec は網羅性が非常に高いのが利点ですが、残念なことに考慮しているのは類似度です。 類似度と共起は近いようで異なるため利用が難しく、例文や用例の生成もできません。 先ほど例示した「追究」と「追及」を例に挙げると、Word2Vec では非常によく似た語として扱われてしまい、 類似の候補としてそれぞれが提示されてしまったりします。 Word2Vec の情報をもとに例文を作ることは厳しいなと思いました。

言葉の出現分布の類似度ベクトルは、必ずしも類義語を示す訳ではありません。 fastText も同じことが言えて、サブワードの出現分布の類似ベクトルが似通っていても、類義語を指すとは限りません。 同じような文脈で使われることが多いことを示すだけです。 結構色々と遊んでみましたが、例文や用例として応用するのはやや難しいという印象です。

例文や用例、共起データをすべて含む WordNet は一番使い勝手が良く、一応は使い物になります。 ただややノイズが強く、概念が冗長過ぎる割に、単語の網羅性が低く、 例文や用例もやや冗長な欠点があります。 いざ使おうとすると様々な問題にぶつかり、仕方なく自作したという事情があります。

作ってみた

それではどのように共起関係を抽出すればいいでしょうか。 共起関係を抽出するには、日本語の助詞をよく見て述語構造解析に近いことをやれば良いだけです。 解析は真面目にやると死ぬので、自明な関係だけを処理します。 日本語も英語も考え方はほとんど一緒なのですが、実装はなかなか面倒です。 話が長くなるだけなので、抽出ルールは以下のページに分けて記載しました。

GPT2 や BERT との比較

N-gram で重要な関係だけ抽出する考え方自体は、GPT2 や BERT の穴埋め問題の考え方に近いところがあります。 ただ長文と短文のバランスを考えたりする必要があって、GPT2 や BERT の計算ステップは無駄が多い。 良い短文は数 gram を頻度カウントすれば生成できる直感があるので、わざわざ GPT2 や BERT を使う必要はない気がしています。 ちなみに GPT2 による例文生成もやってはみました。 なんとなく生成はできるのですが、結果が不安定だし、問題によってはボロボロになりがちなで、実用には耐えませんでした。 わざわざ問題を難しくする必要はないのかなと思います。 BERT もダメダメで使い物になりませんが、GPT2 よりは良いかな。 ただ語彙数が少ないため、それに伴う悪影響が大きかったです。

欠点

欠点もあります。(1) 名詞、動詞、副詞、形容詞に付随する関係性を抽出するのは簡単ですが、接続詞は難しいです。 少し考えてみても、接続詞でいい感じの関係性を抽出するには多くの ngram を必要とします。 もっとも日本語の接続詞はそれほど多くないので、接続詞は別途処理すれば、十分に使い物になるコーパスだと思います。

(2) 関係性を抽出できると言っても、あくまで頻度の多さでしか判断できません。 例えば、「責任を追求する」「顔が火照る」で用例はわかるかも知れませんが、意味は正確にわかりません。 ただ日本語は漢字の並びでだいたいの意味がわかるので、案外どうにかなるのかも知れません。 例えば適当に「激燃る」という動詞を作ったとしても、なんか「すごい燃えるんだな」と、十分に意味が通じます。 「しばしば (屡々)」みたいな現代の知識ではどうにもならないケースだけ対処すればいいはずです。

まとめ

とりあえず生成データは既存手法よりずっと使いやすいです。 抽出手法もわかりやすく、せいぜい 5gram くらいの形態素 Web N-gram と、最低限の文法知識だけ用意すれば、汎用的に多言語対応できるのも利点です。 データセットは使いやすい形で公開しているので、使い方はどうぞ。

日本語の共起コーパス wncc-ja の抽出ルール

日本語の共起コーパス wncc-ja を作りました。 日本語と英語を作っているので、概要については こちら を参照してください。 このページでは日本語の抽出方法についてだけ、まとめています。

さて日本語を解析するためには文法について考えないといけません。 日本語の文法は形態素解析の仕様にまとまっているので、以下の 2ページを読んでみてください。 特に重要なのは「助詞」です。
wncc-ja では 日本語ウェブコーパス 2010 の形態素 N-gram を利用して、 [名詞] に対する共起関係を抽出しています。具体的に利用している抽出ルールは以下の通りです。

前方共起

2gram

  • 形容詞 [名詞]
  • 連体詞 [名詞]
  • 動詞(自立) [名詞]

3gram

  • 形容詞(タ接続) た [名詞]
  • 動詞(自立・タ接続) た [名詞]
  • 動詞(自立) 動詞(非自立) [名詞]
  • サ変接続名詞 動詞する [名詞]

4gram

  • 動詞(自立) 動詞(非自立・タ接続) た [名詞]
  • サ変接続名詞 動詞する た [名詞]

後方共起

3gram

  • [名詞] が(格助詞) 形容詞
  • [名詞] は/も/こそ/でも/しか/さえ(係助詞) 形容詞
  • [名詞] など/なり/やら/か(副助詞) 名詞
  • [名詞] (並列助詞) 名詞
  • [名詞] は/も/こそ/でも/しか/さえ(係助詞) 動詞
  • [名詞] ばかり/まで/だけ/ほど/くらい(副助詞) 動詞
  • [名詞] を/へ/と/から/より/で(格助詞) 動詞

4gram (動詞は 1gram 走る or 2gram 追及|する)

  • [名詞] は/も/こそ/でも/しか/さえ(係助詞) サ変接続名詞 動詞する
  • [名詞] ばかり/まで/だけ/ほど/くらい(副助詞) サ変接続名詞 動詞する
  • [名詞] ばかり/まで/だけ/ほど/くらい(副助詞) 動詞 動詞
  • [名詞] を/へ/と/から/より/で(格助詞) サ変接続名詞 動詞する

3-5gram (不採用)

  • [名詞] が/に(格助詞) 動詞 助動詞
具体例:
  • 猫|が|走る
  • 水|が|飲み|たい
  • ダム|が|破壊|さ|れる
  • 前|に|向かう
  • 風|に|吹か|れる
  • 兄|に|追求|さ|れる

正規化

基本語彙のみ処理するときは、せいぜい 4gram を見ればいいのでかなりシンプルと思います。 助動詞は面倒なので辞めました。 とはいえサクッと考えたルールなので、完璧ではないかも知れません。 ちなみに少し迷ったところは 4つあります。

(1) まずは動詞や形容詞の非自立です。 「走り続ける猫」の「続ける」はあまり意味がない情報です。 ただ非自立かどうかを判定するには gram 数が結構必要なので面倒です。 もう形容詞/連体詞なら 2gram、動詞なら 2-3gram で良い気がしました。

(2) 助詞に関しては、形態素解析器の結果をそのまま使えるかはきちんと検討してないですが、 不採用にした「が」と「に」は難しそうな気がしたのでハードコーディングにしました。

(3) 「赤かった花」のように日本語では高確率に「た」が出現するのですが、 こういった活用形のルールをどこまで真面目に考えるべきか。 無視しても良かったのですが、すべて「赤い花」に正規化してみました。

他にも未然形を除外したり、体現接続特殊を除外したり、数詞を除害したり、細かな解析ルールはあります。 あと gram 縛りをしていると気になるのは「〜性、〜感、〜事、〜度」のような接尾辞です。 接尾辞は 3gramだと名詞と判定されてしまうけど、4gramだと接尾や非自立になるので多少のノイズが発生します。 そのへんはコードを見ればわかるのであまり深くは書きませんでした。 細かいところはデータベースを作って、文法ルールのノイズや漏れを確認するのを 10回くらいくり返して、ルールを決めました。

ルール設定は可能な限り努力してみましたが、もっと良い実装があれば今後も改善はしてみたいと思ってます。

2022年4月9日土曜日

Google Ngram (English) の small 版を作った

Google Ngram (English) の small 版 を作りました。 Google Ngram はとても便利なものですが、いかんせんサイズが大きすぎて個人には使いにくい代物です。

google-ngram-small-en

そこで、英語に限定、時間軸は latest、閾値 > 999 で小さくして 1GB 以内に収めたデータセットを作りました。 ほとんどのユースケースはこの条件で足りると思います。 名前は google-ngram-small-en としました。 案の定データ量がやばかったので、構築には一ヶ月くらい掛かりました。 並列実行すればもっと早くできたと思いますが、あまり Google に負荷掛けるのも嫌なので、まったり作りました。 3gram でもデータ量がキツイので、4gram は作ってません。

英語を使って何かしようとすると、なんやかんやこのデータセットを作らないといけないケースが多々ありました。 割と使えるデータセットになっているんじゃないかな。

2022年4月2日土曜日

英会話アプリ Gratalk を作った

日本の英文法学習に従いながら英会話練習できるアプリ、Gratalk を作りました。 ちなみに Speecha という英会話アプリも以前作っていますが、そちらは平文です。



SpeechaGrament で基盤はすべて作ってあるので一瞬で作れたのですが、 ネーミングセンスがないので相変わらず名前が難しかったです。 悩んだ挙げ句、grammar と talk を混ぜて、Gratalk としました。 以下のように S と G を揃えた命名規則にすることで、平文と英文法のアプリ群を見分けやすくしました。
  • Sentency ↔ Grament
  • Speecha ↔ Gratalk

軽く英会話練習をしてみて思ったのですが、学校で習うテンプレ英語ってやっぱ楽ですね。 Speecha の小3〜小4 モードと Gratalk の難易度はレベル的に大差ないはずですが、 Speecha のほうがかなり難しく感じます。

Gratalk の公開にあたって、Speecha もかなり改良を加えておきました。 これまでは既存の音声認識を使っているせいで、固有名詞の判定が厳しい問題がありました。 これはおそらく固有名詞の出現頻度が低く十分な訓練が行われなかったり、日本語の英語表記が本質的に発音しにくいことによると思っています。 そこで固有名詞っぽい単語が出てきたら未知語として処理し、EASY モードでは採点から外すようにしました。 これによってかなり利用しやすくなったと思います。