違和感は、たった一つの数字から始まった

私たちは、声を録音すると話し方の傾向を数値化する診断ツールを公開しています。

その蓄積データを別の目的で集計していたとき、一つの数字が目に留まりました。

男性の平均基本周波数(F0)の中央値が、168.7Hz

基本周波数とは、声帯が1秒間に何回振動しているかを表す値で、いわゆる「声の高さ」にあたります。この数字は、感覚的に高すぎるように見えました。

対象は、社内テストを除いた外部利用者280名分です。男性101名、女性177名。記録期間は約4か月でした。

データが十分に集まっていても、その数字が何を測っているのかを確かめなければ、集計は意味を持ちません。

文献値と40%ずれていた

成人男性の発話時の基本周波数は、研究では概ね100〜130Hzの範囲で報告されてきました。Hollien と Shipp が1972年に発表した研究をはじめ、複数の調査がこの帯域を示しています。

私たちの実測値168.7Hzは、この上限をさらに30%以上超えています。

女性側も見てみました。中央値238.7Hz。こちらは文献値(およそ190〜220Hz)をやや上回る程度で、日本語話者の女性F0が欧米の報告より高いという指摘もあるため、説明のつく範囲でした。

男性の値だけが、説明しにくい。これが出発点でした。

念のため、分布の形も確認しました。男性101名のうち、140Hz以下だったのは14名だけ。四分位範囲は151.7〜193.1Hzで、分布全体が高いほうへ寄っています。一部の外れた人が引き上げているのではなく、全体が高く出ていました。

一部の異常値なら分布の端に出ます。全体が寄っているときは、測定そのものを疑う必要があります。

最初に立てた仮説は外れた

最初に疑ったのは、推定アルゴリズムそのものでした。

このツールは自己相関という手法でF0を求めています。音の波形を少しずつずらして自分自身と重ね合わせ、最もよく一致するずらし幅から周期を求める方法です。

コードを読んだところ、重ね合わせの計算が「ずらし幅が大きいほど比較できる範囲が狭くなる」性質を持っているように見えました。それなら、短いずらし幅=高い周波数が選ばれやすくなり、F0が高く出る説明がつきます。

この仮説は、後の検証で否定されました。

ここは正直に書いておきます。コードを読んだだけで原因を確信し、修正案まで用意していました。しかし実際に動かしてみると、私たちが「修正版」として書いたコードのほうが、200Hzの音を100Hzと誤る深刻な間違いを起こしました。

コードを読んで立てた仮説は、動かして確かめるまでは仮説のままです。読んだだけで直すと、直した側が壊れます。

正解のわかる音で測ってみる

人の声には「本当のF0」という正解がありません。別のツールで測っても、それもまた推定値です。比較しても、どちらが正しいかを決められません。

そこで、正解が数学的に確定している音を作りました。

声帯の振動を模した倍音を含む波形で、周波数を完全に一定に固定したものです。110Hz、130Hz、200Hzの3種類を用意し、それぞれ40秒分。生成したあと、別の方法で測り直して、設定どおりの周波数になっていることを確認しました。

これを診断のコードにかけた結果です。

正解出力誤差
110Hz110.0Hz−0.0%
130Hz130.1Hz+0.1%
200Hz200.5Hz+0.2%

誤差は0.25%以内。アルゴリズムは正確でした。

さらに、現実の録音で起こりうる劣化も試しました。マイクの特性で基音(最も低い成分)が失われた場合、基音を完全に取り除いた場合、雑音を加えた場合、話している途中で声の高さが変わる場合。

いずれも正しく検出しました。 基音を完全に取り去っても110Hzと答えます。倍音の並び方から周期を読み取っているためで、これはむしろ優れた実装です。

録音環境も原因ではなかった

次に疑ったのは録音環境です。静かな場所では大きな声を出しにくく、それが影響しているのではないか、という見立てでした。

280件のデータで、録音音量とF0の関係を調べました。

音量の区分(男性)F0の中央値
最も静か(下位25%)166.3Hz
やや静か187.4Hz
やや大きい166.4Hz
最も大きい(上位25%)163.8Hz

相関係数は−0.05。ほぼ無関係でした。

なお生理的には、大きな声を出すほど声門下の圧力が上がり、F0は上がる方向に働きます。Coleman らが1977年に報告した音圧レベルとF0の関係もこの向きです。つまり「静かに話したこと」は、F0を下げる方向に働くはずで、今回の高さの説明にはなりません。

ブラウザの録音処理も調べました。同じ人が同じ原稿を、ページの録音機能とスマートフォンの録音アプリの両方で読み、比較しています。結果は160.4Hzと151.4Hz。差は5.9%で、主因ではありませんでした。

一コマずつ見て、ようやく見えた

集計値を眺めている限り、原因は見つかりませんでした。

このツールは、音声を40ミリ秒ごとの小さな区切りに分け、その一つひとつでF0を求めています。42.7秒の録音なら、区切りは2,133個。そのうち音量が十分にあった1,263個が集計に使われていました。

この1,263個を、すべて分布として並べてみました。

F0の帯域区切りの数
0–100Hz90
100–130Hz475
130–160Hz475
160–200Hz133
200–250Hz22
250–400Hz15
400–600Hz53

声の実体は100〜160Hzに集中しています。成人男性としてまったく正常な位置です。

ところが、400〜600Hzに53個が固まっていました。人間の発話のF0としてありえない高さです。

これはサ行やハ行といった摩擦音の区切りでした。声帯があまり振動しない、雑音に近い音です。周期性が乏しいため、自己相関がたまたま短いずらし幅に一致を見つけてしまう。自己相関を使うF0推定では、こうした誤りが起こりうることが知られています。

集計後の数字をいくら眺めても原因は見えません。一段細かい単位に戻して、分布として見る必要があります。

7%の外れ値が、平均を15%押し上げていた

原因が分かったので、影響の大きさを測りました。

集計方法結果
全区切りの単純平均(従来の方法)151.4Hz
中央値134.0Hz
200Hzを超える区切りを除いた平均131.9Hz

200Hzを超えていたのは90個。全体の7.1%です。

この7.1%を取り除くだけで、平均は151.4Hzから131.9Hzへ下がりました。19.5Hz、率にして14.8%の差です。

ばらつきを表す標準偏差は、もっと激しく動きました。

従来の標準偏差82.7Hz
外れ値を除いた場合23.1Hz

3.6倍に膨らんでいました。

標準偏差は、平均からの距離を二乗して足し合わせます。距離が2倍離れた値は4倍、3倍離れた値は9倍の重みで効きます。外れ値の影響が平均よりはるかに大きく出るのは、この計算の仕組みによります。

平均と中央値の差が、そのまま歪みの大きさ

ここで注目したいのは、平均151.4Hzと中央値134.0Hzの差です。

平均と中央値が大きく離れているとき、分布は左右対称ではありません。 どちらか一方に極端な値が伸びています。今回は高いほうへ伸びていました。

中央値は、値を小さい順に並べたときの真ん中です。端にどれだけ極端な値があっても、真ん中の位置はほとんど動きません。10個の値のうち1個が10倍になっても、中央値は変わらないのです。

この性質は、声の分析に限りません。

  • 平均年収と中央値の年収が違う理由も同じです
  • 平均滞在時間が実感より長いのも、ごく一部の長時間利用者が引き上げているからです
  • 平均応答時間が良好に見えるのに苦情が減らないのも、遅い一部が平均に埋もれるからです

平均と中央値を並べて見るだけで、その数字が信用できるかどうかの見当がつきます。差が大きければ、平均は代表値として機能していません。

歪んだ数字は、判定結果まで連れていく

このツールは、測定した数値をもとに話し方を8つの型に分類しています。

分類には2つの指標を使います。

  • 声の高さの水準 — 測定したF0を、性別ごとの基準値で割った比率
  • 抑揚の大きさ — ばらつきをF0で割った比率

基準値は男性120Hz、女性220Hzに設定されていました。これは文献値どおりで、正しい設定です。

しかし、入力される測定値が膨らんでいたため、こうなっていました。

指標実測値「最大」と判定される境界
声の高さの水準1.341.30
抑揚の大きさ0.5590.24

抑揚については、境界の2.3倍です。振り切れています。

そして、これは1人の話ではありませんでした。280件全体で見ても、男性の声の高さの水準は1.41、抑揚は0.35。ほぼ全員が「声が高く、抑揚が極端に大きい」と判定される状態でした。

その結果、8つの型が分離しません。280件のうち58%が同じ型に集中していました。

分類の設計自体は妥当でした。基準値も正しかった。入力される数字だけが歪んでいて、それが最終的な判定まで運ばれていたのです。

何を直したか

修正は2点です。

1つ目は、集計を平均から中央値に変えました。 ばらつきの指標も、中央絶対偏差という外れ値に強い方法に置き換えています。これは正規分布のときに標準偏差と同じ尺度になるため、分類の境界値はそのまま使えます。

2つ目は、探索する周波数の範囲を性別ごとに絞りました。 従来は男女共通で80〜600Hzを探していました。男性の録音で400〜600Hzを探す必要はありません。範囲を70〜250Hzにすれば、あの53個の誤検出は構造的に発生しなくなります。

同じ録音で比べた結果です。

F0ばらつき抑揚の指標
修正前151.4Hz82.7Hz0.546(振り切れ)
修正後132.0Hz25.7Hz0.195(正常範囲)

そしてもう一つ、将来のために変えたことがあります。

従来は、区切りごとのF0を計算していながら、保存していたのは集計後の2つの数字だけでした。そのため、過去280件を新しい方法で計算し直すことができません。 音声も保存していないため、取り返しがつきません。

今後は区切りごとの値をすべて保存します。集計方法をまた変えることになっても、過去に遡って計算し直せます。あわせて、従来の方法で計算した値も併記して残すことにしました。1件増えるごとに新旧の対応が貯まるため、過去データを補正するための係数を、通常の利用から自動的に求められます。

数字を扱う仕事に共通する教訓

この検証から得たことは、声の分析に限りません。

第一に、平均と中央値を並べて見ることです。 差が大きければ、その平均は代表値として機能していません。今回は151.4と134.0という差が、そのまま歪みの大きさでした。

第二に、集計値を眺めても原因は見えないということです。 分布として、できるだけ細かい単位に戻して見る必要があります。私たちも1,263個の区切りを並べて初めて、400〜600Hzの塊に気づきました。

第三に、コードを読んで立てた仮説は仮説にすぎないということです。 私たちは最初の仮説を外しました。読んだだけで修正していたら、直した側が新しい不具合を持ち込んでいました。

第四に、集計後の値だけを残さないことです。 元になった値を残しておけば、方法を変えたときに遡れます。今回、これをしていなかったために280件が救えませんでした。

数字は、集計された瞬間に情報を失います。何を捨てたのかを意識せずに集計すると、後から取り戻せません。

まとめ

自社の声の分析データ280件を検証したところ、全体の7.1%にあたる外れ値が、平均を14.8%押し上げていました。

推定アルゴリズム自体は正確でした。合成音での誤差は0.25%以内で、基音が失われても雑音が入っても正しく動きます。録音環境も原因ではありませんでした。音量との相関は−0.05で、ほぼ無関係です。

原因は、区切りごとの測定値を単純平均で集計していたことでした。摩擦音の区切りで生じる少数の誤検出が、平均と標準偏差の両方を押し上げ、その歪みが最終的な分類結果まで運ばれていました。

修正は、中央値への変更と、性別ごとの探索範囲の限定です。あわせて、区切りごとの値を保存する仕組みを追加しました。

平均値は、少数の極端な値に弱い指標です。中央値と並べて確認する習慣があれば、その数字が実態を映しているかどうかを、集計した本人が最初に気づけます。

参考文献・出典

本記事で触れた研究の一次情報は以下のとおりです。

  • Hollien, H., & Shipp, T. (1972). Speaking Fundamental Frequency and Chronologic Age in Males. Journal of Speech and Hearing Research, 15(1), 155–159. https://doi.org/10.1044/jshr.1501.155
  • Coleman, R. F., Mabis, J. H., & Hinson, J. K. (1977). Fundamental Frequency-Sound Pressure Level Profiles of Adult Male and Female Voices. Journal of Speech and Hearing Research, 20(2), 197–204. https://doi.org/10.1044/jshr.2002.197
  • Staudacher, M., Steixner, V., Griessner, A., & Zierhofer, C. (2016). Fast fundamental frequency determination via adaptive autocorrelation. EURASIP Journal on Audio, Speech, and Music Processing, 2016(1). https://doi.org/10.1186/s13636-016-0095-8