使用迭代值增量进行趋势分析

Dav*_*vis 6 java algorithm data-analysis ireport

我们已经配置 iReport 来生成以下图表:

真实数据点为蓝色,趋势线为绿色。问题包括:

  • 趋势线的数据点太多
  • 趋势线不遵循贝塞尔曲线(样条线)

问题的根源在于增量器类。增量器被迭代地提供数据点。似乎没有办法获取这组数据。计算趋势线的代码如下:

import java.math.BigDecimal;
import net.sf.jasperreports.engine.fill.*;

/**
 * Used by an iReport variable to increment its average.
 */
public class MovingAverageIncrementer
  implements JRIncrementer {
  private BigDecimal average;

  private int incr = 0;

  /**
   * Instantiated by the MovingAverageIncrementerFactory class.
   */
  public MovingAverageIncrementer() {
  }

  /**
   * Returns the newly incremented value, which is calculated by averaging
   * the previous value from the previous call to this method.
   * 
   * @param jrFillVariable Unused.
   * @param object New data point to average.
   * @param abstractValueProvider Unused.
   * @return The newly incremented value.
   */
  public Object increment( JRFillVariable jrFillVariable, Object object, 
                           AbstractValueProvider abstractValueProvider ) {
    BigDecimal value = new BigDecimal( ( ( Number )object ).doubleValue() );

    // Average every 10 data points
    //
    if( incr % 10 == 0 ) {
      setAverage( ( value.add( getAverage() ).doubleValue() / 2.0 ) );
    }

    incr++;

    return getAverage();
  }


  /**
   * Changes the value that is the moving average.
   * @param average The new moving average value.
   */
  private void setAverage( BigDecimal average ) {
    this.average = average;
  }

  /**
   * Returns the current moving average average.
   * @return Value used for plotting on a report.
   */
  protected BigDecimal getAverage() {
    if( this.average == null ) {
      this.average = new BigDecimal( 0 );
    }

    return this.average;
  }

  /** Helper method. */    
  private void setAverage( double d ) {
    setAverage( new BigDecimal( d ) );
  }
}
Run Code Online (Sandbox Code Playgroud)

您将如何创建更平滑、更准确的趋势线表示?

Jay*_*ton 4

这取决于您正在测量的项目的行为。这是以可以建模的方式移动(或改变)的东西吗?

如果预计该项目不会发生变化,那么您的趋势应该是整个样本集的基础平均值,而不仅仅是过去两次测量的平均值。您可以使用贝叶斯定理得到这个。可以使用简单的公式增量计算运行平均值

Mtn1 = (Mtn * N + x) / (N+1)

其中 x 是时间 t+1 时的测量值,Mtn1 是时间 t+1 时的平均值,Mtn 是时间 t 时的平均值,N 是时间 t 时进行的测量次数。

如果您正在测量的项目以某种基本方程可以预测的方式波动,那么您可以使用卡尔曼滤波器根据先前(最近)的测量值和对预测进行建模的方程来提供下一个点的最佳估计行为。

作为起点,维基百科有关贝叶斯估计器和卡尔曼滤波器的条目将会有所帮助。