【Educoder数据挖掘实训】插值填充法处理遗漏值

本文介绍了在数据挖掘中如何使用拉格朗日插值法填充缺失值,以及KNN(K近邻)方法在处理缺失值时的应用,特别是通过Python库如Pandas,Scipy和sklearn的KNNImputer函数实例演示。
摘要由CSDN通过智能技术生成

【Educoder数据挖掘实训】插值填充法处理遗漏值

开挖

这关的介绍非常详细,只要看懂了基本就没有问题。
所谓插值其实就是根据已有的数据构造出函数,然后用这个函数来计算遗漏的数据。
比如这个题目中介绍的拉格朗日插值以及 K K K近邻。
有关拉格朗日插值在这里做一点儿介绍:
一直函数 f ( x ) f(x) f(x) n + 1 n+1 n+1个插值节点 a ≤ x 0 < x 1 < . . . < x n ≤ b a\le x_0 < x_1 <... < x_n \le b ax0<x1<...<xnb上的函数值 f ( x 0 ) , f ( x 1 ) , . . . , f ( x n ) f(x_0), f(x_1),...,f(x_n) f(x0),f(x1),...,f(xn),求构造一个次数不超过 n n n的插值函数多项式 L n ( x ) L_n(x) Ln(x) L n ( x i ) = y i = f ( x i ) L_n(x_i) = y_i = f(x_i) Ln(xi)=yi=f(xi)
给出构造:
L n ( x ) = ∑ i = 0 n l i ( x ) y i L_n(x) = \sum\limits_{i = 0} ^nl_i(x)y_i Ln(x)=i=0nli(x)yi
其中 l i ( x ) l_i(x) li(x)被称为 n n n次插值基函数。
l i ( x j ) = [ x j = = x i ] l_i(x_j) = [x_j == x_i] li(xj)=[xj==xi]
l i ( x ) = ∏ j = 0 , j ≠ i n x − x j x i − x j l_i(x) = \prod\limits_{j = 0, j\neq i}^n \frac{x - x_j}{x_i - x_j} li(x)=j=0,j=inxixjxxj
易知这个构造方程是显然成立的而且次数不会超过 n n n次。
关于 K K K就是用函数 K N N I m p u t e r KNNImputer KNNImputer函数用欧几里得距离寻找最近邻,相当于最近邻算法的具体实现,不多赘述。
代码如下:

import pandas as pd
import numpy as np
from scipy.interpolate import lagrange
import sklearn
from sklearn.impute import KNNImputer

data = pd.read_csv("src/death.csv", index_col='Unnamed: 0')

data = data.dropna(axis=1, thresh=data.shape[0] * 0.2)
data = data.dropna(axis=0, thresh=data.shape[1] * 0.2)


cols = '2007/12/20'
########## Begin ##########
# 求出'2007/12/20'列的缺失行索引
na_index = data.index[data[cols].isna()]

# 将'2007/12/20'列的缺失行使用前后三个数进行拉格朗日法替换

s = data[cols]
for i in na_index :
    y = s[list(range(i - 3, i)) + list(range(i + 1, i + 1 + 3))]
    y = y[y.notnull()]
    data[cols][i] = lagrange(y.index, list(y))(i)
    print('2007/12/20 列的缺失值使用拉格朗日法替换为:', data[cols][i])

########## End ##########

na_index = pd.isna(data['FIPS'])
print('替换前:\n', data[['Lat', 'FIPS', 'Long_']][na_index])

########## Begin ##########
# 使用 'Lat', 'FIPS', 'Long_' 三列进行 K 近邻计算
# data[['Lat', 'FIPS', 'Long_']] = data[['Lat', 'FIPS', 'Long_']].fillna(method='bfill')
imputer = KNNImputer(n_neighbors = 1)
# data[['Lat', 'FIPS', 'Long_']] = imputer.fit_transform(data[['Lat', 'FIPS', 'Long_']])
data[['Lat','FIPS','Long_']] = pd.DataFrame(imputer.fit_transform(data[['Lat','FIPS','Long_']]),columns=[['Lat', 'FIPS', 'Long_']])
print('替换后:\n', data[['Lat', 'FIPS', 'Long_']][na_index])

########## End ##########

依然给出补充
这个题目中间有两行代码,分别是:

# data[['Lat', 'FIPS', 'Long_']] = imputer.fit_transform(data[['Lat', 'FIPS', 'Long_']])
data[['Lat','FIPS','Long_']] = pd.DataFrame(imputer.fit_transform(data[['Lat','FIPS','Long_']]),columns=[['Lat', 'FIPS', 'Long_']])

很疑惑这两行代码具体的区别是什么。
在大多数情况下是没区别的,但是第二种写法会更稳定,保证修改的行就是标记为 c o l u m n s columns columns的行。
两者的区别在于对填充后的数据是否进行了 D a t a F r a m e DataFrame DataFrame 包装,以及是否指定了列名。通常建议使用第一种方式,以确保填充后的数据与原始数据结构一致,并且避免潜在的错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值