【Python】基于python的回歸隨機森林(RandomForestRegression)2:計算各特征指標的權重(IncMSE)(附代碼)

本篇簡介不多,就一行。

IncMSE 是 increase in MSE。就是對每一個自變量(特征)隨機賦值,如果該自變量(特征)重要的話,預測的誤差會增大。


數據

我存為.xlsx格式,可以直接讀取。

一行是一個樣本,前17個為特征(自變量),最后一個是目標變量(因變量)。

我們進行回歸預測通常就是通過一個樣本的特征來預測目標變量。

這個數據是我之前寫論文的時候用的,事先進行歸一化處理。得分是該樣本城市的人口增長。



代碼的基本思想與上一篇文章一樣。

————————————————————————————————

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

import math

import xlrd

import xlwt

import random

import copy

###########1.讀取數據部分##########

#載入數據并且打亂數據集

def load_data(StartPo,EndPo,TestProportion,FeatureNum,Shuffle,FilePath): ? ? ? ?

? ? #load_data(樣本起始行數,結束行數,測試集占總樣本集比重,特征數,是否打亂樣本集) ? ? #如果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 ?#測試集數目

? ? TestSetSphere = int(TestSetSphere)#測試集數目

? ? #獲取全部樣本集并打亂順序

? ? 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:

? ? ? ? #設置訓練集

? ? ? ? for loadtraina in Sample[:(EndPo-TestSetSphere)]:

? ? ? ? ? ? GetTrainValue = loadtraina

? ? ? ? ? ? train.append(GetTrainValue)

? ? ? ? #設置測試集

? ? ? ? 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) ? #回歸樣本個數

? ? 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測試集,特征數,隨機求IncMSE次數,模型(隨機森林)

? ? x_MSE = copy.deepcopy(x_test) ? ? ?#深拷貝不破壞原列表

? ? y_MSE = copy.deepcopy(y_test)

? ? TestNum = len(y_MSE)

? ? #########多次生成隨機數,多次計算IncMSE(由于隨機有不確定性,所以要多次隨機)

? ? IncMSE_Set = []

? ? IncMSE_Times = 1

? ? while IncMSE_Times <= Set_Times: ? ? #多次生成隨機數,多次計算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) ? #復原原特征,深拷貝不破壞原列表 ? ? ? ? ? ?

? ? ? ? IncMSE_Set.append(IncMSE_x) ? ? ? ? ?#多次計算IncMSE后的數據

? ? ? ? IncMSE_Times += 1

? ? IncMSE_SetArray = np.array(IncMSE_Set) ? ?#變換為array

? ? ########計算每個特征的IncMSE平均數########

? ? 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平均數的百分比########

? ? 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的平均數與其百分比

###########4.預設回歸方法##########

####隨機森林回歸####

from sklearn import ensemble

model_RandomForestRegressor = ensemble.RandomForestRegressor(n_estimators=800) ? #esitimators決策樹數量

########5.設置參數與執(zhí)行部分#############

#設置數據參數部分

x_train , y_train , x_test , y_test = load_data(2,121,1,17,0,'C:\Code\MachineLearning\極差標準化數據集.xlsx') ? #行數以excel里為準

#起始行數2,結束行數121,訓練集=測試集,特征數量17,不打亂樣本集

MSE = regression_method(model_RandomForestRegressor) ? ? ? ?#括號內填上方法,并獲取MSE

print('————————————————————————————————————————————————————————————')

IncMSE(MSE,x_test,y_test,17,1000,model_RandomForestRegressor)

#特征數17,x測試集,y測試集,隨機求IncMSE次數30次(輸出結果為其平均值),模型隨機森林 ? ? #隨機次數越多IncMSE越準確

——————————————————————————————————————

由于是同一組數據集,因此在第五部分里load_data()的設置和前一篇文章一樣(前一篇文章的鏈接貼在該文章末尾)。

使用時,一般情況下只需填寫第五部分即可,隨機IncMSE次數越多,得到的IncMSE越準確,當然運行時間也越久,在這里我節(jié)省時間只進行了50次。

值得注意的是,這里的起始和結束行數我設置成了以excel表里為準。


#設置數據參數部分

x_train , y_train , x_test , y_test = load_data(2,121,1,17,0,'C:\Code\MachineLearning\極差標準化數據集.xlsx') ? #行數以excel里為準

#起始行數2,結束行數121,訓練集=測試集,特征數量17,不打亂樣本集

MSE = regression_method(model_RandomForestRegressor) ? ? ? ?#括號內填上方法,并獲取MSE

print('————————————————————————————————————————————————————————————')

IncMSE(MSE,x_test,y_test,17,50,model_RandomForestRegressor)

#特征數17,x測試集,y測試集,隨機求IncMSE次數30次(輸出結果為其平均值),模型隨機森林 ? ? #隨機次數越多IncMSE越準確





本文的代碼不出圖,但是會出幾個參數。

其中包括回歸里的幾個基本參數,如R方、MSE、RSS。

還會求出每個特征的IncMSE值與占比,以此來衡量各特征的重要性。

比如如圖得出第17個自變量(特征)的IncMSE最高,第10個自變量(特征)次之,對照數據可以看出固定資產投資和失業(yè)率對人口增長的影響最大。


?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容