<p>门限回归模型(Threshold Regressive Model,简称TR模型或TRM)的基本思想是通过门限变量的控制作用,当给出预报因子资料后,首先根据门限变量的门限阈值的判别控制作用,以决定不同情况下使用不同的预报方程,从而试图解释各种类似于跳跃和突变的现象。其实质上是把预报问题按状态空间的取值进行分类,用分段的线性回归模式来描述总体非线性预报问题。</p>
<p>多元门限回归的建模步骤就是确实门限变量、率定门限数L、门限值及回归系数的过程,为了计算方便,这里采用二分割(即L=2)说明模型的建模步骤。</p>
<p><strong>基本步骤如下(附代码):</strong></p>
<p>1.读取数据,计算预报对象与预报因子之间的互相关系数矩阵。</p>
<div class="blockcode">
<pre class="brush:py;">
数据读取
#利用pandas读取csv,读取的数据为DataFrame对象
data = pd.read_csv('jl.csv')
# 将DataFrame对象转化为数组,数组的第一列为数据序号,最后一列为预报对象,中间各列为预报因子
data= data.values.copy()
# print(data)
# 计算互相关系数,参数为预报因子序列和滞时k
def get_regre_coef(X,Y,k):
S_xy=0
S_xx=0
S_yy=0
# 计算预报因子和预报对象的均值
X_mean = np.mean(X)
Y_mean = np.mean(Y)
for i in range(len(X)-k):
S_xy += (X[i] - X_mean) * (Y[i+k] - Y_mean)
for i in range(len(X)):
S_xx += pow(X[i] - X_mean, 2)
S_yy += pow(Y[i] - Y_mean, 2)
return S_xy/pow(S_xx*S_yy,0.5)
#计算相关系数矩阵
def regre_coef_matrix(data):
row=data.shape[1]#列数
r_matrix=np.ones((1,row-2))
# print(row)
for i in range(1,row-1):
r_matrix[0,i-1]=get_regre_coef(data[:,i],data[:,row-1],1)#滞时为1
return r_matrix
r_matrix=regre_coef_matrix(data)
# print(r_matrix)
###输出###
#[[0.048979 0.07829989 0.19005705 0.27501209 0.28604638]]
</pre>
</div>
<p>2.对相关系数进行排序,相关系数最大的因子作为门限元。</p>
<div class="blockcode">
<pre class="brush:py;">
#对相关系数进行排序找到相关系数最大者作为门限元
def get_menxiannum(r_matrix):
row=r_matrix.shape[1]#列数
for i in range(row):
if r_matrix.max()==r_matrix[0,i]:
return i+1
return -1
m=get_menxiannum(r_matrix)
# print(m)
##输出##第五个因子的互相关系数最大
#5</pre>
</div>
<p>3.根据选取的门限元因子对数据进行重新排序。</p>
<div class="blockcode">
<pre class="brush:py;">
#根据门限元对因子序列进行排序,m为门限变量的序号
def resort_bymenxian(data,m):
data=data.tolist()#转化为列表
data.sort(key=lambda x: x[m])#列表按照m+1列进行排序(升序)
data=np.array(data)
return data
data=resort_bymenxian(data,m)#得到排序后的序列数组</pre>
</div>
<p>4.将排序后的序列按照门限元分割序列为两段,第一分割第一段1个数据,第二段n-1(n为样本容量)个数据;第二次分割第一段2个数据,第二段n-2个数据,一次类推,分别计算出分割后的F统计量并选出最大统计量对应的门限元的分割点作为门限值。</p>
<div class="blockcode">
<pre class="brush:py;">
def get_var(x):
return x.std() ** 2 * x.size # 计算总方差
#统计量F的计算,输入数据为按照门限元排序后的预报对象数据
def get_F(Y):
col=Y.shape[0]#行数,样本容量
FF=np.ones((1,col-1))#存储不同分割点的统计量
V=get_var(Y)#计算总方差
for i in range(1,col):#1到col-1
S=get_var(Y[0:i])+get_var(Y[i:col])#计算两段的组内方差和
F=(V-S)*(col-2)/S
FF[0,i-1]=F#此步需要判断是否通过F检验,通过了才保留F统计量
return FF
y=data[:,data.shape[1]-1]
FF=get_F(y)
def get_index(FF,element):#获取element在一维数组FF中第一次出现的索引
i=-1
for item in FF.flat:
i+=1
if item==element:
return i
f_index=get_index(FF,np.max(FF))#获取统计量F的最大索引
# print(data[f_index,m-1])#门限元为第五个因子,代入索引得门限值 121
</pre>
</div>
<p>5.以门限值为分割点将数据序列分割为两段,分别进行多元线性回归,此处利用sklearn.linear_model模块中的线性回归模块。再代入预报因子分别计算两段的预测值。</p>
<div class="blockcode">
<pre class="brush:py;">
#以门限值为分割点将新data序列分为两部分,分别进行多元回归计算
def data_excision(data,f_index):
f_index=f_index+1
data1=data[0:f_index,:]
data2=data[f_index:data.shape[0],:]
return data1,data2
data1,data2=data_excision(data,f_index)
# 第一段
def get_XY(data):
# 数组切片对变量进行赋值
Y = data[:, data.shape[1] - 1] # 预报对象位于最后一列
X = data[:, 1:data.shape[1] - 1]#预报因子从第二列到倒数第二列
return X, Y
X,Y=get_XY(data1)
regs=LinearRegression()
regs.fit(X,Y)
# print('第一段')
# print(regs.coef_)#输出回归系数
# print(regs.score(X,Y))#输出相关系数
#计算预测值
Y1=regs.predict(X)
# print('第二段')
X,Y=get_XY(data2)
regs.fit(X,Y)
# print(regs.coef_)#输出回归系数
# print(regs.score(X,Y))#输出相关系数
#计算预测值
Y2=regs.predict(X)
Y=np.column_stack((data[:,0],np.hstack((Y1,Y2)))).copy()
Y=np.column_stack((Y,data[:,data.shape[1]-1]))
Y=resort_bymenxian(Y,0)
</pre>
</div>
<p>6.将预 |
|