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)
三、为完整数据集放入缺失值
#为完整数据集放入缺失值
#先确定希望放入的缺失数据的比例
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)
#所有数据要随机遍布在数据集的各行各列当中,而一个缺失的数据会需要一个行索引和一个列索引
#如果能够创造一个数组,包含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
四、使用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)
#检查是否还有缺失值
pd.DataFrame(x_missing_mean).isnull().sum()
#使用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)
pd.DataFrame(x_missing_0).isnull().sum()
五、使用随机森林填补缺失值
#使用随机森林填补缺失值
'''
对于一个有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)
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)
七、用所得结果画出条形图
#用所得结果画出条形图
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()