python 如何通過KNN來填充缺失值
# 加載庫import numpy as npfrom fancyimpute import KNNfrom sklearn.preprocessing import StandardScalerfrom sklearn.datasets import make_blobs# 創(chuàng)建模擬特征矩陣features, _ = make_blobs(n_samples = 1000, n_features = 2, random_state = 1)# 標(biāo)準(zhǔn)化特征scaler = StandardScaler()standardized_features = scaler.fit_transform(features)standardized_features# 制造缺失值true_value = standardized_features[0,0]standardized_features[0,0] = np.nanstandardized_features# 預(yù)測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# #對比真實(shí)值和預(yù)測值print('真實(shí)值:', true_value)print('預(yù)測值:', features_knn_imputed[0,0])# 加載庫import numpy as npfrom fancyimpute import KNNfrom sklearn.preprocessing import StandardScalerfrom sklearn.datasets import make_blobs# 創(chuàng)建模擬特征矩陣features, _ = make_blobs(n_samples = 1000, n_features = 2, random_state = 1)# 標(biāo)準(zhǔn)化特征scaler = StandardScaler()standardized_features = scaler.fit_transform(features)standardized_features# 制造缺失值true_value = standardized_features[0,0]standardized_features[0,0] = np.nanstandardized_features# 預(yù)測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# #對比真實(shí)值和預(yù)測值print('真實(shí)值:', true_value)print('預(yù)測值:', features_knn_imputed[0,0])真實(shí)值: 0.8730186113995938預(yù)測值: 1.0955332713113226
補(bǔ)充:scikit-learn中一種便捷可靠的缺失值填充方法:KNNImputer
在數(shù)據(jù)挖掘工作中,處理樣本中的缺失值是必不可少的一步。其中對于缺失值插補(bǔ)方法的選擇至關(guān)重要,因?yàn)樗鼤ψ詈竽P蛿M合的效果產(chǎn)生重要影響。
在2019年底,scikit-learn發(fā)布了0.22版本,此次版本除了修復(fù)之前的一些bug外,還更新了很多新功能,對于數(shù)據(jù)挖掘人員來說更加好用了。其中我發(fā)現(xiàn)了一個新增的非常好用的缺失值插補(bǔ)方法:KNNImputer。這個基于KNN算法的新方法使得我們現(xiàn)在可以更便捷地處理缺失值,并且與直接用均值、中位數(shù)相比更為可靠。利用“近朱者赤”的KNN算法原理,這種插補(bǔ)方法借助其他特征的分布來對目標(biāo)特征進(jìn)行缺失值填充。
下面,就讓我們用實(shí)際例子來看看KNNImputer是如何使用的吧使用KNNImputer需要從scikit-learn中導(dǎo)入:
from sklearn.impute import KNNImputer
先來一個小例子開開胃,data中第二個樣本存在缺失值。
data = [[2, 4, 8], [3, np.nan, 7], [5, 8, 3], [4, 3, 8]]
KNNImputer中的超參數(shù)與KNN算法一樣,n_neighbors為選擇“鄰居”樣本的個數(shù),先試試n_neighbors=1。
imputer = KNNImputer(n_neighbors=1)imputer.fit_transform(data)
可以看到,因?yàn)榈诙€樣本的第一列特征3和第三列特征7,與第一行樣本的第一列特征2和第三列特征8的歐氏距離最近,所以缺失值按照第一個樣本來填充,填充值為4。那么n_neighbors=2呢?
imputer = KNNImputer(n_neighbors=2)imputer.fit_transform(data)
此時根據(jù)歐氏距離算出最近相鄰的是第一行樣本與第四行樣本,此時的填充值就是這兩個樣本第二列特征4和3的均值:3.5。
接下來讓我們看一個實(shí)際案例,該數(shù)據(jù)集來自Kaggle皮馬人糖尿病預(yù)測的分類賽題,其中有不少缺失值,我們試試用KNNImputer進(jìn)行插補(bǔ)。
import numpy as npimport pandas as pdimport pandas_profiling as ppimport matplotlib.pyplot as pltimport seaborn as snssns.set(context='notebook', style='darkgrid')import warningswarnings.filterwarnings(’ignore’)%matplotlib inline from sklearn.impute import KNNImputer
#Loading the datasetdiabetes_data = pd.read_csv(’pima-indians-diabetes.csv’)diabetes_data.columns = [’Pregnancies’, ’Glucose’, ’BloodPressure’, ’SkinThickness’,’Insulin’, ’BMI’, ’DiabetesPedigreeFunction’, ’Age’, ’Outcome’]diabetes_data.head()
在這個數(shù)據(jù)集中,0值代表的就是缺失值,所以我們需要先將0轉(zhuǎn)化為nan值然后進(jìn)行缺失值處理。
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個缺失值進(jìn)行KNNImputer插補(bǔ)。
先來看一下缺失值都在哪幾個樣本:
null_index = diabetes_data_copy.loc[diabetes_data_copy[’BloodPressure’].isnull(), :].indexnull_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())
可以看到現(xiàn)在BloodPressure中的35個缺失值消失了。我們看看具體填充后的數(shù)據(jù)(只截圖了部分):
diabetes_data_copy.iloc[null_index]
到此,BloodPressure中的缺失值已經(jīng)根據(jù)DiabetesPedigreeFunction與Age運(yùn)用KNNImputer填充完成了。注意的是,對于非數(shù)值型特征需要先轉(zhuǎn)換為數(shù)值型特征再進(jìn)行KNNImputer填充操作,因?yàn)槟壳癒NNImputer方法只支持?jǐn)?shù)值型特征(ʘ̆ωʘ̥̆‖)՞。
相關(guān)文章:
1. 概述IE和SQL2k開發(fā)一個XML聊天程序2. 利用CSS3新特性創(chuàng)建透明邊框三角3. 存儲于xml中需要的HTML轉(zhuǎn)義代碼4. XML入門精解之結(jié)構(gòu)與語法5. CSS3實(shí)例分享之多重背景的實(shí)現(xiàn)(Multiple backgrounds)6. HTML DOM setInterval和clearInterval方法案例詳解7. CSS Hack大全-教你如何區(qū)分出IE6-IE10、FireFox、Chrome、Opera8. XML解析錯誤:未組織好 的解決辦法9. XML入門的常見問題(一)10. XML入門的常見問題(二)
