当前位置:
首页
文章
后端
详情

python怎么通过KNN来填充缺失值

KNN算法,又叫K近邻分类算法,是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是K个最近的邻居的意思,说的是每个样本都可以用它最接近的K个邻近值来代表。近邻算法就是将数据集合中每一个记录进行分类的方法。我们在样本数据有缺失需要填充的时候,可以使用K近邻算法来训练一个模型,然后让其预估缺失值,这就是python通过knn来填充缺失值的方法,那么具体怎么操作呢?请接着往下看:

看代码吧~

# 加载库
import numpy as np
from fancyimpute import KNN
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_blobs
# 创建模拟特征矩阵
features, _ = make_blobs(n_samples = 1000,
                         n_features = 2,
                         random_state = 1)
# 标准化特征
scaler = StandardScaler()
standardized_features = scaler.fit_transform(features)
standardized_features
# 制造缺失值
true_value = standardized_features[0,0]
standardized_features[0,0] = np.nan
standardized_features
# 预测
features_knn_imputed = KNN(k=5, verbose=0).fit_transform(standardized_features)
# features_knn_imputed = KNN(k=5, verbose=0).complete(standardized_features)
features_knn_imputed
# #对比真实值和预测值
print("真实值:", true_value)
print("预测值:", features_knn_imputed[0,0])
# 加载库
import numpy as np
from fancyimpute import KNN
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_blobs
​
# 创建模拟特征矩阵
features, _ = make_blobs(n_samples = 1000,
                         n_features = 2,
                         random_state = 1)​
# 标准化特征
scaler = StandardScaler()
standardized_features = scaler.fit_transform(features)
standardized_features
# 制造缺失值
true_value = standardized_features[0,0]
standardized_features[0,0] = np.nan
standardized_features
# 预测
features_knn_imputed = KNN(k=5, verbose=0).fit_transform(standardized_features)
# features_knn_imputed = KNN(k=5, verbose=0).complete(standardized_features)
features_knn_imputed
# #对比真实值和预测值
print("真实值:", true_value)
print("预测值:", features_knn_imputed[0,0])
真实值: 0.8730186113995938
预测值: 1.0955332713113226

补充:scikit-learn中一种便捷可靠的缺失值填充方法:KNNImputer

在数据挖掘工作中,处理样本中的缺失值是必不可少的一步。其中对于缺失值插补方法的选择至关重要,因为它会对最后模型拟合的效果产生重要影响。

在2019年底,scikit-learn发布了0.22版本,此次版本除了修复之前的一些bug外,还更新了很多新功能,对于数据挖掘人员来说更加好用了。其中我发现了一个新增的非常好用的缺失值插补方法:KNNImputer。这个基于KNN算法的新方法使得我们现在可以更便捷地处理缺失值,并且与直接用均值、中位数相比更为可靠。利用“近朱者赤”的KNN算法原理,这种插补方法借助其他特征的分布来对目标特征进行缺失值填充。

下面,就让我们用实际例子来看看KNNImputer是如何使用的吧‎

使用KNNImputer需要从scikit-learn中导入:

from sklearn.impute import KNNImputer

先来一个小例子开开胃,data中第二个样本存在缺失值。

data = [[2, 4, 8], [3, np.nan, 7], [5, 8, 3], [4, 3, 8]]

KNNImputer中的超参数与KNN算法一样,n_neighbors为选择“邻居”样本的个数,先试试n_neighbors=1。

imputer = KNNImputer(n_neighbors=1)
imputer.fit_transform(data)

样本矩阵

可以看到,因为第二个样本的第一列特征3和第三列特征7,与第一行样本的第一列特征2和第三列特征8的欧氏距离最近,所以缺失值按照第一个样本来填充,填充值为4。那么n_neighbors=2呢?

imputer = KNNImputer(n_neighbors=2)
imputer.fit_transform(data)

样本数据

此时根据欧氏距离算出最近相邻的是第一行样本与第四行样本,此时的填充值就是这两个样本第二列特征4和3的均值:3.5。

接下来让我们看一个实际案例,该数据集来自Kaggle皮马人糖尿病预测的分类赛题,其中有不少缺失值,我们试试用KNNImputer进行插补。

import numpy as np
import pandas as pd
import pandas_profiling as pp
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(context="notebook", style="darkgrid")
import warnings
warnings.filterwarnings('ignore')
%matplotlib inline
 
from sklearn.impute import KNNImputer
#Loading the dataset
diabetes_data = pd.read_csv('pima-indians-diabetes.csv')
diabetes_data.columns = ['Pregnancies', 'Glucose', 'BloodPressure', 'SkinThickness', 
                       'Insulin', 'BMI', 'DiabetesPedigreeFunction', 'Age', 'Outcome']
diabetes_data.head()

数据样本

在这个数据集中,0值代表的就是缺失值,所以我们需要先将0转化为nan值然后进行缺失值处理。

diabetes_data_copy = diabetes_data.copy(deep=True)
diabetes_data_copy[['Glucose','BloodPressure','SkinThickness','Insulin','BMI']] = diabetes_data_copy[['Glucose','BloodPressure','SkinThickness','Insulin','BMI']].replace(0, np.NaN)
 
print(diabetes_data_copy.isnull().sum())

运行结果

在本文中,我们尝试用DiabetesPedigreeFunction与Age,对BloodPressure中的35个缺失值进行KNNImputer插补。

先来看一下缺失值都在哪几个样本:

null_index = diabetes_data_copy.loc[diabetes_data_copy['BloodPressure'].isnull(), :].index
null_index

运行结果

imputer = KNNImputer(n_neighbors=10)
diabetes_data_copy[['BloodPressure', 'DiabetesPedigreeFunction', 'Age']] = imputer.fit_transform(diabetes_data_copy[['BloodPressure', 'DiabetesPedigreeFunction', 'Age']])
print(diabetes_data_copy.isnull().sum())

运行结果

可以看到现在BloodPressure中的35个缺失值消失了。我们看看具体填充后的数据(只截图了部分):

diabetes_data_copy.iloc[null_index]

运行结果

到此,BloodPressure中的缺失值已经根据DiabetesPedigreeFunction与Age运用KNNImputer填充完成了。注意的是,对于非数值型特征需要先转换为数值型特征再进行KNNImputer填充操作,因为目前KNNImputer方法只支持数值型特征(ʘ̆ωʘ̥̆‖)՞。

小结

以上就是python通过knn来填充缺失值的详细内容,更多python的机器学习和数据挖掘相关知识请关注W3Cschool!


免责申明:本站发布的内容(图片、视频和文字)以转载和分享为主,文章观点不代表本站立场,如涉及侵权请联系站长邮箱:xbc-online@qq.com进行反馈,一经查实,将立刻删除涉嫌侵权内容。

同类热门文章

深入了解C++中的new操作符:使用具体实例学习

C++中的new操作符是动态分配内存的主要手段之一。在程序运行时,我们可能需要动态地创建和销毁对象,而new就是为此提供了便利。但是,使用new也常常会引发一些问题,如内存泄漏、空指针等等。因此,本文将通过具体的示例,深入介绍C++中的new操作符,帮助读者更好地掌握其使用。


深入了解C++中的new操作符:使用具体实例学习

怎么用Java反射获取包下所有类? 详细代码实例操作

Java的反射机制就是在运行状态下,对于任何一个类,它能知道这个类的所有属性和方法;对于任何一个对象,都能调用这个对象的任意一个方法。本篇文章将通过具体的代码示例,展示如何通过Java反射来获取包下的所有类。


怎么用Java反射获取包下所有类? 详细代码实例操作

了解Java中的volati关键字的作用 以及具体使用方法

本篇文章将和大家分享一下Java当中的volatile关键字,下面将为各位小伙伴讲述volatile关键字的作用以及它的具体使用方法。


了解Java中的volati关键字的作用 以及具体使用方法

Java Map 所有的值转为String类型

可以使用 Java 8 中的 Map.replaceAll() 方法将所有的值转为 String 类型: 上面的代码会将 map 中所有的值都转为 String 类型。 HashMap 是 Java

Java Map 所有的值转为String类型

员工线上学习考试系统

有点播,直播,在线支付,三级分销等功能,可以对学员学习情况的监督监控,有源码,可二次开发。支持外网和局域网私有化部署,经过测试源码完整可用!1、视频点播:视频播放,图文资料,课件下载,章节试学,限时免

员工线上学习考试系统