案例学习1.LSTM

声明一下:本人现在在学习机器学习以及深度学习方面的知识,想通过CSDN平台去记录自己的学习历程,也希望可以和大家一起学习,共同进步。

1.读取数据

df = pd.read_csv(
  "london_bike_sharing.csv", 
  parse_dates=['timestamp'], 
  index_col="timestamp"
)

展示部分数据

2.添加特征(小时、天、月份、星期)

df['hour'] = df.index.hour
df['day_of_month'] = df.index.day
df['day_of_week'] = df.index.dayofweek
df['month'] = df.index.month

3.按月进行重新采样

df_by_month = df.resample('M').sum()#向下采样并执行聚合

4.划分训练集和测试集

train_size = int(len(df) * 0.9)
test_size = len(df) - train_size
train, test = df.iloc[0:train_size], df.iloc[train_size:len(df)]
print(len(train), len(test))

最后我们得到训练集和测试集的大小分别为15672 和1742。

5.数据预处理

拓展:我们在机器学习领域,总是看到“算法的鲁棒性”这类字眼。搜查资料发现鲁棒性可以有3个层面的概念:
1.模型具有较高的精度或有效性,这也是对于机器学习中所有学习模型的基本要求;
2.对于模型假设出现的较小偏差,只能对算法性能产生较小的影响; 主要是:噪声(noise)
3.对于模型假设出现的较大偏差,不可对算法性能产生“灾难性”的影响;主要是:离群点(outlier)
为了提高算法的鲁棒性(剔除不必要的离群点),该案例引入sklearn中的RobustScaler 函数。
RobustScaler的计算方法如下:

其中vi表示样本的某个值;median是样本的中位数;IQR是样本的四分位距

from sklearn.preprocessing import RobustScaler#导包
f_columns = ['t1', 't2', 'hum', 'wind_speed']#选择要处理的列
f_transformer = RobustScaler()
cnt_transformer = RobustScaler()
#fit()的作用:可以理解为一个训练过程
f_transformer = f_transformer.fit(train[f_columns].to_numpy())#这里将dataframe转化为numpy
cnt_transformer = cnt_transformer.fit(train[['cnt']])
#分别对训练集和测试集进行处理
train.loc[:, f_columns] = f_transformer.transform(train[f_columns].to_numpy())
train['cnt'] = cnt_transformer.transform(train[['cnt']])
test.loc[:, f_columns] = f_transformer.transform(test[f_columns].to_numpy())
test['cnt'] = cnt_transformer.transform(test[['cnt']])
#transfrom()的作用:在fit的基础上,进行标准化,降维,归一化等操作

拓展:
上面的代码将fit和transform分开写,其实也可以用fit_transform。
1.fit_transform是fit和transform的组合。fit_transform是将fit和transform合并,即先拟合数据,然后转化它将其转化为标准形式。
2.注意的是,训练集使用fit_transform(),而测试集使用tranform(),不再使用fit_transform();原因:必须确保两个训练集有相同的数据指标,即处理方式相同!
3.举个简单的例子
fit_transform(train data)先根据具体转换的目的找到数据的整体指标,如均值、方差、最大值最小值…,然后对train data进行transform,从而实现数据的标准化、归一化…。根据之前fit的整体指标,对test data使用同样的均值、方差、最大最小值等指标进行transform(test data),从而保证train data和test data的处理方式相同。
原文请查看此处

6.设置时间步长(LSTM)

#定义一个设置时间步长的函数
def create_dataset(X, y, time_steps=1):
    Xs, ys = [], []
    for i in range(len(X) - time_steps):
        v = X.iloc[i:(i + time_steps)].values
        Xs.append(v)        
        ys.append(y.iloc[i + time_steps])
    return np.array(Xs), np.array(ys)#转换为numpy数组

对训练、测试集分别调用函数

time_steps = 10#时间步长为10个小时
# reshape to [samples, time_steps, n_features]
X_train, y_train = create_dataset(train, train.cnt, time_steps)
X_test, y_test = create_dataset(test, test.cnt, time_steps)
print(X_train.shape, y_train.shape)

得到训练、测试集的大小为(15662, 10, 13) (15662,)
其中的(15662, 10, 13)可以这样理解 :

  • 15662:样本数
  • 10:10小时
  • 13:除了训练标签以外的列数

7. 建立LSTM模型

model = keras.Sequential()#创建顺序模型
model.add(
  keras.layers.Bidirectional(
    keras.layers.LSTM(
      units=128, 
      input_shape=(X_train.shape[1], X_train.shape[2])#输入层只需要给出样本的特征尺寸
    )
  )
)
Bidirectional:实现RNN类型神经网络的双向构造
model.add(keras.layers.Dropout(rate=0.2))
model.add(keras.layers.Dense(units=1))
model.compile(loss='mean_squared_error', optimizer='adam')#损失函数为'MSE',优化器为Adam

8.训练模型

history = model.fit(
    X_train, y_train, 
    epochs=30, 
    batch_size=32, 
    validation_split=0.1,
    shuffle=False#不打乱顺序
)

看一下训练结果

plt.plot(history.history['loss'], label='train')
plt.plot(history.history['val_loss'], label='test')
plt.legend();

9.模型预测

y_pred = model.predict(X_test)

对标签数据进行反归一化处理(inverse_transform)

y_train_inv = cnt_transformer.inverse_transform(y_train.reshape(1, -1))
y_test_inv = cnt_transformer.inverse_transform(y_test.reshape(1, -1))
y_pred_inv = cnt_transformer.inverse_transform(y_pred)
注意还是要采取之前归一化的标准,即这里的cnt_transformer

如果归一化时的对象的shape是(n, 3),则反归一化时的 data 的shape必须是(m, 3)

10.预测结果可视化

plt.plot(y_test_inv.flatten(), marker='.', label="true")
plt.plot(y_pred_inv.flatten(), 'r', label="prediction")
plt.ylabel('Bike Count')
plt.xlabel('Time Step')
plt.legend()
plt.show();

关于flatten函数的介绍:

  1. 功能:将numpy数组展开为一维数组
  2. 默认方向是行方向,加’a’也是行方向,但是加‘f’是列方向
  3. flatten函数不能直接作用于列表 !

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
乘风的头像乘风管理团队
上一篇 2022年5月22日
下一篇 2022年5月22日

相关推荐