用全连接神经网络做多元回归预测的简单实现

#coding:utf-8
from keras.models import Sequential
from keras.layers import Dense, Dropout
from sklearn.preprocessing import MinMaxScaler
from keras.models import load_model
import pandas as pd
import matplotlib.pyplot as plt
"""
实现功能: nn全连接神经网络回归预测
环境配置: keras 2.2.0   tensorflow 1.10.0  python3.6.4
运行准备:
    1.csv格式的数据集,标签列以data命名,日期列以sdate命名(日期列会删除)
    2.数据量应大于等于batch_size
"""

class data_utils():
    def __init__(self,data_path=r"C:\Users\ld\Desktop\train_1008.csv"):
        self.data_path = data_path #数据集全路径
    #加载数据集
    def load_data(self,split_number=350):
        """
        读取数据集并按index将数据集切分为训练集和测试集
        :param data_path:      #数据集csv全路径,str
        :param split_number :  #将数据集切分为训练/测试集的index,int
        :return:
            x_train,dataframe,不含label列的训练数据集
            y_train,dataframe,label列
            x_valid,dataframe,不含label列的验证数据集
            y_valid,dataframe,label列
        """
        df = pd.read_csv(self.data_path)
        x_train = df[[i for i in df.columns if i not in ["data","sdate"]]].head(split_number)
        y_train = pd.DataFrame( df["data"].head(split_number))
        x_valid = df[[i for i in df.columns if i not in ["data","sdate"]]].tail(df.shape[0]-split_number)
        y_valid = pd.DataFrame(df["data"].tail(df.shape[0]-split_number))
        return x_train,y_train,x_valid,y_valid

    #数据归一化
    def minmax_scale(self,dataset):
        """
        将数据集进行归一化
        :return:
        """
        min_max_scaler = MinMaxScaler()
        min_max_scaler.fit(dataset)
        dataset = min_max_scaler.transform(dataset)
        return dataset

    #数据归一化还原
    def minmax_scale_inverse(self,y_valid,y_new):
        """
        归一化还原
        :param y_valid:用于训练归一化器的数据
        :param y_new: 待还原数据
        :return: 还原结果
        """
        #反归一化还原原始量纲
        min_max_scaler = MinMaxScaler()
        min_max_scaler.fit(y_valid)
        y_new_TURE = min_max_scaler.inverse_transform(y_new)
        return y_new_TURE

class neural_network():
    def __init__(self,epochs=200,batch_size=100,verbose=1,loss='mse',optimizer='adam'):
        self.epochs = epochs          #迭代次数
        self.batch_size = batch_size  #批次大小
        self.verbose = verbose        #日志详细程度
        self.loss = loss              #损失函数
        self.optimizer = optimizer    #优化器
    #训练模型
    def train_nn(self,x_train, y_train,x_valid, y_valid):
        #训练模型
        model = Sequential()  #初始化模型
        model.add(Dense(units = 10,                      #输出维度
                        activation='linear',             #激励函数
                        input_shape=(x_train.shape[1],)  #输入维度(列)
                        ))
        model.add(Dropout(0.2))  #随机舍弃神经元概率
        model.add(Dense(units = 1,  activation='linear')) #激活函数(或relu)
        model.compile(loss=self.loss,optimizer=self.optimizer,) #定义损失及优化
        history = model.fit(x_train, y_train,  epochs=self.epochs,  #迭代次数
                            batch_size=self.batch_size,  #每批数训练据大小
                            verbose=self.verbose,  #日志详细程度
                            validation_data = (x_valid, y_valid))  #验证集

        #训练/验证损失曲线
        plt.title('Loss Curves')
        plt.ylabel('loss')
        plt.xlabel('epochs')
        plt.plot(history.history['loss'])
        plt.plot(history.history['val_loss'])
        plt.show()

        #保存模型
        model.save('nn_model.h5')  #保存模型
    #模型预测
    def predict_nn(self,x_test):
        """
        预测
        :param x_valid: 预测数据集
        :return: np.array,预测结果
        """
        #加载模型
        model = load_model('nn_model.h5')
        #预测
        y_new = model.predict(x_test)
        return y_new

def main(data_path,split_number):
    """

    :param data_path: 数据集全路径 str
    :param split_number: 数据集划分点 int
    :return:
    """
    du = data_utils(data_path) #数据处理类
    nn = neural_network()      #网络定义类
    x_train,y_train,x_valid,y_valid = du.load_data(split_number) #加载训练测试数据
    x_train = du.minmax_scale(x_train)    #训练集
    y_train = du.minmax_scale(y_train)    #训练标签
    x_valid = du.minmax_scale(x_valid)    #验证集
    y_valid = du.minmax_scale(y_valid)    #验证标签
    nn.train_nn(x_train, y_train,x_valid, y_valid)  #训练
    pre_new = nn.predict_nn(x_valid)                #预测
    pre_new = du.minmax_scale_inverse(y_valid, pre_new) #预测结果还原

if __name__ == "__main__":
    main(r"C:\Users\ld\Desktop\train_1008.csv", 350)

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐