【问题标题】:Python Access Labels of Sklearn CountVectorizerSklearn CountVectorizer 的 Python 访问标签
【发布时间】:2018-02-04 22:33:10
【问题描述】:

这是我清理后的df:

    number  summary             cleanSummary
0   1-123   he loves ice cream  love ice cream
1   1-234   she loves ice       love ice
2   1-345   i hate avocado      hate avocado
3   1-123   i like skim milk    like skim milk

如您所见,有两条记录具有相同的number。现在我将创建并拟合矢量化器。

cv = CountVectorizer(token_pattern=r"(?u)\b\w+\b", ngram_range=(1,1), analyzer='word')
cv.fit(df['cleanSummary'])

现在我要变身了。

freq = cv.transform(df['cleanSummary'])

现在如果我看看freq...

freq = sum(freq).toarray()[0]
freq = pd.DataFrame(freq, columns=['frequency'])
freq

    frequency
0   1
1   1
2   1
3   2
4   1
5   2
6   1
7   1

...似乎没有一种合乎逻辑的方式来访问原始number。我已经尝试过遍历每一行的方法,但这会遇到问题,因为每个number 可能会有多个摘要。使用分组 df 的循环...

def extractFeatures(groupedDF, textCol):
    features = pd.DataFrame()
    for id, group in groupedDF:
           freq = cv.transform(group[textCol])
           freq = sum(freq).toarray()[0]
           freq = pd.DataFrame(freq, columns=['frequency'])
           dfinner = pd.DataFrame(cv.get_feature_names(), columns=['ngram'])
           dfinner['number'] = id
           dfinner = dfinner.join(freq)
           features = features.append(dfinner)
    return features

...有效,但性能很糟糕(即 12 小时来运行 45,000 个单句长度的文档)。

如果我改变了

freq = sum(freq).toarray()[0]

freq = freq.toarray()

我得到每个文档的每个 ngram 的频率数组。这很好,但是它不允许我将该列表数组推送到数据框中。而且我仍然无法访问nunmber

如何在不循环分组 df 的情况下访问每个 ngram 的原始标签 number?我想要的结果是:

number    ngram    frequency
1-123     love     1
1-123     ice      1
1-123     cream    1
1-234     love     1
1-234     ice      1
1-345     hate     1 
1-345     avocado  1
1-123     like     1  
1-123     skim     1 
1-123     milk     1

编辑:这是对这个问题的重新审视:Convert CountVectorizer and TfidfTransformer Sparse Matrices into Separate Pandas Dataframe Rows。但是,在实施该答案中描述的方法后,我面临大型语料库的内存问题,因此它似乎不可扩展。

【问题讨论】:

  • 为什么投反对票?我提供了一个清晰的例子和问题。
  • 所以你使用的是 scikit-learn 的简历?
  • 是的,没错

标签: python python-3.x pandas scikit-learn countvectorizer


【解决方案1】:
freq = cv.fit_transform(df.cleanSummary)
dtm = pd.DataFrame(freq.toarray(), columns=cv.get_feature_names(), index=df.number).stack()
dtm[dtm > 0]

number         
1-123   cream      1
        ice        1
        love       1
1-234   ice        1
        love       1
1-345   avocado    1
        hate       1
1-123   like       1
        milk       1
        skim       1
dtype: int64

【讨论】:

  • 这仍然会导致性能问题(即内存不足)。不过,谢谢!
  • 不客气!很遗憾听到您的内存不足。这是否回答了您的问题,How do I access the original labels number for each ngram without looping over a grouped df??根据您的计算设置和语料库大小,即使仅使用本机 Pandas 和 Sci-kit 方法,性能也可能是一个问题,就像这个答案一样。您可以尝试分解组件并进行基准测试以查看瓶颈在哪里。
  • 确实如此,谢谢 - 刚刚接受!我通过将稀疏矩阵从fit_transform 转换为tocooscipy 来解决内存问题。然后就加入到原来的 df 来获取标签。
猜你喜欢
  • 2018-03-20
  • 1970-01-01
  • 2017-03-10
  • 2021-07-17
  • 1970-01-01
  • 2015-08-25
  • 2018-05-05
  • 2016-02-07
  • 1970-01-01
相关资源
最近更新 更多