原文:miceforest: Fast Imputation with Random Forests in Python
miceforest 包实现随机森林的链式方程式(MICE)多重插补,具有快速、内存利用率高的特征,无需太多设置即可插入缺失的分类和数值数据,并且具有一系列可用的诊断图。
一,miceforest包的组成
miceforest 有4个主要的class:
- KernelDataSet:内核数据集是在其上执行mice算法的数据集,模型保存在实例内部,也可以调用该模型以插补新数据。有多种绘图方法,可对插补的数据进行诊断。
- MultipleImputedKernel:KernelDataSet的集合
- ImpulatedDataSet:已被插补的单个数据集,数据集在调用impute_new_data()函数之后返回。
- MultipleImputedDataSet:已被多元插补的数据集的集合,具有用于比较数据集之间的插补的其他方法。
二,使用miceforest
这里举一个简单的插补实例,首先加载软件包,加载数据:
import miceforest as mf
from sklearn.datasets import load_iris
import pandas as pd
import numpy as np
# Load data and introduce missing values
iris = pd.concat(load_iris(as_frame=True,return_X_y=True),axis=1)
iris['target'] = iris['target'].astype('category')
1,随机截取数据
iris_amp = mf.ampute_data(iris,perc=0.25,random_state=1991)
参数:perc是一个标量值,要截取的百分比(0-1),默认值是0.25。
2,插补单个数据集
如果只想创建一个单插补的数据集,那么可以使用KernelDataSet
# Create kernel.
kds = mf.KernelDataSet(
iris_amp,
save_all_iterations=True,
random_state=1991
)
# Run the MICE algorithm for 3 iterations
kds.mice(3)
# Return the completed kernel data
completed_data = kds.complete_data()
3,多元插补
使用MultipleImputedKernel创建多元插补核:
# Create kernel.
kernel = mf.MultipleImputedKernel(
iris_amp,
datasets=4,
save_all_iterations=True,
random_state=1991
)
# Run the MICE algorithm for 3 iterations on each of the datasets
kernel.mice(3)
4,控制决策树的增长
关于随机森林的优势是可以并行化,通过在随机森林的fit和预测方法中设置n_jobs参数,可以节省大量时间:
# Run the MICE algorithm for 2 more iterations on the kernel,
kernel.mice(2,n_jobs=2)
任何其他参数都可以传递给RandomForestClassifier或RandomForestRegressor,在我们的示例中,我们可能没有节省太多(如果有)时间。 这是因为使用多个内核会产生开销,并且我们的数据非常小。
5,创建自定义的插补架构
可以通过变量自定义插补程序,通过把命名列表(named list)传递给参数variable_schema,可以为每个要插补的变量指定预测变量,还可以选择哪些变量应该使用均值匹配(mean matching)来插补,即通过把dict传递给参数mean_match_candidates来指定哪些变量使用均值匹配来插补缺失值。:
var_sch = {
'sepal width (cm)': ['target','petal width (cm)'],
'petal width (cm)': ['target','sepal length (cm)']
}
var_mmc = {
'sepal width (cm)': 5,
'petal width (cm)': 0
}
cust_kernel = mf.MultipleImputedKernel(
iris_amp,
datasets=3,
variable_schema=var_sch,
mean_match_candidates=var_mmc
)
cust_kernel.mice(2)
6,使用现有的模型来插补新数据
多重插补可能需要很长时间,如果您希望使用MICE算法来插补数据集,但又没有时间训练新模型,则可以使用MultipleImputedKernel对象来插补新数据集。impute_new_data()函数使用MultipleImputedKernel收集的随机森林来执行多次插补,而无需在每次迭代时更新随机森林:
# Our 'new data' is just the first 15 rows of iris_amp
new_data = iris_amp.iloc[range(15)]
new_data_imputed = kernel.impute_new_data(new_data=new_data)
print(new_data_imputed)
## Class: MultipleImputedDataSet
## Datasets: 4
## Iterations: 5
## Imputed Variables: 5
## save_all_iterations: False
所有的插补参数(variable_schema,mean_match_candidates等)将从原始的MultipleImputedKernel对象继承。当使用均值匹配(mean matching)时,将从原始内核数据集中提取候选值。为了插入新数据,MultipleImputedKernel中的save_models参数必须>0。如果save_models == 1,则将为每个变量保存最新迭代的模型。 如果save_models> 1,则保存每次迭代的模型,这使得插补新数据的过程与原始mice过程更相似。
三,诊断图形
miceforest有4个可用的诊断图形工具
1,插补值的分布
我们可能想知道插补值的分布方式,我们可以通过使用MultipleImputedKernel对象的plot_imputed_distributions方法,在每个数据集中的插补值分布旁边绘制原始数据集的分布:
kernel.plot_imputed_distributions(wspace=0.3,hspace=0.3)
红线是原始数据,黑线是每个数据集的插补(估算)值。
2,相关的收敛(Convergence of Correlation)
我们可能对数据集之间的值如何在迭代中收敛感兴趣,plot_correlations()方法通过绘制箱线图,显示了在每次迭代时,数据集的每种组合中的插补值之间的相关性,这使您可以查看数据集之间的插补之间的相关性,以及迭代之间的收敛:
kernel.plot_correlations()
3,变量的重要性
一个变量是用哪些变量进行插补?这可以通过使用plot_feature_importance()方法回答该问题。
kernel.plot_feature_importance(annot=True,cmap="YlGnBu",vmin=0, vmax=1)
显示的数字是从sklearn随机森林的_feature_importance属性返回的,每个正方形代表列变量在估算行变量中的重要性。
4,均值收敛(Mean Convergence)
如果我们的数据不是完全随机丢失,我们可能会发现我们的模型需要进行几次迭代才能获得正确插补的分布。 我们可以绘制插补的平均值,以查看是否发生均值收敛:
kernel.plot_mean_convergence(wspace=0.3, hspace=0.4)
由于我们的数据是完全随机性丢失,因此,在这里看不到任何收敛
四,使用插补值
要返回插补的数据,只需要使用complete_data()方法:
dataset_1 = kernel.complete_data(0)
这将返回一个指定的数据集,通常会创建多个数据集,以便对每个预测创建一些置信度度量。由于我们知道原始数据是什么样子,因此我们可以作弊,只创建一个数据集,查看插补值与原始数据的比较:
acclist = []
for iteration in range(kernel.iteration_count()+1):
target_na_count = kernel.na_counts['target']
compdat = kernel.complete_data(dataset=0,iteration=iteration)
# Record the accuract of the imputations of target.
acclist.append(
round(1-sum(compdat['target'] != iris['target'])/target_na_count,2)
)
# acclist shows the accuracy of the imputations
# over the iterations.
print(acclist)
## [0.32, 0.76, 0.78, 0.81, 0.86, 0.86]
在这种实例中,我们从〜32%的准确度提高到〜86%的准确度,多重插补最终以很高的准确度替换了丢失的目标值!
参考文档:
miceforest 2.0.3