【发布时间】:2021-01-27 21:19:08
【问题描述】:
我正在尝试使用一些约束来执行线性回归主题以获得一定的预测。 我想让模型预测一半的线性预测,而后半部分的线性预测接近前半部分的最后一个值,使用非常窄的范围(使用约束),类似于图中的绿线。
完整代码:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
pd.options.mode.chained_assignment = None # default='warn'
data = [5.269, 5.346, 5.375, 5.482, 5.519, 5.57, 5.593999999999999, 5.627000000000001, 5.724, 5.818, 5.792999999999999, 5.817, 5.8389999999999995, 5.882000000000001, 5.92, 6.025, 6.064, 6.111000000000001, 6.1160000000000005, 6.138, 6.247000000000001, 6.279, 6.332000000000001, 6.3389999999999995, 6.3420000000000005, 6.412999999999999, 6.442, 6.519, 6.596, 6.603, 6.627999999999999, 6.76, 6.837000000000001, 6.781000000000001, 6.8260000000000005, 6.849, 6.875, 6.982, 7.018, 7.042000000000001, 7.068, 7.091, 7.204, 7.228, 7.261, 7.3420000000000005, 7.414, 7.44, 7.516, 7.542000000000001, 7.627000000000001, 7.667000000000001, 7.821000000000001, 7.792999999999999, 7.756, 7.871, 8.006, 8.078, 7.916, 7.974, 8.074, 8.119, 8.228, 7.976, 8.045, 8.312999999999999, 8.335, 8.388, 8.437999999999999, 8.456, 8.227, 8.266, 8.277999999999999, 8.289, 8.299, 8.318, 8.332, 8.34, 8.349, 8.36, 8.363999999999999, 8.368, 8.282, 8.283999999999999]
time = range(1,85,1)
x=int(0.7*len(data))
df = pd.DataFrame(list(zip(*[time, data])))
df.columns = ['time', 'data']
# print df
x=int(0.7*len(df))
train = df[:x]
valid = df[x:]
models = []
names = []
tr_x_ax = []
va_x_ax = []
pr_x_ax = []
tr_y_ax = []
va_y_ax = []
pr_y_ax = []
time_model = []
models.append(('LR', LinearRegression()))
for name, model in models:
x_train=df.iloc[:, 0][:x].values
y_train=df.iloc[:, 1][:x].values
x_valid=df.iloc[:, 0][x:].values
y_valid=df.iloc[:, 1][x:].values
model = LinearRegression()
# poly = PolynomialFeatures(5)
x_train= x_train.reshape(-1, 1)
y_train= y_train.reshape(-1, 1)
x_valid = x_valid.reshape(-1, 1)
y_valid = y_valid.reshape(-1, 1)
# model.fit(x_train,y_train)
model.fit(x_train,y_train.ravel())
# score = model.score(x_train,y_train.ravel())
# print 'score', score
preds = model.predict(x_valid)
tr_x_ax.extend(train['data'])
va_x_ax.extend(valid['data'])
pr_x_ax.extend(preds)
valid['Predictions'] = preds
valid.index = df[x:].index
train.index = df[:x].index
plt.figure(figsize=(5,5))
# plt.plot(train['data'],label='data')
# plt.plot(valid[['Close', 'Predictions']])
x = valid['data']
# print x
# plt.plot(valid['data'],label='validation')
plt.plot(valid['Predictions'],label='Predictions before',color='orange')
y =range(0,58)
y1 =range(58,84)
for index, item in enumerate(pr_x_ax):
if index >13:
pr_x_ax[index] = pr_x_ax[13]
pr_x_ax = list([float(i) for i in pr_x_ax])
va_x_ax = list([float(i) for i in va_x_ax])
tr_x_ax = list([float(i) for i in tr_x_ax])
plt.plot(y,tr_x_ax, label='train' , color='red', linewidth=2)
plt.plot(y1,va_x_ax, label='validation1' , color='blue', linewidth=2)
plt.plot(y1,pr_x_ax, label='Predictions after' , color='green', linewidth=2)
plt.xlabel("time")
plt.ylabel("data")
plt.xticks(rotation=45)
plt.legend()
plt.show()
如果你看到这个图:
label:Predictions before,模型预测它没有任何约束(我不需要这个结果)。
标签:Predictions after,模型在约束范围内预测它,但这是在模型预测之后并且所有值都等于 index = 71 , item 8.56 的最后一个值。
我在第 64 行中使用了循环 for index, item in enumerate(pr_x_ax):,曲线是从 71 秒到 85 秒的直线,如您所见,以便向您展示我需要模型如何工作。
我可以建立模型给出相同的结果而不是 for 循环吗???
请多多指教
【问题讨论】:
-
你能把你的问题写得更短更切题吗?我读了两遍,还是没明白。
-
我提出了一个简短的问题。
-
@Algabri 看起来你在绿线上绘制的右转根本无法预测,因为只训练红线点。要使此类转弯可预测,您需要在该转弯位置周围设置一些训练点。否则现在通过给定模型的训练点只是认为所有预测都应该只用直线来近似而不用转弯。
-
@Algabri 为了获得好的解决方案,您需要随机抽取数据进行训练和验证。而不是做
df[:x]和df[x:]你需要将随机的(x, y)点放到训练集和随机到验证集的所需比例,比如70% 用于训练,30% 用于验证。那么你的训练应该会达到正确的绿色结果。 -
@Algabri 此外,LinearRegression 仅使用单条直线预测数据,它不能有转弯,对于分段线性近似,如您在绿线上想要的那样,应该使用一些更复杂的模型,我会尝试阅读文档以找到这样的模型。
标签: python machine-learning scikit-learn linear-regression