sklearn学习记录(菜菜——随机森林回归RandomForestRegressor填补缺失值)


sklearn学习记录(菜菜——随机森林回归RandomForestRegressor填补缺失值)

  • sklearn学习记录(菜菜——随机森林回归RandomForestRegressor填补缺失值)
  • 一、导入库
  • 二、导入数据
  • 三、为完整数据集放入缺失值
  • 四、使用0和均值填补缺失值
  • 五、使用随机森林填补缺失值
  • 六、对填补好的数据进行建模
  • 七、用所得结果画出条形图


#随机森林回归
'''
所有的参数,属性与接口,全部和随机森林分类器一致。
仅有的不同就是回归树与分类树的不同,不纯度的指标,参数Criterion不一致。

criterion:
mse,均方误差
friedman_mse,费尔德曼均方误差
mae,绝对平均误差
'''

一、导入库

#用随机森林回归填补缺失值

#导入需要的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_boston
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_val_score
from sklearn.impute import SimpleImputer

二、导入数据

#导入数据及探索数据
dataset = load_boston()
print(dataset.data.shape)
x_full,y_full=dataset.data,dataset.target
n_samples=x_full.shape[0]
n_features=x_full.shape[1]
print(x_full,y_full,n_samples,n_features)

随机森林填补缺失值 R语言 随机森林处理缺失值_随机森林

三、为完整数据集放入缺失值

#为完整数据集放入缺失值

#先确定希望放入的缺失数据的比例
rng=np.random.RandomState(0)
missing_rate=0.5

'''
计算在一个数据集中,有多少个样本(samples)和特征(features)的值将被标记为缺失,
具体数量由 n_samples、n_features 和 missing_rate 决定。

n_samples 是数据集中的样本数。
n_features 是数据集中的特征数。
missing_rate 是缺失率,即希望有多少比例的数据被标记为缺失。

np.floor 函数是向下取整函数
'''
n_missing_samples=int(np.floor(n_samples*n_features*missing_rate))
print(n_missing_samples)

随机森林填补缺失值 R语言 随机森林处理缺失值_学习_02


#所有数据要随机遍布在数据集的各行各列当中,而一个缺失的数据会需要一个行索引和一个列索引
#如果能够创造一个数组,包含3289个分布在0~506中间的行索引,和3289个分布在0~13之间的列索引,那我们就可以利用索引来为数据中的任意3289个位置赋空值
#然后我们用0,均值和随机森林来填写这些缺失值,然后查看回归的结果如何

'''
rng.randint(0, n_features, n_missing_samples) 生成 n_missing_samples 个在 [0, n_features) 范围内的随机整数,
这些整数代表数据集中将被标记为缺失的特征的索引。
结果存储在 missing_features 变量中。

rng.randint(0, n_samples, n_missing_samples) 生成 n_missing_samples 个在 [0, n_samples) 范围内的随机整数,
这些整数代表数据集中将被标记为缺失的样本的索引。
结果存储在 missing_samples 变量中。
'''
missing_features=rng.randint(0,n_features,n_missing_samples)
missing_samples=rng.randint(0,n_samples,n_missing_samples)

#missing_samples = rng.choice(dataset.data.shape[0],n_missing_samples,replace=False)
#我们现在采样了3289个数据,远远超过我们的样本量506,
#所以我们使用随机抽取的函数randint。
#但如果我们需要的数据量小于我们的样本量506,
#那我们可以采用np.random.choice来抽样,choice会随机抽取不重复的随机数,因此可以帮助我们让数据更加分散,确保数据不会集中在一些行中

x_missing=x_full.copy()
y_missing=y_full.copy()

x_missing[missing_samples,missing_features]=np.nan

x_missing=pd.DataFrame(x_missing)

x_missing

随机森林填补缺失值 R语言 随机森林处理缺失值_sklearn_03

四、使用0和均值填补缺失值

#使用均值进行填补
'''
SimpleImputer:是 scikit-learn 中的一个类,用于处理数据集中的缺失值。
它的作用是通过指定的策略来填充缺失值,使得数据集可以用于机器学习模型的训练。
参数:
strategy:填充缺失值的策略,
可以是 "mean"(均值)、"median"(中位数)、"most_frequent"(众数)或指定一个常数值(constant)。
fill_value:如果选择指定常数值填充缺失值,可以通过这个参数指定常数。
missing_values:指定缺失值的标记,可以是一个具体的值(如 NaN)或一个标记列表。
'''

'''
创建了一个 SimpleImputer 对象 imp_mean,
指定了缺失值的标记为 np.nan(NaN),填充策略为均值(strategy='mean')。
这意味着在数据集中的缺失值将被均值填充。
'''
imp_mean=SimpleImputer(missing_values=np.nan,strategy='mean')

'''
使用 fit_transform 方法,对 x_missing 数据集进行拟合和转换。
先拟合(fit)再转换(transform).
fit_transform 的作用是根据指定的填充策略(均值)计算缺失值的填充值,
并将缺失值替换为计算得到的填充值。
结果存储在 x_missing_mean 中,这是一个不包含缺失值的新数据集。
'''
x_missing_mean=imp_mean.fit_transform(x_missing)

pd.DataFrame(x_missing_mean)

随机森林填补缺失值 R语言 随机森林处理缺失值_回归_04


#检查是否还有缺失值
pd.DataFrame(x_missing_mean).isnull().sum()

随机森林填补缺失值 R语言 随机森林处理缺失值_sklearn_05


#使用0进行填补

imp_0=SimpleImputer(missing_values=np.nan,strategy='constant',fill_value=0)
x_missing_0=imp_0.fit_transform(x_missing)

pd.DataFrame(x_missing_0)

随机森林填补缺失值 R语言 随机森林处理缺失值_学习_06


pd.DataFrame(x_missing_0).isnull().sum()

随机森林填补缺失值 R语言 随机森林处理缺失值_sklearn_07

五、使用随机森林填补缺失值

#使用随机森林填补缺失值

'''
对于一个有n个特征的数据来说,其中特征T有缺失值,我们就把特征T当作标签,
其他的n-1个特征和原本的标签组成新的特征矩阵。
那对于T来说,它没有缺失的部分,就是我们的Y_test,这部分数据既有标签也有特征,
而它缺失的部分,只有特征没有标签,就是我们需要预测的部分。

这种做法,对于某一个特征大量缺失,其他特征却很完整的情况,非常适用

那如果数据中除了特征T之外,其他特征也有缺失值怎么办?
答案是遍历所有的特征,从缺失最少的开始进行填补(因为填补缺失最少的特征所需要的准确信息最少)。
填补一个特征时,先将其他特征的缺失值用0代替,
每完成一次回归预测,就将预测值放到原本的特征矩阵中,再继续填补下一个特征。
每一次填补完毕,有缺失值的特征会减少一个,
所以每次循环后,需要用0来填补的特征就越来越少。
当进行到最后一个特征时(这个特征应该是所有特征中缺失值最多的),
已经没有任何的其他特征需要用0来进行填补了,
而我们已经使用回归为其他特征填补了大量有效信息,可以用来填补缺失最多的特征。
遍历所有特征后,数据就完整了,不再有缺失值了。
'''

x_missing_reg=x_missing.copy()
'''
x_missing_reg.isnull().sum(axis=0):
isnull() 方法用于检测数据中的缺失值,返回一个布尔值的数据框,
其中缺失值为 True(1),非缺失值为 False(0)。
sum(axis=0) 对每一列进行求和,计算出每个特征的缺失值数量。

np.argsort(...):
np.argsort() 返回数组值从小到大的索引值。
在这里,它被用于对特征的缺失值数量进行排序,
得到的是按缺失值数量升序排列的特征索引。

np.argsort() 和 np.sort() 是 NumPy 中用于排序的两个不同的函数,
它们有一些关键的区别。
np.argsort():返回排序后的索引
np.argsort() 返回的是原数组中元素的索引,这些索引按照对应元素的升序排列。
这并不改变原始数组的元素顺序,而是返回一个表示排序后索引的新数组。
np.sort():返回排序后的数组
np.sort() 返回的是原数组元素按升序排列的新数组,而不是返回索引。
这会改变原始数组的元素顺序。
'''
sortindex=np.argsort(x_missing_reg.isnull().sum(axis=0)).values
print(np.argsort(x_missing_reg.isnull().sum(axis=0)))
print(sortindex)

随机森林填补缺失值 R语言 随机森林处理缺失值_学习_08


for i in sortindex:
    #构建新特征矩阵和新标签
    df=x_missing_reg
    fillc=df.iloc[:,i]
    df=pd.concat([df.iloc[:,df.columns!=i],pd.DataFrame(y_full)],axis=1)

    #在新特征矩阵中,对含有缺失值的列,进行0的填补
    df_0=SimpleImputer(missing_values=np.nan,
                       strategy='constant',
                       fill_value=0).fit_transform(df)
    
    '''
    特征T不缺失的值对应的其他n-1个特征 + 本来的标签:X_train
    特征T不缺失的值:Y_train

    特征T缺失的值对应的其他n-1个特征 + 本来的标签:X_test
    特征T缺失的值:未知:我们需要预测的Y_test
    '''
    #找出训练集和测试集
    ytrain=fillc[fillc.notnull()]
    ytest=fillc[fillc.isnull()]
    xtrain=df_0[ytrain.index,:]
    xtest=df_0[ytest.index,:]

    #用随机森林回归填补缺失值
    rfr=RandomForestRegressor(n_estimators=100)
    rfr=rfr.fit(xtrain,ytrain)
    ypredict=rfr.predict(xtest)

    #将填补好的特征返回到我们的原始的特征矩阵中
    '''
    x_missing_reg.iloc[:, i] 选择 x_missing_reg 数据框中的第 i 列。
    x_missing_reg.iloc[:, i].isnull() 生成一个布尔 Series,其中缺失值对应的位置为 True。
    x_missing_reg.loc[...] 用于根据条件选择数据框的子集,其中条件是缺失值的位置。
    = ypredict 将符合条件的缺失值位置的元素用 ypredict 的值进行填充。
    '''
    x_missing_reg.loc[x_missing_reg.iloc[:,i].isnull(),i]=ypredict

六、对填补好的数据进行建模

#对所有填补好的数据进行建模,取得MSE结果

x=[x_full,x_missing_mean,x_missing_0,x_missing_reg]

mse=[]

for xi in x:
    estimator=RandomForestRegressor(random_state=0,n_estimators=100)
    scores=cross_val_score(estimator,
                           xi,y_full,
                           scoring='neg_mean_squared_error',
                           cv=5).mean()
    mse.append(-1*scores)

print(mse)

随机森林填补缺失值 R语言 随机森林处理缺失值_sklearn_09

七、用所得结果画出条形图

#用所得结果画出条形图
x_labels=['Full data',
          'Zero Imputation',
          'Mean Imputation',
          'Regressor Imputation']
colors=['r','g','b','orange']

'''
plt.figure(figsize=(12,6)) 创建一个图表,指定图表的大小为 12x6。
ax = plt.subplot(111) 创建一个子图,
其中 111 表示一个 1x1 网格,当前选中的是第一个子图。
'''
plt.figure(figsize=(12,6))
ax=plt.subplot(111)

'''
使用 for 循环遍历每个填充方法,使用 ax.barh 绘制水平条形图。
i 表示当前填充方法的索引,mse[i] 表示对应的均方误差。
color=colors[i] 指定条形的颜色,alpha=0.6 设置透明度,align='center' 表示条形居中对齐。
'''
for i in np.arange(len(mse)):
    ax.barh(i,mse[i],color=colors[i],alpha=0.6,align='center')

'''
ax.set_title('Imputation Techniques with Boston Data') 设置图表标题。
ax.set_xlim(left=np.min(mse)*0.9, right=np.max(mse)*1.1) 设置 x 轴的范围。
ax.set_yticks(np.arange(len(mse))) 设置 y 轴的刻度。
ax.set_xlabel('MSE') 设置 x 轴标签。
ax.set_yticklabels(x_labels) 设置 y 轴标签。
'''
ax.set_title('Imputation Techniques with Boston Data')
ax.set_xlim(left=np.min(mse)*0.9,
            right=np.max(mse)*1.1)
ax.set_yticks(np.arange(len(mse)))
ax.set_xlabel('MSE')
ax.set_yticklabels(x_labels)

plt.show()

随机森林填补缺失值 R语言 随机森林处理缺失值_回归_10