如何在 scikit learn 中矢量化具有多个文本列的数据框而不会丢失对原始列的跟踪

Eri*_*c L 3 python numpy machine-learning pandas scikit-learn

我有几个 Pandas 数据系列,想训练这些数据映射到输出 df["output"]。

到目前为止,我已将系列合并为一个,并用逗号分隔每个系列。

df = pd.read_csv("sourcedata.csv")
sample = df["catA"] + "," + df["catB"] + "," + df["catC"]

def my_tokenizer(s):
    return s.split(",")

vect = CountVectorizer()
vect = CountVectorizer(analyzer='word',tokenizer=my_tokenizer, ngram_range=(1, 3), min_df=1) 
train = vect.fit_transform(sample.values)

lf = LogisticRegression()
lfit = lf.fit(train, df["output"])
pred = lambda x: lfit.predict_proba(vect.transform([x]))
Run Code Online (Sandbox Code Playgroud)

问题是这是一个词袋方法,没有考虑
- 每个类别中的唯一顺序。(“橙香蕉”与“香蕉橙”不同)
-文本是一个类别的含义与另一个类别不同(一个类别中的“美国”可能意味着原产国与目的地国家/地区)

例如,整个字符串可以是:
pred("US, Chiquita Banana, China")
A 类:原产国
B 类:公司和水果类型(订单很重要)
C 类:目的地

我目前的做法是忽略任何类型的排序,并且出于某种原因还在我的功能名称中生成了额外的空格(这会使事情更加混乱):

In [1242]: vect.get_feature_names()[0:10]
Out[1242]:
[u'',
 u' ',
 u'  ',
 u'   ',
 u'    ',
 u'     ',
 u'   US',
 u'   CA',
 u'   UK']
Run Code Online (Sandbox Code Playgroud)

欢迎任何建议!!非常感谢

max*_*moo 5

好的,首先让我们通过选择相关列并使用strip以下命令删除前导和尾随空格来准备您的数据集:

sample = df[['catA','catB','catC']]
sample = df.apply(lambda col: col.str.strip())
Run Code Online (Sandbox Code Playgroud)

从这里开始,您有几个选项可用于如何将其矢量化以用于训练集。如果您的所有特征的级别数量很少(比如总共少于 1000 个),您可以简单地将它们视为分类变量并设置train = pd.get_dummies(sample)为将它们转换为二元指标变量。在此之后,您的数据将如下所示:

catA_US   catA_CA ... cat_B_chiquita_banana   cat_B_morningstar_tomato ... catC_China ...
1         0           1                       0                            1   
...
Run Code Online (Sandbox Code Playgroud)

请注意,变量名称以其原点列开头,因此这可确保模型知道它们来自何处。此外,您使用的是精确字符串,因此将保留第二列中的词序。

如果您有太多级别无法执行此操作,或者您想考虑 incatB以及 bigrams 中的单个单词,您可以将您的CountVectorizer单独应用于每一列,然后使用 和hstack连接生成的输出矩阵:

import scipy.sparse as sp
vect = CountVectorizer(ngram_range=(1, 3))
train = sp.hstack(sample.apply(lambda col: vect.fit_transform(col)))
Run Code Online (Sandbox Code Playgroud)