本篇簡介不多莱预,就一行柠掂。
IncMSE 是 increase in MSE。就是對每一個自變量(特征)隨機賦值依沮,如果該自變量(特征)重要的話涯贞,預(yù)測的誤差會增大枪狂。
數(shù)據(jù)
我存為.xlsx格式,可以直接讀取宋渔。
一行是一個樣本州疾,前17個為特征(自變量),最后一個是目標變量(因變量)皇拣。
我們進行回歸預(yù)測通常就是通過一個樣本的特征來預(yù)測目標變量严蓖。
這個數(shù)據(jù)是我之前寫論文的時候用的,事先進行歸一化處理氧急。得分是該樣本城市的人口增長颗胡。
代碼的基本思想與上一篇文章一樣。
————————————————————————————————
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import math
import xlrd
import xlwt
import random
import copy
###########1.讀取數(shù)據(jù)部分##########
#載入數(shù)據(jù)并且打亂數(shù)據(jù)集
def load_data(StartPo,EndPo,TestProportion,FeatureNum,Shuffle,FilePath): ? ? ? ?
? ? #load_data(樣本起始行數(shù)吩坝,結(jié)束行數(shù)杭措,測試集占總樣本集比重,特征數(shù),是否打亂樣本集) ? ? #如果Testproportion為0或1就訓練集=測試集
? ? #打開excel文件
? ? workbook = xlrd.open_workbook(str((str(FilePath)))) ? ? ? #excel路徑
? ? sheet = workbook.sheet_by_name('Sheet1') ? ? ? ? ? ? #sheet表
? ? Sample = []#總樣本集
? ? train = []#訓練集
? ? test = []#測試集
? ? TestSetSphere = (EndPo-StartPo+1)*TestProportion ?#測試集數(shù)目
? ? TestSetSphere = int(TestSetSphere)#測試集數(shù)目
? ? #獲取全部樣本集并打亂順序
? ? for loadi in range(StartPo-1,EndPo):
? ? ? ? RowSample = sheet.row_values(loadi)
? ? ? ? Sample.append(RowSample)
? ? if Shuffle == 1: ?#是否打亂樣本集
? ? ? ? random.shuffle(Sample) ?#如果shuffle=1钾恢,打亂樣本集
? ? #如果Testproportion為0就訓練集=測試集
? ? if TestProportion == 0 or TestProportion == 1:
? ? ? ? TrainSet = np.array(Sample) ? ? ? ? ?#變換為array
? ? ? ? TestSet = np.array(Sample)
? ? else:
? ? ? ? #設(shè)置訓練集
? ? ? ? for loadtraina in Sample[:(EndPo-TestSetSphere)]:
? ? ? ? ? ? GetTrainValue = loadtraina
? ? ? ? ? ? train.append(GetTrainValue)
? ? ? ? #設(shè)置測試集
? ? ? ? for loadtesta in range(-TestSetSphere-1,-1):
? ? ? ? ? ? GetTestValue = Sample[loadtesta]
? ? ? ? ? ? test.append(GetTestValue)
? ? ? ? #變換樣本集
? ? ? ? TrainSet = np.array(train) ? ? ? ? ? ? ? ? ?#變換為array
? ? ? ? TestSet = np.array(test) ? ? ? ?
? ?#分割特征與目標變量
? ? x1 , y1 = TrainSet[:,:FeatureNum] , TrainSet[:,-1]
? ? x2 , y2 = TestSet[:,:FeatureNum] , TestSet[:,-1]
? ? return x1 , y1 , x2 , y2
###########2.回歸部分##########
def regression_method(model):
? ? model.fit(x_train,y_train)
? ? score = model.score(x_test, y_test)
? ? result = model.predict(x_test)
? ? ResidualSquare = (result - y_test)**2 ? ? #計算殘差平方
? ? RSS = sum(ResidualSquare) ? #計算殘差平方和
? ? MSE = np.mean(ResidualSquare) ? ? ? #計算均方差
? ? num_regress = len(result) ? #回歸樣本個數(shù)
? ? print(f'n={num_regress}')
? ? print(f'R^2={score}')
? ? print(f'MSE={MSE}')
? ? print(f'RSS={RSS}')
? ? return MSE
##########3.計算MSE########
def IncMSE(MSE,x_test, y_test,FeatureNum,Set_Times,model): ? ?#獲取MSE,x測試集鸳址,y測試集瘩蚪,特征數(shù),隨機求IncMSE次數(shù)稿黍,模型(隨機森林)
? ? x_MSE = copy.deepcopy(x_test) ? ? ?#深拷貝不破壞原列表
? ? y_MSE = copy.deepcopy(y_test)
? ? TestNum = len(y_MSE)
? ? #########多次生成隨機數(shù)疹瘦,多次計算IncMSE(由于隨機有不確定性,所以要多次隨機)
? ? IncMSE_Set = []
? ? IncMSE_Times = 1
? ? while IncMSE_Times <= Set_Times: ? ? #多次生成隨機數(shù)巡球,多次計算IncMSE(由于隨機有不確定性言沐,所以要多次隨機)
? ? ? ? IncMSE_x = []
? ? ? ? for i in range(0,FeatureNum):
? ? ? ? ? ? MSE_Replace = np.random.random(TestNum)
? ? ? ? ? ? x_MSE[:,i] = MSE_Replace ? ? ? ? ? #替換第i個特征
? ? ? ? ? ? MSE_Score = model.score(x_MSE,y_MSE)
? ? ? ? ? ? MSE_Result = model.predict(x_MSE)
? ? ? ? ? ? MSE_ResidualSquare = (MSE_Result - y_MSE)**2 ? #計算殘差平方
? ? ? ? ? ? MSE_RSS = sum(MSE_ResidualSquare) ? #計算殘差平方和
? ? ? ? ? ? MSE_MSE = np.mean(MSE_ResidualSquare) ? #計算均方差
? ? ? ? ? ? IncMSE = MSE_MSE - MSE
? ? ? ? ? ? IncMSE_x.append(IncMSE)
? ? ? ? ? ? x_MSE = copy.deepcopy(x_test) ? #復(fù)原原特征,深拷貝不破壞原列表 ? ? ? ? ? ?
? ? ? ? IncMSE_Set.append(IncMSE_x) ? ? ? ? ?#多次計算IncMSE后的數(shù)據(jù)
? ? ? ? IncMSE_Times += 1
? ? IncMSE_SetArray = np.array(IncMSE_Set) ? ?#變換為array
? ? ########計算每個特征的IncMSE平均數(shù)########
? ? X_IncMSE_Average = []
? ? for j in range(0,FeatureNum):
? ? ? ? X_IncMSE_Set = IncMSE_SetArray[:,j]
? ? ? ? X_IncMSE = np.mean(X_IncMSE_Set) ? ? ? #求多次IncMSE的平均值(由于隨機有不確定性酣栈,所以要多次隨機)
? ? ? ? X_IncMSE_Average.append(X_IncMSE)
? ? X_IncMSE_Average_Sum = sum(X_IncMSE_Average)
? ? ########計算每個特征的IncMSE平均數(shù)的百分比########
? ? print('IncMSE:')
? ? for k in range(0,FeatureNum):
? ? ? ? X_Percent = X_IncMSE_Average[k]/X_IncMSE_Average_Sum ? ? ? #計算每個特征IncMSE的百分比
? ? ? ? print(f' ? ?x{k+1} = {X_IncMSE_Average[k]} ? {X_Percent*100}%') ? ? ? ?#輸出各特征的IncMSE的平均數(shù)與其百分比
###########4.預(yù)設(shè)回歸方法##########
####隨機森林回歸####
from sklearn import ensemble
model_RandomForestRegressor = ensemble.RandomForestRegressor(n_estimators=800) ? #esitimators決策樹數(shù)量
########5.設(shè)置參數(shù)與執(zhí)行部分#############
#設(shè)置數(shù)據(jù)參數(shù)部分
x_train , y_train , x_test , y_test = load_data(2,121,1,17,0,'C:\Code\MachineLearning\極差標準化數(shù)據(jù)集.xlsx') ? #行數(shù)以excel里為準
#起始行數(shù)2险胰,結(jié)束行數(shù)121,訓練集=測試集矿筝,特征數(shù)量17,不打亂樣本集
MSE = regression_method(model_RandomForestRegressor) ? ? ? ?#括號內(nèi)填上方法起便,并獲取MSE
print('————————————————————————————————————————————————————————————')
IncMSE(MSE,x_test,y_test,17,1000,model_RandomForestRegressor)
#特征數(shù)17,x測試集窖维,y測試集榆综,隨機求IncMSE次數(shù)30次(輸出結(jié)果為其平均值),模型隨機森林 ? ? #隨機次數(shù)越多IncMSE越準確
——————————————————————————————————————
由于是同一組數(shù)據(jù)集铸史,因此在第五部分里load_data()的設(shè)置和前一篇文章一樣(前一篇文章的鏈接貼在該文章末尾)鼻疮。
使用時,一般情況下只需填寫第五部分即可琳轿,隨機IncMSE次數(shù)越多判沟,得到的IncMSE越準確耿芹,當然運行時間也越久,在這里我節(jié)省時間只進行了50次水评。
值得注意的是猩系,這里的起始和結(jié)束行數(shù)我設(shè)置成了以excel表里為準。
#設(shè)置數(shù)據(jù)參數(shù)部分
x_train , y_train , x_test , y_test = load_data(2,121,1,17,0,'C:\Code\MachineLearning\極差標準化數(shù)據(jù)集.xlsx') ? #行數(shù)以excel里為準
#起始行數(shù)2中燥,結(jié)束行數(shù)121寇甸,訓練集=測試集,特征數(shù)量17,不打亂樣本集
MSE = regression_method(model_RandomForestRegressor) ? ? ? ?#括號內(nèi)填上方法疗涉,并獲取MSE
print('————————————————————————————————————————————————————————————')
IncMSE(MSE,x_test,y_test,17,50,model_RandomForestRegressor)
#特征數(shù)17拿霉,x測試集,y測試集咱扣,隨機求IncMSE次數(shù)30次(輸出結(jié)果為其平均值)绽淘,模型隨機森林 ? ? #隨機次數(shù)越多IncMSE越準確
本文的代碼不出圖,但是會出幾個參數(shù)闹伪。
其中包括回歸里的幾個基本參數(shù)沪铭,如R方、MSE偏瓤、RSS杀怠。
還會求出每個特征的IncMSE值與占比,以此來衡量各特征的重要性厅克。
比如如圖得出第17個自變量(特征)的IncMSE最高赔退,第10個自變量(特征)次之,對照數(shù)據(jù)可以看出固定資產(chǎn)投資和失業(yè)率對人口增長的影響最大证舟。