Translator|布加迪评论家|SunShujuanImputer如果你的数据集中有一些缺失值,你可能会移除缺失值行甚至列。强烈建议不要使用这种方法,因为它会减小数据的大小,而且数据分析可能会偏离事实。相反,我们应该使用不受缺失值影响的机器学习算法,或者使用Imputer来填充缺失信息。Imputer是一个用于填充数据集中缺失值的估计器。对于数值,它使用平均值、中值和常数。对于分类值,它使用最常用的常量值。您还可以训练模型来预测缺失的标签。在本教程中,我们将了解Scikit-learn的SimpleImputer、IterativeImputer和KNNImputer。我们还将创建一个管道来估算分类和数字特征,并将它们输入机器学习模型。如何使用Scikit-learn的Imputer?scikit-learn的插补函数为我们提供了一个易于填充的选项,只需几行代码。我们可以集成这些输入器并创建管道来重现结果并改进机器学习开发过程。首先,我们将使用Deepnote环境,它类似于JupyterNotebook,但在云端。从Kaggle下载并解压缩数据。必须安装KagglePython包并使用API下载spaceship-titanic数据集。最后,将数据解压到数据集文件夹中。%%capture!pipinstallkaggle!kagglecompetitionsdownload-cspaceship-titanic!unzip-d./datasetspaceship-titanic接下来,我们将导入数据摄取、插补和转换管道创建所需的Python包。导入numpy作为npimportpandas作为pdfromsklearn.iptimportimportimportimimputerfromsklearn.enfimentimimportimentimportenable_iter_iter_imerative_imputerfromsklearn.ipputeimportimportimportipiterativeImputer,knnimputerfromsklearn.piplearn.pipelineimportintern.pipelineimportinternionimplenioninternioniTiTiTiTiTiTENTRENINE包括培训、测试和提交CSV文件。我们将使用train.csv,其中包含有关飞船乘客的信息。pandasread_csv()函数读取train.csv,然后显示数据框。df=pd.read_csv("dataset/train.csv")df图1数据分析我们将在本节中探索具有缺失值的列,但首先我们需要检查数据集的形状。它有8693行和14列。df.shape>>>(8693,14)我们现在将按列显示缺失值计数和百分比。为了在数据框中显示它,我们将创建一个包含缺失值的新数据框,并将样式渐变应用于NACount列。NA=pd.DataFrame(data=[df.isna().sum().tolist(),["{:.2f}".format(i)+'%'\foriin(df.isna().sum()/df.shape[0]*100).tolist()]],columns=df.columns,index=['NACount','NAPercent']).transpose()NA.style.background_gradient(cmap="Pastel1_r",subset=['NACount'])图2除了PassengerID和Transported之外的每一列都有缺失值。数值插补我们将使用缺失列中的信息并将它们分为分类列和数值列。我们以不同的方式对待他们。对于数值插补,我们将选择年龄列并显示数值缺失值。它将帮助我们验证之前和之后的结果。all_col=df.columnscat_na=['HomePlanet','CryoSleep','Destination','VIP']num_na=['Age','RoomService','FoodCourt','ShoppingMall','Spa','VRDeck']data1=df.copy()data2=df.copy()data1['Age'].isna().sum()>>>179data1.Age[0:5]>>>039.0>>>124.0>>>258.0>>>333.0>>>416.0接下来,我们将使用sklearn的SimpleImputer并将其应用于Age列。它将用列的平均值替换缺失的数据。正如我们所看到的,年龄列中没有缺失值。imp=SimpleImputer(strategy='mean')data1['Age']=imp.fit_transform(data1['Age'].values.reshape(-1,1))data1['Age'].isna().sum()>>>0如果是数值列??,可以使用常量、均值、中位数策略;如果是分类列,可以使用most_frequent和constant策略。分类插补在分类插补的情况下,我们将使用具有201个缺失值的HomePlanet列。data1['HomePlanet'].isna().sum()>>>201data1.HomePlanet[0:5]>>>0Europa>>>1Earth>>>2Europa>>>3Europa>>>4Earth为了填充分类缺失值,我们将使用具有most_frequent策略的SimpleImputer。mp=SimpleImputer(strategy="most_frequent")data1['HomePlanet']=imp.fit_transform(data1['HomePlanet'].values.reshape(-1,1))我们把HomePlanet这一列的缺失值都填上了.data1['HomePlanet'].isna().sum()>>>0MultivariateImputerInunivariateImputermissingvaluesarecalculatedusingthesamefeatures,whileinmultivariateImputer该算法使用整套可用的特征维度来预测缺失值。我们将一次性估算数字列;正如我们所见,它们都有超过150个缺失值。data2[num_na].isna().sum()>>>Age179>>>RoomService181>>>FoodCourt183>>>ShoppingMall208>>>Spa183>>>VRDeck188我们将使用IterativeImputer和10max_iter来估计并填充数字列中的缺失值。该算法在进行价值估计时将考虑所有列。imp=IterativeImputer(max_iter=10,random_state=0)data2[num_na]=imp.fit_transform(data2[num_na])data2[num_na].isna().sum()>>>年龄0>>>RoomService0>>>FoodCourt0>>>ShoppingMall0>>>Spa0>>>VRDeck0ImputingCategoricalandNumericalValuesforMachineLearning为什么选择Scikit-learn的Imputer?除了Imputer之外,该机器学习框架还提供特征转换、数据操作、管道和机器学习算法。他们都顺利融入。只需几行代码,您就可以在任何数据集上估算、归一化、转换和训练模型。在本节中,我们将学习如何将Imputer集成到机器学习项目中以获得更好的结果。首先,我们将从sklearn中导入相关函数。然后我们将删除不相关的列以创建X和Y变量。我们的目标列是“已运输”。之后,我们将它们分成训练集和测试集。fromsklearn.preprocessingimportLabelEncoder,StandardScaler,OrdinalEncoderfromsklearn.treeimportDecisionTreeClassifierfromsklearn.model_selectionimporttrain_test_splitX,y=df.drop(['Transported','PassengerId','Name','Cabin'],axis=1),df['Transported']X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=100,random_state=0)要创建数值和分类转换数据管道,我们将使用sklearn的Pipeline函数。在numeric_transformer的情况下,我们使用:具有2个n_neighbors和统一权重的KNNImputer。在第二步中,我们使用了具有默认配置的StandardScaler。在categorical_transformer的情况下,我们使用:具有most_frequent策略的SimpleImputer。在第二步中,我们使用OrdinalEncoder将类别转换为数字。numeric_transformer=Pipeline(steps=[('Imputer',KNNImputer(n_neighbors=2,weights="uniform")),('scaler',StandardScaler())])categorical_transformer=Pipeline(steps=[('Imputer',SimpleImputer(strategy='most_frequent')),('onehot',OrdinalEncoder())])现在,我们将使用ColumnTransformer处理和转换训练特征。在numeric_transformer的情况下,我们给它一个数字列的列表;在categorical_transformer的情况下,我们使用分类列列表。注意:我们只准备管道和变压器。我们还没有处理任何数据。preprocessor=ColumnTransformer(remainder='passthrough',transformers=[('numeric',numeric_transformer,num_na),('categorical',categorical_transformer,cat_na)])最后,我们将创建一个带有处理器的转换管道和用于二进制分类的DecisionTreeClassifier任务。管道将在训练分类器模型之前处理和转换数据。transform=Pipeline(steps=[("processing",preprocessor),("DecisionTreeClassifier",DecisionTreeClassifier()),])这时,神奇的一幕发生了。我们将在转换管道上拟合训练数据集。之后,我们将使用测试数据集评估我们的模型。我们使用默认配置实现了75%的准确率。效果很好!model=transform.fit(X_train,y_train)model.score(X_test,y_test)>>>0.75接下来,我们将对测试数据集进行预测并创建结构化分类报告。fromsklearn.metricsimportclassification_reportprediction=model.predict(X_test)print(classification_report(prediction,y_test))我们可以看到,True类和False类的分数比较稳定。precisionrecallf1-score支持False0.700.740.7243True0.800.750.7757accuracy0.75100macroavg0.750.750.75100weightedavg0.750.750.75100weightedavg0.750.750.75必须决定构建一个系统需要多少时间和资源,以及它带来什么价值。在大多数情况下,Scikit-learn的Imputers提供了更大的价值,我们只需要几行代码就可以对整个数据集进行插值。在这篇博文中,我们了解了插补以及Scikit-learn库如何估算缺失值。我们还学习了单变量、多变量、分类和数值插补。在上一节中,我们使用了数据管道、列转换器和机器学习管道来估算、转换、训练和评估我们的模型。原标题:使用Scikit-learn的Imputer,作者:AbidAliAwan
