應用深度神經網絡預測學生期末成績


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 :\n \
mse_1_train = %s  \n mse_2_train = %s  \n mse_3_train = %s  \n 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 :\n \
mse_1_test = %s  \n mse_2_test = %s  \n mse_3_test = %s  \n 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 :\n \
mse_1_train = %s  \n mse_2_train = %s  \n mse_3_train = %s  \n 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 :\n \
mse_1_test = %s  \n mse_2_test = %s  \n mse_3_test = %s  \n 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM