python-编码实现趋势外推法

实现趋势外推法

:一次、二次、三次,指数曲线法;

步骤

1.收集研究对象的动态数列(自选);
2.画数据点分布图,判断近似曲线;
3.计算差分,确定曲线方程;
4.求曲线参数;

概念

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码

# -*- coding=utf-8 -*-
# name: nan chen
# date: 2021/4/22 14:22

import csv
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import numpy as np

font = FontProperties(fname=r"C:\\Windows\\Fonts\\STKAITI.TTF", size=7)

# 计算差分 选取相应模型
def count_difference_choose(t_array, y_array):
    # 计算差分
    y1 = []
    y2 = []
    yy = []
    for i in range(1, len(y_array)):
        y1.append(round(y_array[i] - y_array[i - 1], 2))
    for i in range(1, len(y1)):
        y2.append(round((y1[i] - y1[i - 1]), 2))
    for i in range(1, len(y_array)):
        yy.append(round((y_array[i] / y_array[i - 1]), 2))
    '''
    print("一阶差分为:", y1)
    print("二阶差分为:", y2)
    print("一阶差比率为:", yy)
    '''
    plt.figure(2)
    plt.plot(y1, '--', label="一阶差分")
    plt.plot(y2, '-.', label="二阶差分")
    plt.plot(yy, label="一阶差比率")
    plt.legend(prop=font)
    std1 = np.std(y1)
    std2 = np.std(y2)
    std3 = np.std(yy)
    print("一阶差分的方差为:", std1)
    print("二阶差分的方差为:", std2)
    print("一阶差比率的方差为:", std3)

    if std1 <= std2 and std1 <= std3:
        linear_trend(t_array, y_array)
    elif std2 <= std1 and std2 <= std3:
        Conic_trend(t_array, y_array)
    elif std3 <= std2 and std3 <= std1:
        index_trend(t_array, y_array)

# 一次
def linear_trend(t_array, y_array):
    y_avg = np.mean(y_array)
    b = np.sum(t_array * y_array) / np.sum(t_array ** 2)
    a = y_avg
    predict = a + b * (t_array[-1] + 1)
    print(predict)

# 二次
def Conic_trend(t_array, y_array):
    a = (np.sum(t_array ** 4) * np.sum(y_array) - np.sum(t_array ** 2) * np.sum((t_array ** 2) * y_array)) / (
            len(t_array) * np.sum(t_array ** 4) - (np.sum(t_array ** 2)) ** 2)
    b = np.sum(t_array * y_array) / np.sum(t_array ** 2)
    c = len(t_array) * np.sum((t_array ** 2) * y_array) - np.sum(y_array) * np.sum(t_array ** 2) / (
            len(t_array) * np.sum(t_array ** 4) - (np.sum(t_array ** 2)) ** 2)
    predict = a + b + c * (t_array[-1] + 1)

# 指数
def index_trend(t_array, y_array):
    a = np.sum(np.log10(y_array)) / len(y_array)
    b = np.sum(t_array * np.log10(y_array)) / (np.sum(t_array ** 2))
    A = 10 ** a
    B = 10 ** b
    predict = A * (B ** (t_array[-1] + 3))
    predicts = []
    for i in t_array:
        predicts.append(A * (B ** i))
    plt.figure(3)
    plt.plot(predicts, label="预测值")
    plt.plot(price, '.', label="实际值")
    plt.legend(prop=font)
    plt.show()
    print("下一年金价的预测值为:", predict)


if __name__ == '__main__':
    # 读取数据文件

    with open(r"D:\Downloads\gold_annual_price.csv", encoding="utf-8") as f:
        reader = csv.reader(f)
        header_row = next(reader)
        date = []
        price = []
        for row in reader:
            date.append(row[0])
            price.append(round(float(row[1]), 2))
        plt.figure(1)
        plt.plot(price, '.')
    n = int(len(date) / 2)
    t_array = np.array(range(-1 * n, n + 1))
    y_array = np.array(price)
    '''
    t_array = np.array(range(-7, 8))
    y_array = np.array(
        [121.12, 127.87, 139.12, 160.69, 189.26, 255.61, 268.25, 302.36, 348.63,408.86, 438.6, 543.85, 575.62, 703.26,
         816.22])
    '''
    count_difference_choose(t_array, y_array)

结果及分析

  1. 数据的散点图
    在这里插入图片描述

  2. 差分:一阶、二阶、一阶差比率
    在这里插入图片描述

  3. 绘图观察一阶、二阶、三阶、一阶差比率
    在这里插入图片描述

  4. 计算差分的方程,选择相应的曲线方程
    在这里插入图片描述

  5. 预测结果
    在这里插入图片描述

  6. 预测值与真实值对比
    在这里插入图片描述

结果分析:

  • 本次实验选取的数据集为1951年-2021年历史每一年度的国际金价。绘制散点图可以看出,大致呈指数分布,猜测应该使用指数曲线模型。
  • 通过观察一阶、二阶、一阶差比率可以看出一阶差比率大致相等,而一阶差分及二阶差分的波动幅度则特别大,验证了我们刚刚的观察应选取指数曲线模型。
  • 通过公式计算参数,确定参数方程,可以求得预测值为2048.19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值