phát hiện số đỉnh trong bản ghi âm


12

Tôi đang cố gắng tìm ra cách phát hiện số lượng âm tiết trong một bản ghi âm. Tôi nghĩ rằng một proxy tốt có thể là đỉnh trong tệp sóng.

Đây là những gì tôi đã thử với một tập tin tôi nói bằng tiếng Anh (trường hợp sử dụng thực tế của tôi là bằng tiếng Kiswaya). Bảng điểm của bản ghi ví dụ này là: "Đây là tôi đang cố gắng sử dụng chức năng hẹn giờ. Tôi đang xem tạm dừng, phát âm." Có tổng cộng 22 âm tiết trong đoạn văn này.

tập tin wav: https://www.dropbox.com/s/koqyfeaqge8t9iw/test.wav?dl=0

Các seewavegói vào R là rất tốt, và có một số chức năng tiềm năng. Điều đầu tiên trước tiên, nhập tệp sóng.

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

Điều đầu tiên tôi đã thử là timer()chức năng. Một trong những điều nó trả về là thời lượng của mỗi lần phát âm. Chức năng này xác định 7 cách phát âm, thiếu 22 âm tiết. Nhìn nhanh vào cốt truyện cho thấy rằng cách phát âm không bằng các âm tiết.

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

nhập mô tả hình ảnh ở đây

Tôi cũng đã thử chức năng fpeaks mà không đặt ngưỡng. Nó đã trả lại 54 đỉnh.

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

nhập mô tả hình ảnh ở đây

Âm mưu này biên độ theo tần số chứ không phải thời gian. Thêm một tham số ngưỡng bằng 0,005 lọc tiếng ồn và giảm số đếm xuống còn 23 đỉnh, khá gần với số lượng âm tiết thực tế (22).

nhập mô tả hình ảnh ở đây

Tôi không chắc đây là cách tiếp cận tốt nhất. Kết quả sẽ nhạy cảm với giá trị của tham số ngưỡng và tôi phải xử lý một lô tệp lớn. Bất kỳ ý tưởng tốt hơn về cách mã hóa này để phát hiện các đỉnh đại diện cho âm tiết?


2
Đây là một câu hỏi rất thú vị, nhưng bạn có thể nhận được trợ giúp tốt hơn về các phương pháp tại trang web Hỏi & Đáp xử lý tín hiệu Stack Exchange .
eipi10

được rồi cảm ơn. sẽ kiểm tra xem nếu không ai phản hồi. Nhiều đánh giá cao.
Eric Green

Chỉ là một ý tưởng, nhưng nó có đáng để xem xét thực hiện phân tích điểm thay đổi ? Việc phân tích có thể được thực hiện dễ dàng trong R với việc sử dụng changepointgói. Nói một cách đơn giản, phân tích điểm thay đổi tập trung vào việc phát hiện thay đổi, ví dụ được liên kết có liên quan đến dữ liệu thương mại nhưng thật thú vị khi áp dụng kỹ thuật này vào dữ liệu âm thanh.
Konrad

Tôi sẽ chấp nhận câu trả lời có nhiều phiếu bầu nhất, đó là nỗ lực của tôi để thực hiện một ý tưởng CV khác. Tuy nhiên, tôi nghĩ rằng câu hỏi cốt lõi vẫn là: làm thế nào để sử dụng các tính năng của bản ghi để phát hiện chính xác một số đỉnh tương ứng với số lượng âm tiết được nói. Cảm ơn bạn cho tất cả các ý tưởng. Tôi sẽ đăng lại ở đây khi tôi có một giải pháp.
Eric Green

Câu trả lời:


5

Tôi không nghĩ những gì sau đây là giải pháp tốt nhất, nhưng @ eipi10 có một gợi ý hay để xem câu trả lời này trên CrossValidated . Tôi cũng vậy.

Một cách tiếp cận chung là làm mịn dữ liệu và sau đó tìm các đỉnh bằng cách so sánh bộ lọc tối đa cục bộ với độ mịn.

Bước đầu tiên là tạo argmaxchức năng:

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

Giá trị trả về của nó bao gồm các đối số của cực đại cục bộ (x) - câu trả lời cho câu hỏi - và các chỉ mục vào các mảng x và y nơi xảy ra các cực đại cục bộ đó (i).

Tôi đã thực hiện các sửa đổi nhỏ cho testhàm vẽ: (a) để xác định rõ ràng x và y và (b) để hiển thị số lượng đỉnh:

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

Giống như fpeakscách tiếp cận tôi đã đề cập trong câu hỏi ban đầu của mình, cách tiếp cận này cũng đòi hỏi một sự điều chỉnh tốt. Tôi sẽ không biết câu trả lời "đúng" (nghĩa là số lượng âm tiết / đỉnh) đi vào điều này, vì vậy tôi không chắc chắn cách xác định quy tắc quyết định.

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)

nhập mô tả hình ảnh ở đây

Tại thời điểm này fpeakscó vẻ ít phức tạp hơn với tôi, nhưng vẫn không thỏa mãn.


Nó có thể không thỏa mãn vì các tham số hoàng thổ của bạn không làm đủ mịn. Việc lựa chọn nhu cầu mượt mà hơn phải được hướng dẫn bởi bản chất của dữ liệu và các mục tiêu; nó không phải là thứ để lại cho bất cứ thứ gì được cung cấp bởi nền tảng điện toán và các giá trị mặc định mà nó cung cấp.
whuber

Đây không phải là mặc định. Chỉ là ví dụ. Tôi bối rối trước thách thức lớn hơn của việc học tập không giám sát trong trường hợp này. Tôi không biết số lượng âm tiết trong bản ghi, vì vậy tôi không chắc cách điều chỉnh một loạt tệp. Các tham số không đổi có thể không có ý nghĩa, nhưng tôi không chắc cách thiết lập một số quy tắc quyết định khác (ví dụ: các số liệu khác của sóng có thể được sử dụng để xác định giá trị tối ưu cho các tham số này). Tôi nghĩ rằng tôi cần phải tạo một tập huấn luyện giúp một số thuật toán đặt các tham số này. Không chắc chắn mặc dù.
Eric Green

Trong lệnh của bạn loess, tôi thấy không có đối số được đưa ra rõ ràng cho mức độ làm mịn. Trên thực tế, có rất ít điểm để chạy hoàng thổ trên một cửa sổ đang di chuyển: nó đã thực hiện điều đó trong nội bộ.
whuber

Tôi thấy điểm của bạn. Tôi cho rằng đó wlà một đối số trong làm mịn. Đây là cách tác giả của giải pháp ban đầu mô tả hàm: "Có hai tham số được điều chỉnh theo các trường hợp: w là nửa chiều rộng của cửa sổ được sử dụng để tính toán tối đa cục bộ ... Một - không rõ ràng trong điều này mã - là đối số nhịp của hoàng thổ mượt mà hơn. "
Eric Green

Tác giả đó bao gồm wmột trong các tham số vì anh ta có một cách tiếp cận rất chung chung, trong đó mượt mà hơn có thể không phải là hoàng thổ nhưng có lẽ sẽ là một trung gian cửa sổ, hoặc Hanning, hoặc bất cứ điều gì khác được coi là phù hợp với hành vi thống kê của dữ liệu và mục tiêu của nhà phân tích. Các thuộc tính của nhiều máy làm mịn sẽ phụ thuộc vào chiều rộng của cửa sổ.
whuber

1

Tôi đã có vấn đề tương tự để phân tích hồ sơ điện di protein. Tôi đã giải quyết chúng bằng cách áp dụng một số chức năng của gói ms process R trên các dẫn xuất thứ hai của các cấu hình (xem https://fr.wikipedia.org/wiki/D%C3%A9pouillement_d 'une_courbe # Position_et_hauteur_du_pic). Điều này đã được xuất bản ở đây: http : // onlinel Library.wiley.com/doi/10.1111/1755-0998.12389/abauge;jsessionid=8EE0B64238728C0979FF71C576884771.f02t03

Tôi không biết liệu giải pháp tương tự có thể làm việc cho bạn. Chúc may mắn


cảm ơn, @ user17493.bis. Kudos cho bạn để xuất bản với các tài liệu bổ sung. sẽ làm cho nó dễ dàng hơn nhiều để tôi thử ý tưởng này!
Eric Green

0

Đây là một thư viện trong Python tôi đã sử dụng trước đó trong khi cố gắng ước tính tính định kỳ bằng cách tìm các đỉnh trong hàm tự tương quan.

Nó sử dụng các khác biệt thứ nhất / các dẫn xuất riêng biệt để phát hiện đỉnh và hỗ trợ điều chỉnh theo các tham số ngưỡng và khoảng cách tối thiểu (giữa các đỉnh liên tiếp). Người ta cũng có thể tăng cường độ phân giải cực đại bằng cách sử dụng ước lượng và nội suy mật độ Gaussian (xem liên kết).

Nó hoạt động khá tốt đối với tôi mà không cần chỉnh sửa nhiều, ngay cả đối với dữ liệu ồn ào. Hãy thử một lần.


Cảm ơn, @ tool.ish. Nó trông giống như một sự thay thế tốt cho các phương pháp R mà tôi đã trích dẫn. Tôi nghĩ rằng tôi vẫn có thách thức điều chỉnh, tuy nhiên.
Eric Green

0

Tôi muốn đề xuất một giải pháp sử dụng changepointgói. Ví dụ đơn giản dưới đây cố gắng xác định các đỉnh, được xác định ở đây là các điểm thay đổi bằng cách xem xét một kênh từ dữ liệu có sẵn.

Thí dụ

Tìm nguồn dữ liệu

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

Chuẩn bị dữ liệu

# Libs
require(changepoint)

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

## Preview
plot.ts(leftTS)

Biểu đồ được tạo qua plot.tscuộc gọi: Kênh theo chuỗi thời gian

Phân tích điểm thay đổi

Các changepointgói cung cấp một số tùy chọn để xác định những thay đổi / đỉnh trong dữ liệu. Mã dưới đây chỉ cung cấp một ví dụ đơn giản về việc tìm 3 đỉnh bằng phương pháp BinSeg :

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

Biểu đồ thu được: Một số điểm thay đổi Cũng có thể nhận được các giá trị:

cpts(leftTSpelt)
[1]  89582 165572 181053

Ghi chú bên

Ví dụ được cung cấp chủ yếu liên quan đến việc minh họa cách phân tích điểm thay đổi có thể được áp dụng cho dữ liệu được cung cấp; cần thận trọng đối với các tham số được truyền cho cp.varhàm. Một lời giải thích chi tiết về gói và các chức năng có sẵn được đưa ra trong bài báo sau:

Thay đổi Killick, Rebecca và Eckley, Idris (2014) : gói R để phân tích thay đổi. Tạp chí phần mềm thống kê, 58 (3). trang 1-19.

ecp

ecp, là một gói R đáng nói . Việc ecptạo điều kiện thực hiện phân tích điểm thay đổi đa biến không tham số, có thể hữu ích nếu người ta muốn xác định các điểm thay đổi xảy ra trên nhiều kênh.


Cảm ơn, @konrad. Tôi không biết về một trong hai gói, vì vậy cảm ơn bạn đã dành thời gian để demo. Tôi nghĩ rằng thách thức cơ bản mà tôi có với tất cả các gói này là tôi không biết cần tìm bao nhiêu đỉnh, vì vậy tôi không chắc chắn làm thế nào để điều chỉnh các tham số. Đây có vẻ vẫn là một tình huống mà tôi phải sử dụng một số thuật toán để xác định cách đặt các tham số để xác định chính xác số lượng đỉnh chính xác (nghĩa là các âm tiết).
Eric Green

@EricGreen Về mặt chính, phân tích điểm thay đổi sẽ cho phép bạn xác định các đỉnh của mình chỉ bằng cách xem phân phối. Nó sẽ là một vấn đề của việc áp dụng một phương pháp phù hợp, hình phạt và như vậy. Tôi sẽ đề nghị bạn nên xem trang web được liên kết trong bình luận trước đây của tôi vì nó phác thảo chi tiết quá trình.
Konrad

Tôi không chắc chắn nếu bạn thực sự có nghĩa là nhãn cầu phân phối. Tôi có 2000 tệp và cần một cách để tự động hóa việc này. Ngay cả khi tôi có thể kiểm tra từng tệp, tôi cũng khó thấy số lượng âm tiết là đỉnh. Có lẽ tôi đang dày đặc và tôi sẽ đến để thấy những ưu điểm của phương pháp này. Tôi vẫn bị mắc kẹt khi cần một cách để tự động điều chỉnh các tham số của mỗi tệp để số lượng đỉnh được phát hiện là một proxy chính xác cho số lượng âm tiết.
Eric Green

@EricGreen Không, tất nhiên không phải là văn học. Nếu bạn tìm ra các tham số thích hợp sẽ được chuyển đến một trong các hàm cpt, bạn sẽ có thể chạy nó trên bất kỳ số lượng đối tượng nào. Vì tôi không có chuyên môn về ngôn ngữ học nên tôi không biết liệu âm tiết có tương ứng với các đỉnh thông thường được quan sát trên dữ liệu chuỗi thời gian hay không.
Konrad

gotcha. Tôi nghĩ rằng tôi đang vấp phải bước "tìm ra các thông số phù hợp" cho trường hợp sử dụng cụ thể này. Nhưng tôi đã đánh giá cao tất cả các ý tưởng và tìm hiểu về một vài gói mới có thể là lựa chọn thay thế tốt cho những gói tôi đã thử.
Eric Green
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.