python实训——回归类型数据挖掘任务

  1. 回归类型数据挖掘任务

基于ARIMA和多层神经网络模型的地铁站点日客流量预测。有郑州市2015年8月-11月各地铁闸机刷卡数据集。对每日各地铁站的客流量进行分析并进行可视化。基于上一步的分析结果,分别采用ARIMA模型和多层神经网络模型对数据进行建模,训练优化模型并分别给出评估指标。

原始数据如下所示,共分为4个文件,近15GB。

2.1总体流程

2.2数据分析

2.2.1读取数据

使用pandas读取下列文件,并将读取到的DataFrame进行合并。

acc_08_final_mini.csv

acc_09_final_mini.csv

acc_10_final_mini.csv

acc_11_final_mini.csv

得到的DataFrame如图所示:

代码:

python 复制代码
import pandas as pd
# 创建一个空的DataFrame列表来存储所有读取的DataFrame  
df_list = []  
  
# 循环读取所有CSV文件  
for year in range(8, 12):  # 从2008年到2011年  
    filename = fr'C:\Users\zjl15\PycharmProjects\pythonProject1\shixundata\2\acc_{year:02d}_final_mini.csv'  # 注意fr的使用  
    df = pd.read_csv(filename)  # 读取CSV文件  
    df_list.append(df)  # 将读取的DataFrame添加到列表中  
  
# 使用concat函数进行纵向合并(堆叠)  
combined_df = pd.concat(df_list, ignore_index=True)  
  
# 显示合并后的DataFrame  
print(combined_df)  
  

特征含义:

|-----|------------------|---------------|------------|
| 特征名 | TRADE_TYPE | TRADE_ADDRESS | TRADE_DATE |
| 含义 | 交易类型 21:进站 22:出站 | 交易站点 | 交易时间 |

2.2.2分析数据

2.2.2.1日期处理

提取TRADE_DATE中的日期部分作为新的TRADE_DATE的内容。

建议使用pandas库的apply函数。

2.2.2.2分组统计

统计各个站点每天的客流量,并将客流量数据作为1列加入到原数据中,列名为COUNT。建议使用pandas库的groupby函数和transform函数。

2.2.2.3删除TRADE_TYPE列

因本次分析不考虑交易类型这个因素,因此要删掉TRADE_TYPE列。建议使用pandas库的drop函数。

2.2.2.4排序去重

将数据按照TRADE_ADDRESS和TRADE_DATE两列进行排序,并进行去重处理。建议使用pandas库的sort_values函数和drop_duplicates函数。

python 复制代码
# 将 TRADE_DATE 列转换为 datetime 类型
combined_df['TRADE_DATE'] = pd.to_datetime(combined_df['TRADE_DATE'], format='%Y-%m-%d-%H.%M.%S.%f')
# 使用 apply 函数提取日期部分并创建新的列
combined_df['DATE_ONLY'] = combined_df['TRADE_DATE'].apply(lambda x: x.date())
#去除TRADE_DATE列
df=combined_df.drop(columns=['TRADE_DATE'])
# 使用 groupby 和 transform 计算每个站点每天的交易数量并将结果作为新列加入原数据
df['COUNT'] = df.groupby(['DATE_ONLY', 'TRADE_ADDRESS'])['TRADE_TYPE'].transform('count')
#去除TRADE_TYPE列
df=df.drop(columns=['TRADE_TYPE'])
# 按照 TRADE_ADDRESS 和 DATE_ONLY 进行排序
df_sorted = df.sort_values(by=['TRADE_ADDRESS', 'DATE_ONLY'])
# 去重处理
df_unique = df_sorted.drop_duplicates(subset=['TRADE_ADDRESS', 'DATE_ONLY'])
# 根据日期和站点对数据进行分组,并计算客流量总和
grouped_data = df_unique.groupby(['DATE_ONLY', 'TRADE_ADDRESS'])['COUNT'].sum().unstack()

2.2.2.5绘制所有站点8月1日-11月30日的客流量折线图

python 复制代码
# 绘制折线图
grouped_data.plot(figsize=(12, 8))
plt.title('Daily Traffic for Each Station')
plt.xlabel('Date')
plt.ylabel('Traffic Count')
plt.legend(title='Station', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.show()

2.3模型构建

2.3.1 ARIMA模型(以 121站 为例)

以2.2.2.4步骤中的数据为基础,筛选出TRADE_ADDRESS=121的行。

以121站点客流量数据为例,使用时间序列分析方法进行建模。

python 复制代码
# 从原始数据中筛选出TRADE_ADDRESS=121的行
data_121 = df_unique[df_unique['TRADE_ADDRESS'] == 121]
#重新定义一个变量,将数据备份
data = data_121
#删除多余的列
data_121 = data_121.drop(columns=['TRADE_ADDRESS','DATE_ONLY'])

2.3.1.1划分训练集和测试集

共122条记录,前115条为训练集,后7条为测试集

python 复制代码
# 划分训练集和测试集
train_set = data_121.iloc[:115]
test_set = data_121.iloc[115:]

2.3.1.2平稳性检验

对训练集进行平稳性检验,分别采用时序图、自相关图、ADF单位根检测方法。

(1)绘制时序图

(2)绘制自相关图

(3)ADF单位根检测

通过检验,发现该序列为非平稳序列。如想使用ARIMA模型进行建模分析,需处理转换为平稳序列。

python 复制代码
# 绘制时序图
plt.figure(figsize=(12, 6))
plt.plot(train_set['COUNT'])
plt.title('Traffic Count at Station 121 (Training Set)')
plt.xlabel('Date')
plt.ylabel('Traffic Count')
plt.show()
# 绘制自相关图
fig, ax = plt.subplots(2, 1, figsize=(12, 8))
sm.graphics.tsa.plot_acf(train_set['COUNT'], lags=30, ax=ax[0])
sm.graphics.tsa.plot_pacf(train_set['COUNT'], lags=30, ax=ax[1])
plt.show()
# ADF单位根检测
result = adfuller(train_set['COUNT'])
print('ADF Statistic:', result[0])
print('p-value:', result[1])
print('Critical Values:', result[4])

2.3.1.3差分处理

使用2阶差分对训练集进行处理。

对差分处理后的训练集再次进行平稳性检验,分别采用时序图、自相关图、ADF单位根检测方法。

python 复制代码
# 对训练集进行2阶差分处理
train_set_diff = train_set['COUNT'].diff().diff().dropna()



# 绘制2阶差分后的时序图
plt.figure(figsize=(12, 6))
plt.plot(train_set_diff)
plt.title('Differenced Traffic Count at Station 121 (Training Set)')
plt.xlabel('Date')
plt.ylabel('Differenced Traffic Count')
plt.show()
# 绘制2阶差分后的自相关图
fig, ax = plt.subplots(2, 1, figsize=(12, 8))
sm.graphics.tsa.plot_acf(train_set_diff, lags=30, ax=ax[0])
sm.graphics.tsa.plot_pacf(train_set_diff, lags=30, ax=ax[1])
plt.show()
# ADF单位根检测(2阶差分后)
result_diff = adfuller(train_set_diff)
print('ADF Statistic (after differencing):', result_diff[0])
print('p-value (after differencing):', result_diff[1])
print('Critical Values (after differencing):', result_diff[4])

2.3.1.4纯随机性检验

对差分处理后的训练集进行纯随机性检验。

python 复制代码
# 计算自相关系数
acf = sm.tsa.acf(train_set_diff, fft=False)
# 绘制自相关函数图
plt.figure(figsize=(12, 6))
plt.bar(range(len(acf)), acf)
plt.xlabel('Lag')
plt.ylabel('ACF')
plt.title('Autocorrelation Function')
plt.show()

2.3.1.5 ARIMA模型建模

选择合适的参数q和q来构建ARIMA模型。

2.3.1.6 ARIMA模型训练

  1. 使用差分处理后的数据对ARIMA模型进行训练
  2. 绘制训练集真实值和预测值对比图

参考代码:

python 复制代码
# 定义 ARIMA 模型的参数 (p, d, q)
p = 6  # 自回归阶数
d = 2  # 差分阶数
q = 6  # 移动平均阶数
# 训练 ARIMA 模型
model = ARIMA(train_set, order=(p, d, q))
model_fit = model.fit()
# 使用训练好的模型进行预测

# 绘制训练集真实值和预测值对比图
plt.figure(figsize=(12, 6))
plt.plot(train_set, label='Actual')
plt.plot(forecast, label='Predicted', color='red')
plt.title('Comparison of Actual and Predicted Values')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.show()

2.3.2多层神经网络模型

2.3.2.1 特征构造

构造多层神经网络模型所需特征。

  1. 筛选121站点数据

以2.2.2.4步骤中的数据为基础,筛选出TRADE_ADDRESS=121的行。

  1. 删掉TRADE_ADDRESS列

因所有行均为121站点的数据,所以TRADE_ADDRESS没有意义,删掉。建议使用pandas库的drop函数。

  1. 从TRADE_DATE列中提取出星期几数据

对TRADE_DATE列进行计算,根据日期推算出星期几,然后赋值给新的一列TRADE_DAY。建议使用pandas库的apply函数。

  1. 从TRADE_DAY列中提取出周末数据

对TRADE_DAY列进行计算,得出是否为周末,然后赋值给新的一列WEEKEND(1:周末,0:工作日)。建议使用pandas库的apply函数。

  1. 从TRADE_DATE列中提取出月份数据

对TRADE_DATE列进行计算,提取出月份信息,然后赋值给新的一列MONTH。建议使用pandas库的apply函数。

  1. 从TRADE_DATE列中提取出日数据

对TRADE_DATE列进行计算,提取出日信息,然后赋值给新的一列DAY。建议使用pandas库的apply函数。

  1. 删掉TRADE_DATE列

TRADE_DATE里的信息已经提取完毕,可以删掉。建议使用pandas库的drop函数。

  1. 对数据的列进行重新排序

顺序为:['MONTH','DAY','TRADE_DAY','WEEKEND', 'COUNT']

python 复制代码
#删掉TRADE_ADDRESS列
df = data.drop(columns=['TRADE_ADDRESS'])
# 将 DATE_ONLY 列转换为日期时间类型
df['DATE_ONLY'] = pd.to_datetime(df['DATE_ONLY'])
# 使用 apply 函数计算星期几,并赋值给新列 DAY_OF_WEEK
df['DAY_OF_WEEK'] = df['DATE_ONLY'].dt.day_name()
# 使用 dt.dayofweek + 1 将星期几转换为数字表示,并赋值给新列 DAY_OF_WEEK_NUM
df['DAY_OF_WEEK_NUM'] = df['DATE_ONLY'].dt.dayofweek + 1
#删除DAY_OF_WEEK
df2 = df.drop(columns=['DAY_OF_WEEK'])
# 将 TRADE_DATE 列转换为日期时间类型
df2['DATE_ONLY'] = pd.to_datetime(df2['DATE_ONLY'])
# 使用 apply 函数结合 dt.month 提取出月份信息,并赋值给新列 MONTH
df2['MONTH'] = df2['DATE_ONLY'].apply(lambda x: x.month)
# 使用 apply 函数结合 dt.day 提取出日信息,并赋值给新列 DAY
df2['DAY'] = df2['DATE_ONLY'].apply(lambda x: x.day)
#删除DATE_ONLY
df2 = df2.drop(columns=['DATE_ONLY'])
# 自定义函数来判断是否为周末
def is_weekend(day_of_week):
    return 1 if day_of_week >= 6 else 0
# 使用 apply 函数调用自定义函数对 DAY_OF_WEEK_NUM 列进行计算,生成 WEEKEND 列
df2['WEEKEND'] = df2['DAY_OF_WEEK_NUM'].apply(is_weekend)
#按指定顺序排好['MONTH', 'DAY', 'DAY_OF_WEEK_NUM', 'WEEKEND', 'COUNT']
df2 = df2[['MONTH', 'DAY', 'DAY_OF_WEEK_NUM', 'WEEKEND', 'COUNT']]
  1. 绘制数据的多变量联合分布图

使用seaborn库的pairplot方法绘制数据的联合分布图。

python 复制代码
# 绘制多变量联合分布图
sns.pairplot(df2)
plt.show()

2.3.2.2划分训练集和测试集

  1. 提取特征x和目标值y

根据2.3.2.1构建出的数据集,提取出特征x和目标值y。

  1. 划分训练集和测试集

共122条记录,前115条为训练集,后7条为测试集。

python 复制代码
# 提取特征 x
X = df2[['MONTH', 'DAY', 'DAY_OF_WEEK_NUM', 'WEEKEND']]  # 选择需要作为特征的列
# 提取目标值 y
y = df2['COUNT']  # 选择目标列
# 划分训练集和测试集
# 划分训练集和测试集
X_train = X[:115]  # 前115条作为训练集
X_test = X[115:]   # 后7条作为测试集
y_train = y[:115]  # 对应的目标值作为训练集
y_test = y[115:]   # 对应的目标值作为测试集

2.3.2.3模型构建

模型参数:

参考代码

python 复制代码
#构建多层神经网络模型
model = tf.keras.Sequential([
    tf.keras.layers.Dense(64,activation='relu',input_shape=[len(X_train.keys())]),
    tf.keras.layers.Dropout(0.3),
    tf.keras.layers.Dense(64,activation='relu'),
    tf.keras.layers.Dropout(0.3),
    tf.keras.layers.Dense(64,activation='relu'),
    tf.keras.layers.Dropout(0.3),
    tf.keras.layers.Dense(1)
])
# 编译模型
model.compile(optimizer='adam', loss='mse', metrics=['mae','mse'])
model.summary()  
# 训练模型并保存历史数据
history = model.fit(X_train, y_train, epochs=3000, validation_split=0.3)

2.3.2.4模型编译

编译参数参考:

python 复制代码
# 优化器

optimizer='adam'

# 损失函数

loss='mse'

# 评估指标

metrics=['mae','mse']

2.3.2.5模型训练

使用fit函数对训练集进行拟合训练,并将训练过程中产生的历史数据history保存至变量中。

训练参数参考:

python 复制代码
# 迭代次数

epochs=1000

# 验证集比例

validation_split=0.2

2.3.2.6训练过程可视化

对history中保存下来的训练过程中的mae和mse的变化情况进行绘图。

参考代码:

python 复制代码
# 获取训练过程中的指标数值
mae = history.history['mae']
mse = history.history['loss']
val_mae = history.history['val_mae']
val_mse = history.history['val_mse']
#可视化mae、mse
plt.plot(mae, label='MAE')
plt.plot(val_mae, label='Validation MAE')
plt.title('MAE vs')
plt.legend()
plt.show()
plt.plot(mse, label='MSE')
plt.plot(val_mse, label='Validation MSE')
plt.title('MSE')
plt.legend()
plt.show()
print('MAE:', mae)
print('MSE:', mse)

2.4模型评估

2.4.1 ARIMA模型评估

2.4.1.1测试

  1. 绘制测试集真实值和预测值对比图
  2. 计算模型在测试集上的MAE,MSE,RMSE,MAPE
python 复制代码
# 获取训练过程中的指标数值
mae = history.history['mae']
mse = history.history['loss']
val_mae = history.history['val_mae']
val_mse = history.history['val_mse']

plt.plot(mae, label='MAE')
plt.plot(val_mae, label='Validation MAE')
plt.title('MAE vs')
plt.legend()
plt.show()
plt.plot(mse, label='MSE')
plt.plot(val_mse, label='Validation MSE')
plt.title('MSE')
plt.legend()
plt.show()

# history.plot()
# plt.plot(history)
# plt.show()
print('MAE:', mae)
print('MSE:', mse)


y_arima = model_fit.forecast(7)
print('预测未来'+str(len(y_arima))+'天的客流量:\n',y_arima)
y_arima.index = test_set.index
# # # 创建一个新的DataFrame来保存预测值,索引与测试集相同  
# test_set = pd.read_csv(r'test.csv')
# print(test_set)
# test_set.to_csv('test_set.xlsx', index=False)
# y_arima = pd.Series(y_arima, index=test_set.index)  
test_set['p'] = y_arima
plt.figure()  
plt.plot(test_set, label='Actual')  
# plt.plot(y_arima, label='Predicted', color='red')  

plt.legend(['y_true','y_arima'])  
plt.show()

2.4.2多层神经网络模型评估

2.4.2.1测试

  1. 根据测试集的预测结果和真实值、ARIMA模型预测结果进行对比并绘图

参考代码:

python 复制代码
y_test = pd.DataFrame(y_test)
y_mlp = pd.DataFrame(y_mlp)
y_mlp.index = y_arima.index
y_test['P1']=y_arima
y_test['P2']=y_mlp
print(y_test)
plt.figure()  
plt.plot(y_test, label='Actual')  
plt.legend(['y_true','y_arima','y_mlp'])  
plt.show()

完整代码:

python 复制代码
import pandas as pd  
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller
from statsmodels.stats.diagnostic import acorr_ljungbox
from statsmodels.tsa.vector_ar.var_model import VAR
from sklearn import metrics
import numpy as np
import tensorflow as tf
from statsmodels.tsa.arima.model import ARIMA
import matplotlib.pyplot as plt
import seaborn as sns
#%%
import pandas as pd
# 创建一个空的DataFrame列表来存储所有读取的DataFrame  
df_list = []  
  
# 循环读取所有CSV文件  
for year in range(8, 12):  # 从2008年到2011年  
    filename = fr'C:\Users\zjl15\PycharmProjects\pythonProject1\shixundata\2\acc_{year:02d}_final_mini.csv'  # 注意fr的使用  
    df = pd.read_csv(filename)  # 读取CSV文件  
    df_list.append(df)  # 将读取的DataFrame添加到列表中  
  
# 使用concat函数进行纵向合并(堆叠)  
combined_df = pd.concat(df_list, ignore_index=True)  
  
# 显示合并后的DataFrame  
print(combined_df)  
  
#%%
# #如果你需要将合并后的DataFrame保存到新的CSV文件  
# combined_df.to_csv('combined_final_mini.csv')
#%%
# 将 TRADE_DATE 列转换为 datetime 类型
combined_df['TRADE_DATE'] = pd.to_datetime(combined_df['TRADE_DATE'], format='%Y-%m-%d-%H.%M.%S.%f')

# 使用 apply 函数提取日期部分并创建新的列
combined_df['DATE_ONLY'] = combined_df['TRADE_DATE'].apply(lambda x: x.date())

# 打印结果
print(combined_df)

#%%
df=combined_df.drop(columns=['TRADE_DATE'])
print(df)
#%%
# 使用 groupby 和 transform 计算每个站点每天的交易数量并将结果作为新列加入原数据
df['COUNT'] = df.groupby(['DATE_ONLY', 'TRADE_ADDRESS'])['TRADE_TYPE'].transform('count')

# 打印结果
print(df)
#%%
df=df.drop(columns=['TRADE_TYPE'])
print(df)
#%% md

#%%
# 按照 TRADE_ADDRESS 和 DATE_ONLY 进行排序
df_sorted = df.sort_values(by=['TRADE_ADDRESS', 'DATE_ONLY'])

# 去重处理
df_unique = df_sorted.drop_duplicates(subset=['TRADE_ADDRESS', 'DATE_ONLY'])

# 打印结果
print(df_unique)

#%%
# 根据日期和站点对数据进行分组,并计算客流量总和
grouped_data = df_unique.groupby(['DATE_ONLY', 'TRADE_ADDRESS'])['COUNT'].sum().unstack()

# 绘制折线图
grouped_data.plot(figsize=(12, 8))
plt.title('Daily Traffic for Each Station')
plt.xlabel('Date')
plt.ylabel('Traffic Count')
plt.legend(title='Station', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.show()

#%%
# 从原始数据中筛选出TRADE_ADDRESS=121的行
data_121 = df_unique[df_unique['TRADE_ADDRESS'] == 121]
data = data_121
print(data_121)
data_121 = data_121.drop(columns=['TRADE_ADDRESS','DATE_ONLY'])
print(data_121)
#%%
# 划分训练集和测试集
train_set = data_121.iloc[:115]
test_set = data_121.iloc[115:]

print("训练集:")
print(train_set)
print("\n测试集:")
print(test_set)

#%%
# 绘制时序图
plt.figure(figsize=(12, 6))
plt.plot(train_set['COUNT'])
plt.title('Traffic Count at Station 121 (Training Set)')
plt.xlabel('Date')
plt.ylabel('Traffic Count')
plt.show()

# 绘制自相关图
fig, ax = plt.subplots(2, 1, figsize=(12, 8))
sm.graphics.tsa.plot_acf(train_set['COUNT'], lags=30, ax=ax[0])
sm.graphics.tsa.plot_pacf(train_set['COUNT'], lags=30, ax=ax[1])
plt.show()

# ADF单位根检测
result = adfuller(train_set['COUNT'])
print('ADF Statistic:', result[0])
print('p-value:', result[1])
print('Critical Values:', result[4])

#%%
# 对训练集进行2阶差分处理
train_set_diff = train_set['COUNT'].diff().diff().dropna()

# 绘制2阶差分后的时序图
plt.figure(figsize=(12, 6))
plt.plot(train_set_diff)
plt.title('Differenced Traffic Count at Station 121 (Training Set)')
plt.xlabel('Date')
plt.ylabel('Differenced Traffic Count')
plt.show()

# 绘制2阶差分后的自相关图
fig, ax = plt.subplots(2, 1, figsize=(12, 8))
sm.graphics.tsa.plot_acf(train_set_diff, lags=30, ax=ax[0])
sm.graphics.tsa.plot_pacf(train_set_diff, lags=30, ax=ax[1])
plt.show()

# ADF单位根检测(2阶差分后)
result_diff = adfuller(train_set_diff)
print('ADF Statistic (after differencing):', result_diff[0])
print('p-value (after differencing):', result_diff[1])
print('Critical Values (after differencing):', result_diff[4])

#%%
# 计算残差序列
residuals = train_set_diff # 这里填入差分处理后的训练集数据的残差序列
# 进行Ljung-Box检验
lb_test_stat, lb_p_value = acorr_ljungbox(residuals, lags=1)
# 输出检验结果
print("Ljung-Box test statistic:", lb_test_stat)
print("P-values:", lb_p_value)
#%%
# 定义 ARIMA 模型的参数 (p, d, q)
p = 6  # 自回归阶数
d = 2  # 差分阶数
q = 6  # 移动平均阶数

# 训练 ARIMA 模型
model = ARIMA(train_set, order=(p, d, q))
model_fit = model.fit()

print(model_fit.summary())

# 使用训练好的模型进行预测
forecast = model_fit.predict(typ='levels')
print(forecast)
# 绘制训练集真实值和预测值对比图
plt.figure(figsize=(12, 6))
plt.plot(train_set, label='Actual')
plt.plot(forecast, label='Predicted', color='red')
plt.title('Comparison of Actual and Predicted Values')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.show()

#%% md

#%%
y_arima = model_fit.forecast(7)
print('预测未来'+str(len(y_arima))+'天的客流量:\n',y_arima)
y_arima.index = test_set.index
# # # 创建一个新的DataFrame来保存预测值,索引与测试集相同  
# test_set = pd.read_csv(r'test.csv')
# print(test_set)
# test_set.to_csv('test_set.xlsx', index=False)
# y_arima = pd.Series(y_arima, index=test_set.index)  
test_set['p'] = y_arima
plt.figure()  
plt.plot(test_set, label='Actual')  
# plt.plot(y_arima, label='Predicted', color='red')  

plt.legend(['y_true','y_arima'])  
plt.show()

#%%
# (2)删掉TRADE_ADDRESS列
df = data.drop(columns=['TRADE_ADDRESS'])
print(df)
#%%
# 将 DATE_ONLY 列转换为日期时间类型
df['DATE_ONLY'] = pd.to_datetime(df['DATE_ONLY'])

# 使用 apply 函数计算星期几,并赋值给新列 DAY_OF_WEEK
df['DAY_OF_WEEK'] = df['DATE_ONLY'].dt.day_name()

# 使用 dt.dayofweek + 1 将星期几转换为数字表示,并赋值给新列 DAY_OF_WEEK_NUM
df['DAY_OF_WEEK_NUM'] = df['DATE_ONLY'].dt.dayofweek + 1

# 显示结果
print(df)
#%%
df2 = df.drop(columns=['DAY_OF_WEEK'])

print(df2)
#%%
# 将 TRADE_DATE 列转换为日期时间类型
df2['DATE_ONLY'] = pd.to_datetime(df2['DATE_ONLY'])

# 使用 apply 函数结合 dt.month 提取出月份信息,并赋值给新列 MONTH
df2['MONTH'] = df2['DATE_ONLY'].apply(lambda x: x.month)
# 使用 apply 函数结合 dt.day 提取出日信息,并赋值给新列 DAY
df2['DAY'] = df2['DATE_ONLY'].apply(lambda x: x.day)
# 显示结果
print(df2)
#%%
df2 = df2.drop(columns=['DATE_ONLY'])
print(df2)
#%%
# 自定义函数来判断是否为周末
def is_weekend(day_of_week):
    return 1 if day_of_week >= 6 else 0

# 使用 apply 函数调用自定义函数对 DAY_OF_WEEK_NUM 列进行计算,生成 WEEKEND 列
df2['WEEKEND'] = df2['DAY_OF_WEEK_NUM'].apply(is_weekend)

print(df2)
#%%
df2 = df2[['MONTH', 'DAY', 'DAY_OF_WEEK_NUM', 'WEEKEND', 'COUNT']]
print(df2)
#%%
# 绘制多变量联合分布图
sns.pairplot(df2)
plt.show()
#%%
from sklearn.model_selection import train_test_split
# 提取特征 x
X = df2[['MONTH', 'DAY', 'DAY_OF_WEEK_NUM', 'WEEKEND']]  # 选择需要作为特征的列

# 提取目标值 y
y = df2['COUNT']  # 选择目标列

# 划分训练集和测试集
# 划分训练集和测试集
X_train = X[:115]  # 前115条作为训练集
X_test = X[115:]   # 后7条作为测试集
y_train = y[:115]  # 对应的目标值作为训练集
y_test = y[115:]   # 对应的目标值作为测试集
print(X_train)
print(y_train)
print(X_test)
print(y_test)
#%%
#构建模型
model = tf.keras.Sequential([
    tf.keras.layers.Dense(64,activation='relu',input_shape=[len(X_train.keys())]),
    tf.keras.layers.Dropout(0.3),
    tf.keras.layers.Dense(64,activation='relu'),
    tf.keras.layers.Dropout(0.3),
    tf.keras.layers.Dense(64,activation='relu'),
    tf.keras.layers.Dropout(0.3),
    tf.keras.layers.Dense(1)
])

# 编译模型
model.compile(optimizer='adam', loss='mse', metrics=['mae','mse'])

model.summary()  

# 训练模型并保存历史数据
history = model.fit(X_train, y_train, epochs=3000, validation_split=0.3)

#%%
#model.save('roch_classification2_cnn.keras')
#%%
# 获取训练过程中的指标数值
mae = history.history['mae']
mse = history.history['loss']
val_mae = history.history['val_mae']
val_mse = history.history['val_mse']

plt.plot(mae, label='MAE')
plt.plot(val_mae, label='Validation MAE')
plt.title('MAE vs')
plt.legend()
plt.show()
plt.plot(mse, label='MSE')
plt.plot(val_mse, label='Validation MSE')
plt.title('MSE')
plt.legend()
plt.show()

# history.plot()
# plt.plot(history)
# plt.show()
print('MAE:', mae)
print('MSE:', mse)
#%%
y_mlp = model.predict(X_test)
#%%
y_test = pd.DataFrame(y_test)
y_mlp = pd.DataFrame(y_mlp)
y_mlp.index = y_arima.index
y_test['P1']=y_arima
y_test['P2']=y_mlp
print(y_test)
plt.figure()  
plt.plot(y_test, label='Actual')  
plt.legend(['y_true','y_arima','y_mlp'])  
plt.show()
#%%
# 计算MAE,MSE,RMSE,MAPE
from sklearn import metrics
import math
MAE = metrics.mean_absolute_error(X_test.iloc[:,0],X_test.iloc[:,1])
MSE = metrics.mean_squared_error(X_test.iloc[:,0],X_test.iloc[:,1])
RMSE = math.sqrt(MSE)
MAPE = metrics.mean_absolute_percentage_error(X_test.iloc[:,0],X_test.iloc[:,1])
print('MAE:',MAE)
print('MSE:',MSE)
print('RMSE:',RMSE)
print('MAPE:',MAPE)
#%%
from sklearn.ensemble import RandomForestRegressor
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.metrics import mean_squared_error
# 初始化随机森林回归器
rf_regressor = RandomForestRegressor(n_estimators=2500,max_depth=100,random_state=42)
# 训练随机森林模型
rf_regressor.fit(X_train, y_train)
# 使用训练好的模型进行预测
y_regressor_pred = rf_regressor.predict(X_test)
print(y_regressor_pred)
y_regressor_pred = pd.DataFrame(y_regressor_pred)
print(y_regressor_pred)
y_regressor_pred.index = y_mlp.index
y_test['P3'] = y_regressor_pred
print(y_test)
plt.figure()  
plt.plot(y_test, label='Actual')  
plt.legend(['y_true','y_arima','y_mlp','y_regressor_pred'])  
plt.show()
# 计算均方误差
mse = mean_squared_error(y_test['COUNT'], y_test['P3'])
print("Mean Squared Error:", mse)
#%%
from xgboost import XGBRegressor
from sklearn.metrics import mean_squared_error
# 1. 准备数据集
# 假设数据集已准备好,包含特征和目标变量
# 4. 定义模型
model = XGBRegressor(
    n_estimators=3000,  # 树的数量
    max_depth=5,       # 树的最大深度
    learning_rate=0.3, # 学习率
    random_state=42
)
# 5. 训练模型
model.fit(X_train, y_train)
# 6. 模型评估
y_XGBRegressor_pred = model.predict(X_test)
y_XGBRegressor_pred = pd.DataFrame(y_XGBRegressor_pred)
y_XGBRegressor_pred.index = y_mlp.index
y_test['P4'] = y_XGBRegressor_pred
print(y_test)
plt.figure()  
plt.plot(y_test, label='Actual')  
plt.legend(['y_true','y_arima','y_mlp','y_regressor_pred','y_XGBRegressor_pred'])  
plt.show()
# 计算均方误差
mse = mean_squared_error(y_test['COUNT'], y_test['P3'])
print("Mean Squared Error:", mse)
mse = mean_squared_error(y_test['COUNT'], y_XGBRegressor_pred)
print("Mean Squared Error:", mse)
#%%
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error

# 4. 定义模型
model = SVR(kernel='rbf', C=1.0, epsilon=0.1)

# 5. 训练模型
model.fit(X_train, y_train)

# 6. 模型评估
y_SVR_pred = model.predict(X_test)
y_SVR_pred = pd.DataFrame(y_SVR_pred)
y_SVR_pred.index = y_mlp.index
y_test['P5'] = y_SVR_pred
print(y_test)
plt.figure()  
plt.plot(y_test, label='Actual')  
plt.legend(['y_true','y_arima','y_mlp','y_regressor_pred','y_XGBRegressor_pred','y_SVR_pred'])  
plt.show()
# 计算均方误差
mse = mean_squared_error(y_test['COUNT'], y_test['P5'])
print("Mean Squared Error:", mse)
mse = mean_squared_error(y_test['COUNT'], y_SVR_pred)
print("Mean Squared Error:", mse)
#%%
相关推荐
葬爱家族小阿杰39 分钟前
python执行测试用例,allure报乱码且未成功生成报告
开发语言·python·测试用例
xx155802862xx41 分钟前
Python如何给视频添加音频和字幕
java·python·音视频
酷爱码41 分钟前
Python实现简单音频数据压缩与解压算法
开发语言·python
花果山总钻风1 小时前
SQLAlchemy 中的 func 函数使用指南
python
知识中的海王1 小时前
Python html 库用法详解
开发语言·python
面朝大海,春不暖,花不开2 小时前
使用 Python 正则表达式实现文本替换与电话号码规范化
python·mysql·正则表达式
淘小白_TXB21962 小时前
Python网页自动化Selenium中文文档
python·selenium·自动化·网页自动化
Clair-Sean2 小时前
【JavaSE】多线程基础学习笔记
笔记·python·学习
wzy06233 小时前
MADlib —— 基于 SQL 的数据挖掘解决方案(4)—— 数据类型之矩阵
数据挖掘·madlib
EverBule3 小时前
Python 训练 day46
开发语言·python