迭代插补与回归分析

在数据分析和机器学习中,处理缺失值是一个常见的问题。迭代插补是一种有效的处理方法,它通过模拟不同变量之间的复杂关系来估计缺失值。本文将探讨如何使用迭代插补与多种回归分析器结合,以提高模型的准确性。

在本例中,比较了几种不同的估计器,用于缺失特征的插补,包括贝叶斯岭回归、随机森林回归、最近邻回归等。特别关注的是迭代插补器模仿missForest的能力,missForest是一个流行的R语言插补包。需要注意的是,最近邻回归与KNN插补不同,后者通过使用考虑缺失值的距离度量从有缺失值的样本中学习,而不是插补它们。

目标是比较不同的估计器,看看哪一个最适合迭代插补器。在加利福尼亚房屋数据集上使用贝叶斯岭估计器时,发现贝叶斯岭回归和随机森林回归给出了最好的结果。值得注意的是,一些估计器如直方梯度提升回归估计器可以原生处理缺失特征,通常推荐使用,而不是构建复杂的缺失值插补策略的管道。

数据处理与分析

为了进行比较,首先导入必要的库,包括matplotlib、numpy、pandas和scikit-learn中的相关模块。然后,从scikit-learn的datasets模块中获取加利福尼亚房屋数据集,并对其进行处理,以模拟每行数据中随机移除一个值的情况。

import matplotlib.pyplot as plt import numpy as np import pandas as pd from sklearn.datasets import fetch_california_housing from sklearn.ensemble import RandomForestRegressor from sklearn.experimental import enable_iterative_imputer from sklearn.impute import IterativeImputer, SimpleImputer from sklearn.kernel_approximation import Nystroem from sklearn.linear_model import BayesianRidge, Ridge from sklearn.model_selection import cross_val_score from sklearn.neighbors import KNeighborsRegressor from sklearn.pipeline import make_pipeline N_SPLITS = 5 rng = np.random.RandomState(0) X_full, y_full = fetch_california_housing(return_X_y=True) X_full = X_full[:::10] y_full = y_full[:::10] n_samples, n_features = X_full.shape

接下来,使用贝叶斯岭回归估计器对完整数据集进行评分,然后向每行数据中添加一个缺失值,并使用不同的插补策略进行评分。最后,使用迭代插补器与不同的估计器结合,对缺失值进行插补,并评分。

# 估计完整数据集的分数,没有缺失值 br_estimator = BayesianRidge() score_full_data = pd.DataFrame(cross_val_score(br_estimator, X_full, y_full, scoring="neg_mean_squared_error", cv=N_SPLITS), columns=["Full Data"]) # 向每行添加一个缺失值 X_missing = X_full.copy() y_missing = y_full missing_samples = np.arange(n_samples) missing_features = rng.choice(n_features, n_samples, replace=True) X_missing[missing_samples, missing_features] = np.nan # 使用不同的插补策略估计分数 score_simple_imputer = pd.DataFrame() for strategy in ("mean", "median"): estimator = make_pipeline(SimpleImputer(missing_values=np.nan, strategy=strategy), br_estimator) score_simple_imputer[strategy] = cross_val_score(estimator, X_missing, y_missing, scoring="neg_mean_squared_error", cv=N_SPLITS) # 使用迭代插补器与不同的估计器结合估计分数 estimators = [ BayesianRidge(), RandomForestRegressor(n_estimators=4, max_depth=10, bootstrap=True, max_samples=0.5, n_jobs=2, random_state=0), make_pipeline(Nystroem(kernel="polynomial", degree=2, random_state=0), Ridge(alpha=1e3)), KNeighborsRegressor(n_neighbors=15), ] score_iterative_imputer = pd.DataFrame() tolerances = (1e-3, 1e-1, 1e-1, 1e-2) for impute_estimator, tol in zip(estimators, tolerances): estimator = make_pipeline(IterativeImputer(random_state=0, estimator=impute_estimator, max_iter=25, tol=tol), br_estimator) score_iterative_imputer[impute_estimator.__class__.__name__] = cross_val_score(estimator, X_missing, y_missing, scoring="neg_mean_squared_error", cv=N_SPLITS) scores = pd.concat([score_full_data, score_simple_imputer, score_iterative_imputer], keys=["Original", "SimpleImputer", "IterativeImputer"], axis=1)

最后,使用matplotlib绘制加利福尼亚房屋回归结果,比较不同的插补方法。图表显示了不同方法的平均均方误差(MSE),较小的MSE表示更好的性能。

fig, ax = plt.subplots(figsize=(13, 6)) means = -scores.mean() errors = scores.std() means.plot.barh(xerr=errors, ax=ax) ax.set_title("California Housing Regression with Different Imputation Methods") ax.set_xlabel("MSE (smaller is better)") ax.set_yticks(np.arange(means.shape[0])) ax.set_yticklabels([" w/ ".join(label) for label in means.index.tolist()]) plt.tight_layout(pad=1) plt.show()
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485