流程包括:导入库——读取数据——构造缺失数据——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 from sklearn.model_selection import cross_val_score
dt = load_boston() print(dt.data.shape)
x, y = dt.data,dt.target n_samples = x.shape[0] # 样本数 n_features = x.shape[1] # 特征数
# 构造缺失数据 rng = np.random.RandomState(0) missing_rate = 0.5 # 假设缺失50% n_missing_data = int(np.floor(n_samples*n_features*missing_rate)) # 缺失数据个数 #所有数据要随机遍布在数据集的各行各列当中,而一个缺失的数据会需要一个行索引和一个列索引 #如果能够创造一个数组,包含3289个分布在0~506中间的行索引,和3289个分布在0~13之间的列索引,那我们就可以利用索引来为数据中的任意3289个位置赋空值 #然后我们用0,均值和随机森林来填写这些缺失值,然后查看回归的结果如何 missing_features = rng.randint(0, n_features,n_missing_data) missing_samples = rng.randint(0, n_samples,n_missing_data)
print(len(missing_features))
构造初始缺失数据
x_miss = x.copy() y_miss = y.copy() x_miss[missing_samples,missing_features] = np.nan x_miss
x_miss = pd.DataFrame(x_miss) # 0填补缺失值 imp0 = SimpleImputer(missing_values=np.nan, strategy='constant',fill_value=0) x_miss0 = imp0.fit_transform(x_miss) x_miss0
# 均值填补缺失值 impmean = SimpleImputer(missing_values=np.nan, strategy='mean') x_miss_mean = impmean.fit_transform(x_miss) x_miss_mean
# 随机森林填补缺失值 x_miss_reg = x_miss.copy() # 按特征对缺失数据进行一一构造,要填充的特征视为标签,标签视为特征数据 sortindex = np.argsort(x_miss_reg.isnull().sum(axis=0)).values # 从缺失最少的一类特征开始填充,因为缺失最少的特征在填充时需要的信息最少 for i in sortindex: # 构建新特征矩阵和新标签 df = x_miss_reg fillc = df.iloc[:,i] # 新标签 df = pd.concat([df.iloc[:,df.columns!=i],pd.DataFrame(y)],axis=1) # 在新的特征矩阵中,0填补缺失值 df0 = SimpleImputer(missing_values=np.nan, strategy='constant',fill_value=0).fit_transform(df) # 分出训练集和测试集 ytrain = fillc[fillc.notnull()] ytest = fillc[fillc.isnull()] xtrain = df0[ytrain.index,:] xtest = df0[ytest.index,:] # 随机森林回归 rfc = RandomForestRegressor(n_estimators=100) rfc = rfc.fit(xtrain,ytrain) ypre = rfc.predict(xtest) # 将填补好的特征返回原始矩阵中 x_miss_reg.loc[x_miss_reg.iloc[:,i].isnull(),i] = ypre
对比不同缺失值填充的效果
# 对所有数据建模,得到mse x_all = [x,x_miss_mean,x_miss0,x_miss_reg] mse = [] std = [] for xx in x_all: estimator = RandomForestRegressor(n_estimators=100,random_state=0) scores = cross_val_score(estimator,xx,y,scoring='neg_mean_squared_error',cv=5).mean() mse.append(scores*-1) # 作图 x_labels = ['full data' ,'zero imp' ,'mean imp' ,'reg imp'] 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') 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()
在所使用的数据集缺失50%的情况下,0填充和均值填充的效果远不及回归填充,随机森林回归填充甚至比原数据集表现更好。
标签:填充,填补,missing,随机,np,mse,miss,缺失 From: https://www.cnblogs.com/shi-yi/p/17066543.html