为sklearn

时间:2017-01-31 09:57:41

标签: python pandas scikit-learn

由于这是一个复杂的问题(至少对我而言),我会尽量保持这个简短。

我的数据格式为

import pandas as pd
import numpy as np
# edit: a1 and a2 are linked as they are part of the same object
a1 = np.array([[1, 2, 3], [4, 5], [7, 8, 9, 10]])
a2 = np.array([[5, 6, 5], [2, 3], [3, 4, 8, 1]])

b = np.array([6, 15, 24])
y = np.array([0, 1, 1])

df = pd.DataFrame(dict(a1=a1.tolist(),a2=a2.tolist(), b=b, y=y))  


                  a1            a2   b  y
0      [1, 2, 3]     [5, 6, 5]   6  0
1         [4, 5]        [2, 3]  15  1
2  [7, 8, 9, 10]  [3, 4, 8, 1]  24  1

我想在sklearn中用于分类,例如

from sklearn import tree
X = df[['a1', 'a2', 'b']]
Y = df['y']
clf = tree.DecisionTreeClassifier()
clf = clf.fit(X, Y)
print(clf.predict([[2., 2.]]))

然而,虽然pandas可以将列表作为条目处理,但sklearn在设计上却不能。在此示例中,clf.fit将生成ValueError: setting an array element with a sequence.,您可以在其中找到大量答案。

但您如何处理此类数据?

我尝试将数据拆分为多个列(即a1[0] ... a1[3] - 代码有点冗长),但a1[3]为空(NaN,{{1}或者你想到的任何无效值)。这里的估算没有意义,因为没有价值在那里。

当然,这样的程序会对分类结果产生影响,因为算法可能会将“零”值视为有意义的

如果数据集足够大,我想,可能值得将它分成相同长度的0。但是这个过程会降低分类算法的功能,因为a1的长度可能有助于区分类。

我还考虑过将a1用于支持(例如Perceptron)的算法,并将其与按warm start长度分割的数据相匹配。但这肯定会失败,不是吗?数据集将具有不同数量的特征,因此我认为会出现问题。

这个问题的解决方案肯定必须存在,而我在文档中找不到合适的位置。

2 个答案:

答案 0 :(得分:0)

让我们假设这些数字是数字类别。 您可以做的是将列'a'转换为一组二进制列,其中每列对应于'a'的可能值。

采用您的示例代码,我们会:

import pandas as pd
import numpy as np

a = np.array([[1, 2, 3], [4, 5], [7, 8, 9, 10]])
b = np.array([6, 15, 24])
y = np.array([0, 1, 1])

df = pd.DataFrame(dict(a=a.tolist(),b=b,y=y))

from sklearn.preprocessing import MultiLabelBinarizer
MLB = MultiLabelBinarizer()
df_2 = pd.DataFrame(MLB.fit_transform(df['a']), columns=MLB.classes_)
df_2

    1   2   3   4   5   7   8   9   10
0   1   1   1   0   0   0   0   0   0
1   0   0   0   1   1   0   0   0   0
2   0   0   0   0   0   1   1   1   1

然后,我们可以连接旧数据和新数据:

new_df = pd.concat([df_2, df.drop('a',1)],1)

    1   2   3   4   5   7   8   9   10  b   y
0   1   1   1   0   0   0   0   0   0   6   0
1   0   0   0   1   1   0   0   0   0   15  1
2   0   0   0   0   0   1   1   1   1   24  1

请注意,如果你有训练和测试集,那么首先连接em,进行转换,然后将它们分开是明智的。那是因为其中一个数据集可以包含不属于另一个的术语。

希望有所帮助

编辑:

如果您担心可能会使您的df太大,那么将PCA应用于二值化变量是完全可以的。它将减少基数,同时保持任意数量的方差/相关性。

答案 1 :(得分:0)

Sklearn喜欢二维数组中的数据,即形状(batch_size,要素) 最简单的解决方案是通过使用numpy.concatenate连接数组来准备一个特征向量。将此特征向量传递给sklearn。由于每列的长度是固定的,因此应该可以使用。