【Python】缺失值处理和拉格朗日插值法(含源代码实现)

目录:缺失值处理和拉格朗日插值法

一、前言

对于含有缺失值的数据集,如果通过删除小部分记录达到既定的目标,那么删除含有缺失值的记录的方法是最有效的。然而,这种方法也有很多问题,删除缺失值的同时也会损失一定的信息,对于那些数据集较小的来说这是影响很大的。

所以可以对这些缺失值进行填充。

最简单的处理原则:

  1. 缺失值少于20%

连续变量使用均值或者中位数填补;

分类变量不需要填补,单算一类即可,或者用众数填补。

  1. 缺失值在20%-80%

填补方法同上;

另外每个有缺失值的变量生成一个指示哑变量,参与后续的建模。

  1. 缺失值大于80%

每个有缺失值的变量生成一个指示哑变量,参与后续的建模,原始变量不使用。

也可以用最近邻插补法,可以在数据集中寻找与该样本除掉缺失属性最相近的样本,用相似的样本的属性值代替,求相似度可以采用聚类方法。

其次还有回归方法和插值法,回归方法及时建立回归模型,用已有的数据训练模型然后再预测。

插值法就有朗日插值法和牛顿插值法,这里就介绍一下拉格朗日插值法。

二、理论知识

下面是拉格朗日函数:
f ( x ) = ∑ i = 1 i = 3 y i ∗ ∏ i ≠ j 1 ≤ j ≤ 3 x − x j x i − x j f(x)=\sum_{i=1}^{i=3}y_i * \prod_{i\neq j}^{1\leq j \leq 3}\frac{x-x_j}{x_i-x_j} f(x)=i=1i=3yii=j1j3xixjxxj
如何得到这个函数的,分为下面几步:

三个点 ( x 1 , y 1 ) , ( x 2 , y 2 ) , ( x 3 , y 3 ) (x_1,y_1),(x_2,y_2),(x_3,y_3) (x1,y1),(x2,y2),(x3,y3)可以确定一条二次多项式的函数。这需要把三个点带入多项式然后解出各个系数。

但是拉格朗日的这个解法就不一样了。

第一步构建了一个函数:
f 1 ( x ) = ( x − x 2 ) ( x − x 3 ) ( x 1 − x 2 ) ( x 1 − x 3 ) f_1(x)=\frac{(x-x_2)(x-x_3)}{(x_1-x_2)(x_1-x_3)} f1(x)=(x1x2)(x1x3)(xx2)(xx3)
这个函数在 x = x 1 x=x_1 x=x1时,值为1; x = x 2 x=x_2 x=x2时,值为0; x = x 3 x=x_3 x=x3时,值为0。

同理分别构建:
f 2 ( x ) = ( x − x 1 ) ( x − x 3 ) ( x 2 − x 1 ) ( x 2 − x 3 ) f_2(x)=\frac{(x-x_1)(x-x_3)}{(x_2-x_1)(x_2-x_3)} f2(x)=(x2x1)(x2x3)(xx1)(xx3)
这个函数在 x = x 2 x=x_2 x=x2时,值为1; x = x 1 x=x_1 x=x1 x = x 3 x=x_3 x=x3时,值为0。
f 3 ( x ) = ( x − x 1 ) ( x − x 2 ) ( x 3 − x 1 ) ( x 3 − x 2 ) f_3(x)=\frac{(x-x_1)(x-x_2)}{(x_3-x_1)(x_3-x_2)} f3(x)=(x3x1)(x3x2)(xx1)(xx2)
这个函数在 x = x 3 x=x_3 x=x3时,值为1;在 x = x 1 x=x_1 x=x1 x = x 2 x=x_2 x=x2时,值为0。

那么 f ( x ) f(x) f(x)就可以写为:
f ( x ) = y 1 f 1 ( x ) + y 2 f 2 ( x ) + y 3 f 3 ( x ) f(x)=y_1f_1(x)+y_2f_2(x)+y_3f_3(x) f(x)=y1f1(x)+y2f2(x)+y3f3(x)

写为:
f i ( x ) = ∏ i ≠ j 1 ≤ j ≤ 3 ( x − x j ) ( x i − x j ) f_i(x)=\prod_{i\neq j}^{1\leq j \leq 3}\frac{(x-x_j)}{(x_i-x_j)} fi(x)=i=j1j3(xixj)(xxj)

得到拉格朗日函数。

三、代码实现

from scipy.interpolate import lagrange
def lag_fill(df, i, k):
    r = 0 if (i - k) < 0 else (i - k)
    l = len(df.index) if (i + 1 + k) > len(df.index) else (i + 1 + k)
    y = df.loc[list(range(r, i)) + list(range(i + 1, l))]
    for j in y.index:
        if y.isnull().loc[j]:
            y.drop(index = j, inplace = True)
    x = y.index
    lag = lagrange(x.values, y.values)
    return lag(i)
index = np.array(data['Age'][data['Age'].isnull()].index)
nums = []
for i in index:
    num = int(lag_fill(data['Age'], i, 5))
    nums.append(num)
df = data['Age'].copy()
index = np.array(df[df.isnull()].index) # 缺失值的索引
for i in range(len(index)):
    df.loc[index[i]] = nums[i]
df.isnull().sum()

结果为:

0

最后替换一下:

data['Age'] = df
data['Age'].isnull().sum()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旅途中的宽~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值