gpt4 book ai didi

python - NaN 设置为 -1 时缩放功能的影响

转载 作者:行者123 更新时间:2023-12-01 09:19:37 27 4
gpt4 key购买 nike

我有一个数据集,其中包含一些具有大量 NaN(高达 80%)的特征。删除它们会扭曲我的整体分布,因此我的选择是将所有 NaN 设置为 -1/-99 或将我的连续变量分组,使其成为分类特征。

由于我已经拥有许多分类特征,因此我不想将少数连续特征也分类。但是,如果我将 NaN 设置为 -1/-99,当我缩放这些特征时,这会显着影响结果吗?

或者从不同的角度来看,是否有一种方法可以在不让 -1 对其缩放影响太大的情况下缩放特征?

最佳答案

我知道您从上面的评论中得到了答案,但为了向新的 scikit-learn 用户展示如何解决这样的问题,我整理了一个非常基本的解决方案,演示如何构建一个可以处理这个问题的自定义变压器:

from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.utils.validation import check_array, check_is_fitted
import numpy as np

class NanImputeScaler(BaseEstimator, TransformerMixin):
"""Scale an array with missing values, then impute them
with a dummy value. This prevents the imputed value from impacting
the mean/standard deviation computation during scaling.

Parameters
----------
with_mean : bool, optional (default=True)
Whether to center the variables.

with_std : bool, optional (default=True)
Whether to divide by the standard deviation.

nan_level : int or float, optional (default=-99.)
The value to impute over NaN values after scaling the other features.
"""
def __init__(self, with_mean=True, with_std=True, nan_level=-99.):
self.with_mean = with_mean
self.with_std = with_std
self.nan_level = nan_level

def fit(self, X, y=None):
# Check the input array, but don't force everything to be finite.
# This also ensures the array is 2D
X = check_array(X, force_all_finite=False, ensure_2d=True)

# compute the statistics on the data irrespective of NaN values
self.means_ = np.nanmean(X, axis=0)
self.std_ = np.nanstd(X, axis=0)
return self

def transform(self, X):
# Check that we have already fit this transformer
check_is_fitted(self, "means_")

# get a copy of X so we can change it in place
X = check_array(X, force_all_finite=False, ensure_2d=True)

# center if needed
if self.with_mean:
X -= self.means_
# scale if needed
if self.with_std:
X /= self.std_

# now fill in the missing values
X[np.isnan(X)] = self.nan_level
return X

其工作方式是通过计算 nanmeannanstdfit 部分中,以便在计算统计数据时忽略 NaN 值。然后,在 transform 部分中,在对变量进行缩放和居中后,剩余的 NaN 值将使用您指定的值进行估算(您提到了 -99,所以这就是我默认的值)。您始终可以将变压器的该组件分解为另一个变压器,但我将其包含在内只是为了演示目的。

实际示例:

在这里,我们将设置一些存在 NaN 的数据:

nan = np.nan
data = np.array([
[ 1., nan, 3.],
[ 2., 3., nan],
[nan, 4., 5.],
[ 4., 5., 6.]
])

当我们拟合缩放器并检查平均值/标准差时,您可以看到它们没有考虑 NaN 值:

>>> imputer = NanImputeScaler().fit(data)
>>> imputer.means_
array([ 2.33333333, 4. , 4.66666667])
>>> imputer.std_
array([ 1.24721913, 0.81649658, 1.24721913])

最后,当我们转换数据时,数据会被缩放并处理 NaN 值:

>>> imputer.transform(data)
array([[ -1.06904497, -99. , -1.33630621],
[ -0.26726124, -1.22474487, -99. ],
[-99. , 0. , 0.26726124],
[ 1.33630621, 1.22474487, 1.06904497]])

流水​​线

您甚至可以在 scikit-learn 管道内使用此模式(甚至将其保存到磁盘):

from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
pipe = Pipeline([
("scale", NanImputeScaler()),
("clf", LogisticRegression())
]).fit(data, y)

关于python - NaN 设置为 -1 时缩放功能的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50910867/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com