【问题标题】:How to combine numeric and text data in a scikit dataset如何在 scikit 数据集中组合数字和文本数据
【发布时间】:2017-11-08 01:03:11
【问题描述】:

我有一些数据,例如:

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

我希望能够使用 SciKit 的一个聚类模块按名称和价格对它们进行分组(例如,“脱脂牛奶”与“全脂牛奶”相关,而 2.99 美元的五种东西将被评为相似) ,比如kmeans

我知道我必须将名称转换为数字,我正在使用HashingVectorizer 进行此操作,这给了我一个稀疏矩阵。但是,那时,我不确定如何将其与成本列结合起来。我见过的示例采用 HashingVectorizer 的输出并将其直接输入kmeans.fit

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

【问题讨论】:

    标签: python scikit-learn


    【解决方案1】:

    您可以使用以下链接中的示例中的“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')),
                ])),
            ])
    

    【讨论】:

      【解决方案2】:

      熊猫

      你可以使用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.  ]])
      

      【讨论】:

      • 此答案不包括问题中要求的 CountVectorizer。
      猜你喜欢
      • 1970-01-01
      • 2014-04-20
      • 2016-11-01
      • 1970-01-01
      • 2019-03-25
      • 1970-01-01
      • 2021-07-21
      • 2012-07-27
      • 1970-01-01
      相关资源
      最近更新 更多