ses kaydındaki tepe sayısını algıla


12

Ben ses kayıtları bir grup hece sayısını tespit etmek anlamaya çalışıyorum. Bence iyi bir vekil dalga dosyasında zirveler olabilir.

İşte İngilizce konuşan bir dosya ile denedim (gerçek kullanım durumum Kiswahili'de). Bu örnek kaydın transkripti: "Bu benim zamanlayıcı işlevini kullanmaya çalışıyorum. Duraklamalara, seslendirmelere bakıyorum." Bu pasajda toplam 22 hece vardır.

wav dosyası: https://www.dropbox.com/s/koqyfeaqge8t9iw/test.wav?dl=0

seewaveR paket harika ve birkaç olası fonksiyonlar vardır. İlk önce dalga dosyasını içe aktarın.

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

Denediğim ilk şey işlevdi timer(). Geri döndüğü şeylerden biri de her seslendirmenin süresidir. Bu işlev, 22 heceden çok kısa olan 7 vokalizasyonu tanımlar. Konuya hızlı bir bakış, seslendirmelerin hecelere eşit olmadığını göstermektedir.

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

resim açıklamasını buraya girin

Ayrıca bir eşik ayarlamadan fpeaks işlevini denedim. 54 tepe döndü.

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

resim açıklamasını buraya girin

Bu, genliği zaman yerine frekansa göre çizer. 0.005'e eşit bir eşik parametresi eklemek gürültüyü filtreler ve sayıyı gerçek hecelerin sayısına oldukça yakın olan 23 pik'e düşürür (22).

resim açıklamasını buraya girin

Bunun en iyi yaklaşım olduğundan emin değilim. Sonuç, eşik parametresinin değerine duyarlı olacak ve büyük bir dosya toplu işlemek zorundayım. Heceleri temsil eden zirveleri tespit etmek için bunu nasıl kodlayacağınız hakkında daha iyi fikirler var mı?


2
Bu çok ilginç bir soru, ancak Stack Exchange Sinyal İşleme Soru-Cevap sitesindeki yöntemler konusunda daha iyi yardım alabilirsiniz .
eipi10

tamam teşekkürler. kimse yanıt vermezse kontrol edecektir. çok takdir etmek.
Eric Green

Sadece bir fikir, ama değişim noktası analizi yapmayı düşünmek faydalı olur mu? Analiz , ambalajın kullanımı ile R'de kolayca yapılabilir changepoint. Basitçe söylemek gerekirse, değişim noktası analizi değişimin algılanmasına odaklanır , bağlantılı örnek ticaret verileri ile ilgilidir, ancak bu tekniği sağlam verilere uygulamak ilginç olabilir.
Konrad

En çok oy alan cevabı kabul edeceğim, bu da başka bir CV fikri uygulama girişimim olacak. Ancak asıl soru kalıyor: konuşulan hecelerin sayısına karşılık gelen bir dizi zirveyi doğru bir şekilde tespit etmek için kayıtların özelliklerinin nasıl kullanılacağı. Tüm fikirler için teşekkür ederim. Bir çözüm bulduğumda buraya geri göndereceğim.
Eric Green

Yanıtlar:


5

Aşağıdaki en iyi çözüm olduğunu düşünmüyorum, ancak @ eipi10 CrossValidated üzerinde bu yanıtı kontrol etmek için iyi bir öneri vardı . Ben de yaptım.

Genel bir yaklaşım, verileri düzeltmek ve daha sonra yerel bir maksimum filtreyi pürüzsüz ile karşılaştırarak tepe noktaları bulmaktır.

İlk adım argmaxişlevi oluşturmaktır :

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)
}

Dönüş değeri, soruyu cevaplayan yerel maxima (x) argümanlarını ve bu yerel maxima'nın meydana geldiği x- ve y-dizilerine indeksleri içerir (i).

testÇizim işlevinde küçük değişiklikler yaptım : (a) açıkça x ve y tanımlamak için ve (b) tepe sayısını göstermek için:

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)
}

fpeaksOrijinal sorumda bahsettiğim yaklaşım gibi , bu yaklaşım da iyi bir ayarlama gerektirir. Bunun içine "doğru" cevabı (yani hece / zirve sayısı) bilmiyorum, bu yüzden nasıl bir karar kuralı tanımlamak için emin değilim.

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)

resim açıklamasını buraya girin

Bu noktada fpeaksbenim için biraz daha az karmaşık görünüyor, ancak yine de tatmin edici değil.


Less parametreleriniz yeterli yumuşatma yapmadığından tatmin edici olmayabilir. Daha pürüzsüz seçim, verilerin niteliği ve hedefleri tarafından yönlendirilmelidir; bilgi işlem platformu ve sağladığı varsayılan değerler tarafından sunulanlara bırakılacak bir şey değildir.
whuber

Bunlar varsayılan değerler değildir. Sadece örnekler. Bu durumda denetimsiz öğrenmenin daha büyük zorluklarından dolayı şaşırıyorum. Kayıtlardaki hecelerin sayısını bilmiyorum, bu yüzden bir grup dosyayı nasıl ayarlayacağımdan emin değilim. Sabit parametreler muhtemelen anlamlı değildir, ancak diğer bazı karar kurallarının nasıl ayarlanacağından emin değilim (örneğin, bu parametreler için en uygun değerleri belirlemek için kullanılabilecek dalganın diğer metrikleri). Bazı algoritmaların bu parametreleri ayarlamasına yardımcı olan bir eğitim seti oluşturmam gerektiğini düşünüyorum. Yine de emin değilim.
Eric Green

Emrinizle In loess, ben açıkça yumuşatma derecesi için verilen hiçbir argümanları görüyoruz. Aslında, hareket eden bir pencerede loess'i çalıştırmanın pek bir anlamı yoktur: bunu zaten dahili olarak yapar.
whuber

Senin değinmek istediğin noktayı anlıyorum. Bunun wyumuşatmadaki bir argüman olduğunu varsaydım . Orijinal çözümün yazarı şu şekilde açıklanmıştır: "Koşullara göre ayarlanacak iki parametre vardır: w, yerel maksimum değeri hesaplamak için kullanılan pencerenin yarım genişliğidir ... Başka - bu açık değil kodu - daha düzgün olan daha iyi bir yayılma argümanıdır. "
Eric Green

Bu yazar wparametrelerden biri olarak dahil edildi, çünkü daha pürüzsüz olanın yalnız olmayabileceği, ancak belki de pencereli bir medyan veya Hanning veya verilerin istatistiksel davranışı için uygun görülen başka bir şey olabileceği çok genel bir yaklaşıma sahipti. analistin amaçları. Bu düzleştiricilerin çoğunun özellikleri pencerenin genişliğine bağlı olacaktır.
whuber

1

Protein elektroforez profillerini analiz etmek için benzer problemler yaşadım. Profillerin ikinci türevlerine msprocess R paketinin bazı işlevlerini uygulayarak bunları çözdüm (bkz. Https://fr.wikipedia.org/wiki/D%C3%A9pouillement_d 'une_courbe # Position_et_hauteur_du_pic). Bu, burada yayınlanmıştır: http://onlinelibrary.wiley.com/doi/10.1111/1755-0998.12389/abstract;jsessionid=8EE0B64238728C0979FF71C576884771.f02t03

Benzer çözümün sizin için işe yarayıp yaramayacağı hakkında hiçbir fikrim yok. İyi şanslar


teşekkürler, @ user17493.bis. tamamlayıcı malzeme ile yayınladığınız için size kudos. bu fikri denememi çok daha kolaylaştıracak!
Eric Green

0

İşte otokorelasyon fonksiyonundaki zirveleri bularak periyodunu tahmin etmek isterken Python I'de bir kütüphane daha önce kullanılır.

Tepe tespiti için birinci dereceden farklar / ayrık türevler kullanır ve eşik ve minimum mesafe (ardışık pikler arasında) parametreleriyle ayarlamayı destekler. Gauss yoğunluk kestirimi ve enterpolasyon kullanılarak tepe çözünürlüğü de artırılabilir (bağlantıya bakınız).

Gürültülü veriler için bile, çok ince ayar yapmadan benim için kutudan oldukça iyi çalıştı. Bir şans ver.


Teşekkürler, @ tool.ish. Belirttiğim R yöntemlerine iyi bir alternatif gibi görünüyor. Ancak yine de ayarlama zorluğuna sahip olacağımı düşünüyorum.
Eric Green

0

changepointPaketi kullanan bir çözüm önermek istiyorum . Aşağıdaki basit örnek , mevcut verilerden bir kanala bakarak, burada değişiklik noktaları olarak tanımlanan zirveleri belirlemeye çalışır .

Misal

Veri kaynağı

# 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)

Veri Hazırlama

# Libs
require(changepoint)

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

## Preview
plot.ts(leftTS)

plot.tsÇağrı yoluyla oluşturulan grafik : Zaman serisi olarak kanal

Değişim noktası analizi

changepointPaket tanımlanması için seçenek bir dizi sağlar değişiklikleri / tepe noktaları veri. Aşağıdaki kod, BinSeg yöntemini kullanarak 3 tepe noktası bulmanın basit bir örneğini sunmaktadır :

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

Elde edilen grafik: Değer Bazı değişiklik noktaları almak da mümkündür:

cpts(leftTSpelt)
[1]  89582 165572 181053

Yan notlar

Sağlanan örnek çoğunlukla değişiklik noktası analizinin sağlanan verilere nasıl uygulanabileceğini göstermekle ilgilidir; cp.varişleve iletilen parametreler konusunda dikkatli olunmalıdır . Paketin ve mevcut işlevselliklerin ayrıntılı bir açıklaması aşağıdaki makalede verilmiştir:

Killick, Rebecca ve Eckley, Idris (2014) değişim noktası: değişim noktası analizi için bir R paketi. İstatistiksel Yazılım Dergisi, 58 (3). s. 1-19.

ecp

ecp, R paketinden bahsetmeye değer başka bir şeydir . ecpBir birden fazla kanal üzerinden meydana gelen değişim noktaları tespit etmek istiyorum yararlı olabilir kolaylaştırır girişim parametrik olmayan çok değişkenli değiştirme noktası analizi.


Teşekkürler, @konrad. Her iki paketi de bilmiyordum, bu yüzden demoya zaman ayırdığınız için teşekkürler. Bence bu paketlerin hepsiyle ilgili temel zorluk, kaç tane tepe noktası arayacağımı bilmememdir, bu yüzden parametreleri nasıl ayarlayacağımdan emin değilim. Bu hala doğru sayıda tepe noktası (yani heceler) doğru tanımlamak için parametreleri ayarlamak için bazı algoritma kullanmak zorunda olduğu bir durum gibi görünüyor.
Eric Green

@EricGreen Prensip olarak, değişim noktası analizi, sadece dağılıma bakarak zirvelerinizi belirlemenizi sağlayacaktır. Bu uygun bir yöntem, cezalar vb. Uygulamak meselesidir. Süreci ayrıntılı olarak özetlediğinden önceki yorumumda bağlantı verilen web sitesine göz atmanızı öneririm.
Konrad

Kelimenin tam anlamıyla dağılımı hizalamak istediğinizden emin değilim. 2000 dosyam var ve bunu otomatikleştirmek için bir yola ihtiyacım var. Her dosyayı inceleyebilsem bile, hecelerin sayısını zirve olarak görmekte zorlanıyorum. Belki yoğunum ve bu yaklaşımın esasını görmeye geleceğim. Hâlâ tespit edilen zirve sayısı hecelerin sayısı için doğru bir proxy olduğundan, her dosyanın parametrelerini otomatik olarak ayarlamanın bir yoluna ihtiyacım var.
Eric Green

@EricGreen Hayır, elbette edebi değil. Cpt işlevlerinden birine geçirilmesi gereken uygun parametreleri anlarsanız , onu istediğiniz sayıda nesne üzerinde çalıştırabilirsiniz. Dilbilimde uzmanlığım olmadığı için, hecelerin zaman serisi verilerinde görülen olağan zirvelere karşılık gelip gelmeyeceğini bilmiyorum.
Konrad

Anladım. Ben bu özel kullanım durumu için "uygun parametreleri bulmak" adım tökezlemek düşünüyorum. Ancak tüm fikirleri takdir ettim ve denediklerime iyi alternatif olabilecek birkaç yeni paket öğrendim.
Eric Green
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.