オーディオ録音のピークの数を検出する


12

オーディオ録音のコーパス内の音節の数を検出する方法を見つけようとしています。良いプロキシは、Waveファイルのピークかもしれません。

英語で話す私のファイルで試してみたものがあります(私の実際の使用例は、キスワヒリ語です)。このサンプル録音のトランスクリプトは、「これはタイマー機能を使用しようとしている私です。一時停止、発声を見ています。」このパッセージには合計22音節があります。

wavファイル:https : //www.dropbox.com/s/koqyfeaqge8t9iw/test.wav? dl=0

seewaveR のパッケージは素晴らしく、いくつかの潜在的な機能があります。まず最初に、waveファイルをインポートします。

library(seewave)
library(tuneR)
w <- readWave("YOURPATHHERE/test.wav")  
w
# Wave Object
# Number of Samples:      278528
# Duration (seconds):     6.32
# Samplingrate (Hertz):   44100
# Channels (Mono/Stereo): Stereo
# PCM (integer format):   TRUE
# Bit (8/16/24/32/64):    16

私が最初に試したのはtimer()関数です。返されるものの1つは、各発声の持続時間です。この関数は7つの発声を識別しますが、これは22音節に相当しません。プロットをざっと見てみると、発声は音節に等しくないことが示唆されています。

t <- timer(w, threshold=2, msmooth=c(400,90), dmin=0.1)
length(t$s)
# [1] 7

ここに画像の説明を入力してください

また、しきい値を設定せずにfpeaks機能を試しました。54のピークを返しました。

ms <- meanspec(w)
peaks <- fpeaks(ms)

ここに画像の説明を入力してください

これは、時間ではなく周波数で振幅をプロットします。0.005に等しいしきい値パラメーターを追加すると、ノイズが除去され、カウントが23ピークに減少します。これは実際の音節の数にかなり近い値です(22)。

ここに画像の説明を入力してください

これが最善のアプローチかどうかはわかりません。結果は、thresholdパラメーターの値に敏感であり、大量のファイルを処理する必要があります。これをコード化して音節を表すピークを検出する方法についてのより良いアイデアはありますか?


2
これは非常に興味深い質問ですが、Stack Exchange Signal Processing Q&Aサイトでメソッドに関するより良いヘルプを得ることができます
eipi10

わかった、ありがとう。誰も応答しない場合はチェックアウトします。大変感謝いたします。
エリックグリーン

単なるアイデアですが、変化点分析の実施を検討する価値はありますか?分析は、パッケージを使用してRで簡単に実行できchangepointます。簡単に言えば、変化点分析は変化の検出に焦点を当てており、リンクされた例は貿易データに関するものですが、この手法をサウンドデータに適用することは興味深いかもしれません。
コンラッド

投票数が最も多い回答を受け入れますが、これはたまたま別のCVアイデアを実装しようとする試みです。しかし、核となる質問は残っていると思います:録音の機能を使用して、話された音節の数に対応するピークの数を正確に検出する方法。すべてのアイデアをありがとう。解決策がありましたらここに投稿します。
エリックグリーン

回答:


5

以下が最善の解決策だとは思いませんが、@ eipi10にはCrossValidatedでこの答えを確認する良い提案がありました。だから私はやった。

一般的なアプローチは、データを平滑化し、局所最大フィルターと平滑化を比較してピークを見つけることです。

最初のステップは、argmax関数を作成することです:

argmax <- function(x, y, w=1, ...) {
  require(zoo)
  n <- length(y)
  y.smooth <- loess(y ~ x, ...)$fitted
  y.max <- rollapply(zoo(y.smooth), 2*w+1, max, align="center")
  delta <- y.max - y.smooth[-c(1:w, n+1-1:w)]
  i.max <- which(delta <= 0) + w
  list(x=x[i.max], i=i.max, y.hat=y.smooth)
}

その戻り値には、質問に答えるローカル最大値(x)の引数と、それらのローカル最大値が発生するxおよびy配列のインデックス(i)が含まれます。

testプロット関数を少し変更しました。(a)xとyを明示的に定義し、(b)ピークの数を表示します。

test <- function(x, y, w, span) {
  peaks <- argmax(x, y, w=w, span=span)

  plot(x, y, cex=0.75, col="Gray", main=paste("w = ", w, ", span = ", 
                                              span, ", peaks = ", 
                                              length(peaks$x), sep=""))
  lines(x, peaks$y.hat,  lwd=2) #$
  y.min <- min(y)
  sapply(peaks$i, function(i) lines(c(x[i],x[i]), c(y.min, peaks$y.hat[i]),
                                    col="Red", lty=2))
  points(x[peaks$i], peaks$y.hat[peaks$i], col="Red", pch=19, cex=1.25)
}

fpeaks元の質問で述べたアプローチと同様に、このアプローチでもかなりのチューニングが必要です。これに該当する「正しい」答え(つまり、音節/ピークの数)がわからないので、決定ルールを定義する方法がわかりません。

par(mfrow=c(3,1))
test(ms[,1], ms[,2], 2, 0.01)
test(ms[,1], ms[,2], 2, 0.045)
test(ms[,1], ms[,2], 2, 0.05)

ここに画像の説明を入力してください

この時点でfpeaks、私には少し複雑ではないように見えますが、まだ満足できるものではありません。


黄土パラメーターが十分な平滑化を行わないため、満足できない場合があります。よりスムーズな選択は、データの性質と目的によって導かれる必要があります。コンピューティングプラットフォームによって提供されるものや、それが提供するデフォルト値に任せられるものではありません。
whuber

これらはデフォルトではありません。ほんの一例です。この場合、教師なし学習の大きな課題に困惑しています。録音の音節の数がわからないので、ファイルのバッチを調整する方法がわかりません。定数パラメータはおそらく意味をなさないでしょうが、他の決定ルール(たとえば、これらのパラメータの最適値を決定するために使用できる波の他のメトリック)を設定する方法がわかりません。これらのパラメータを設定するアルゴリズムを支援するトレーニングセットを作成する必要があると考えています。わからない。
エリックグリーン

へのコマンドにはloess、平滑化の程度について明示的に指定された引数はありません。実際、移動するウィンドウ上で黄土を実行することはほとんど意味がありません。すでに内部的に実行されています。
whuber

あなたの言ってる事がわかります。それがw平滑化の議論だと思いました。これは、元のソリューションの作成者が関数を説明した方法です。「状況に合わせて調整する2つのパラメーターがあります。wは、極大値を計算するために使用されるウィンドウの半幅です...コード-レスのスパン引数はよりスムーズです。」
エリックグリーン

その著者はw、スムーザーがレスではないかもしれないが、おそらくウィンドウ化された中央値、またはハニング、またはデータとアナリストの目的。これらのスムーザーの多くのプロパティは、ウィンドウの幅に依存します。
whuber

1

タンパク質電気泳動プロファイルを分析する際にも、同様の問題がありました。プロファイルの2番目の派生物にmsprocess Rパッケージのいくつかの関数を適用することでそれらを解決しました(https://fr.wikipedia.org/wiki/D%C3%A9pouillement_d 'une_courbe#Position_et_hauteur_du_picを参照)。これはここで公開されています:http : //onlinelibrary.wiley.com/doi/10.1111/1755-0998.12389/abstract ; jsessionid=8EE0B64238728C0979FF71C576884771.f02t03

同様の解決策があなたのために働くことができるかどうかはわかりません。幸運を


ありがとう、@ user17493.bis。補足資料を公開してくださったことを称賛します。このアイデアを試してみるのがとても簡単になります!
エリックグリーン

0

ここでは、自己相関関数のピークを見つけることによって周期を推定しようとしたときに、Pythonの私でライブラリが以前に使用しています。

ピーク検出に1次差分/離散微分を使用し、しきい値と最小距離(連続するピーク間の)パラメーターによる調整をサポートします。ガウス密度推定と補間を使用してピーク分解能を向上させることもできます(リンクを参照)。

ノイズの多いデータであっても、微調整することなくすぐに使用できました。試してみる。


ありがとう、@ tool.ish。これは、私が引用したRメソッドの優れた代替手段のように見えます。ただし、チューニングの課題はまだ残っていると思います。
エリックグリーン

0

changepointパッケージを利用したソリューションを提案したいと思います。以下の単純化した例では、利用可能なデータから1つのチャネルを見ることにより、ここで変化点として定義されているピークを識別しようとします。

データソース

# Libs
library(seewave)
library(tuneR)

# Download
tmpWav <- tempfile(fileext = ".wav")
download.file(url = "https://www.dropbox.com/s/koqyfeaqge8t9iw/test.wav?dl=0",
              destfile = tmpWav)

# Read
w <- readWave(filename = tmpWav)

データ準備

# Libs
require(changepoint)

# Create time series data for one channel as an example
leftTS <- ts(data = w@left)

## Preview
plot.ts(leftTS)

plot.ts呼び出しによって生成されたチャート: 時系列としてのチャネル

変化点分析

このchangepointパッケージには、データの変更/ピークを識別するための多数のオプションが用意されています。以下のコードは、BinSegメソッドを使用して3つのピークを見つける簡単な例を示しています。

# BinSeg method (example)
leftTSpelt <- cpt.var(data = leftTS, method = "BinSeg", penalty = "BIC", Q = 3)
## Preview
plot(leftTSpelt, cpt.width = 3)

得られたチャート: いくつかの変更点 値を取得することも可能です:

cpts(leftTSpelt)
[1]  89582 165572 181053

サイドノート

提供された例は、提供されたデータに変更点分析を適用する方法を説明することに主に関係しています。cp.var関数に渡されるパラメーターに関しては注意が必要です。パッケージと利用可能な機能の詳細な説明は、次のペーパーに記載されています。

Killick、Rebecca、Eckley、Idris(2014)changepoint:チェンジポイント分析用のRパッケージ。Journal of Statistics Software、58(3)。1-19ページ

ecp

ecpRパッケージに言及する価値があります。これecpにより、ノンパラメトリックな多変量変化点分析が容易になります。これは、複数のチャネルで発生する変化点を特定したい場合に便利です。


ありがとう、@ konrad。私はどちらのパッケージも知らなかったので、デモに時間を割いてくれてありがとう。これらすべてのパッケージで私が抱えている根本的な課題は、探すべきピークの数がわからないことだと思うので、パラメータの調整方法がわかりません。これは、いくつかのアルゴリズムを使用して、パラメーターを設定して正しいピーク(つまり、音節)の数を正確に特定する方法を決定する必要がある状況のようです。
エリックグリーン

@EricGreen原則として、変化点分析では、分布を見ることでピークを特定できます。適切な方法、罰則などを適用することになるでしょう。プロセスの詳細を概説しているので、以前のコメントでリンクされているWebサイトをご覧になることをお勧めします。
コンラッド

あなたが文字通り分布を目で見て意味するかどうかはわかりません。2000個のファイルがあり、これを自動化する方法が必要です。各ファイルを調べることができたとしても、音節の数をピークとして見るのは困難です。たぶん私は密集していて、このアプローチのメリットを見に来るでしょう。検出されたピークの結果の数が音節の数の正確なプロキシとなるように、各ファイルのパラメーターを自動調整する方法が必要になっています。
エリックグリーン

@EricGreenいいえ、もちろん文学ではありません。cpt関数の1つに渡す必要のある適切なパラメーターを把握すれば、任意の数のオブジェクトで実行できます。言語学の専門知識がないため、音節が時系列データで観察される通常のピークに対応するかどうかはわかりません。
コンラッド

わかった。この特定のユースケースの「適切なパラメーターを図に示す」ステップにつまずいていると思います。しかし、私はすべてのアイデアを高く評価し、私が試したパッケージの良い代替品になる可能性のあるいくつかの新しいパッケージについて学びました。
エリックグリーン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.