问题: 什么是将从sklearn的CountVectorizer和TfidfTransformer得出的稀疏矩阵转换为Pandas DataFrame列的最佳方法,每个bigram及其相应的频率和tf-idf得分都有单独的行?
流程: 从SQL数据库中获取文本数据,将文本拆分成bigrams并计算每个文档的频率和每个bigram在每个文档中的tf-idf,然后将结果加载回SQL数据库。
当前状态:
带入两列数据(number
,text
)。通过清理text
来产生第三列cleanText
:
number text cleanText
0 123 The farmer plants grain farmer plants grain
1 234 The farmer and his son go fishing farmer son go fishing
2 345 The fisher catches tuna fisher catches tuna
这个数据框被输入到sklearn的特征提取器:
cv = CountVectorizer(token_pattern=r"(?u)\b\w+\b", stop_words=None, ngram_range=(2,2), analyzer='word')
dt_mat = cv.fit_transform(data.cleanText)
tfidf_transformer = TfidfTransformer()
tfidf_mat = tfidf_transformer.fit_transform(dt_mat)
然后将这些矩阵反馈到原始的数据框中,并在转换为数组后再进行操作:
data['frequency'] = list(dt_mat.toarray())
data['tfidf_score']=list(tfidf_mat.toarray())
输出:
number text cleanText \
0 123 The farmer plants grain farmer plants grain
1 234 The farmer and his son go fishing farmer son go fishing
2 345 The fisher catches tuna fisher catches tuna
frequency tfidf_score
0 [0, 1, 0, 0, 0, 1, 0] [0.0, 0.707106781187, 0.0, 0.0, 0.0, 0.7071067...
1 [0, 0, 1, 0, 1, 0, 1] [0.0, 0.0, 0.57735026919, 0.0, 0.57735026919, ...
2 [1, 0, 0, 1, 0, 0, 0] [0.707106781187, 0.0, 0.0, 0.707106781187, 0.0...
问题:
- 特征名称(即二元语法)不在数据框中
frequency
和tfidf_score
没有分别列出每个二元语法的行
期望输出:
number bigram frequency tfidf_score
0 123 farmer plants 1 0.70
0 123 plants grain 1 0.56
1 234 farmer son 1 0.72
1 234 son go 1 0.63
1 234 go fishing 1 0.34
2 345 fisher catches 1 0.43
2 345 catches tuna 1 0.43
我使用以下代码将一个数字列分配到DataFrame的不同行:
data.reset_index(inplace=True)
rows = []
_ = data.apply(lambda row: [rows.append([row['number'], nn])
for nn in row.tfidf_score], axis=1)
df_new = pd.DataFrame(rows, columns=['number', 'tfidf_score'])
输出:
number tfidf_score
0 123 0.000000
1 123 0.707107
2 123 0.000000
3 123 0.000000
4 123 0.000000
5 123 0.707107
6 123 0.000000
7 234 0.000000
8 234 0.000000
9 234 0.577350
10 234 0.000000
11 234 0.577350
12 234 0.000000
13 234 0.577350
14 345 0.707107
15 345 0.000000
16 345 0.000000
17 345 0.707107
18 345 0.000000
19 345 0.000000
20 345 0.000000
然而,我不确定如何针对两个数字列执行此操作,并且这不会涉及到 bigram(特征名称)本身。此外,此方法需要一个数组(这就是我在第一次将稀疏矩阵转换为数组时的原因),如果可能的话,我希望避免使用此方法,因为它会存在性能问题,而且我还需要去除无意义的行。
非常感谢您抽出时间来阅读此问题并提供任何见解!如果有任何改进此问题或澄清我的过程的方法,请告诉我。
number
和bigrams
在您的示例中具有相同的索引 -bigrams
中的每一行不是一个bigram实例,而是指向data
中的一行。这就是为什么我们可以直接添加data.number
的原因。只有在从宽格式转换为长格式时,行才会从text
变为text
-bigram
对。您能否确认我的答案在您发布的3行示例数据上有效?如果存在边缘情况或异常情况(例如缺少值),请更新您的帖子以包含演示您所看到的问题的代表性样本数据集。 - andrew_reecepd.DataFrame(dt_mat.todense(), ...)
和tfidf_mat
时,我会添加index=df.index
。 - MaxU - stand with Ukraine