python基于XGBoost开发构建海上船舶航行轨迹多变量序列预测分析模型

在船舶航行状态评估、船舶碰撞概率检测等场景种有着对海面船舶航行轨迹较高的预测需求,准确实时地对航行轨迹进行预测分析有助于评估船舶航行的状态,及时对可能存在的潜在威胁进行发现预警处理,航行轨迹预测本质上来讲就是时间序列建模,在我之前的博文中已经有大量的博文和对应的教程,对于时间序列预测建模有比较详细的介绍。

很多场景下多变量序列预测建模大都是基于深度学习完成的,这个也是因为深度学习模型天然的优势,能够处理高维度的数据,基于机器学习模型本质上来讲也是可以完成这项工作的,只不过会比深度学习更加麻烦,这里主要的目的就是以船舶航行轨迹数据集为基准来开发XGBoost时间序列预测模型。

首先看下数据集:

mmsi,lat,lon,Sog,Cog,timestamp
33,30.430935,121.840168,13.3,218,1530665006
33,30.431335,121.840587,13.2,33,1530665016
33,30.432252,121.84158,13.2,145,1530665036
33,30.432675,121.841973,13.2,30,1530665046
33,30.433992,121.84337,13.2,20,1530665076
33,30.434867,121.844305,13.1,39,1530665096
33,30.435257,121.844728,13.1,43,1530665106
33,30.434867,121.844305,13.1,23,1530665119
33,30.43619,121.845688,13.1,50,1530665126
33,30.437892,121.847477,13.1,53,1530665166
33,30.43838,121.84798,13.1,50,1530665176
33,30.43887,121.848482,13.2,28,1530665187
33,30.44061,121.850253,13.1,50,1530665226
33,30.441017,121.850657,13.1,42,1530665236
33,30.43749,121.84707,13.012,54,1530665238
33,30.44155,121.85121,13.1,117,1530665247
33,30.442865,121.852583,13.1,182,1530665276
33,30.443728,121.853523,13.2,0,1530665296
33,30.44415,121.854003,13.2,200,1530665307
33,30.444593,121.854473,13.2,140,1530665317
33,30.445012,121.854958,13.2,107,1530665327
33,30.44195,121.85162,13.212,275,1530665339
33,30.447153,121.857333,13.2,277,1530665377
33,30.447575,121.857832,13.2,267,1530665387
33,30.447575,121.857832,13.2,276,1530665410
33,30.448822,121.859192,13.2,272,1530665416
33,30.45052,121.861037,13.2,260,1530665456
33,30.451377,121.861993,13.2,274,1530665476
33,30.4519,121.86256,13.2,265,1530665486
33,30.452343,121.863042,13.2,250,1530665497
33,30.452773,121.863522,13.2,291,1530665507
33,30.454465,121.86536,13.1,104,1530665547
33,30.455717,121.866725,13.1,99,1530665576
33,30.456632,121.867703,13.1,92,1530665596

可以看到:数据集中给出来了航行过程中记录得到的详细数据,包括:经度和维度还有sog与cog。

首先需要对原始数据集进行解析处理,如下:

with open(data) as f:
    data_list = json.load(f)
data_dict = {}
for one_list in data_list:
    mmsi, ts, lat, lon, Sog, Cog = one_list
    if mmsi in data_dict:
        data_dict[mmsi].append([ts, lat, lon, Sog, Cog])
    else:
        data_dict[mmsi]=[[ts, lat, lon, Sog, Cog]]
X, y = [], []
for one_mmsi in data_dict:
    one_data = data_dict[one_mmsi]
    one_data = sorted(one_data, key = lambda e:e[0])
    one_X, one_y = sliceWindow(one_data, step)
    X += one_X
    y += one_y
X_train, X_test, y_train, y_test = splitData(X, y, ratio=ratio)
dataset = {}
dataset["X_train"], dataset["y_train"] = X_train, y_train
dataset["X_test"], dataset["y_test"] = X_test, y_test
with open(save_path, "w") as f:
    f.write(json.dumps(dataset))

处理完成后 ,就得到了随机划分后形成的训练集和测试集。

得到数据集后就可以搭建模型了,核心实现如下:

if not os.path.exists(saveDir):
    os.makedirs(saveDir)
X_train,y_train,X_test,y_test = loadDataSet(data=data, label=label)
#模型构建
model = xgb.XGBRegressor(
    max_depth=5,
    n_estimators=200,
    objective="reg:linear",
)
#训练拟合
model.fit(X_train, y_train)
# 预测
res_dict = {}
train_pred = model.predict(X_train)
evs, mae, mse, r2 = calPerformance(y_train, train_pred)
mapev = mape(train_pred, y_train)
rmse = math.sqrt(mse)
train_info = (
    "训练集评估指标分析\nRMSE: "
    + str(round(rmse, 4))
    + ", MAPE: "
    + str(round(mapev, 4))
    + ", R2: "
    + str(round(r2, 4))
)
res_dict["train_true"] = y_train
res_dict["train_predict"] = train_pred.tolist()
plt.clf()
plt.figure(figsize=(12,8))
plt.plot(y_train, label="训练集真实值曲线")
plt.plot(train_pred, label="训练集预测值曲线")
plt.legend()
plt.title(train_info)
plt.savefig(saveDir + "train_compare.png")

这里以lat为例看下训练集对比拟合曲线如下所示:

测试集对比拟合曲线如下:

总体对比曲线如下:

可以看到:模型的拟合效果是很好的了,这里绘制了特征重要性图像:

接下来整合多维度的数据集来依次构建模型,核心方法同上,这里就不再重复介绍了,绘图有别于上述实现,这里着重介绍一下,以训练集数据集为例如下:

plt.clf()
plt.figure(figsize=(40,16))
i=1
for one_label in res_dict:
    y_true=res_dict[one_label]["train_true"]
    y_pred=res_dict[one_label]["train_predict"]
    evs, mae, mse, r2 = calPerformance(y_true, y_pred)
    mapev = mape(y_pred, y_true)
    rmse = math.sqrt(mse)
    train_info = one_label+ " 训练集评估指标分析\nRMSE: " + str(round(rmse, 4)) + ", MAPE: " + str(round(mapev, 4)) + ", R2: " + str(round(r2, 4))
    plt.subplot(2,2,i)
    plt.plot(y_true, label="训练集真实值曲线")
    plt.plot(y_pred, label="训练集预测值曲线")
    plt.legend()
    plt.title(train_info)
    i+=1
plt.savefig(saveDir + "train_compare.png")

效果如下:

测试集可视化同上,效果如下:

总体对比可视化如下所示:

同样这里也绘制了特征重要性可视化:

这个跟我们常识还是比较接近的哈。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个基于LSTM的多变量时间序列预测模型的Python代码示例: 首先,需要导入必要的库:numpy、pandas、tensorflow和sklearn。 ```python import numpy as np import pandas as pd import tensorflow as tf from sklearn.preprocessing import MinMaxScaler ``` 然后,我们读取数据并进行预处理。假设我们有一个包含多个变量的时间序列,每个变量都有多个时间步长的数据集,我们需要将数据集分成训练集和测试集,并对它们进行归一化处理。这里我们使用`MinMaxScaler`对数据进行归一化。 ```python # 读取数据 data = pd.read_csv('data.csv') # 将数据分成训练集和测试集 train_data = data.iloc[:800, :] test_data = data.iloc[800:, :] # 归一化处理 scaler = MinMaxScaler() train_data = scaler.fit_transform(train_data) test_data = scaler.transform(test_data) ``` 接下来,我们需要定义模型的输入和输出。对于多变量时间序列预测模型,输入序列通常是一个多维数组,每个维度表示一个变量,而输出序列通常是一个单变量数组,表示我们要预测变量。在这个例子中,我们要预测第一个变量,因此我们将输入序列定义为前9个时间步长的所有变量,输出序列定义为第10个时间步长的第一个变量。 ```python # 定义输入和输出序列 train_X, train_y = train_data[:, :-1], train_data[:, 0] test_X, test_y = test_data[:, :-1], test_data[:, 0] # 将输入序列重构为三维数组 train_X = train_X.reshape((train_X.shape[0], 9, train_X.shape[1])) test_X = test_X.reshape((test_X.shape[0], 9, test_X.shape[1])) ``` 然后,我们定义LSTM模型。这个模型包含一个LSTM层和一个全连接层,其中LSTM层的输出形状为`(batch_size, time_steps, hidden_size)`,我们需要将其展平为`(batch_size, time_steps*hidden_size)`,然后将其传递给全连接层进行预测。 ```python # 定义LSTM模型 model = tf.keras.Sequential([ tf.keras.layers.LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])), tf.keras.layers.Dense(1) ]) # 编译模型 model.compile(loss='mse', optimizer='adam') ``` 接下来,我们训练模型并进行预测。 ```python # 训练模型 model.fit(train_X, train_y, epochs=50, batch_size=64, validation_data=(test_X, test_y), verbose=2, shuffle=False) # 预测测试集 yhat = model.predict(test_X) # 反归一化处理 test_y = test_y.reshape((len(test_y), 1)) yhat = scaler.inverse_transform(yhat) test_y = scaler.inverse_transform(test_y) # 计算RMSE rmse = np.sqrt(np.mean((yhat - test_y)**2)) print(f'RMSE: {rmse}') ``` 完整代码如下: ```python import numpy as np import pandas as pd import tensorflow as tf from sklearn.preprocessing import MinMaxScaler # 读取数据 data = pd.read_csv('data.csv') # 将数据分成训练集和测试集 train_data = data.iloc[:800, :] test_data = data.iloc[800:, :] # 归一化处理 scaler = MinMaxScaler() train_data = scaler.fit_transform(train_data) test_data = scaler.transform(test_data) # 定义输入和输出序列 train_X, train_y = train_data[:, :-1], train_data[:, 0] test_X, test_y = test_data[:, :-1], test_data[:, 0] # 将输入序列重构为三维数组 train_X = train_X.reshape((train_X.shape[0], 9, train_X.shape[1])) test_X = test_X.reshape((test_X.shape[0], 9, test_X.shape[1])) # 定义LSTM模型 model = tf.keras.Sequential([ tf.keras.layers.LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])), tf.keras.layers.Dense(1) ]) # 编译模型 model.compile(loss='mse', optimizer='adam') # 训练模型 model.fit(train_X, train_y, epochs=50, batch_size=64, validation_data=(test_X, test_y), verbose=2, shuffle=False) # 预测测试集 yhat = model.predict(test_X) # 反归一化处理 test_y = test_y.reshape((len(test_y), 1)) yhat = scaler.inverse_transform(yhat) test_y = scaler.inverse_transform(test_y) # 计算RMSE rmse = np.sqrt(np.mean((yhat - test_y)**2)) print(f'RMSE: {rmse}') ``` 注意,这里的模型只是一个简单的示例,实际应用中需要根据数据集的特点来调整模型参数和架构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值