day 4 随机森林 回归填补缺失值

from pprint import pprint

from sklearn.ensemble import RandomForestRegressor  # 随机森林回归器
from sklearn.impute import SimpleImputer  # 用来填补缺失值的
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_boston

pd.set_option('display.max_columns', None)
# 以波士顿数据集为例,导入完整的数据集并探索
dataset = load_boston()
# print(dataset.data.shape)  # (506, 13)
x_full, y_full = dataset.data, dataset.target

# todo: 首先把完美的数据改成含缺失值的
n_sample = x_full.shape[0]  # 获取样本数量  行  506
n_feature = x_full.shape[1]  # 获取标签数量  列 13
# 我们希望的缺失数据的比例,假设为50%,共有506*13*0.5个数据缺失
rng = np.random.RandomState(0)  # 确认一个随机数种子
missing_rate = 0.5
# np.floor 向下取整 返回.0的浮点数
n_missing_samples = int(np.floor(n_sample * n_feature * missing_rate))  # 数据总量/2个
# print(n_missing_samples)
missing_features = rng.randint(0, n_feature, n_missing_samples)  # 取出 0到nfeature范围内的n_missing_samples个随机数
missing_samples = rng.randint(0, n_sample, n_missing_samples)
# 也可以抽样来完成
# missing_samples = rng.choice(dataset.data.shape[0], n_missing_samples, replace=False)
# 复制一份完整的数据集,原数据不动
X_missing = x_full.copy()
Y_missing = y_full.copy()
#  让它遍布空值
X_missing[missing_samples, missing_features] = np.nan
X_missing = pd.DataFrame(X_missing)

# todo: 使用均值进行补缺
imp_mean = SimpleImputer(missing_values=np.nan, strategy="mean")  # 要补啥,用啥补
# 训练加导出 fit+predict -----》特殊的接口 fit_transform
X_missing_mean = imp_mean.fit_transform(X_missing)
# print(pd.DataFrame(X_missing_mean).isnull().sum())
# todo: 使用0进行补缺
imp_mean0 = SimpleImputer(missing_values=np.nan, strategy="constant", fill_value=0)  # 要补啥,用啥补
# 训练加导出 fit+predict -----》特殊的接口 fit_transform
X_missing_0 = imp_mean0.fit_transform(X_missing)
# print(pd.DataFrame(X_missing_mean))

# todo:                             以上填补实际都不是很合适
# todo:使用随机森林回归填补缺失值
# 把特征不缺失的特征+原本的标签作为新的标签
# 遍历所有的特征,从缺失值最少的开始填补(因为所需要的准确信息最少)
X_missing_reg = X_missing.copy()
# print(X_missing_reg)
# print(X_missing_reg.isnull())
# print(X_missing_reg.isnull().sum(axis=0)) # 获取按行看每列 共有多少缺失值
# 从小到大排序
# np.sort(X_missing_reg.isnull().sum(axis=0))
# todo 从小到大排序(获取对应特征索引)
sortindex = np.argsort(X_missing_reg.isnull().sum(axis=0)).values
# print(sortindex)  ###[ 6 12  8  7  9  0  2  1  5  4  3 10 11]  ## 第几行特征缺失最少,排序

# todo 构建新特征矩阵和新标签---->逐个把排序好的特征作为标签来用,其他的用作构建成新的特征矩阵

# 新标签
for i in sortindex:
    # 原特征之一,目前是 新标签
    df = X_missing_reg
    fillc = df.iloc[:, i]
    # 新特征矩阵
    # print([*df.columns])                                   ###可以查看所有的列索引
    # print(df.iloc[:, df.columns != 6])
    # 连接俩个矩阵得到新特征矩阵
    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)
    # print(pd.DataFrame(df_0))
    # 找出我们的训练集和测试集
    # 是被选中要填充的特征中(现在是我们的标签),存在的那些值,非nan值
    # print(fillc.isnull())
    Y_train = fillc[fillc.notnull()]
    # 是被选中要填充的特征中(现在是我们的标签),不存在的那些值,为nan的空值
    # 我们需要的不是Ytest,而是ytest所带的索引
    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)  # 用predict接口将x_test导入 ,得到我们的预测结果(回归结果),就是我们要用来填补空缺的这些值
    # print(len(Ypredict))

    # 将填补好的特征返回我们的原始的特征矩阵中
    X_missing_reg.loc[X_missing_reg.iloc[:, i].isnull(), i] = Ypredict
# print(X_missing_reg)

# 目前已经有了四组数据 : 原数据,0填充的数据,均值填充的数据,回归填充的数据
# 对填充好的数据进行建模
X = [x_full, X_missing_mean, X_missing_0, X_missing_reg]
mse = []
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)
# print(mse) # mse越小越好
pprint([*zip(["x_full", "X_missing_mean", "X_missing_0", "X_missing_reg"], mse)])
# [('x_full', 21.62860460743544),
#  ('X_missing_mean', 40.84405476955929),
#  ('X_missing_0', 49.50657028893417),
#  ('X_missing_reg', 20.907999984896122)]    #########比原始数据打分都高
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用Python语言和Scikit-Learn库对Capital Bikeshare数据集进行随机森林需求预测的代码示例: ```python # 导入所需的库 import pandas as pd import numpy as np from sklearn.ensemble import RandomForestRegressor from sklearn.model_selection import train_test_split, GridSearchCV # 加载数据集 bikeshare_data = pd.read_csv('bikeshare.csv') # 数据预处理 # 转换日期和时间 bikeshare_data['datetime'] = pd.to_datetime(bikeshare_data['datetime']) bikeshare_data['year'] = bikeshare_data['datetime'].dt.year bikeshare_data['month'] = bikeshare_data['datetime'].dt.month bikeshare_data['day'] = bikeshare_data['datetime'].dt.day bikeshare_data['hour'] = bikeshare_data['datetime'].dt.hour # 删除不需要的特征 bikeshare_data = bikeshare_data.drop(['datetime', 'casual', 'registered'], axis=1) # 划分数据集 X = bikeshare_data.drop('count', axis=1) y = bikeshare_data['count'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 定义随机森林模型 rf_model = RandomForestRegressor(random_state=42) # 定义需要调整的参数范围 param_grid = {'n_estimators': [10, 50, 100], 'max_features': ['sqrt', 'log2', None], 'max_depth': [None, 10, 20]} # 定义网格搜索对象 grid_search = GridSearchCV(rf_model, param_grid, cv=5) # 训练模型 grid_search.fit(X_train, y_train) # 输出最佳参数 print(grid_search.best_params_) # 预测测试集 y_pred = grid_search.predict(X_test) # 输出模型评估指标 print('R-squared score:', grid_search.score(X_test, y_test)) print('Mean absolute error:', np.mean(abs(y_pred - y_test))) ``` 在这个代码中,我们首先加载了Capital Bikeshare数据集,并进行了一些数据预处理,如将日期和时间转换为可供模型使用的形式,并删除了不需要的特征。然后,我们将数据集分为训练集和测试集,并定义了一个随机森林模型。 接下来,我们使用网格搜索方法来选择最佳的模型参数。在这个例子中,我们调整了随机森林中的n_estimators(决策树数量)、max_features(每个决策树使用的最大特征数)和max_depth(决策树的最大深度)三个参数。 最后,我们使用训练好的模型对测试集进行预测,并输出了模型评估指标,如R-squared分数和平均绝对误差。这些指标可以帮助我们了解模型的预测能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值