Факторинг шума в алгоритме - PullRequest
0 голосов
/ 07 февраля 2012

У меня, по сути, есть куча объектов данных, которые отображают временные метки в миллисекундах для плавающих значений. Я ищу, по существу, найти пик / максимум данных в заданном диапазоне. По сути, я использовал что-то вроде этого:

float previousValue = 0;
for (int i = 0; i < data.size(); i++) {
    MyData value = data.get(i);
    if (value.getData() < previousValue) {
        // found the peak!
        break;
    } else {
        previousValue = value.getData();
    }
}

Единственная проблема этого алгоритма в том, что он не учитывает шум. По сути, я мог бы иметь такие значения:

[0.1025, 0.3000, 0.3025, 0.3500, 0.3475, 0.3525, 0.1025]

Фактический пик находится на уровне 0,3525, но мой алгоритм, приведенный выше, будет видеть его как 0,3500, поскольку он идет первым. Из-за характера моих вычислений я не могу просто сделать max() для массива и найти наибольшее значение, мне нужно найти наибольшее значение, которое приходит первым, прежде чем оно упадет.

Как я могу найти вершину своего пика, учитывая некоторую дисперсию шума?

Ответы [ 2 ]

1 голос
/ 07 февраля 2012

Есть две проблемы:

  1. фильтрация шума;
  2. поиск пика.

Похоже, у вас уже есть решение для2, и нужно решить 1.

Чтобы отфильтровать шум, вам нужен какой-то фильтр нижних частот . скользящее среднее является одним из таких фильтров.Например, экспоненциальное скользящее среднее очень просто реализовать и должно работать хорошо.

В итоге: проведите серию через фильтр, а затем примените алгоритм поиска пиков.

0 голосов
/ 20 марта 2014

Более простой способ найти один пик (или самое высокое значение) в массиве (любой числовой массив: int, double) - это циклически проходить по массиву и устанавливать для переменной самое высокое значение ...

Пример: (во всех примерах используется массив с плавающей запятой, называемый «data»)

float highest = 0; //use a number equal to or below the lowest possible value
for (int i = 0; i < data.length; i++){
    if (data[i] > highest){
        highest = data[i];
    }
}

, чтобы найти несколько пиков в шумной фильтрации данных, из-за некоторого шума Я использовал этот метод:

boolean[] isPeak = new boolean[20]; // I am looking for 20 highest peaks
float[] filter = new float[9]; // the range to which I want to define a peak is 9
float[] peaks = new float[20]; // again the 20 peaks I want to find
float lowpeak = 100; // use a value higher than the highest possible value
// first we start the filter cycling through the data
for (int i = 0; i < data.length; i++){
    for (int a = filter.length-1; a > 0; a--){
        filter[a] = filter[a-1];
    }
    filter[0] = data[1]
    // now we check to see if the filter detects a peak
    if (filter[4]>filter[0] && filter[4]>filter[1] && filter[4]>filter[2] &&
            filter[4]>filter[3] && filter[4]>filter[5] && filter[4]>filter[6] &&
            filter[4]>filter[7] && filter[4]>filter[8]){
        // now we find the lowest peak
        for (int x = 0; x < peaks.lengt-1; x++){
            if (peaks[x] < lowpeak){
                lowpeak = peaks[x];
            }
        }
        // now we check to see if the peak is above the lowest peak 
        for (int x = 0; x < peaks.length; x++){
            if (peaks[x] > lowpeak && peaks[x] != peaks[x+1]){
                for (int y = peaks.length-1; y > 0 && !isPeak[y]; y--){
                peaks[y] = peaks[y-1];
                }
                peaks[0] = filter[4];
            }
        }
    }
}

это может быть не самый эффективный способ сделать это, но он выполняет свою работу!

...