Как определить тренды по некоторым значениям? - PullRequest
2 голосов
/ 16 декабря 2011

Я пытаюсь отметить некоторые тренды, поэтому у меня 1 - самое низкое, а 5 - самое большое.

Так, например,

У меня может быть следующий случай:

5,4,5,5   (UP)
3,4,      (UP)
4,3,3     (DOWN)
4,4,4,4,  (FLAT - this is OK for all same numbers)

Я планирую иметь неограниченное количество упорядоченных значений в качестве входных данных, а в качестве выходных данных я просто покажу изображение (UP), (DOWN) или (FLAT).

Есть идеи, как мне этого добиться?

Извините, если я недостаточно описательный.

Спасибо всем за потраченное время.

Ответы [ 6 ]

4 голосов
/ 16 декабря 2011

Используйте метод наименьших квадратов для расчета «наклона» значений.

function leastSquareFit(array $values) {
    $x_sum = array_sum(array_keys($values));
    $y_sum = array_sum($values);
    $meanX = $x_sum / count($values);
    $meanY = $y_sum / count($values);
    // calculate sums
    $mBase = $mDivisor = 0.0;
    foreach($values as $i => $value) {
        $mBase += ($i - $meanX) * ($value - $meanY);
        $mDivisor += ($i - $meanX) * ($i - $meanX);
    }

    // calculate slope
    $slope = $mBase / $mDivisor;
    return $slope;
}   //  function leastSquareFit()

$trend = leastSquareFit(array(5,4,5,5));

(не проверено)

Если наклон положительный, тренд восходящий;если отрицательный, это вниз.Используйте свое собственное суждение, чтобы решить, какая маржа (положительная или отрицательная) считается плоской.

2 голосов
/ 16 декабря 2011

Сложно ответить на основании предоставленной вами ограниченной информации, но при условии, что:

  • , если вообще нет движения, тренд - FLAT,
  • в противном случае,тренд - последнее направление движения,

, тогда этот код должен работать:

$input = array();

$previousValue = false;
$trend = 'FLAT';

foreach( $input as $currentValue ) {
    if( $previousValue !== false ) {
        if( $currentValue > $previousValue ) {
            $trend = 'UP';
        } elseif( $currentValue < $previousValue ) {
            $trend = 'DOWN';
        }
    }
    $previousValue = $currentValue;
} 
0 голосов
/ 28 мая 2014

Я использовал код из @liquorvicar для определения тенденций рейтинга страниц поиска Google, но добавил некоторые дополнительные значения трендов, чтобы сделать его более точным:

без изменений - без изменений

лучше (более высокая позиция Google = меньшее число)

хуже (нижняя позиция Google = большее число)

Я также добавил дополнительные проверки, когда последнее значение не изменилось, но с учетом предыдущих изменений, т.е.

worsenochange (без изменений, предыдущий был хуже - меньшее число)

betternochange (без изменений, предыдущий был лучше - меньшее число)

Я использовал эти значения для отображения диапазона значков трендов:

$_trendIndicator="<img title="trend" width="16" src="/include/main/images/trend-'. $this->getTrend($_positions). '-icon.png">";

example of trend icons

    private function getTrend($_positions)
{
    // calculate trend based on last value
    //
    $_previousValue = false;
    $_trend = 'nochange';

    foreach( $_positions as $_currentValue ) {

        if( $_previousValue !== false ) {

            if( $_currentValue > $_previousValue ) {
                $_trend = 'better';
            } elseif( $_currentValue < $_previousValue ) {
                $_trend = 'worse';
            }

            if ($_trend==='worse' && ($_previousValue == $_currentValue)) {$_trend = 'worsenochange';}

            if ($_trend==='better' && ($_previousValue == $_currentValue)) {$_trend = 'betternochange';}
        }

        $_previousValue = $_currentValue;
    } 

    return $_trend;
}
0 голосов
/ 16 декабря 2011
echo foo(array(5,4,5,5)); // UP
echo foo(array(3,4)); // UP
echo foo(array(4,3,3)); // DOWN
echo foo(array(4,4,4,4)); // FLAT

function foo($seq)
{
    if (count(array_unique($seq)) === 1)
        return 'FLAT';

    $trend = NULL;
    $count = count($seq);
    $prev = $seq[0];
    for ($i = 1; $i < $count; $i++)
    {
        if ($prev < $seq[$i])
        {
            $trend = 'UP';
        }
        if ($prev > $seq[$i])
        {
            $trend = 'DOWN';
        }
        $prev = $seq[$i];
    }

    return $trend;
}
0 голосов
/ 16 декабря 2011

Для ваших примеров:

  • Вычислить самую длинную возрастающую подпоследовательность, A
  • Вычислить самую длинную убывающую подпоследовательность, B

Исходя из вашей логики, если длинаA больше, чем B, его вверх, в противном случае вниз.Вам также необходимо отслеживать все равные, используя одну булеву переменную для обозначения тренда FLAT.

Запрос: Какой тренд будет:

3,4,5,4,3 ?
3,4,4,4,3 ?
1,2,3,4,4,3,2,2,1 ?

Тогда логике могут потребоваться некоторые изменения в зависимости откаковы ваши требования.

0 голосов
/ 16 декабря 2011

Я не уверен, полностью ли я понимаю вашу проблему, но я бы поместил значения в массив и использовал такой код (написанный в псевдокоде):

    int i = 0;
    String trend = "FLAT":
    while(i<length(array)) {
       if(array(i)<array(i+1)) {
          trend = "UP";
       }
       else if(array(i)>array(i+1) {
          trend = "DOWN";
       }
       i++;
    }

РЕДАКТИРОВАТЬ: это, очевидно, толькоотображать тренд последнего изменения, можно также посчитать, сколько раз тренд был восходящим или нисходящим, и определить общий тренд по этим значениям

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...