如何对给定序列进行趋势预测

1. 趋势预测的定义

趋势预测法又称趋势分析法。是指自变量为时间,因变量为时间的函数的模式。

趋势预测法的主要优点是考虑时间序列发展趋势,使预测结果能更好地符合实际。

2. 如何对给定序列计算趋势

序号

1

562

2

345

3

567

4

652

5

249

已知以上序列,分别计算趋势线性趋势,指数趋势,对数趋势以及乘幂趋势。

2.1线性趋势

a) 趋势图
b) 计算方法:

/// <summary>

/// 计算序列的线性趋势相关系数

/// </summary>

/// <param name="serials"></param>

public void CalculateLinEstTrendline(Dictionary<double, double> serials)

{

double[] xArray = new double[serials.Count];

double[] yArray = new double[serials.Count];

xArray = serials.Keys.ToArray<double>();

yArray = serials.Values.ToArray<double>();

//计算线性回归线的斜率

object m = worksheetFuncion.Slope(yArray, xArray);

//计算线性回归线的截距

object b = worksheetFuncion.Intercept(yArray, xArray);

//计算 Pearson 乘积矩相关系数的平方

object rsquare = worksheetFuncion.RSq(yArray, xArray);

//趋势参数赋值

linEstParams[0] = (double)rsquare;

linEstParams[1] = (double)m;

linEstParams[2] = (double)b;

}

2.2指数趋势

a) 趋势图
b) 计算方法

/// <summary>

/// 计算序列的指数趋势相关系数

/// </summary>

/// <param name="serials"></param>

public void CalculateExponentialTrendline(Dictionary<double, double> serials)

{

double[] xArray = new double[serials.Count];

double[] yArray = new double[serials.Count];

xArray = serials.Keys.ToArray<double>();

yArray = serials.Values.ToArray<double>();

double[] lnyArray = new double[serials.Count];

for (int i = 0; i < yArray.Length; i++)

{

lnyArray[i] = worksheetFuncion.Ln(yArray[i]);

}

object tmp = worksheetFuncion.LinEst(lnyArray, xArray, oMissing, oMissing);

object b = worksheetFuncion.Index(tmp, 1, oMissing, oMissing);

object c = Math.Exp((double)worksheetFuncion.Index(tmp, 1, 2, oMissing));

//计算 Pearson 乘积矩相关系数的平方

object rsquare = worksheetFuncion.RSq(lnyArray, xArray);

//趋势参数赋值

exponentialParams[0] = (double)rsquare;

exponentialParams[1] = (double)c;

exponentialParams[2] = (double)b;

}

2.3对数趋势

a) 趋势图
b) 计算方法

/// <summary>

/// 计算序列的对数趋势相关系数

/// </summary>

/// <param name="serials"></param>

public void CalculateLogarithmicTrendline(Dictionary<double, double> serials)

{

double[] xArray = new double[serials.Count];

double[] yArray = new double[serials.Count];

xArray = serials.Keys.ToArray<double>();

yArray = serials.Values.ToArray<double>();

double[] lnxArray = new double[serials.Count];

for (int i = 0; i < xArray.Length; i++)

{

lnxArray[i] = worksheetFuncion.Ln(xArray[i]);

}

object tmp = worksheetFuncion.LinEst(yArray, lnxArray, oMissing, oMissing);

object b = worksheetFuncion.Index(tmp, 1, oMissing, oMissing);

object c = worksheetFuncion.Index(tmp, 1, 2, oMissing);

//计算 Pearson 乘积矩相关系数的平方

object rsquare = worksheetFuncion.RSq(yArray, lnxArray);

//趋势参数赋值

logarithmicParams [0] = (double)rsquare;

logarithmicParams[1] = (double)b;

logarithmicParams[2] = (double)c;

}

2.4乘幂趋势

a) 趋势图
b) 计算方法:

/// <summary>

/// 计算序列的乘幂趋势相关系数

/// </summary>

/// <param name="serials"></param>

public void CalculatePowerTrendline(Dictionary<double, double> serials)

{

double[] lnxArray=new double[serials.Count];

double[] lnyArray = new double[serials.Count];

for (int i = 0; i < serials.Count; i++)

{

lnxArray[i] = worksheetFuncion.Ln(serials.Keys.ToArray()[i]);

lnyArray[i] = worksheetFuncion.Ln(serials.Values.ToArray()[i]);

}

object tmp=worksheetFuncion.LinEst(lnyArray ,lnxArray ,oMissing ,oMissing );

object b = worksheetFuncion.Index(tmp, 1, oMissing, oMissing);

object c = Math.Exp((double)worksheetFuncion.Index(tmp, 1, 2, oMissing));

//计算 Pearson 乘积矩相关系数的平方

object rsquare = worksheetFuncion.RSq(lnyArray, lnxArray);

//趋势参数赋值

powerParams[0] = (double)rsquare;

powerParams[1] = (double)c;

powerParams[2] = (double)b;

}

3给定序列,分别计算线性趋势,对数趋势,指数趋势,乘幂趋势,并根据R2值得到最合理的趋势方程。

完整代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Office.Interop.Excel;

/***********************************************************************
    * Module: 
    * Author:      hbb0b0@163.com
    * Create Date:  2010/11/28        
    * Summary: Excel内置函数辅助类
 **********************************************************************
*/

namespace TrendlinesLib
{
    
/// <summary>
    
/// 趋势计算委托
    
/// </summary>
    
/// <param name="x">输入值</param>
    
/// <returns>返回趋势值</returns>
    public delegate double TrendlineExpression(double x);

    
/// <summary>
    
/// Excel趋势辅助工具
    
/// </summary>
    public class ExcelTrendLineHelper : IDisposable
    {
       
        
#region Filed

        
/// <summary>
        
/// 用于存放 Application的实例 
        
/// </summary>
        private _Application xlApp = null;

        
/// <summary>
        
/// Excel 函数集对象
        
/// </summary>
        private WorksheetFunction worksheetFuncion = null;

        
public WorksheetFunction WorksheetFuncion
        {
            
get { return worksheetFuncion; }
            
set { worksheetFuncion = value; }
        }

        
/// <summary>
        
/// 缺省参数的默认值
        
/// </summary>
        private System.Reflection.Missing oMissing = System.Reflection.Missing.Value;

        
/// <summary>
        
/// 是否被处置标志
        
/// </summary>
        private bool Disposed = false;

        
/// <summary>
        
/// 趋势表达式
        
/// </summary>
        private TrendlineExpression trendLineExpression = null;

        
/// <summary>
        
/// 线性趋势相关参数
        
/// </summary>
        private double[] linEstParams = new double[3];

        
public double[] LinEstParams
        {
            
get { return linEstParams; }
            
        }

        
/// <summary>
        
/// 乘幂趋势相关参数
        
/// </summary>
        private double[] exponentialParams = new double[3];

        
public double[] ExponentialParams
        {
            
get { return exponentialParams; }
         
        }

        
/// <summary>
        
/// 对数趋势相关参数
        
/// </summary>
        private double[] logarithmicParams = new double[3];

        
public double[] LogarithmicParams
        {
            
get { return logarithmicParams; }
         
        }

        
/// <summary>
        
/// 指数趋势相关参数
        
/// </summary>
        private double[] powerParams = new double[3];

        
public double[] PowerParams
        {
            
get { return powerParams; }
            
        }

        
/// <summary>
        
/// 趋势表达式
        
/// </summary>
        public  TrendlineExpression TrendLineExpression
        {
            
get { return trendLineExpression; }
        }
 
        
#endregion

        
#region Property


        
#endregion

        
#region Method

        
#region IDisposable 成员

        
public void Dispose()
        {

            Dispose(
true);
            GC.SuppressFinalize(
this);
        }

        
protected virtual void Dispose(Boolean disposing)
        {
            
if (!this.Disposed)
            {
                
if (disposing)
                {

                    xlApp.Application.Quit();
                    xlApp.Quit();

                    System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheetFuncion);
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);

                    xlApp 
= null;
                    worksheetFuncion 
= null;
                    GC.Collect();
                }
                
this.Disposed = true;

            }
        }

        
#endregion

        
~ExcelTrendLineHelper()
        {
            Dispose(
false);

        }

        
/// <summary>
        
/// 构造函数
        
/// </summary>
        public ExcelTrendLineHelper()
        {
            xlApp 
= new ApplicationClass();

            worksheetFuncion 
= xlApp.WorksheetFunction;
        }

        
        
/// <summary>
        
/// 计算序列的线性趋势相关系数
        
/// </summary>
        
/// <param name="serials"></param>
        public void CalculateLinEstTrendline(Dictionary<doubledouble> serials)
        {
            
double[] xArray = new double[serials.Count];

            
double[] yArray = new double[serials.Count];

            xArray 
= serials.Keys.ToArray<double>();

            yArray 
= serials.Values.ToArray<double>();

            
//计算线性回归线的斜率
            object m = worksheetFuncion.Slope(yArray, xArray);


            
//计算线性回归线的截距
            object b = worksheetFuncion.Intercept(yArray, xArray);

            
//计算 Pearson 乘积矩相关系数的平方
            object rsquare = worksheetFuncion.RSq(yArray, xArray);

            
//趋势参数赋值
            linEstParams[0= (double)rsquare;
            linEstParams[
1= (double)m;
            linEstParams[
2= (double)b;

        }

        
/// <summary>
        
/// 计算序列的对数趋势相关系数
        
/// </summary>
        
/// <param name="serials"></param>
        public void CalculateLogarithmicTrendline(Dictionary<doubledouble> serials)
        {
            
double[] xArray = new double[serials.Count];

            
double[] yArray = new double[serials.Count];

            xArray 
= serials.Keys.ToArray<double>();

            yArray 
= serials.Values.ToArray<double>();

            
double[] lnxArray = new double[serials.Count];

            
for (int i = 0; i < xArray.Length; i++)
            {

                lnxArray[i] 
= worksheetFuncion.Ln(xArray[i]);
            }

            
object tmp = worksheetFuncion.LinEst(yArray, lnxArray, oMissing, oMissing);

            
object b = worksheetFuncion.Index(tmp, 1, oMissing, oMissing);

            
object c = worksheetFuncion.Index(tmp, 12, oMissing);

            
//计算 Pearson 乘积矩相关系数的平方
            object rsquare = worksheetFuncion.RSq(yArray, lnxArray);

            
//趋势参数赋值
            logarithmicParams [0= (double)rsquare;
            logarithmicParams[
1= (double)b;
            logarithmicParams[
2= (double)c;

           

        }

        
/// <summary>
        
/// 计算序列的指数趋势相关系数
        
/// </summary>
        
/// <param name="serials"></param>
        public void CalculateExponentialTrendline(Dictionary<doubledouble> serials)
        {
            
double[] xArray = new double[serials.Count];

            
double[] yArray = new double[serials.Count];

            xArray 
= serials.Keys.ToArray<double>();

            yArray 
= serials.Values.ToArray<double>();

            
double[] lnyArray = new double[serials.Count];

            
for (int i = 0; i < yArray.Length; i++)
            {
                
                lnyArray[i] 
= worksheetFuncion.Ln(yArray[i]);
            }

            
object tmp = worksheetFuncion.LinEst(lnyArray, xArray, oMissing, oMissing);

            
object b = worksheetFuncion.Index(tmp, 1, oMissing, oMissing);

            
object c = Math.Exp((double)worksheetFuncion.Index(tmp, 12, oMissing));

            
//计算 Pearson 乘积矩相关系数的平方
            object rsquare = worksheetFuncion.RSq(lnyArray, xArray);

            
//趋势参数赋值
            exponentialParams[0= (double)rsquare;
            exponentialParams[
1= (double)c;
            exponentialParams[
2= (double)b;

        }

        
/// <summary>
        
/// 计算序列的乘幂趋势相关系数
        
/// </summary>
        
/// <param name="serials"></param>
        public void  CalculatePowerTrendline(Dictionary<doubledouble> serials)
        {
           
            
double[] lnxArray=new double[serials.Count];
            
double[] lnyArray = new double[serials.Count];

            
for (int i = 0; i < serials.Count; i++)
            {
                lnxArray[i] 
= worksheetFuncion.Ln(serials.Keys.ToArray()[i]);
                lnyArray[i] 
= worksheetFuncion.Ln(serials.Values.ToArray()[i]);
            }

            
object tmp=worksheetFuncion.LinEst(lnyArray ,lnxArray ,oMissing ,oMissing  );

            
object b = worksheetFuncion.Index(tmp, 1, oMissing, oMissing);

            
object c = Math.Exp((double)worksheetFuncion.Index(tmp, 12, oMissing));
            
            
//计算 Pearson 乘积矩相关系数的平方
            object rsquare = worksheetFuncion.RSq(lnyArray, lnxArray);

            
//趋势参数赋值
            powerParams[0= (double)rsquare;
            powerParams[
1= (double)c;
            powerParams[
2= (double)b;

        }

        
/// <summary>
        
/// 线性趋势表达式
        
/// </summary>
        
/// <param name="x">输入值</param>
        
/// <returns>预测值</returns>
        private double LinEstExpressionTrendline(double x)
        {
            
double y = linEstParams[1* x + linEstParams[2];
            
return y;
        }

        
/// <summary>
        
/// 对数趋势表达式
        
/// </summary>
        
/// <param name="x">输入值</param>
        
/// <returns></returns>
        private double LogarithmicExpressionTrendline(double x)
        {
            
double y = logarithmicParams[1*Math.Log(x) - logarithmicParams[2];
            
return y;
        }

        
/// <summary>
        
/// 指数趋势表达式
        
/// </summary>
        
/// <param name="x">输入值</param>
        
/// <returns></returns>
        private double ExponentialExpressionTrendline(double x)
        {
            
double y = exponentialParams[1* Math.Pow(Math.E, x * exponentialParams[2]);
            
return y;
        }

        
/// <summary>
        
/// 乘幂趋势表达式
        
/// </summary>
        
/// <param name="x">输入值</param>
        
/// <returns></returns>
        private double PowerExpressionTrendline(double x)
        {
            
double y = powerParams[1* Math.Pow(x,powerParams[2]);
            
return y;
        }

        
/// <summary>
        
/// 生成给定序列的趋势表达式
        
/// </summary>
        
/// <returns></returns>
        public void CreateTrendLineExpression(Dictionary<doubledouble> serials)
        {
            
//计算
            CalculateLinEstTrendline(serials);
            CalculateExponentialTrendline(serials);
            CalculateLogarithmicTrendline(serials);
            CalculatePowerTrendline(serials);

            
//rsqare与方程关联
            Dictionary<double,TrendlineExpression> dic = new Dictionary<double,TrendlineExpression>();
            dic.Add(linEstParams[
0],  LinEstExpressionTrendline );
            dic.Add(exponentialParams[
0],ExponentialExpressionTrendline);
            dic.Add(logarithmicParams[
0],LogarithmicExpressionTrendline );
            dic.Add(powerParams[
0], PowerExpressionTrendline);

            
//查找rsquare最大值对应的方程
            KeyValuePair<double,TrendlineExpression> result= dic.Where(p => p.Key == dic.Keys.Max()).SingleOrDefault();

            
//委托赋值
            trendLineExpression=result.Value  ;
            
        }

        
#endregion
    }

}


原文地址:https://www.cnblogs.com/hbb0b0/p/1932904.html