1、缺失值的处理
我们将学习三种处理缺失值的方法。然后我们将比较这些方法在实际数据集上的有效性。
缺失值的介绍:
有很多种方法可以使数据以丢失的值结束。
例如:
两居室的房子不包括第三居室大小的价值。
调查对象可选择不分享其收入。
如果尝试使用缺少值的数据构建模型,大多数机器学习库(包括SciKit学习)都会给出错误。
2、三种处理缺失值的方法
1)一个简单的选项:删除缺少值的列
最简单的选择是删除缺少值的列。
除非已删除列中的大多数值都丢失,否则模型将无法访问大量(可能有用!)
此方法的信息:
作为一个极端的例子,考虑一个具有10000行的数据集,其中一个重要列缺少一个条目。这种方法会完全删除列!
2)、更好的选择:插补
插补用一些数字填充缺失的值。例如,我们可以沿着每列填写平均值。
在大多数情况下,插补值并不完全正确,但它通常会导致比完全删除列得到的模型更精确。
3)、插补的扩展
插补法是标准的方法,通常工作得很好。但是,输入值可能系统地高于或低于其实际值(数据集中未收集)。
或者缺少值的行在其他方面可能是唯一的。在这种情况下,通过考虑最初缺少的值,您的模型可以做出更好的预测。
在这种方法中,我们像以前一样输入缺失的值。另外,对于原始数据集中缺少条目的每一列,我们添加一个新列,显示输入条目的位置。
在某些情况下,这将有意义地改善结果。在其他情况下,这根本没有帮助。
3、举例表明
1、准备活动
import pandas as pd from sklearn.model_selection import train_test_split #加载数据 data = pd.read_csv('E:/data_handle/melb_data.csv') #选择目标 y = data.Price #使用数字预测器 melb_predictors = data.drop(['Price'],axis=1) X = melb_predictors.select_dtypes(exclude=['object']) #将数据分为训练和验证子集 X_trian, X_valid, y_train, y_valid = train_test_split(X,y,train_size=0.8, test_size =0.2,random_state=0)
2、定义功能来度量每种方法的质量
我们定义了一个函数score_dataset()来比较处理缺失值的不同方法。该函数报告随机森林模型的平均绝对误差(MAE)。
from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_absolute_error #函数用于比较不同的方法 def score_dataset(X_train, X_valid, y_train, y_valid): model = RandomForestRegressor(n_estimators=10, random_state=0) model.fit(X_train, y_train) preds = model.predict(X_valid) return mean_absolute_error(y_valid,preds)
3、方法1的得分(删除缺少值的列)
由于我们同时使用培训和验证集,因此我们小心地在两个数据帧中删除相同的列。
#获得缺失值的列名 cols_with_missing = [col for col in X_train.columns if X_train[col].isnull().any()] #删除训练和验证数据的列 reduced_X_train = X_train.drop(cols_with_missing,axis=1) reduced_X_valid = X_valid.drop(cols_with_missing, axis=1) print("MAE from Approach 1 (Drop columns with missing values):") print(score_dataset(reduced_X_train, reduced_X_valid, y_train, y_valid))
4、方法二的得分(插补)
接下来,我们使用simpleinputer将缺失的值替换为每列的平均值。
虽然这很简单,但是填充平均值通常会很好地执行(但这会因数据集而异)。
虽然统计学家已经尝试了更复杂的方法来确定插补值(例如回归插补),但一旦将结果插入复杂的机器学习模型中,复杂的策略通常不会带来额外的好处。
#插补 my_imputer = SimpleImputer() imputed_X_train = pd.DataFrame(my_imputer.fit_transform(X_train)) imputed_X_valid = pd.DataFrame(my_imputer.transform(X_valid)) #插补删除列名,并放回原处 imputed_X_train.columns = X_train.columns imputed_X_valid.columns = X_valid.columns print("MAE from Approach 2 (Imputation):") print(score_dataset(imputed_X_train, imputed_X_valid, y_train, y_valid))
5、方法3的得分(插补的扩展)
接下来,我们输入缺失的值,同时跟踪哪些值被输入。
#复制以避免更改原始数据(输入时) X_train_plus = X_train.copy() X_valid_plus = X_valid.copy() #新建列,指示将要输入的内容 for col in cols_with_missing: X_train_plus[col + '_was_missing'] = X_train_plus[col].isnull() X_valid_plus[col + '_was_missing'] = X_valid_plus[col].isnull() # 插补 my_imputer = SimpleImputer() imputed_X_train_plus = pd.DataFrame(my_imputer.fit_transform(X_train_plus)) imputed_X_valid_plus = pd.DataFrame(my_imputer.transform(X_valid_plus)) #插补删除列名,并放回原处 imputed_X_train_plus.columns = X_train_plus.columns imputed_X_valid_plus.columns = X_valid_plus.columns print("MAE from Approach 3 (An Extension to Imputation):") print(score_dataset(imputed_X_train_plus, imputed_X_valid_plus, y_train, y_valid))
6、总结
#打印训练的形状(行、列) print(X_train.shape) #每列培训数据中缺少的值的数目 missing_val_count_by_column = (X_train.isnull().sum()) print(missing_val_count_by_column[missing_val_count_by_column > 0])
与常见的情况一样,与我们简单地删除缺少值的列(在方法1中)相比,输入缺少值(在方法2和方法3中)会产生更好的结果。
此次学习到此结束!!!!!
Score from Approach 3 (An Extension to Imputation)
Next, we impute the missing values, while also keeping track of which values were imputed.