【问题标题】:Choosing between imputation methods [closed]在插补方法之间进行选择[关闭]
【发布时间】:2019-12-17 18:02:31
【问题描述】:

我正在尝试评估 2 种数据插补方法。
我的数据集:https://www.kaggle.com/c/house-prices-advanced-regression-techniques/data

我的目标标签是LotFrontage
首先,我使用 OneHotEncoding 对所有类别特征进行编码,然后使用相关矩阵过滤-0.30.3 以上的任何内容。

encoded_df = pd.get_dummies(train_df, prefix_sep="_", columns=['MSZoning', 'Street', 'Alley',
                                                       'LotShape', 'LandContour', 'Utilities',
                                                       'LotConfig', 'LandSlope', 'Neighborhood',
                                                       'Condition1', 'Condition2', 'BldgType', 'HouseStyle'])

corrmat = encoded_df.corr()
corrmat[(corrmat > 0.3) | (corrmat < -0.3)]
# filtering out based on corrmat output...
encoded_df = encoded_df[['SalePrice', 'MSSubClass', 'LotFrontage', 'LotArea',
                         'BldgType_1Fam', 'BldgType_2fmCon', 'BldgType_Duplex', 'BldgType_Twnhs', 'BldgType_TwnhsE',
                         'MSZoning_C (all)', 'MSZoning_FV', 'MSZoning_RH', 'MSZoning_RL', 'MSZoning_RM']]

然后我尝试了两种插补方法:

  1. 使用LotFrontage 的平均值(使用此方法是因为我发现离群率较低)
  2. 尝试用DecisionTreeRegressor预测LotFrontage
# imputate LotFrontage with the mean value (we saw low outliers ratio so we gonna use this)
encoded_df1 = encoded_df.copy()
encoded_df1['LotFrontage'].fillna(encoded_df['LotFrontage'].mean(), inplace=True)
X1 = encoded_df1.drop('LotFrontage', axis=1)
y1 = encoded_df1['LotFrontage']
X1_train, X1_test, y1_train, y1_test = train_test_split(X1, y1)
classifier1 = DecisionTreeRegressor()
classifier1.fit(X1_train, y1_train)
y1_pred = classifier1.predict(X1_test)
print('score1: ', classifier1.score(X1_test, y1_test))

# imputate LotFrontage with by preditcing it using DecisionTreeRegressor
encoded_df2 = encoded_df.copy()
X2 = encoded_df2[~encoded_df2['LotFrontage'].isnull()].drop('LotFrontage', axis=1)
y2 = encoded_df2[~encoded_df2['LotFrontage'].isnull()]['LotFrontage']
X2_train, X2_test, y2_train, y2_test = train_test_split(X2, y2)
classifier2 = DecisionTreeRegressor()
classifier2.fit(X2_train, y2_train)
y2_pred = classifier2.predict(encoded_df2[encoded_df2['LotFrontage'].isnull()].drop('LotFrontage', axis=1))
imputated_encoded_df2 = encoded_df2[encoded_df2['LotFrontage'].isnull()].assign(LotFrontage=y2_pred)
X3 = imputated_encoded_df2.drop('LotFrontage', axis=1)
y3 = imputated_encoded_df2['LotFrontage']
X3_train, X3_test, y3_train, y3_test = train_test_split(X3, y3)
classifier2.fit(X3_train, y3_train)
y3_pred = classifier2.predict(X3_test)
print('score2: ', classifier2.score(X3_test, y3_test))

我的问题是:

  1. 我首先使用fillna 的平均值然后拆分训练和测试并检查分数是否正确?因为如果我在拟合模型之前填充值,它不会在插补数据上拟合模型,从而给我带来有偏见的结果吗?第二种方法也一样
  2. 我做错了什么,因为我无法确定最佳的插补方法,因为这两种方法的得分都不好,而且是随机的

【问题讨论】:

  • 我投票结束这个问题,因为它与 help center 中定义的编程无关,而是关于 ML 理论和/或方法 - 请参阅 stackoverflow.com/tags/machine-learning/info 中的介绍和注意事项跨度>
  • @Turing85 在技术上是正确的,但可以说这里不是适当的密切原因:如果 OP 删除了他们的第二个问题(因此使问题成为焦点),这会成为主题吗?可能不会……

标签: python machine-learning regression decision-tree imputation


【解决方案1】:

1.使用(均值/中值)值进行插补:

这通过计算列中非缺失值的平均值/中值,然后分别替换每列中的缺失值并独立于其他列来实现。它只能用于数字数据。

优点
简单快捷。
适用于小型数值数据集。

缺点
不考虑特征之间的相关性。
它仅适用于列级别。
在编码的分类特征上会给出很差的结果(不要在分类特征上使用它)。
不是很准确。
不考虑插补中的不确定性。

2.使用(最频繁)或(零/常数)值的插补:

最频繁是另一种估算缺失值的统计策略,是的!它通过用每列中最常见的值替换缺失数据来处理分类特征(字符串或数字表示)。

优点
适用于分类特征。
缺点
它也没有考虑特征之间的相关性。
它会在数据中引入偏差。

零或常数插补——顾名思义——它用零或您指定的任何常数值替换缺失值

3. 使用 k-NN 进行插补:

k 最近邻是一种用于简单分类的算法。该算法使用“特征相似性”来预测任何新数据点的值。这意味着根据新点与训练集中的点的相似程度,为新点分配一个值。这对于预测缺失值非常有用,方法是找到 k 与缺失数据的观测值最近的邻居,然后根据邻域中的非缺失值进行估算。

它是如何工作的?
它创建一个基本的平均插补,然后使用生成的完整列表来构造一个 KDTree。然后,它使用生成的 KDTree 来计算最近邻 (NN)。找到 k-NN 后,对它们进行加权平均。

优点
可以比均值、中值或最常见的插补方法准确得多(这取决于数据集)。

缺点
计算成本高。 KNN 通过将整个训练数据集存储在内存中来工作。 K-NN 对数据中的异常值非常敏感(与 SVM 不同)

由于离群率较低,我们可以使用方法3
它对估算的目标变量(即 LotFrontage)与其他特征之间的相关性影响也较小。

import sys
from impyute.imputation.cs import fast_knn
sys.setrecursionlimit(100000) #Increase the recursion limit of the OS

# start the KNN training
train_df['LotFrontage']=fast_knn(train_df[['LotFrontage','1stFlrSF','MSSubClass']], k=30)

考虑到它们与 LotFrontage 列的相关性,我选择了这两个功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-17
    • 1970-01-01
    • 1970-01-01
    • 2011-07-02
    • 2012-07-14
    • 2011-11-26
    • 2020-08-08
    • 2017-06-14
    相关资源
    最近更新 更多