好的,各位听众,各位观众,欢迎来到“数据江湖风云录”之“高级缺失值处理大作战”现场!我是你们的老朋友,数据挖掘界的“段子手”——阿星。今天,咱们不谈“人生苦短,我用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)
代码解释:
KNNImputer(n_neighbors=2)
: 创建一个 KNNImputer 对象,设置 K 值为 2。这意味着我们将使用与缺失值样本最相似的 2 个样本来填充缺失值。imputer.fit_transform(df)
: 使用 KNNImputer 填充缺失值,并返回填充后的 NumPy 数组。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 算法会这样做:
- 初始化: 首先,用一些简单的方法(比如均值、中位数)填充缺失值。
- 迭代: 然后,对每个包含缺失值的变量,都建立一个预测模型,用其他变量来预测该变量的缺失值。比如,用收入和教育程度来预测年龄的缺失值,用年龄和教育程度来预测收入的缺失值。
- 多重插补: 重复上述步骤多次,每次迭代都会更新缺失值的估计值。最终,你会得到多个完整的数据集,每个数据集的缺失值都被填充了不同的值。
- 分析: 对每个完整的数据集进行分析,得到多个分析结果。
- 合并: 将多个分析结果进行合并,得到最终的分析结果。
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)
代码解释:
IterativeImputer(max_iter=10, random_state=0)
: 创建一个 IterativeImputer 对象,设置最大迭代次数为 10,随机种子为 0。imputer.fit_transform(df)
: 使用 IterativeImputer 填充缺失值,并返回填充后的 NumPy 数组。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 算法: 考虑了变量之间的复杂关系,适用于复杂数据集。
希望今天的讲解能够帮助大家在数据挖掘的道路上更进一步!记住,没有完美的方法,只有最适合的方法。
未来的路还很长,缺失值处理的方法也在不断发展。希望大家能够不断学习,不断探索,成为数据挖掘界的“武林盟主”!
好了,今天的“数据江湖风云录”就到这里,咱们下期再见! 拜拜! 👋