基本预测类算法
一:灰色预测算法G(1,1),可用于小样本时间序列预测。首先,介绍相关基本概念。白色系统:系统的相关信息全部已知。黑色系统:系统全部信息未知。灰色系统:处于黑色和白色系统的过渡阶段,只有部分信息已知。算法流程: (1)对数据进行处理和检验:计算数列的级比:前一项和后一项的比值。如果所有的级比都落在区间(e-2/(n+1),e2/(n+1))。则满足数据满足要求。如果不满足的话,可以进行平移变换,
一:灰色预测算法G(1,1),可用于小样本时间序列预测。
首先,介绍相关基本概念。
白色系统:系统的相关信息全部已知。
黑色系统:系统全部信息未知。
灰色系统:处于黑色和白色系统的过渡阶段,只有部分信息已知。
算法流程:
(1)对数据进行处理和检验:计算数列的级比:前一项和后一项的比值。如果所有的级比都落在区间(e-2/(n+1),e2/(n+1))。则满足数据满足要求。如果不满足的话,可以进行平移变换,使得原数列中每一个数据加上常数c,至于c的值,以实验为准。
(2)当数据满足要求后,就可以建立GM(1,1)模型。
x0(k)+az1(k)=b。求解的话利用最小二乘法,直接进行求解。其中,
z1(k)=cx1(k)+(1-c)x1。在这里,要注意几个符号的含义和区别。x1(k)是累加生成数列中的一项。上标1。表示使用原始数列,经过一次累加得到。x1是表示通过原始数列,经过一次累加得到的数列。
(3)求解相应的白化方程:x1(t)’+ax1(t)=b。求解微分方程,得到解为:x1(t)=(x(0)(1)-b/a)e-a(t-1)+b/a。
(4)联立得到预测值:x(1)(k+1)=(x(0)(1)-b/a)e-ak+b/a。
x0(k+1)=x1(k+1)-x1(k)。
(5)估计误差,可以通过残差检验或者级比偏差值检验。
python代码如下:
def GM1_1(x0):
#验证数据是否可以用
if check_data(x0) ==0:
pass
else:
x0 = offset(x0)
#计算AOG
x0 = np.array(x0)
x1 = np.cumsum(x0)
#计算x1的均值生成序列
x1 = pd.DataFrame(x1)
z1 = (x1+x1.shift())/2.0#该项与该项的前一项相加除以2,用shift比循环代码更简单
z1 = z1[1:].values.reshape((len(z1)-1,1))#再将刚刚算出的数据转成ndarray,删去nan
B = np.append(-z1,np.ones_like(z1),axis=1)#合并数据形成B矩阵
Y = x0[1:].reshape((len(x0)-1,1))#建立Y矩阵
#计算参数a,b np.dot为点乘,np.linalg.inv为矩阵求逆
[[a],[b]] = np.dot(np.dot((np.linalg.inv(np.dot(B.T,B))),B.T),Y)
#方程求解 f(k+1)表示x1(k+1)
f = lambda k: (x0[0]-b/a)*np.exp(-a*(k-1))-(x0[0]-b/a)*np.exp(-a*(k-2))
#求出估计的所有x1的预测值,大小和x0一样
x1_pre = [f(k) for k in range(1,len(x0)+1)]
#求x0的预测值
#x1_pre = pd.DataFrame(x1_pre)
delta = np.abs(x0 - np.array([f(i) for i in range(1,len(x0)+1)]))
#检验预测值,利用残差检验
residual_error = np.abs(x0-np.array(x1_pre))
residual_error_max = residual_error.max
#级比偏差值检验
p = [1-((1-0.5*a)/(1+0.5*a))*l for l in lambda_k]
return a,b,residual_error_max,p,f
二 BP神经网络预测
我们将神经网络输出层映射到[0,1]之间,可以实现分类功能,映射方法可以通过选定合适的激活函数得到。同样地,通过改变激活函数,也可以实现预测功能。
一般流程如下:
(1)特征提取,特征提取的算法很多,选取合适的算法即可。当然,具体问题具体分析。
(2)数据标准化处理:主要为消除不同特征之间量纲的影响。
(3)接着是,神经网络结构的设计。BP神经网络,三级层级结构:input layyer,hidden layyer,output layyer。
输入层神经元个数是输入特征的数目加上偏置节点数目。
输出层经元个数是想要得到的结果的个数。
对于隐藏层来说,神经元数目极大程度影响网络性能。一般是大规模调参得到最优值,当然,也有经验公式L=(n+m)1/2+a (1<a<10) 。
(4)模型训练,前向传播计算loss,反向传播更新权重。
接着,附上一道例题。
房价预测
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
def sigmoid(x):
# 第一层到第二层的激活函数
return 1 / (1 + np.exp(-x))
def deriv_sigmoid(x):
# 第一层到第二层的激活函数的求导函数
fx = sigmoid(x)
return fx * (1 - fx)
def mse_loss(y_true, y_pred):
# 使用方差作为损失函数
return ((y_true - y_pred) ** 2).mean()
class OurNeuralNetwork:
def __init__(self):
# 第一层到第二层的函数
self.w11 = np.random.normal()
self.w12 = np.random.normal()
self.w13 = np.random.normal()
self.w14 = np.random.normal()
self.w21 = np.random.normal()
self.w22 = np.random.normal()
self.w23 = np.random.normal()
self.w24 = np.random.normal()
# 第二层到第三层的函数
self.w1 = np.random.normal()
self.w2 = np.random.normal()
# 截距项,Biases
self.b1 = np.random.normal()
self.b2 = np.random.normal()
self.b3 = np.random.normal()
def feedforward(self, x):
# 前向传播学习
h1 = sigmoid(self.w11 * x[0] + self.w12 * x[1] + self.w13 * x[2] + self.w14 * x[3] + self.b1)
h2 = sigmoid(self.w21 * x[0] + self.w22 * x[1] + self.w23 * x[2] + self.w24 * x[3] + self.b1)
o1 = self.w1 * h1 + self.w2 * h2 + self.b3
return o1
#训练函数
def train(self, data, all_y_trues):
learn_rate = 0.01 # 学习率
epochs = 1000 # 训练的次数
# 画图数据
self.loss = np.zeros(100)
self.sum = 0;
# 开始训练
for epoch in range(epochs):
for x, y_true in zip(data, all_y_trues):
# 计算h1
h1 = sigmoid(self.w11 * x[0] + self.w12 * x[1] + self.w13 * x[2] + self.w14 * x[3] + self.b1)
# 计算h2
h2 = sigmoid(self.w21 * x[0] + self.w22 * x[1] + self.w23 * x[2] + self.w24 * x[3] + self.b2)
#计算输出节点
y_pred = self.w1 * h1 + self.w2 * h2 + self.b3
# 反向传播计算导数
d_L_d_ypred = -2 * (y_true - y_pred)
d_ypred_d_w1 = h1
d_ypred_d_w2 = h2
d_ypred_d_b3 = 0
d_ypred_d_h1 = self.w1
d_ypred_d_h2 = self.w2
sum_1=self.w11 * x[0] + self.w12 * x[1] + self.w13 * x[2] + self.w14 * x[3] + self.b1
d_h1_d_w11 = x[0] * deriv_sigmoid(sum_1)
d_h1_d_w12 = x[1] * deriv_sigmoid(sum_1)
d_h1_d_w13 = x[2] * deriv_sigmoid(sum_1)
d_h1_d_w14 = x[3] * deriv_sigmoid(sum_1)
d_h1_d_b1 = deriv_sigmoid(sum_1)
sum_2 = self.w21 * x[0] + self.w22 * x[1] + self.w23 * x[2] + self.w24 * x[3] + self.b2
d_h1_d_w21 = x[0] * deriv_sigmoid(sum_2)
d_h1_d_w22 = x[1] * deriv_sigmoid(sum_2)
d_h1_d_w23 = x[2] * deriv_sigmoid(sum_2)
d_h1_d_w24 = x[3] * deriv_sigmoid(sum_2)
d_h1_d_b2 = deriv_sigmoid(sum_2)
# 梯度下降法
self.w11 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_w11
self.w12 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_w12
self.w13 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_w13
self.w14 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_w14
self.b1 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_b1
self.w21 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h1_d_w21
self.w22 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h1_d_w22
self.w23 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h1_d_w23
self.w24 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h1_d_w24
self.b2 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h1_d_b2
self.w1 -= learn_rate * d_L_d_ypred * d_ypred_d_w1
self.w1 -= learn_rate * d_L_d_ypred * d_ypred_d_w2
self.b3 -= learn_rate * d_L_d_ypred * d_ypred_d_b3
if epoch % 10 == 0:
y_preds = np.apply_along_axis(self.feedforward, 1, data)
loss = mse_loss(all_y_trues, y_preds)
print("Epoch %d loss: %.3f" % (epoch, loss))
self.loss[self.sum] = loss
self.sum = self.sum + 1
# 文件的名字
FILENAME = "../data.xlsx"
# 禁用科学计数法
pd.set_option('float_format', lambda x: '%.3f' % x)
np.set_printoptions(suppress=True, threshold=np.nan)
# 得到的DataFrame分别为总价、面积、房间、客厅、年份
data = pd.read_excel(FILENAME, header=0, usecols="A,D,H,I,J")
# DataFrame转化为array
DataArray = data.values
Y = DataArray[:, 0]
X = DataArray[:, 1:5]
X = np.array(X)#转化为array,自变量
Y = np.array(Y)#转化为array,因变量房价
# 处理数据
data = np.array(X)
data_mean = np.sum(data, axis=0) / np.size(data, 0)
data = (data - data_mean) / np.max(data)
all_y_trues = np.array(Y)
all_y_trues_mean = np.sum(all_y_trues) / np.size(all_y_trues)
all_y_trues = (all_y_trues - all_y_trues_mean) / np.max(all_y_trues)
# 训练数据
network = OurNeuralNetwork()
network.train(data, all_y_trues)
# 输出神经网络参数
print("w11-->%.3f" % network.w11)
print("w12-->%.3f" % network.w12)
print("w13-->%.3f" % network.w13)
print("w14-->%.3f" % network.w14)
print("w21-->%.3f" % network.w21)
print("w22-->%.3f" % network.w22)
print("w23-->%.3f" % network.w23)
print("w24-->%.3f" % network.w24)
print("w1-->%.3f" % network.w1)
print("w2-->%.3f" % network.w2)
print("b1-->%.3f" % network.b1)
print("b2-->%.3f" % network.b2)
print("b3-->%.3f" % network.b3)
# 标题显示中文
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 测试数据
testData = np.array([99, 3, 2, 2014])
testPrice = network.feedforward(testData)
# 损失函数曲线图
plt.plot(np.arange(100), network.loss)
plt.show()
# 真实值与预测值对比
y_preds = np.apply_along_axis(network.feedforward, 1, data)
plt.plot(np.arange(380), all_y_trues,"r^")
plt.plot(np.arange(380),y_preds,"bs")
plt.title("红色为真实值,蓝色为预测值")
plt.show()
时间序列预测
主要用来,小样本预测。基本特点:假设事物的过去趋势会延伸到未来。常用的模型有:自回归AR,移动平均MA,ARMA模型等。注意:白噪声随机性过强,不能做时间序列预测。
要求数据具有平稳性:即序列的均值和方差不发生明显的变化,一般要求均值和协方差不随时间变化。如果,序列不平稳,则无效。可以利用差分法转换,求原始数据的一阶差分,二阶差分等等。
接着,介绍AR模型。利用变量自身历史数据对自身做预测。需要满足平稳性和自相关性。公式如下:
Yt=a1Y(t-1)+a2Y(t-2)+……+anY(t-n)+Zt
也就是将t时刻前n个时刻,对应的值做线性组合。zt是白噪声。AR模型认为,t时刻的值,只和自身的值有关,而与系统在这些时刻中进来的噪声无关。
接着,是移动平均MA模型。和AR模型相反,系统认为自身的值只和噪声有关,而与自身的值无关。
Yt=a1E(t-1)+a2E(t-2)+……+anE(t-n)+Zt
也就是将t时刻前n个时刻的白噪声,对应的值做线性组合。zt是白噪声
将上述两个模型整合在一起,得到ARMA模型:
Yt=a1Y(t-1)+a2Y(t-2)+……+apY(t-p)+Zt+b1E(t-1)+b2E(t-2)+……+bqE(t-q)+Zt
得到时间序列Yt服从(p,q)阶自回归方程。
ARIMA模型是在ARMA模型的基础上加入差分。即之前的序列是不平稳的,在加入差分后,是平稳的。如果采用了d阶差分,结合上述ARMA模型,可得出ARIMA符合(p,d,q)阶模型。
更多推荐










所有评论(0)