如何在scikit数据集中组合数字和文本数据

时间:2017-11-06 22:59:07

标签: python scikit-learn

我有一些数据:

name    | cost
-----------------
milk    | 1.20
butter  | 3.50
eggs    |  .99

我希望能够通过名称和价格对这些进行分组(例如,"脱脂牛奶"与#34;全脂牛奶"以及五种2.99美元相关将使用SciKit的一个集群模块(如kmeans)进行评分。

我知道我必须把名字变成数字,这是我用HashingVectorizer做的,这给了我一个稀疏矩阵。但是,在那时,我不确定如何将其与成本列相结合。我已经看过的示例将HashingVectorizer的输出直接输入kmeans.fit

有人可以给(或指向我)使用文本数据+至少一个其他列的示例吗?

2 个答案:

答案 0 :(得分:2)

您可以使用' ItemSelector'如下面链接中的示例所示,为数据中的每一列提供不同的处理方法,然后使用sklearn的FeatureUnion将所有内容重新组合在一起。

我认为您所说的是您想要处理价格,就像它们是分类数据一样?我想说将数字转换为字符串然后使用CountVectorizer并将二进制标志设置为True。

这是一个非常有用的例子: http://scikit-learn.org/stable/auto_examples/hetero_feature_union.html#sphx-glr-auto-examples-hetero-feature-union-py

编辑:此外,计数向量化器将删除我认为的句点,所以最好在没有像这样的标记器的情况下调用它。在更少的线路中可能有更优雅的解决方案,但这也有效。

def no_tokenizer(t):
    return [t]

CountVectorizer(binary=False, tokenizer=no_tokenizer)

编辑:这是一个带ItemSelector的管道示例。我已经设置了一个pandas数据帧,我通过传递关键字来传递文本,数字数据。

class ItemSelector(BaseEstimator, TransformerMixin):
    def __init__(self, key, dt):
        self.key = key
        self.dt = dt

    def fit(self, x, y=None):
        # does nothing
        return self

    def transform(self, data_dict):
        # this returns the column requested
        print "Selecting",self.key
        if self.dt == 'text':
            return data_dict.loc[:,self.key]
        elif self.dt == 'num2text':
            return data_dict.loc[:,self.key].astype(unicode)
        elif self.dt == 'date':
            return (data_dict.loc[:,self.key].squeeze() - pd.Timestamp(1900,1,1)).dt.days.to_frame()
        else:
            return data_dict.loc[:,[self.key]].astype(float)

def preproc_pipeline():
    return FeatureUnion(
        transformer_list=[
            ('artist_name', Pipeline([
                ('selector', ItemSelector(key='artist_name', dt='text')),
                ('cv', CountVectorizer(binary=False),
            ])),
            ('composer', Pipeline([
                ('selector', ItemSelector(key='composer', dt='text')),
                ('cv', CountVectorizer(binary=False),
            ])),
            ('song_length', Pipeline([
                ('selector', ItemSelector(key='song_length', dt='num')),
            ])),
        ])

答案 1 :(得分:1)

熊猫

您可以使用one-hot编码。

import pandas as pd

# you can easily load the data using pd.read_csv()
# Or, if the data is in a numpy array, just use pd.Dataframe(data) and pass the appropriate column names to columns parameter as a list of strings

# For this example,
df = pd.DataFrame({'name':['milk', 'butter', 'eggs'],
              'cost':[10, 3.50, 0.99]}) 

print(df)

     name   cost
0    milk  10.00
1  butter   3.50
2    eggs   0.99

df=pd.get_dummies(data=df, columns=['name']) # indicates that we want to encode the name column
print(df)

    cost  name_butter  name_eggs  name_milk
0  10.00            0          0          1
1   3.50            1          0          0
2   0.99            0          1          0

您可以通过df.values

获取数据集
array([[ 10.  ,   0.  ,   0.  ,   1.  ],
   [  3.5 ,   1.  ,   0.  ,   0.  ],
   [  0.99,   0.  ,   1.  ,   0.  ]])