Python利用随机森林对数据的缺失值进行填充的教程(实例附完整代码)
前言:随机森林填补缺失值的优点:(1)随机森林填补通过构造多棵决策树对缺失值进行填补,使填补的数据具有随机性和不确定性,更能反映出这些未知数据的真实分布;(2)由于在构造决策树过程中,每个分支节点选用随机的部分特征而不是全部特征,所以能很好的应用到高维数据的填补;(3)随机森林算法本身就具有很好的分类精度,从而也更进一步确保了得到的填补值的准确性和可靠性。废话不多说,直接上python代码:首先导
·
前言:
随机森林填补缺失值的优点:
(1)随机森林填补通过构造多棵决策树对缺失值进行填补,使填补的数据具有随机性和不确定性,更能反映出这些未知数据的真实分布;
(2)由于在构造决策树过程中,每个分支节点选用随机的部分特征而不是全部特征,所以能很好的应用到高维数据的填补;
(3)随机森林算法本身就具有很好的分类精度,从而也更进一步确保了得到的填补值的准确性和可靠性。
废话不多说,直接上python代码:
首先导入需要的包:
# 准备需要的包
import numpy as np
import pandas as pd
from sklearn.impute import SimpleImputer
from sklearn.ensemble import RandomForestRegressor
导入原始数据:
data = pd.read_excel(r"C:\Users\xw\Desktop\预测数据.xlsx")# 导入原始数据
target = data['车辆 id']
# 这里的‘车辆 id’是指没有数据缺失的那一列的名称,选取一列即可
# 如果每一列的数据都缺失了,可以再创建一列都是1的完整数据并填写名称
features = data.iloc[:,1:-1]
#注意这里没有我没有取最后一列,可根据自己的情况改动
进行随机森林预测(这段代码可不用改动):
X_full, y_full = features,target
n_samples = X_full.shape[0] # 样本
n_features = X_full.shape[1] # 特征
print(n_samples)
print(n_features)
#首先确定我们希望放入的缺失值数据的比例,在这里我假设是50%,可以自己改动
rng = np.random.RandomState(0)
missing_rate = 0.5
n_missing_samples = int(np.floor(n_samples * n_features *missing_rate))
#np.floor 向下取整
#所有数据要随机遍布在数据集的各行各列当中,而一个确实的数据会需要一盒行索引和一个列索引
#如果能够创造一个数组,就可以利用索引来赋空值
X_missing_reg = X_full.copy()
# 查看缺失情况
missing = X_missing_reg .isna().sum()
missing = pd.DataFrame(data={'特征': missing.index,'缺失值个数':missing.values})
#通过~取反,选取不包含数字0的行
missing = missing[~missing['缺失值个数'].isin([0])]
# 缺失比例
missing['缺失比例'] = missing['缺失值个数']/X_missing_reg .shape[0]
X_df = X_missing_reg.isnull().sum()
# 得出列名 缺失值最少的列名 到 缺失值最多的列名
colname = X_df[~X_df.isin([0])].sort_values().index.values
# 缺失值从小到大的特征顺序
sortindex = []
for i in colname:
sortindex.append(X_missing_reg.columns.tolist().index(str(i)))
# 遍历所有的特征,从缺失最少的开始进行填补,每完成一次回归预测,就将预测值放到原本的特征矩阵中,再继续填补下一个特征
for i in sortindex:
# 构建我们的新特征矩阵和新标签
df = X_missing_reg # 充当中间数据集
fillc = df.iloc[:, i] # 缺失值最少的特征列
# 除了第 i 特征列,剩下的特征列+原有的完整标签 = 新的特征矩阵
df = pd.concat([df.drop(df.columns[i], axis=1), pd.DataFrame(y_full)], axis=1)
# 在新特征矩阵中,对含有缺失值的列,进行0的填补 ,没循环一次,用0填充的列越来越少
df_0 = SimpleImputer(missing_values=np.nan, strategy='constant', fill_value=0).fit_transform(df)
# 找出训练集和测试集
# 标签
Ytrain = fillc[fillc.notnull()] # 没有缺失的部分,就是 Y_train
Ytest = fillc[fillc.isnull()] # 不是需要Ytest的值,而是Ytest的索引
# 特征矩阵
Xtrain = df_0[Ytrain.index, :]
Xtest = df_0[Ytest.index, :] # 有缺失值的特征情况
rfc = RandomForestRegressor(n_estimators=100) # 实例化
rfc = rfc.fit(Xtrain, Ytrain) # 训练
Ypredict = rfc.predict(Xtest) # 预测结果,就是要填补缺失值的值
# 将填补好的特征返回到我们的原始的特征矩阵中
X_missing_reg.loc[X_missing_reg.iloc[:, i].isnull(), X_missing_reg.columns[i]] = Ypredict
# 最后,再次查看缺失值是否全部被替换
missing2 = X_missing_reg.isna().sum()
missing2 = pd.DataFrame(data={'列名': missing2.index, '缺失值个数': missing2.values})
# 通过~取反,选取不包含数字0的行
missing3=missing2[~missing2['缺失值个数'].isin([0])]
print(missing2)
print(missing3)
最后导出完整的数据:
#导出完整的数据
X_missing_reg.to_excel(r"C:\Users\xw\Desktop\完整数据.xlsx")
到这里就完成了!
附上完整代码:
# 准备需要的包
import numpy as np
import pandas as pd
from sklearn.impute import SimpleImputer
from sklearn.ensemble import RandomForestRegressor
data = pd.read_excel(r"C:\Users\xw\Desktop\预测数据.xlsx")# 导入原始数据
target = data['车辆 id']
# 这里的‘车辆 id’是指没有数据缺失的那一列的名称
# 如果每一列的数据都缺失了,可以再创建一列都是1的完整数据并填写名称
features = data.iloc[:,1:-1]
#注意这里没有我没有取最后一列,可根据自己的情况改动
X_full, y_full = features,target
n_samples = X_full.shape[0] # 样本
n_features = X_full.shape[1] # 特征
print(n_samples)
print(n_features)
#首先确定我们希望放入的缺失值数据的比例,在这里我假设是50%,可以自己改动
rng = np.random.RandomState(0)
missing_rate = 0.5
n_missing_samples = int(np.floor(n_samples * n_features *missing_rate))
#np.floor 向下取整
#所有数据要随机遍布在数据集的各行各列当中,而一个确实的数据会需要一盒行索引和一个列索引
#如果能够创造一个数组,就可以利用索引来赋空值
X_missing_reg = X_full.copy()
# 查看缺失情况
missing = X_missing_reg .isna().sum()
missing = pd.DataFrame(data={'特征': missing.index,'缺失值个数':missing.values})
#通过~取反,选取不包含数字0的行
missing = missing[~missing['缺失值个数'].isin([0])]
# 缺失比例
missing['缺失比例'] = missing['缺失值个数']/X_missing_reg .shape[0]
X_df = X_missing_reg.isnull().sum()
# 得出列名 缺失值最少的列名 到 缺失值最多的列名
colname = X_df[~X_df.isin([0])].sort_values().index.values
# 缺失值从小到大的特征顺序
sortindex = []
for i in colname:
sortindex.append(X_missing_reg.columns.tolist().index(str(i)))
# 遍历所有的特征,从缺失最少的开始进行填补,每完成一次回归预测,就将预测值放到原本的特征矩阵中,再继续填补下一个特征
for i in sortindex:
# 构建我们的新特征矩阵和新标签
df = X_missing_reg # 充当中间数据集
fillc = df.iloc[:, i] # 缺失值最少的特征列
# 除了第 i 特征列,剩下的特征列+原有的完整标签 = 新的特征矩阵
df = pd.concat([df.drop(df.columns[i], axis=1), pd.DataFrame(y_full)], axis=1)
# 在新特征矩阵中,对含有缺失值的列,进行0的填补 ,没循环一次,用0填充的列越来越少
df_0 = SimpleImputer(missing_values=np.nan, strategy='constant', fill_value=0).fit_transform(df)
# 找出训练集和测试集
# 标签
Ytrain = fillc[fillc.notnull()] # 没有缺失的部分,就是 Y_train
Ytest = fillc[fillc.isnull()] # 不是需要Ytest的值,而是Ytest的索引
# 特征矩阵
Xtrain = df_0[Ytrain.index, :]
Xtest = df_0[Ytest.index, :] # 有缺失值的特征情况
rfc = RandomForestRegressor(n_estimators=100) # 实例化
rfc = rfc.fit(Xtrain, Ytrain) # 训练
Ypredict = rfc.predict(Xtest) # 预测结果,就是要填补缺失值的值
# 将填补好的特征返回到我们的原始的特征矩阵中
X_missing_reg.loc[X_missing_reg.iloc[:, i].isnull(), X_missing_reg.columns[i]] = Ypredict
# 最后,再次查看缺失值是否全部被替换
missing2 = X_missing_reg.isna().sum()
missing2 = pd.DataFrame(data={'列名': missing2.index, '缺失值个数': missing2.values})
# 通过~取反,选取不包含数字0的行
missing3=missing2[~missing2['缺失值个数'].isin([0])]
print(missing2)
print(missing3)
#导出完整的数据
X_missing_reg.to_excel(r"C:\Users\xw\Desktop\完整数据.xlsx")
欢迎大家在评论区指正错误,我们共同进步!!
更多推荐
已为社区贡献2条内容
所有评论(0)