本篇简介不多,就一行。
IncMSE 是 increase in MSE。就是对每一个自变量(特征)随机赋值,如果该自变量(特征)重要的话,预测的误差会增大。
数据
我存为.xlsx格式,可以直接读取。
一行是一个样本,前17个为特征(自变量),最后一个是目标变量(因变量)。
我们进行回归预测通常就是通过一个样本的特征来预测目标变量。
这个数据是我之前写论文的时候用的,事先进行归一化处理。得分是该样本城市的人口增长。
![](https://img.haomeiwen.com/i6751519/3c4b1f9be9a125bb.png)
代码的基本思想与上一篇文章一样。
————————————————————————————————
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.设置参数与执行部分#############
#设置数据参数部分
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越准确,当然运行时间也越久,在这里我节省时间只进行了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个自变量(特征)次之,对照数据可以看出固定资产投资和失业率对人口增长的影响最大。
![](https://img.haomeiwen.com/i6751519/0ff11e9497082785.png)
网友评论