Hatena::ブログ(Diary)

糞ネット弁慶

日本声優統計学会/声優統計についてはこちら

2017-07-08

[] 「声優統計コーパス : 二次配布可能な音素バランス文とその読み上げ音声の構築」を書いた 17:17  「声優統計コーパス : 二次配布可能な音素バランス文とその読み上げ音声の構築」を書いたを含むブックマーク

声優統計コーパス : 二次配布可能な音素バランス文とその読み上げ音声の構築 (pdf, GitHub)

というわけで

プロの女性声優 3 名が 3 パターンの感情表現で読み上げた音声 2 時間分 を「声優統計コーパス」として無料公開します - 糞ネット弁慶

で公開した声優統計コーパスについて,その作り方,特に音素バランス文の選択について書いた.

やっていることは単純だけど細かい話などがあるので,音素バランス文や音声コーパスを作りたい人の手助けになればいいと思う.

今回はカバーすべきダイフォンの最低登場回数しか考慮していないが,分布そのものを近付ける必要があるのかないのか,理想的なダイフォンの分布があるのか,より読み上げに適した文章や単語を選ぶ必要があるのか,といった話はよくわかっていない.

きっと音声処理を行なう研究室や企業にさまざまなノウハウがあるのだと思う.

[] golangBPR な Factorization Machines を書いた 17:30  golang で BPR な Factorization Machines を書いたを含むブックマーク

Factorization Machines by Golang (BPR, HogWild)

python で実装はしていたけれどもう少し速度が欲しかった.

C++で書こうと思っていたけれど,周りから golang を薦められたので従った.

高速化のためにパラメータ更新は[1106.5730] HOGWILD!: A Lock-Free Approach to Parallelizing Stochastic Gradient Descentにあるような衝突しても構わない形での SGD を使っている.

golang,はじめて書いたけれど型があると気分がいい.go-flymake で書いている最中に何が間違っているかすぐにわかるのもいい.

トラックバック - http://d.hatena.ne.jp/repose/20170708

2017-07-06

[] Field-aware Factorization Machines in a Real-world Online Advertising System (WWW 2017) 読んだ 18:33  Field-aware Factorization Machines in a Real-world Online Advertising System (WWW 2017) 読んだを含むブックマーク

[1701.04099] Field-aware Factorization Machines in a Real-world Online Advertising System

Criteo で Field-aware Factorization Machines を活用している,という話.

気になった点をメモしておく.

複数マシンでの推定

  • Iterative Parameter Mixing を行っているがマシンが増えるほど収束が遅くなる
  • 学習率を大きくすると収束は早くなるが精度が悪くなる
  • そこで学習率を大きくしつつ AdaGrad を用いて精度良く収束させる

FFM と warm start

warm start

FFM を CTR に用いる際の実運用を考えてみると,時系列に従ってパラメータを再学習する必要がある.また, FFM は油断するとすぐに過学習をしてしまうため, early stopping (予測対象とは別に精度評価用のデータを用意し,そのデータに対する予測精度が悪化した時点で学習を止め,その 1 epoch 前のパラメータを返す) を行う必要がある.

なので,ある年の6月のCTRを予測するために1月から4月までを学習データ (train),5月のデータを early stopping 用のデータ (validation) としてパラメータを学習する.7月の CTR を予測するためには2月から5月までを train , 6月を validation にする,といった具合にデータをずらしていく必要がある.

一般パラメータ推定は時間がかかるわけだが,よく考えてみると6月予測と7月予測とでは学習データの多くが重複している.なので,6月予測時に推定したパラメータを,7月予測時にパラメータの初期値に用いることで学習時間を削減することができる.これが warm start.

FFM における naive な warm start は失敗する

ロジスティクス回帰であれば大域的最適解を求めることができるのでこれで問題無い.しかし FFM だと案外問題になってくる.

これを検証するために Criteo data set で実験している.

データを(恐らく時系列に従って)90分割し,1から44ブロックを train,45ブロック目を validation, 46ブロック目を test にして推定と予測を行う.続いて,これを 1 ブロック次にずらして推定と予測を行う(2から45ブロックを train,46ブロックを validation,47ブロックをtest).これを最後まで続けてみる.

この時,何も考えずに warm start を行うと,期間が進めば進むほど予測精度は (warm start を用いないベースラインに比べ) どんどん悪化していく.これではよくない.

pre-mature warm-start

そこで提案しているのが pre-mature な warm-start.

手法はシンプルで, validation set に対する予測誤差が悪化したのが t epoch だとする.ここで推定を終え,t - 1 のパラメータを採用するのはこれまでと同様だが,次のパラメータ推定の初期値に採用するパラメータは t - 2 epoch のものを用いる.

これだけで計算時間も約半分に削減できるし (ベースラインで 7 epoch だったのが 2-3 epoch で終わっている),精度もむしろ良くなっている.

更に, pre-mature warm-start を行うことで train のブロック数を少なくしても十分な精度を発揮している.特に上記実験の期間が進めば進むほどその改善度合いは顕著になっている.

もっと極端な例としては train に 1 ブロックだけ用い, warm-start させなくともいいらしい.CTR においてはデータが多すぎると問題になるという話なのか,そもそも FFM があまりに複雑なモデルである,という話なのか,恐らく両者であると思われる.

[] Trajectory Recovery From Ash: User Privacy Is NOT Preserved in Aggregated Mobility Data (WWW 2017) 読んだ 18:31  Trajectory Recovery From Ash: User Privacy Is NOT Preserved in Aggregated Mobility Data (WWW 2017) 読んだを含むブックマーク

[1702.06270] Trajectory Recovery From Ash: User Privacy Is NOT Preserved in Aggregated Mobility Data

ユーザのプライバシーなどに考慮し,「誰がいつどこにいたか」という生の位置情報ではなく,「どの領域にいつ何人いたか」という集計情報の公開,共有が行われることが増えてきた.例えば,ある基地局がカバーするエリア内に何人の携帯電話所有者がいるか,といったものである.

この論文では,そのような位置情報の集計データから個別のユーザの移動系列に比較的高い精度で分解が可能な,教師なしの手法を提案している.

タイトルがかっこいい.

手法

今, 人のユーザと 個の位置について,時刻 における各地点の総数 の情報が公開されているとする.

この といったように,各ユーザが時刻 にどこにいるか,という情報を集約したものであると考えることができる.

今,時刻 までの各ユーザ ごとの軌跡 (trajectory) が分解でき, で得られているとする.すると,時刻 の位置情報 を軌跡に紐付けるためには

を解けばいいことがわかる.は軌跡と位置情報を紐付ける行列であるため,あとはコスト行列 が適切に設定できれば を求めることができる.

コスト行列は次の 3 要素から構成される.

  • nighttime
    • 夜は同じ場所に留まりやすい,なので位置の距離をコストにすることで近い位置を紐付けやすくする
  • daytime
    • 昼間は移動するので軌跡の差分を移動速度とし,やはり距離をコストにする
  • accross days
    • 上記2つの要素で特定の日付における軌跡を紐付けることはできたが,1日目と2日目の軌跡をどう紐付けたらいいか
    • 「同じユーザは日をまたいでも似たような行動を取る」という知見にもとづき,情報利得をコストにすることで紐付けを行う

実験はスマートフォンの起動時に得られる位置データと,携帯電話会社が提供したユーザの位置情報の二つを用い,集約した後に復元可能かを検証している.精度は73-91%.

全体を通してシンプルかつ自然な話でとても良かった.

トラックバック - http://d.hatena.ne.jp/repose/20170706

2017-06-27

[] プロの女性声優 3 名が 3 パターンの感情表現で読み上げた音声 2 時間分 を「声優統計コーパス」として無料公開します 13:42  プロの女性声優 3 名が 3 パターンの感情表現で読み上げた音声 2 時間分 を「声優統計コーパス」として無料公開しますを含むブックマーク

日本声優統計学会

サークル「日本声優統計学会」の最後の活動として,読んでくださった方々への恩返しの意味を込め, id:reposeid:MagnesiumRibbon声優統計コーパスを上記ページにて公開しました.

概要

声優統計コーパス

  • diphone の出現頻度を考慮しながら独自に構築した音素バランス文
  • その音素バランス文をプロの女性声優 3 名が 3 パターンの感情表現(ニュートラル,喜び,怒り)で読み上げた総長約 2 時間,総ファイルサイズ 720 MB,計900個の音声ファイル

の 2 つで構成されています.

音素バランス文については表示 - 継承 4.0 国際 (CC BY-SA 4.0)で公開しています.

音声ファイルについては研究・分析目的でのみ無償で利用可能です.

音素バランス文

音素バランス文は日本語版 Wikipedia の本文データを元に構築しています.

詳細な手法は後ほど公開しますが,方針としては「声優統計 第九号」で発表した「二次配布可能な音素バランス文と声優統計音声コーパスの構築 (y_benjo, 2017)」と同じです.

すなわち,

  • 全本文データに対して MeCabNEologd を用いて読み推定を行う
  • 読み推定の結果から diphone を数え上げる
  • 頻出 diphone 上位 500 種が最低 N 回含まれるような M 本の文章を線形計画問題を解くことで抽出する
    • この時,MeCab による読み推定が失敗したり, NEologd のいくつかのエントリで読みが壊れている項目があったため,目視による検証,修正を実施

という手続きで構築しています.

音素バランス文では,ATR音素バランス503文が最も有名です.

当初はこちらの利用を検討しましたが,ライセンスを確認したところ503文を読み上げた音声ファイルの無料配布が困難であったため,独自に構築することになりました.

音声ファイル

声優に読み上げてもらうのならばどういう音声がいいだろう」と検討した結果,「演技」に着目し,同一人物に同一文章を異なる感情表現で読み上げてもらう,ということに着地し,このようなファイルとなりました.

コーパスの無料公開という非常識なお願いに加えて無茶な台本に無茶な感情表現リクエストに応えてくださった声優 3 名様のご協力に感謝いたします.


最終号となった第九号の後書きに書いた

同人誌としての声優統計はこれでひとまず終了です.が,サークルとしてはやり残した事が一つあります.

が無事に終了しました.

この声優統計コーパス音声合成や話者推定,感情合成など,音声にまつわる研究や分析の手助けになれば幸いです.

また, google での検索結果に「引用元:N件」の表示がされておもしろくなって欲しいので,ご利用の際は bibtex ファイルを用いて引用していただけると嬉しい.

トラックバック - http://d.hatena.ne.jp/repose/20170627

2017-05-27

[] 自分で実装した Factorization Machines による Bayesian Personalized Ranking を用いた implicit feedback の推定はうまくいった 17:10  自分で実装した Factorization Machines による Bayesian Personalized Ranking を用いた implicit feedback の推定はうまくいったを含むブックマーク

Factorization Machines で Bayesian Personalized Ranking を用いた implicit feedback の推定を行いたかったけどうまくいかなかった - 糞ネット弁慶

Matrix Factorization で Bayesian Personalized Ranking を用いた implicit feedback の推定はうまくいった - 糞ネット弁慶

の続き.

要約

  • Bayesian Personalized Ranking がまだまだ諦められない
  • 前回の実装を発展させ, Factorization Machines を実装して推定したところ AUC が適切な値になった
  • fastFM の使い方が本当に謎.

手法

Factorization Machines である.

入力が「誰が何を買ったか」の 0/1 のみであるとし,その他の特徴量を用いないとすると,

Matrix Factorization は に対する評価は前回同様 となる.この時 は共に 次元の低次元表現ベクトル

Factorization Machines の交互作用を色々と含んだ式をこれに当てはめると となる.ただ が加わっただけであwることがわかる. 次元の行列であり, 次元のベクトル

実装

書いたものを gist にアップロードした.また,前回の実装は正則化項の正負が誤っていたので修正した.

推定する際,本来は であるのだけど, となるため,勾配の計算時にが消えてしまう.そのため今回は 次元で推定している.

実験

データセットは MovieLens 100K Dataset | GroupLens . 5-fold CV 用にデータが既に分かれているのでそれに従う.

元データは Rating だが, implicit feedback の状況を作りたいので,「ユーザが映画をレビューしたかどうか」とし,レビューしていた場合は '1' とする.

学習率は 0.01 ,正則化は V/W 共に = 0.01,行列分解の次元数を 10 とした時,SGD のステップ数とテストデータに対する AUC の平均値との関係を以下に記す.

ステップ数AUC
1 * 800000.5537658848362093
10 * 800000.7635102655525375
50 * 800000.8624333710084262
50 * 80000 (MF)0.8091419600355472

適切に学習できており,ナイーブな Matrix Factorization より改善している.やはり Factorization Machines は少なくともこのデータ,および限定された特徴量ではうまく動いていることがわかる.

ここからは特徴量を増やすことで精度が改善するか確認したい.

では何が問題か

GitHub - ibayer/fastFM: fastFM: A Library for Factorization Machinesの正しい使い方がわかっていない.

自分だけが勘違いしているのかもしれないが,他の人も同じように失敗しているし,そもそもこれで成功している人を見かけない.

トラックバック - http://d.hatena.ne.jp/repose/20170527

2017-05-26

[] Matrix Factorization で Bayesian Personalized Ranking を用いた implicit feedback の推定はうまくいった 17:02  Matrix Factorization で Bayesian Personalized Ranking を用いた implicit feedback の推定はうまくいったを含むブックマーク

Factorization Machines で Bayesian Personalized Ranking を用いた implicit feedback の推定を行いたかったけどうまくいかなかった - 糞ネット弁慶の続き.

要約

  • Bayesian Personalized Ranking が諦められない
  • pairwise な loss を考慮した Matrix Factorization で MovieLens 100K を学習・予測すると AUC が 0.8 程度を示した

手法

Matrix Factorization は ユーザ u \in U とアイテム i \in I を行列 X で表し,X を 2 つの密行列に分解 X \approx H W^T に分解する手法

通常は分解後の行列の積を推定値とし,観測値との誤差を最小化するように分解後の行列の値を更新するが,今回は BPR を目的関数にして学習する.

レコメンドアルゴリズム(BPR)の導出から実装まで - VASILY DEVELOPERS BLOGを読むのが早い.

実装

レコメンドアルゴリズム(BPR)の導出から実装まで - VASILY DEVELOPERS BLOG

機械学習アルゴリズムのボトルネックをCythonで改善する話 - Qiita

実装はこの2記事を参考にしつつ Python3 で動かしたかったので書いたものを gist にアップロードした

勾配計算とパラメータ更新には Cython は使わず numpy を用いたが今回実験に用いたデータぐらいであれば十分な速度が出た.

また,学習データに対する誤差は愚直に BPR を計算すると重すぎる.例えば movielens 100K の cv 1 では 118596998 個のデータに対して計算が必要になる.

vasily の記事ではどうしているのだろうと実装を読むと元行列の値との二乗誤差を学習誤差としていた.これならば 80000 回の計算で済むのでとりあえず真似することした.

しかし,BPR は値の大小関係のみを考慮し、値そのものに対しては無頓着であるため,評価したアイテムに対する予測値が1を超えたり,評価していないアイテムへの予測値が0から遠ざかる(かつ,評価しているアイテムより値が小さい)場合には予測時の AUC が改善するのに学習誤差が悪化するという現象が発生しうる(と思っていたら手元で発生した,良かった)のでその点だけは忘れないようにしたい.

実験

データセットは MovieLens 100K Dataset | GroupLens . 5-fold CV 用にデータが既に分かれているのでそれに従う.

元データは Rating だが, implicit feedback の状況を作りたいので,「ユーザが映画をレビューしたかどうか」とし,レビューしていた場合は '1' とする.

学習率は 0.01 ,正則化の lambda =0.01,行列分解の次元数を 10 とした時,SGD のステップ数とテストデータに対する AUC の平均値との関係を以下に記す.

ステップ数AUC
1 * 800000.5025368957322833
10 * 800000.715481069666248
50 * 800000.8091419600355472

適切に学習できている.良かった.しかし通常の目的関数との比較は未知なので BPR をあえて選ぶかどうかはまた別の実験が必要だと思う.

トラックバック - http://d.hatena.ne.jp/repose/20170526

2017-05-24

[] Factorization Machines で Bayesian Personalized Ranking を用いた implicit feedback の推定を行いたかったけどうまくいかなかった 00:22  Factorization Machines で Bayesian Personalized Ranking を用いた implicit feedback の推定を行いたかったけどうまくいかなかったを含むブックマーク

何故上手くいかなかったのか,あとから再現できるよう忘れないために書く.

要約

  • 回帰や分類ではなく, Bayesian Personalized Ranking にもとづく Factorization Machines を試したい
  • 実装はibayer/fastFM を使い,データに MovieLens 100K を選び実験するも AUC が 0.5 程度から改善しない
  • どう考えても自分の使い方が間違っている

導入

Factorization Machines (ICDM 2010)という手法がある.

論文説明は昔書いた記事( Factorization Machines (ICDM 2010) 読んだ - 糞ネット弁慶)を自分でも見返したりしている.

それとは別の話で BPR (Bayesian Personalized Ranking) と呼ばれる目的関数があり,特に implicit feedback と呼ばれる状況において有効である,とされている.

BPR: Bayesian Personalized Ranking from Implicit Feedback (UAI 2009)

レコメンドアルゴリズム(BPR)の導出から実装まで - VASILY DEVELOPERS BLOG

implicit feedback の例としては,ユーザがある動画を閲覧したかどうか,というデータである.

例えば,ユーザ u_1 が 全 item i_1, ..., i_M のうち,i_1, i_2, i_3 だけを閲覧していたとする.

この時,BPR では「閲覧しなかったものより閲覧したものの方が優れている」という仮定をおき,そのようなスコアを出力する関数を学習する.

つまり,なんらかのスコアを返す関数 f(u, i) について,

f(u_1, i_1) > f(u_1, i_4), f(u_1, i_1) > f(u_1, i_5), ..., f(u_1, i_1) > f(u_1, i_M),

f(u_1, i_2) > f(u_1, i_4), f(u_1, i_2) > f(u_1, i_5), ..., f(u_1, i_2) > f(u_1, i_M),

f(u_1, i_3) > f(u_1, i_4), f(u_1, i_3) > f(u_1, i_5), ..., f(u_1, i_3) > f(u_1, i_M)

といった形の pairwise なデータを作り,この差の和が最大になるように学習を行う.

あとは予測対象の (u, i) に対して学習した関数適用し,スコアを得たならば AUC なり top-K なりが計算できる.

この時,関数は Ranking を学習するものであるため,値の大小関係のみが重要であり,値そのものをなんらかの形では利用できないことは注意する必要がある.

好奇心から BPR を試してみたかったが手頃な実装が見当たらなかった.ちょうどいいところに BRP を目的関数に取る Factorization Machins の実装があったので実験することにした.

実装

Factorization Machines の実装は ibayer/fastFM を使った.

実験に使ったスクリプトgistにアップロードした

pairwise なデータを作るところで愚直に list を使うと重いので np.array を長めに確保して切り詰めるというしょうもないことをやっている.

実験

データは MovieLens 100K Dataset | GroupLens を使った. 5-fold CV 用にデータが既に分かれているのでそれに従う.

元データは Rating だが, implicit feedback の状況を作りたいので「ユーザが映画をレビューしたかどうか」とし,レビューしていた場合は '1' とする.

特徴ベクトルはシンプルにユーザとアイテムとを one-hot encoding したものを concat している.なので今回の場合は 943 + 1682 次元.

学習率は 0.01 ,正則化パラメータデフォルト値,行列分解の次元数を 20 とした時,SGD のステップ数と AUC の平均値との関係を以下に記す.

ステップ数AUC
100.491907136
500.491988281
1000.491724715

明らかにまともに学習できていない.学習率や次元数を変えてみたが改善しない.何か失敗していると思われるが原因が分からない.

トラックバック - http://d.hatena.ne.jp/repose/20170524