Python:在scikitlearn中如何正确处理pandas数据框中的NaN

2024-10-02 00:41:31 发布

您现在位置:Python中文网/ 问答频道 /正文

这与我发布的here问题有关,但这个问题更具体、更简单。在

我有一个pandas数据帧,它的索引是唯一的用户标识符,列对应于唯一事件,值为1(已出席)、0(未出席)或NaN(未邀请/不相关)。关于NaNs,矩阵是相当稀疏的:有几百个事件,大多数用户最多只邀请了几十个。在

我创建了一些额外的专栏来衡量“成功”的程度,我将其定义为相对于邀请的出席率仅为%

my_data['invited'] = my_data.count(axis=1)
my_data['attended'] = my_data.sum(axis=1)-my_data['invited']
my_data['success'] = my_data['attended']/my_data['invited']

我现在的目标是在事件/列上进行特性选择,从最基本的基于方差的方法开始:删除方差较小的那些。然后我会看一个关于事件的线性回归,只保留那些有大系数和小p值的事件。在

但我的问题是我有太多的NaN,我不确定如何正确地处理它们,因为大多数scikit-learn方法都会因为它们而出错。一个想法是用-1替换“did not attended”,将“not invested”替换为0,但我担心这会改变事件的重要性。在

有人能提出正确的方法来处理所有这些NaN而不改变每个特征/事件的统计意义吗?在

编辑:我想补充的是,如果有一个合理的指标可以让我继续进行功能选择,我很乐意从上面更改我的“成功”指标。我只是想确定哪些事件可以有效地捕捉用户的兴趣。它的开放性很强,这主要是一个练习功能选择的练习。在

谢谢你!在


Tags: 方法用户功能pandasdataheremy事件
1条回答
网友
1楼 · 发布于 2024-10-02 00:41:31

如果我理解正确的话,您希望在不显著改变NaN的统计属性的情况下从NaN中清除您的数据,这样您就可以在后面运行一些分析。在

我最近也遇到过类似的情况,你可能会感兴趣的一个简单方法是使用sklearn的“Imputer”。正如EdChum之前提到的,一个想法是用轴上的平均值代替。其他选项包括替换为中值。在

比如:

from sklearn.preprocessing import Imputer
imp = Imputer(missing_values='NaN', strategy='mean', axis=1)
cleaned_data = imp.fit_transform(original_data)

在本例中,这将用每个轴上的平均值替换NaN(例如,让我们通过事件进行插补,因此轴=1)。然后,可以对清理后的数据进行四舍五入,以确保得到0和1

我将按事件为数据绘制一些直方图,以检查这种预处理是否会显著地改变您的分布-因为我们可能会引入太多的偏差,因为沿每个轴将如此多的值交换为平均值/模式/中值。在

参考链接:http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.Imputer.html

再进一步(假设以上还不够),您可以交替执行以下操作:

  • 取数据中的每个事件列,在去掉所有nan数字后,计算参加(“p”)与不参加(“1-p”)的概率。[即p=出席/(出席+不出席)]
  • 然后,使用伯努利分布生成的随机数替换每个事件列中的NaN数,我们将其与您估计的“p”相符,大致如下:

    import numpy as np

    n = 1 # number of trials

    p = 0.25 # estimated probability of each trial (i.e. replace with what you get for attended / total)

    s = np.random.binomial(n, p, 1000)

    # s now contains random a bunch of 1's and 0's you can replace your NaN values on each column with

再说一遍,这本身并不是完美的,如果你最终还是会稍微偏向你的数据(例如,一个更准确的方法是考虑每个用户的事件之间的数据依赖性),但是通过从大致匹配的分布中抽样,这至少比用平均值替换更可靠

希望这有帮助!在

相关问题 更多 >

    热门问题