如何根据某些值定义趋势?

时间:2011-12-16 08:46:51

标签: php math

我试图标记一些趋势,所以我有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 个答案:

答案 0 :(得分:4)

使用最小二乘拟合来计算值的“斜率”。

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

(未测试的)

如果斜率为正,则趋势向上;如果是负面的,那就是向下的。用你自己的判断来决定什么边际(正面或负面)被认为是平的。

答案 1 :(得分:2)

根据您提供的有限信息有点难以回答,但假设:

  • 如果没有任何动作,那么趋势是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;
} 

答案 2 :(得分:0)

我不确定我是否完全理解你的问题,但我会将值放在数组中并使用这样的代码(用伪代码编写):

    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++;
    }

编辑:这显然只会显示最新更改的趋势 也可以计算趋势上升或下降的次数,并通过该值确定整体趋势

答案 3 :(得分:0)

对于您的示例:

  • 计算最长的增加子序列A
  • Calulate最长的减少子序列B

按照你的逻辑,如果A的长度大于B,则为UP,否则为DOWN。 您还需要使用一个布尔变量跟踪所有等于标记FLAT趋势。

查询: 趋势是什么:

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

然后逻辑可能需要根据您的要求进行一些更改。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

我使用@liquorvicar中的代码来确定Google搜索页面排名趋势,但添加了一些额外的趋势值以使其更准确:

nochange - 没有变化

更好(更高的谷歌位置=更低的数字)

更糟糕的是(较低的谷歌位置=较高的数字)

当最后一个值没有变化时,我还添加了额外的检查,但考虑到之前的变化,即

恶化改变(没有变化,前期更糟糕 - 更低的数字)

betternochange(没有变化,previouse更好 - 更低的数字)

我使用这些值来显示一系列趋势图标:

$_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;
}