这里呢,首先将波士顿数据进行填空,然后在对含有空值的数据进行,0、均值、随机森林回归填充,并比较其好坏,并以图像视之。
首先导入所需要的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_boston#数据集
from sklearn.impute import SimpleImputer#填补缺失的类
from sklearn.ensemble import RandomForestRegressor
获取数据,并查看数据
dataset = load_boston()#数据
dataset.data.shape#查看数据结构
n_samples = x_full.shape[0]#样本数量
n_features = x_full.shape[1]#标签数量
确定缺失值
#首先确定我们希望放入的缺失值数据的比例,在这里我们假设是50%,那就要有3289个数据缺失
rng = np.random.RandomState(0)
missing_rate = 0.5
n_missing_samples = int(np.floor(n_samples * n_features *missing_rate))
取出将赋值为空值的索引
#np.floor 向下取整
#所有数据要随机遍布在数据集的各行各列当中,而一个确实的数据会需要一盒行索引和一个列索引
#如果能够创造一个数组,就可以利用索引来赋空值
#用0,均值,随机森林来填写这些缺失值,然后查看这些回归结果
missing_features = rng.randint(0,n_features,n_missing_samples)
missing_samples =rng.randint(0,n_samples,n_missing_samples)
#randint(上限,下限,n) 请在下限和上限之间取出n个整数
#我们现在采样了3289个数据,远远超过了我们的样本量,所以可以使用随机抽取的函数randint
将数据赋值为nan
#但是如果我们的数据量小于我们的样本量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)
#转换成DataFrame时为了后面方便操作,索引方便
#均值
from sklearn.impute import SimpleImputer
imp_mean = SimpleImputer(missing_values=np.nan,strategy='mean')
x_missing_mean = imp_mean.fit_transform(x_missing)
#训练fit+导出predict >>> 特殊的接口fit_transform
pd.DataFrame(x_missing_mean).isnull().sum()#查看缺失值
#使用0进行填补
imp_0 = SimpleImputer(missing_values=np.nan,strategy="constant",fill_value=0)#censtant 常数
x_missing_0 = imp_0.fit_transform(x_missing)
pd.DataFrame(x_missing_0).isnull().sum()#查看缺失值
x_missing_reg = x_missing.copy()
sortindex = np.argsort(x_missing_reg.isnull().sum(axis=0)).values
#用argsort 排序可以返回索引位置
for i in sortindex:
#构建我们的新特征矩阵(没有被选中去填充的特征+原始的标签)和新标签(被选中去填充的特征)
df = x_missing_reg
fillc = df.iloc[:,i]
df = pd.concat([df[df != fillc],pd.DataFrame(y_full)])
#在新特征矩阵中,对含有缺失值的列,进行0的填补
df_0 = SimpleImputer(missing_values=np.nan
,strategy = "constant"
,fill_value = 0
).fit_transform(df)
#找出我们的训练集和测试集
y_train = fillc[fillc.notnull()]#是被选中要填充的值,存在的那些值,非空值
y_test = fillc[fillc.isnull()]#是被选中 的要填充给的值,不存在的那些值,是空值
x_train = df_0[y_train.index,:]#在新特征矩阵中,我们需要非空值所对应的的索引
x_test = df_0[y_test.index,:]#空值所对应的记录
#用随机森林回归来填补缺失值
rfc = RandomForestRegressor(n_estimators=100)#实例化
rfc = rfc.fit(x_train,y_train) #导入训练集去进行训练
Ypredict = rfc.predict(x_test)#用oredicr接口将x_TEST,就是我们要填补空值的这些值
#将填补号的特征返回到我们的原始的特征矩阵中
x_missing_reg.loc[x_missing_reg.iloc[:,i].isnull(),i] = Ypredict
from sklearn.model_selection import cross_val_score
x = [x_full,X_missing_mean,x_missing_0,x_missing_reg]
mse = []
std = []
for x in x:
estimator = RandomForestRegressor(random_state=0, n_estimators=100)#实例化
scores = cross_val_score(estimator,x,y_full,scoring='neg_mean_squared_error', cv=5).mean()
mse.append(scores * -1)
[*zip(['Full data','Zero Imputation','Mean Imputation','Regressor Imputation'],mse)]
将结果用图的形式展现出来
#画图
x_labels = ['Full data',
'Zero Imputation',
'Mean Imputation',
'Regressor Imputation']
colors = ['r', 'g', 'b', 'orange']
plt.figure(figsize=(12, 6))#画出画布
ax = plt.subplot(111)#添加子图
for i in np.arange(len(mse)):
ax.barh(i, mse[i],color=colors[i], alpha=0.6, align='center')#bar为条形图,barh为横向条形图,alpha表示条的粗度
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)))
ax.set_xlabel('MSE')
ax.set_yticklabels(x_labels)
plt.show()
由此可见随机森林最小,说明效果好,比源数据拟合程度逗号,但是最小不一定是最好的,容易过拟合。