用DNN做回归预测对比XGBoost

前言

现在神经网络的运用越来越流行了,即使在结构化数据领域神经网络也随着数据量的增大而逐渐替代传统机器学习方法,能够创建一个基础的深度神经网络解决问题对一个合格的算法工程师来说变得越来越关键了。我就从一个初学者的角度出发,对我们常见的回归问题运用神经网络对和集成学习大杀器XGBoost进行预测效果对比。

气温数据集下载地址:https://pan.baidu.com/s/1KNYfb2S7ct4KsIJxUFz2Uw
提取码:DJNB

数据集探索

打印前11行数据:
在这里插入图片描述
可以看到,气温数据集只有9个特征属性(有year,month,day,week这样的离散型数据,也有temp1,temp2,average,friend这样的连续型数据),我们数据的label也就是我们需要预测的值就是actual列,属于比较简单的结构化数据,而且总共数据只有348条,非常小,适合新手练手。

数据预处理

这里数据预处理没有做太多操作,因为数据集比较简单,没有缺失值,由于只有训练集,所以数据的分布问题也不需要考虑,这里主要就需要对week列进行编码,至于其他数据的标准化也可以做,这里我就没进行标准化。

data=pd.read_csv("Temps.csv")
#独热编码
data_onehot = pd.get_dummies(data['week'])
data = pd.concat([data,data_onehot],axis=1)
data=data.drop(['week'],axis=1)
#切分特征和标签
train_x=data.drop(['actual'],axis=1)
target=data['actual']

构建模型预测

XGBoost模型

首先上我们的老大哥XGBoost,回归问题对于xgboost来说轻而易举,即使凭借简单特征,也能拟合出很好的效果:

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
import numpy as np
import itertools
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
from sklearn.preprocessing import MinMaxScaler
import statsmodels.api as sm
import matplotlib.dates as dates
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import math
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
import time
import xgboost as xgb
from sklearn.model_selection import KFold, StratifiedKFold
#数据预处理
data=pd.read_csv("Temps.csv")
data_onehot = pd.get_dummies(data['week'])
data = pd.concat([data,data_onehot],axis=1)
data=data.drop(['week'],axis=1)
train_x=data.drop(['actual'],axis=1)
target=data['actual']
#xgb
model=xgb.XGBRegressor(max_depth=2
                      ,learning_rate=0.01
                      ,n_estimators=20000,
                          subsample=0.8)
oof1 = np.zeros(len(train_x))
answers = []
score = 0
n_fold = 5
num_epochs = 100
#五折交叉
folds = KFold(n_splits=n_fold, shuffle=True,random_state=2000) #2020 #1000
for fold_n, (train_index, valid_index) in enumerate(folds.split(train_x)):
    X_train, X_valid = train_x.iloc[train_index], train_x.iloc[valid_index]
    y_train, y_valid = target[train_index], target[valid_index]
    model.fit(X_train,y_train,eval_set=[(X_valid, y_valid)],verbose=100,early_stopping_rounds=200)
    y_pre = model.predict(X_valid)
    oof1[valid_index]=y_pre.reshape(y_pre.shape[0])
print('RMSE-----------',
      np.sqrt(mean_squared_error(data['actual'], oof1)))
#画图看看最终效果怎么样      
plt.figure(figsize=(50, 25))
plt.plot(range(len(oof1)), oof1, label='prediction', lineWidth=5)
plt.plot(range(len(target)), target, label='true', lineWidth=5)
plt.ylabel('co2')
plt.xlabel('date')
plt.legend()
plt.title("prediction and true")
plt.show()

在训练集上面的预测效果与真实值对比(黄色是真实值,蓝色是预测结果):
在这里插入图片描述
可以看到,效果还是不错,想要更加精确可以做更加复杂的特征工程,不过由于训练集数据非常少,容易发生过拟合,所以简单点模型的泛化能力好点。

DNN模型

我做得非常简单,网络结构只设置了三个全连接层,而且神经元数量也比较少,主要是做个示范,网络结构可自行设置,可以更加复杂化。

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
import numpy as np
import itertools
from tensorflow import keras
from tensorflow.keras import layers
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
from sklearn.preprocessing import MinMaxScaler
import statsmodels.api as sm
import matplotlib.dates as dates
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import math
from keras.models import Sequential
from keras.layers import Dense, Activation
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from keras import optimizers
import time
from sklearn.model_selection import KFold, StratifiedKFold
#数据预处理
data=pd.read_csv("Temps.csv")
data_onehot = pd.get_dummies(data['week'])
data = pd.concat([data,data_onehot],axis=1)
data=data.drop(['week'],axis=1)
train_x=data.drop(['actual'],axis=1)
target=data['actual']
#DNN构建得非常简单,完全没有技术含量,主要是举个例子,可以自行增加各种层
model = Sequential()
model.add(layers.Dense(64, activation='relu',
                           input_shape=(train_x.shape[1],)))
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(1))
model.compile(optimizer=keras.optimizers.Adam(0.01), loss='mse', metrics=['mse'])
#同样采用五折交叉
oof1 = np.zeros(len(train_x))
answers = []
score = 0
n_fold = 5
num_epochs = 100
folds = KFold(n_splits=n_fold, shuffle=True,random_state=2000) #2020 #1000
for fold_n, (train_index, valid_index) in enumerate(folds.split(train_x)):
    X_train, X_valid = train_x.iloc[train_index], train_x.iloc[valid_index]
    y_train, y_valid = target[train_index], target[valid_index]
    model.fit(X_train, y_train,epochs=num_epochs, batch_size=1, verbose=1)
    y_pre = model.predict(X_valid)
    oof1[valid_index]=y_pre.reshape(y_pre.shape[0])
print('RMSE-----------',
      np.sqrt(mean_squared_error(data['actual'], oof1)))
plt.figure(figsize=(50, 25))
plt.plot(range(len(oof1)), oof1, label='prediction', lineWidth=5)
plt.plot(range(len(target)), target, label='true', lineWidth=5)
plt.legend()
plt.title("prediction and true")
plt.show()

神经网络预测结构和真实值对比效果(黄色是真实值,蓝色是预测值):
在这里插入图片描述
可以看到,一个简单结构的神经网络的预测能力也还不错,在峰值的预测上面好像比XGBoost还要稍微好一点点。而且大家还可以进行网络结构的复杂化,比如增加网络层数,比如添加卷积层,或者使用embedding操作进行数据关系映射,但是一定要防止神经网络模型的过拟合,由于神经网络的强大学习能力,它很容易学傻,所以要注意过拟合问题。

总结

神经网络非常强大,在这个数据集上面效果其实都还可以,但是它的优势在这个数据集上面还体现不出来,神经网络的优势在于能在大量数据里面比传统机器学习更能找到数据之间微妙的关系,通过训练大量的参数更能发现海量数据里面的潜在规律,本次数据集只有几百条数据,优势体现不明显,而在实际工业生产中大量数据能让神经网络模型的准确性和学习能力比机器学习方法更加出色!

写在最后

本人才疏学浅,如果有理解错误或者理解不到位的地方请指正!

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值