美文网首页
【Python】基于python的回归随机森林(RandomFo

【Python】基于python的回归随机森林(RandomFo

作者: 一颗小柚子lyc | 来源:发表于2023-01-12 16:32 被阅读0次

本篇简介不多,就一行。

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.设置参数与执行部分#############

#设置数据参数部分

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个自变量(特征)次之,对照数据可以看出固定资产投资和失业率对人口增长的影响最大。

相关文章

网友评论

      本文标题:【Python】基于python的回归随机森林(RandomFo

      本文链接:https://www.haomeiwen.com/subject/karwcdtx.html