高级缺失值处理:KNN Imputer 与 MICE 算法

好的,各位听众,各位观众,欢迎来到“数据江湖风云录”之“高级缺失值处理大作战”现场!我是你们的老朋友,数据挖掘界的“段子手”——阿星。今天,咱们不谈“人生苦短,我用Python”,咱们来聊聊数据挖掘路上的一大拦路虎:缺失值。

江湖传言:数据好比武林高手,缺失值好比高手身上的“罩门”。罩门越多,实力越弱,甚至可能走火入魔,练成“废材神功”。所以,如何巧妙地弥补这些罩门,让我们的数据重回巅峰,就成了数据挖掘工程师的必修课。

今天,阿星就带大家深入“缺失值”的腹地,探索两种高级又实用的缺失值处理方法:KNN Imputer 和 MICE 算法。保证让大家听得懂,学得会,用得上!

第一章:缺失值,你这个磨人的小妖精!

在正式开讲之前,咱们先来认识一下这位“磨人的小妖精”——缺失值。

1.1 缺失值的“前世今生”

啥是缺失值?说白了,就是数据里头空着的那部分。想象一下,你正在统计用户的信息,结果发现有些用户没填年龄,有些用户没填收入,这些没填的,就是缺失值。

缺失值出现的理由千奇百怪,可能是:

  • 人为错误: 填表的时候手抖了一下,或者系统出了bug,导致数据丢失。
  • 信息未提供: 有些用户就是不愿意透露自己的隐私,比如收入、年龄、健康状况等等。
  • 设备故障: 传感器失灵,网络中断,都会导致数据采集不完整。
  • 数据合并: 从不同的数据源合并数据时,字段不一致,导致部分数据为空。

1.2 缺失值的“庐山真面目”

缺失值可不是铁板一块,根据它的“脾气”,可以分成三种类型:

  • 完全随机缺失 (Missing Completely at Random, MCAR): 这种缺失完全是随机发生的,与其他变量没有任何关系。比如,你扔硬币决定哪些数据要删除,这就是MCAR。
  • 随机缺失 (Missing at Random, MAR): 这种缺失与其他变量有关,但与自身无关。比如,女性更不愿意透露自己的收入,那么收入的缺失就与性别有关。
  • 非随机缺失 (Missing Not at Random, MNAR): 这种缺失与自身有关。比如,收入越高的人,越不愿意透露自己的收入,那么收入的缺失就与收入本身有关。

1.3 缺失值的“危害”

缺失值可不是闹着玩的,它会带来一系列问题:

  • 降低模型准确性: 缺失值会影响模型的训练,导致模型预测不准确。
  • 引入偏差: 如果缺失值不是随机发生的,那么分析结果可能会产生偏差。
  • 浪费数据: 直接删除包含缺失值的样本,会浪费大量有用的信息。

所以,处理缺失值,势在必行!

第二章:神器登场!KNN Imputer 大显神威!

面对缺失值这个“小妖精”,我们不能坐以待毙,必须祭出神器!今天,阿星要介绍的第一位英雄,就是 KNN Imputer。

2.1 KNN Imputer 的“独门秘籍”

KNN Imputer 的核心思想是:物以类聚,人以群分。简单来说,就是用与缺失值样本最相似的 K 个样本的平均值(或众数)来填充缺失值。

想象一下,你有一个朋友小明,他忘记了自己的年龄,但是你认识小明的朋友们,你可以看看小明的朋友们平均年龄是多少,用这个平均年龄来估计小明的年龄。这就是 KNN Imputer 的基本思路。

2.2 KNN Imputer 的“使用方法”

KNN Imputer 用起来非常简单,只需几行代码:

from sklearn.impute import KNNImputer
import pandas as pd
import numpy as np

# 构造一个包含缺失值的 DataFrame
data = {'Age': [25, 30, np.nan, 35, 40, np.nan],
        'Income': [50000, 60000, 70000, np.nan, 80000, 90000],
        'Education': [1, 2, 3, 4, 5, 1]}
df = pd.DataFrame(data)

# 初始化 KNNImputer
imputer = KNNImputer(n_neighbors=2) # 设置 K 值为 2

# 使用 KNNImputer 填充缺失值
df_filled = imputer.fit_transform(df)

# 转换回 DataFrame
df_filled = pd.DataFrame(df_filled, columns=df.columns)

print(df)
print(df_filled)

代码解释:

  1. KNNImputer(n_neighbors=2): 创建一个 KNNImputer 对象,设置 K 值为 2。这意味着我们将使用与缺失值样本最相似的 2 个样本来填充缺失值。
  2. imputer.fit_transform(df): 使用 KNNImputer 填充缺失值,并返回填充后的 NumPy 数组。
  3. pd.DataFrame(df_filled, columns=df.columns): 将填充后的 NumPy 数组转换回 DataFrame。

2.3 KNN Imputer 的“优缺点”

KNN Imputer 优点多多:

  • 简单易用: 使用起来非常简单,几行代码就能搞定。
  • 适用性广: 可以处理数值型和类别型数据。
  • 考虑了变量之间的关系: 通过寻找相似的样本,考虑了变量之间的关系。

当然,KNN Imputer 也有一些缺点:

  • 计算量大: 需要计算所有样本之间的距离,当数据量很大时,计算量会很大。
  • 对 K 值敏感: K 值的选择会影响填充结果,需要仔细调参。
  • 受异常值影响: 异常值会影响相似样本的寻找,导致填充结果不准确。

2.4 KNN Imputer 的“注意事项”

  • 数据标准化: 在使用 KNN Imputer 之前,最好对数据进行标准化,避免因为变量的量纲不同而影响距离的计算。
  • K 值选择: K 值的选择很重要,可以尝试不同的 K 值,并评估填充效果。一般来说,K 值不宜过大,也不宜过小。
  • 缺失值比例: 当缺失值比例很高时,KNN Imputer 的效果可能不太好。

第三章:MICE 算法:多重插补,妙手回春!

如果说 KNN Imputer 是一位“朴实无华”的侠客,那么 MICE 算法就是一位“风度翩翩”的公子。MICE 算法,全称 Multivariate Imputation by Chained Equations,是一种基于链式方程的多重插补方法。

3.1 MICE 算法的“原理”

MICE 算法的核心思想是:用多个模型来预测缺失值,并进行多次迭代,最终得到多个完整的数据集,然后对这些数据集进行分析,并将结果进行合并。

听起来有点复杂?没关系,阿星用一个例子来解释:

假设你正在统计用户的信息,包括年龄、收入和教育程度。但是,有些用户没有填写年龄和收入。MICE 算法会这样做:

  1. 初始化: 首先,用一些简单的方法(比如均值、中位数)填充缺失值。
  2. 迭代: 然后,对每个包含缺失值的变量,都建立一个预测模型,用其他变量来预测该变量的缺失值。比如,用收入和教育程度来预测年龄的缺失值,用年龄和教育程度来预测收入的缺失值。
  3. 多重插补: 重复上述步骤多次,每次迭代都会更新缺失值的估计值。最终,你会得到多个完整的数据集,每个数据集的缺失值都被填充了不同的值。
  4. 分析: 对每个完整的数据集进行分析,得到多个分析结果。
  5. 合并: 将多个分析结果进行合并,得到最终的分析结果。

3.2 MICE 算法的“使用方法”

MICE 算法的使用也很简单,可以使用 sklearn.impute 中的 IterativeImputer,或者使用 statsmodels 中的 MICE 类。

这里,阿星使用 sklearn.impute 中的 IterativeImputer 来演示:

from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer
import pandas as pd
import numpy as np

# 构造一个包含缺失值的 DataFrame
data = {'Age': [25, 30, np.nan, 35, 40, np.nan],
        'Income': [50000, 60000, 70000, np.nan, 80000, 90000],
        'Education': [1, 2, 3, 4, 5, 1]}
df = pd.DataFrame(data)

# 初始化 IterativeImputer
imputer = IterativeImputer(max_iter=10, random_state=0) # 设置最大迭代次数和随机种子

# 使用 IterativeImputer 填充缺失值
df_filled = imputer.fit_transform(df)

# 转换回 DataFrame
df_filled = pd.DataFrame(df_filled, columns=df.columns)

print(df)
print(df_filled)

代码解释:

  1. IterativeImputer(max_iter=10, random_state=0): 创建一个 IterativeImputer 对象,设置最大迭代次数为 10,随机种子为 0。
  2. imputer.fit_transform(df): 使用 IterativeImputer 填充缺失值,并返回填充后的 NumPy 数组。
  3. pd.DataFrame(df_filled, columns=df.columns): 将填充后的 NumPy 数组转换回 DataFrame。

3.3 MICE 算法的“优缺点”

MICE 算法的优点:

  • 考虑了变量之间的复杂关系: 通过建立多个预测模型,考虑了变量之间的复杂关系。
  • 可以处理多种类型的缺失值: 可以处理 MCAR, MAR, MNAR 三种类型的缺失值。
  • 可以生成多个完整的数据集: 可以生成多个完整的数据集,从而更好地估计缺失值的不确定性。

MICE 算法的缺点:

  • 计算量大: 需要建立多个预测模型,并进行多次迭代,计算量很大。
  • 模型选择: 需要选择合适的预测模型,不同的模型可能会影响填充结果。
  • 收敛性: 需要保证算法能够收敛,否则填充结果可能不准确。

3.4 MICE 算法的“注意事项”

  • 模型选择: 可以根据变量的类型选择合适的预测模型。对于数值型变量,可以使用线性回归模型;对于类别型变量,可以使用逻辑回归模型。
  • 迭代次数: 迭代次数不宜过少,也不宜过多。一般来说,10-20 次迭代就足够了。
  • 收敛性诊断: 可以通过观察迭代过程中缺失值估计值的变化来判断算法是否收敛。

第四章:实战演练:信用卡欺诈检测

理论讲了一大堆,不如来点实际的。咱们用一个信用卡欺诈检测的例子,来演示一下 KNN Imputer 和 MICE 算法的威力。

4.1 数据准备

我们使用一个公开的信用卡欺诈数据集,该数据集包含信用卡交易的各种信息,包括交易金额、交易时间、交易地点等等。

首先,我们加载数据集,并随机生成一些缺失值:

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 加载数据集
df = pd.read_csv('creditcard.csv')

# 随机生成缺失值
np.random.seed(0)
missing_rate = 0.05 # 缺失值比例
for col in df.columns[:-1]:  # 除了 'Class' 列
    mask = np.random.rand(len(df)) < missing_rate
    df.loc[mask, col] = np.nan

# 分割数据集
X = df.drop('Class', axis=1)
y = df['Class']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)

# 数据标准化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

X_train = pd.DataFrame(X_train, columns=X.columns)
X_test = pd.DataFrame(X_test, columns=X.columns)

4.2 KNN Imputer 填充缺失值

from sklearn.impute import KNNImputer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

# KNN Imputer
imputer = KNNImputer(n_neighbors=5)
X_train_knn = imputer.fit_transform(X_train)
X_test_knn = imputer.transform(X_test)

# Logistic Regression
model_knn = LogisticRegression(random_state=0)
model_knn.fit(X_train_knn, y_train)
y_pred_knn = model_knn.predict(X_test_knn)

# 评估模型
print("KNN Imputer:")
print("Accuracy:", accuracy_score(y_test, y_pred_knn))
print("Precision:", precision_score(y_test, y_pred_knn))
print("Recall:", recall_score(y_test, y_pred_knn))
print("F1 Score:", f1_score(y_test, y_pred_knn))

4.3 MICE 算法填充缺失值

from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer

# MICE
imputer = IterativeImputer(max_iter=10, random_state=0)
X_train_mice = imputer.fit_transform(X_train)
X_test_mice = imputer.transform(X_test)

# Logistic Regression
model_mice = LogisticRegression(random_state=0)
model_mice.fit(X_train_mice, y_train)
y_pred_mice = model_mice.predict(X_test_mice)

# 评估模型
print("nMICE:")
print("Accuracy:", accuracy_score(y_test, y_pred_mice))
print("Precision:", precision_score(y_test, y_pred_mice))
print("Recall:", recall_score(y_test, y_pred_mice))
print("F1 Score:", f1_score(y_test, y_pred_mice))

4.4 结果分析

运行上述代码,我们可以得到 KNN Imputer 和 MICE 算法在信用卡欺诈检测任务上的表现。通过比较 Accuracy, Precision, Recall 和 F1 Score 等指标,我们可以评估两种算法的优劣。

一般来说,MICE 算法在处理复杂数据集时,往往表现更好,因为它考虑了变量之间的复杂关系。但是,KNN Imputer 在简单数据集上,也能取得不错的效果,而且计算速度更快。

第五章:总结与展望

今天,我们一起学习了 KNN Imputer 和 MICE 算法这两种高级缺失值处理方法。总的来说,这两种方法各有优缺点,选择哪种方法,取决于你的数据特点和业务需求。

  • KNN Imputer: 简单易用,计算速度快,适用于简单数据集。
  • MICE 算法: 考虑了变量之间的复杂关系,适用于复杂数据集。

希望今天的讲解能够帮助大家在数据挖掘的道路上更进一步!记住,没有完美的方法,只有最适合的方法。

未来的路还很长,缺失值处理的方法也在不断发展。希望大家能够不断学习,不断探索,成为数据挖掘界的“武林盟主”!

好了,今天的“数据江湖风云录”就到这里,咱们下期再见! 拜拜! 👋

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注