编程语言
首页 > 编程语言> > Python:如何正确处理熊猫DataFrame中的NaN,以在Scikit-learn中进行功能选择

Python:如何正确处理熊猫DataFrame中的NaN,以在Scikit-learn中进行功能选择

作者:互联网

这与我发布的here问题有关,但是这个问题更具体,更简单.

我有一个pandas DataFrame,其索引是唯一的用户标识符,列对应于唯一的事件,并且值1(有人值守),0(未出席)或NaN(未邀请/不相关).相对于NaN,矩阵非常稀疏:有数百个事件,大多数用户最多只被邀请参加几十个事件.

我创建了一些额外的列来衡量“成功”,我将其定义为相对于邀请仅出席的百分比:

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”代替“不参加”,用“ 0”代替“未邀请”,但我担心这会改变事件的重要性.

谁能在不改变每个功能/事件统计显着性的情况下,提出处理所有这些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(例如,让我们根据事件进行估算,使axis = 1).然后,您可以对清除的数据进行四舍五入,以确保得到0和1.

我将通过事件为数据绘制一些直方图,以理智地检查这种预处理是否会显着改变您的分布-因为我们可能会通过沿每个轴将这么多的值交换为均值/众数/众数/中位数来引入过多的偏差.

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

再往前走一步(假设以上内容还不够),您可以选择执行以下操作:

>删除所有nan数后,获取数据中的每个事件列,并计算出参加(‘p’)与未参加(‘1- p’)的概率. [即p =参加/(未参加)
>然后,使用从伯努利分布生成的随机数替换每个事件列上的NaN数,我们将其与您估计的’p’相匹配,大致类似于:

将numpy导入为np

n = 1#次试验

p = 0.25#每次审判的估计概率(即替换为您获得的出席/总数)

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

#s现在随机包含一堆1和0,您可以将每列的NaN值替换为

再说一次,这本身并不完美,因为您仍将最终稍微偏向数据(例如,更准确的方法是考虑每个用户事件之间数据的依存关系),而是通过大致匹配来采样分布至少比用平均值等任意替换更健壮.

希望这可以帮助!

标签:pandas,scikit-learn,feature-selection,python
来源: https://codeday.me/bug/20191120/2045172.html