在python中使用KNN算法处理缺失的数据

处理缺失的数据并不是一件容易的事 。方法的范围从简单的均值插补和观察值的完全删除到像MICE这样的更高级的技术 。解决问题的挑战性是选择使用哪种方法 。今天 , 我们将探索一种简单但高效的填补缺失数据的方法-KNN算法 。
在python中使用KNN算法处理缺失的数据文章插图
KNN代表" K最近邻居" , 这是一种简单算法 , 可根据定义的最接近邻居数进行预测 。它计算从您要分类的实例到训练集中其他所有实例的距离 。
正如标题所示 , 我们不会将算法用于分类目的 , 而是填充缺失值 。本文将使用房屋价格数据集 , 这是一个简单而著名的数据集 , 仅包含500多个条目 。
这篇文章的结构如下:
1. 数据集加载和探索
1. KNN归因
1. 归因优化
1. 结论
数据集加载和探索如前所述 , 首先下载房屋数据集 。另外 , 请确保同时导入了Numpy和Pandas 。这是前几行的外观:
在python中使用KNN算法处理缺失的数据文章插图
默认情况下 , 数据集缺失值非常低-单个属性中只有五个:
在python中使用KNN算法处理缺失的数据文章插图
让我们改变一下 。您通常不会这样做 , 但是我们需要更多缺少的值 。首先 , 我们创建两个随机数数组 , 其范围从1到数据集的长度 。第一个数组包含35个元素 , 第二个数组包含20个(任意选择):
i1 = np.random.choice(a=df.index, size=35) i2 = np.random.choice(a=df.index, size=20)这是第一个数组的样子:
在python中使用KNN算法处理缺失的数据文章插图
您的数组将有所不同 , 因为随机化过程是随机的 。接下来 , 我们将用NAN替换特定索引处的现有值 。这是如何做:
df.loc[i1, 'INDUS'] = np.nan df.loc[i2, 'TAX'] = np.nan现在 , 让我们再次检查缺失值-这次 , 计数有所不同:
在python中使用KNN算法处理缺失的数据文章插图
这就是我们从归因开始的全部前置工作 。让我们在下一部分中进行操作 。
KNN归因整个插补可归结为4行代码-其中之一是库导入 。我们需要sklearn.impute中的KNNImputer , 然后以一种著名的Scikit-Learn方式创建它的实例 。该类需要一个强制性参数– n_neighbors 。它告诉冒充参数K的大小是多少 。
首先 , 让我们选择3的任意数字 。 稍后我们将优化此参数 , 但是3足以启动 。接下来 , 我们可以在计算机上调用fit_transform方法以估算缺失的数据 。
最后 , 我们将结果数组转换为pandas.DataFrame对象 , 以便于解释 。这是代码:
from sklearn.impute import KNNImputerimputer = KNNImputer(n_neighbors=3)imputed = imputer.fit_transform(df)df_imputed = pd.DataFrame(imputed, columns=df.columns)非常简单 。让我们现在检查缺失值:
在python中使用KNN算法处理缺失的数据文章插图
尽管如此 , 仍然存在一个问题-我们如何为K选择正确的值?
归因优化该住房数据集旨在通过回归算法进行预测建模 , 因为目标变量是连续的(MEDV) 。这意味着我们可以训练许多预测模型 , 其中使用不同的K值估算缺失值 , 并查看哪个模型表现最佳 。
但首先是导入 。我们需要Scikit-Learn提供的一些功能-将数据集分为训练和测试子集 , 训练模型并进行验证 。我们选择了"随机森林"算法进行训练 。RMSE用于验证:
from sklearn.model_selection import train_test_splitfrom sklearn.ensemble import RandomForestRegressorfrom sklearn.metrics import mean_squared_errorrmse = lambda y, yhat: np.sqrt(mean_squared_error(y, yhat))以下是执行优化的必要步骤:
【在python中使用KNN算法处理缺失的数据】迭代K的可能范围-1到20之间的所有奇数都可以
1. 使用当前的K值执行插补
1. 将数据集分为训练和测试子集
1. 拟合随机森林模型
1. 预测测试集
1. 使用RMSE进行评估
听起来很多 , 但可以归结为大约15行代码 。这是代码段:
def optimize_k(data, target):errors = []for k in range(1, 20, 2):imputer = KNNImputer(n_neighbors=k)imputed = imputer.fit_transform(data)df_imputed = pd.DataFrame(imputed, columns=df.columns)X = df_imputed.drop(target, axis=1)y = df_imputed[target]X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)model = RandomForestRegressor()model.fit(X_train, y_train)preds = model.predict(X_test)error = rmse(y_test, preds)errors.append({'K': k, 'RMSE': error})return errors