• 应用深度神经网络预测学生期末成绩


    0、引言

    • 写作目的:只是为了学习一下DNN的用法
    • 基本思路:
      • 首先,将学生成绩(平时成绩x、期末成绩y:csv格式)装载;
      • 接着,将成绩数据标准化。(PS:虽然这里的成绩已经[0~100]之间了,本文是为了学习DNN,故不省略这一步)
      • 接着,将平时成绩x,期末成绩y进一步拆分(按比例,如20%)为训练数据和测试数据。PS:测试数据用来检验训练出的模型性能
      • 接着,创建DNN模型。依次设置一系列的参数。
      • 接着,训练模型(fit函数)。model1.fit(x_train, y_train)
      • 接着,评估模型性能。用测试集数据评估,还可以用训练集数据。 如果性能不好,则调参(第四步)
      • 最后,可以应用所得模型,进行期末成绩的预测。
    • 实验环境
      • Mac OSX
      • python 2
      • 应用到的包(好多,缺什么你安装什么好了,有(很多)时候还会出错,自己百度、谷歌等可以解决,我花费了1天时间才搞好)

    1、装载数据

    • 预先加载包 import csv, os
    • 装载数据,到 score_data ; 标题写到score_header, 代码如下:
    score_file = 'score.csv'
    
    if not os.path.exists(score_file):
        print "File ", score_file, " does not exist!"
    else :
    	score_data = []
    	with open(score_file) as csvfile:
    		csv_reader = csv.reader(csvfile)
    		score_header = next(csv_reader) # 读取第1行, 不是标题
    		score_header = next(csv_reader) # 读取第2行每一列的标题
    		for row in csv_reader: 		    # 将csv 文件中的数据保存到score_data中
    			score_data.append(row)
    		csvfile.close()                 # 关闭文件
    
    • score_data结果:

    2、数据标准化

    • 拆分数据集 x(平时成绩),y(期末成绩;
    • 将其标准化。即将输入区间:$(-infty , +infty ) $映射到区间(0,1)

    2.1 切片 score_data, 数据导入 x ,y 。代码:

    x , y = [], []
    for item in score_data:
    	x0 , y0 = item[0:13], item[13]         # 注意:LL的切片[m:n] ,从 LL[m] ... LL[n-1]  
    	x.append(x0)
    	y.append(y0)
    

    2.2 标准化

    • 应用包:sklearn.preprocessing 中 MinMaxScaler()。 将 x和 y 映射成 [0,1] 区间的值。 代码:
    from sklearn.preprocessing import MinMaxScaler
    
    x_MinMax = MinMaxScaler ()
    y_MinMax = MinMaxScaler ()
    
    import numpy as np
    y = np.array(y).reshape((len(y), 1))
    x = x_MinMax.fit_transform(x)
    y = y_MinMax.fit_transform(y)
    x.mean(axis =0)
    
    # print x_MinMax.scale_
    # print y_MinMax.scale_
    
    # print y_MinMax.inverse_transform([[0.8725]])  # 如果预测值为“0.8725”,则可用 inverse_transform 映射回实际值
    
    
    • 问题:如何将一个标准化的(预测)值value,再映射回实际值?

      • 应用 y_MinMax.inverse_transform([[value]]) 。
    • 以y为例,显示top 5 个转换后的数。

    3、数据拆分为训练集和测试集

    • 应用包:sklearn.model_selection 中 train_test_split()。 将 x和 y 按照比例(test_size)拆分。 代码:
    import random
    from sklearn.model_selection import train_test_split
    
    np.random.seed(2019)
    x_train , x_test , y_train , y_test = train_test_split(x, y, test_size = 0.2)
    

    4、设置DNN模型

    • 先引入包:
      from sknn.mlp import Regressor, Layer

    • 参数设置步骤

      • 先设置DNN每层计算方式,先设置每个隐层、最后设置输出层
        • 隐层。设置参数:激活函数(Sigmoid、ReLU: Rectifier)、计算单元数量units
        • 输出层。Layer("Linear")
      • 学习速率: learning_rate=0.02
      • random_rate = 2019 : 用来再现相同的数据
      • 模型允许最大迭代次数:n_iter = 10
    • 代码:

    from sknn.mlp import Regressor, Layer
    ## 模型1,fit1_Sigmoid:激活函数 "Sigmoid"
    fit1_Sigmoid = Regressor(layers=[
        Layer("Sigmoid", units=6),
        Layer("Sigmoid", units=14),
        Layer("Linear")],
        learning_rate=0.02,
        random_state=2019,
        n_iter=10)
    
    ## 模型2,fit2_ReLU :激活函数 "ReLU"
    fit2_ReLU = Regressor(layers=[
        Layer("Rectifier", units=6),
        Layer("Rectifier", units=14),
        Layer("Linear")],
        learning_rate=0.02,
        random_state=2019,
        n_iter=10)
    
    ## 模型3,fit3_ReLU:激活函数 "ReLU", 调整迭代次数为100
    fit3_ReLU = Regressor(layers=[
        Layer("Rectifier", units=6),
        Layer("Rectifier", units=14),
        Layer("Linear")],
        learning_rate=0.02,
        random_state=2019,
        n_iter=100)
    
    ## 模型4,fit4_ReLU:激活函数 "ReLU", 调整迭代次数为100,
    ##  采用L2正则化,和一个相对小的权重衰减系数0.001来调整期末考试得分模型
    fit4_ReLU = Regressor(layers=[
        Layer("Rectifier", units=6),
        Layer("Rectifier", units=14),
        Layer("Linear")],
        learning_rate=0.02,
        regularize = "L2",
        random_state=2019,
        weight_decay =0.001,
        n_iter=100)
    

    5、训练模型

    • 用函数fit()训练模型,即使用数据(x_train, y_train),拟合模型。代码:
    print "fitting model right now"
    fit1_Sigmoid.fit(x_train,y_train)
    fit2_ReLU.fit(x_train,y_train)
    fit3_ReLU.fit(x_train,y_train)
    fit4_ReLU.fit(x_train,y_train)
    

    6、评估模型

    6.0 用预测结果与实际结果的相关性 R的平方来评估模型。

    • 引入下面的包 mean_squared_error。 代码:
      from sklearn.metrics import mean_squared_error

    6.1 评估模型在训练集上的表现

    pred1_train = fit1_Sigmoid.predict(x_train)
    pred2_train = fit2_ReLU.predict(x_train)
    pred3_train = fit3_ReLU.predict(x_train)
    pred4_train = fit4_ReLU.predict(x_train)
    
    mse_1_train = mean_squared_error(pred1_train, y_train)
    mse_2_train = mean_squared_error(pred2_train, y_train)
    mse_3_train = mean_squared_error(pred3_train, y_train)
    mse_4_train = mean_squared_error(pred4_train, y_train)
    
    print "train ERROR :
     
    mse_1_train = %s  
     mse_2_train = %s  
     mse_3_train = %s  
     mse_4_train = %s "
    %(mse_1_train, mse_2_train,mse_3_train,mse_4_train)
    
    • 运行结果:

    6.2 评估模型在测试集上的表现

    pred1_test = fit1_Sigmoid.predict(x_test)
    pred2_test = fit2_ReLU.predict(x_test)
    pred3_test = fit3_ReLU.predict(x_test)
    pred4_test = fit4_ReLU.predict(x_test)
    
    mse_1_test = mean_squared_error(pred1_test, y_test)
    mse_2_test = mean_squared_error(pred2_test, y_test)
    mse_3_test = mean_squared_error(pred3_test, y_test)
    mse_4_test = mean_squared_error(pred4_test, y_test)
    
    print "test ERROR :
     
    mse_1_test = %s  
     mse_2_test = %s  
     mse_3_test = %s  
     mse_4_test = %s "
    %(mse_1_test, mse_2_test,mse_3_test,mse_4_test)
    
    • 运行结果:

    7、应用模型

    • 给出一组平时成绩,预测期末成绩 y'

    • 映射到实际的分数

      • 用MinMaxScaler的函数inverse_transform()
      • y_MinMax.inverse_transform([[y']])

    7.1. 输入:csv格式数据,存入:x_data

     score_file_pred = 'score_pred.csv'
    
    if not os.path.exists(score_file_pred):
        print "File ", score_file_pred, " does not exist!"
    else :
        x_data = []
        with open(score_file_pred) as csvfile_pred:
            csv_reader = csv.reader(csvfile_pred)
            score_header = next(csv_reader) # 读取第1行, 不是标题
            score_header = next(csv_reader) # 读取第2行每一列的标题
            for row in csv_reader:                # 将csv 文件中的数据保存到score_data中
                x_data.append(row[0:NumberOfPractice])
            csvfile_pred.close()                     # 关闭文件
    

    7.2. 将 x_src 标准化

    x_src = x_MinMax.fit_transform(x_data)
    x_src.mean(axis =0)
    

    7.3. 应用4个模型预测。

    • 得到的预测值:pred1_src、pred2_src、pred3_src、pred4_src
    # print "根据平时成绩预测期末成绩 ......"
    pred1_src = fit1_Sigmoid.predict(x_src)
    pred2_src = fit2_ReLU.predict(x_src)
    pred3_src = fit3_ReLU.predict(x_src)
    pred4_src = fit4_ReLU.predict(x_src)
    

    7.4. 将标准化的预测值,映射到实践值

    pred_real1 = y_MinMax.inverse_transform(pred1_src)
    pred_real2 = y_MinMax.inverse_transform(pred2_src)
    pred_real3 = y_MinMax.inverse_transform(pred3_src)
    pred_real4 = y_MinMax.inverse_transform(pred4_src)
    
    # print "期末成绩"
    # print pred_real1, pred_real2, pred_real3, pred_real4
    

    7.5. 将预测结果,写到csv文件

    • 新建了一个csv文件
    # print "期末成绩写入文件... "
    
    with open("score_pred_result.csv", 'w') as f:
        result_writer = csv.writer(f)
        result_writer.writerow(score_header + ["Pred1","Pred2","Pred3","Pred4"])
        i = 0
        for row in x_data:
        	row.append(pred_real1[i])
        	row.append(pred_real2[i])
        	row.append(pred_real3[i])
        	row.append(pred_real4[i])
        	i = i + 1
        	result_writer.writerow(row)
    
    f.close()                 # 关闭文件
    

    附录1:本次实验完整的代码

    # -*- coding: utf-8 -*-
    # 可以处理指定目录下的 对应分数的score.csv
    
    import pdb
    
    import csv
    import os
    
    # step 1: 装载数据,到 score_data ; 标题写到score_header
    
    # 数据集名称
    score_file = 'score.csv'
    NumberOfPractice = 13  # 平时作业次数
    
    if not os.path.exists(score_file):
        print "File ", score_file, " does not exist!"
    else :
    	score_data = []
    	with open(score_file) as csvfile:
    		csv_reader = csv.reader(csvfile)
    		score_header = next(csv_reader) # 读取第1行, 不是标题
    		score_header = next(csv_reader) # 读取第2行每一列的标题
    		for row in csv_reader: 		    # 将csv 文件中的数据保存到score_data中
    			score_data.append(row)
    		csvfile.close()                 # 关闭文件
    
    # step 2:拆分数据集 x(平时成绩),y(期末成绩),并将其标准化
    # 2.1 切片 score_data
    x , y = [], []
    for item in score_data:
    	x0 , y0 = item[0:NumberOfPractice], item[NumberOfPractice]
    	x.append(x0)
    	y.append(y0)
    
    # 2.2 标准化
    from sklearn.preprocessing import MinMaxScaler
    
    x_MinMax = MinMaxScaler ()
    y_MinMax = MinMaxScaler ()
    
    import numpy as np
    y = np.array(y).reshape((len(y), 1))
    x = x_MinMax.fit_transform(x)
    y = y_MinMax.fit_transform(y)
    x.mean(axis =0)
    
    # print x_MinMax.scale_
    # print y_MinMax.scale_
    
    # print y_MinMax.inverse_transform([[0.8725]])  # 如果预测值为“0.8725”,则可用 inverse_transform 映射回实际值
    
    ## step 3:拆分为训练集和测试集
    
    import random
    from sklearn.model_selection import train_test_split
    
    np.random.seed(2019)
    x_train , x_test , y_train , y_test = train_test_split(x, y, test_size = 0.2)
    
    
    ## step 4:创建DNN模型。 PS: 可以创建很多类型的DNN, 
    from sknn.mlp import Regressor, Layer
    ## 模型1,fit1_Sigmoid:激活函数 "Sigmoid"
    fit1_Sigmoid = Regressor(layers=[
        Layer("Sigmoid", units=6),
        Layer("Sigmoid", units=14),
        Layer("Linear")],
        learning_rate=0.02,
        random_state=2019,
        n_iter=10)
    
    ## 模型2,fit2_ReLU :激活函数 "ReLU"
    fit2_ReLU = Regressor(layers=[
        Layer("Rectifier", units=6),
        Layer("Rectifier", units=14),
        Layer("Linear")],
        learning_rate=0.02,
        random_state=2019,
        n_iter=10)
    
    ## 模型3,fit3_ReLU:激活函数 "ReLU", 调整迭代次数为100
    fit3_ReLU = Regressor(layers=[
        Layer("Rectifier", units=6),
        Layer("Rectifier", units=14),
        Layer("Linear")],
        learning_rate=0.02,
        random_state=2019,
        n_iter=100)
    
    ## 模型4,fit4_ReLU:激活函数 "ReLU", 调整迭代次数为100,
    ##  采用L2正则化,和一个相对小的权重衰减系数0.001来调整期末考试得分模型
    fit4_ReLU = Regressor(layers=[
        Layer("Rectifier", units=6),
        Layer("Rectifier", units=14),
        Layer("Linear")],
        learning_rate=0.02,
        regularize = "L2",
        random_state=2019,
        weight_decay =0.001,
        n_iter=100)
    
    ## step 5: 用函数fit()训练模型,即使用数据(x_train, y_train),拟合模型
    print "fitting model right now"
    fit1_Sigmoid.fit(x_train,y_train)
    fit2_ReLU.fit(x_train,y_train)
    fit3_ReLU.fit(x_train,y_train)
    fit4_ReLU.fit(x_train,y_train)
    
    ## step 6: 评估模型。 
    ### 6.0 用预测结果与实际结果的相关性 R的平方来评估模型,引入下面的包 mean_squared_error
    from sklearn.metrics import mean_squared_error
    ### 6.1 评估模型在训练集上的表现
    pred1_train = fit1_Sigmoid.predict(x_train)
    pred2_train = fit2_ReLU.predict(x_train)
    pred3_train = fit3_ReLU.predict(x_train)
    pred4_train = fit4_ReLU.predict(x_train)
    
    mse_1_train = mean_squared_error(pred1_train, y_train)
    mse_2_train = mean_squared_error(pred2_train, y_train)
    mse_3_train = mean_squared_error(pred3_train, y_train)
    mse_4_train = mean_squared_error(pred4_train, y_train)
    
    print "train ERROR :
     
    mse_1_train = %s  
     mse_2_train = %s  
     mse_3_train = %s  
     mse_4_train = %s "
    %(mse_1_train, mse_2_train,mse_3_train,mse_4_train)
    
    ### 6.2 评估模型在测试集上的表现
    pred1_test = fit1_Sigmoid.predict(x_test)
    pred2_test = fit2_ReLU.predict(x_test)
    pred3_test = fit3_ReLU.predict(x_test)
    pred4_test = fit4_ReLU.predict(x_test)
    
    mse_1_test = mean_squared_error(pred1_test, y_test)
    mse_2_test = mean_squared_error(pred2_test, y_test)
    mse_3_test = mean_squared_error(pred3_test, y_test)
    mse_4_test = mean_squared_error(pred4_test, y_test)
    
    print "test ERROR :
     
    mse_1_test = %s  
     mse_2_test = %s  
     mse_3_test = %s  
     mse_4_test = %s "
    %(mse_1_test, mse_2_test,mse_3_test,mse_4_test)
    
    ## step 7: 应用模型s
    ### 7.1. 输入:csv格式数据,存入:x_data
    print "读取新数据 ... "
    score_file_pred = 'score_pred.csv'
    
    if not os.path.exists(score_file_pred):
        print "File ", score_file_pred, " does not exist!"
    else :
        x_data = []
        with open(score_file_pred) as csvfile_pred:
            csv_reader = csv.reader(csvfile_pred)
            score_header = next(csv_reader) # 读取第1行, 不是标题
            score_header = next(csv_reader) # 读取第2行每一列的标题
            for row in csv_reader:          # 将csv 文件中的数据保存到score_data中
                x_data.append(row[0:NumberOfPractice])
            csvfile_pred.close()            # 关闭文件
        
    
    ### 7.2. 将 x_src 标准化
    x_src = x_MinMax.fit_transform(x_data)
    x_src.mean(axis =0)
    
    ### 7.3. 应用4个模型预测。
    ## 得到的预测值:pred1_src、pred2_src、pred3_src、pred4_src
    # print "根据平时成绩预测期末成绩 ......"
    pred1_src = fit1_Sigmoid.predict(x_src)
    pred2_src = fit2_ReLU.predict(x_src)
    pred3_src = fit3_ReLU.predict(x_src)
    pred4_src = fit4_ReLU.predict(x_src)
    
    ### 7.4. 将标准化的预测值,映射到实践值
    pred_real1 = y_MinMax.inverse_transform(pred1_src)
    pred_real2 = y_MinMax.inverse_transform(pred2_src)
    pred_real3 = y_MinMax.inverse_transform(pred3_src)
    pred_real4 = y_MinMax.inverse_transform(pred4_src)
    
    # print "期末成绩"
    # print pred_real1, pred_real2, pred_real3, pred_real4
    
    ### 7.5. 将预测结果,写到csv文件
    
    # print "期末成绩写入文件... "
    
    with open("score_pred_result.csv", 'w') as f:
        result_writer = csv.writer(f)
        result_writer.writerow(score_header + ["Pred1","Pred2","Pred3","Pred4"])
        i = 0
        for row in x_data:
        	row.append(pred_real1[i])
        	row.append(pred_real2[i])
        	row.append(pred_real3[i])
        	row.append(pred_real4[i])
        	i = i + 1
        	result_writer.writerow(row)
    
    f.close()                 # 关闭文件
    # 
    
    

    附录二 数据集(训练数据、测试数据)

    1. 学生平时成绩和期末考试成绩 score.csv
  • 相关阅读:
    Confluence wiki——CentOS6.8搭建详解
    ifconfig不显示网卡eth0
    VMware vSphere克隆虚拟机
    VMware ESXI6.0服务器安装
    虚拟化技术的基本介绍
    HTTP协议详解
    Shell中的case命令
    Linux通过ssh登录其他服务器,不用输入密码
    Linux下/etc/passwd、/etc/shadow、/etc/group文件
    Linux挂载详解
  • 原文地址:https://www.cnblogs.com/juking/p/11223699.html
Copyright © 2020-2023  润新知