- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
问题:将 sklearn 的 CountVectorizer 和 TfidfTransformer 生成的稀疏矩阵转换为 Pandas DataFrame 列的最佳方法是什么,每个二元组及其对应的频率和 tf-idf 分数单独一行?
管道:从 SQL 数据库中引入文本数据,将文本拆分为双字母组并计算每个文档的频率和每个文档每个双字母组的 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
此 DataFrame 被输入到 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)
然后将矩阵转化为数组后反馈到原始DataFrame中:
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
但是,我不确定如何对两个数字列执行此操作,而且这不会引入双字母组(特征名称)本身。此外,此方法需要一个数组(这就是为什么我首先将稀疏矩阵转换为数组的原因),并且由于性能问题以及我随后必须去除无意义的行的事实,我想尽可能避免这种情况.
非常感谢任何见解!非常感谢您花时间阅读这个问题 - 对于长度,我深表歉意。如果我可以做些什么来改进问题或澄清我的流程,请告诉我。
最佳答案
可以使用 CountVectorizer
的 get_feature_names()
捕获二元组名称.从那里它只是一系列 melt
和 merge
操作:
print(data)
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
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
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)
在这种情况下,CountVectorizer
特征名称是双字母组:
print(cv.get_feature_names())
[u'catches tuna',
u'farmer plants',
u'farmer son',
u'fisher catches',
u'go fishing',
u'plants grain',
u'son go']
CountVectorizer.fit_transform()
返回一个稀疏矩阵。我们可以将其转换为密集表示,将其包装在 DataFrame
中,然后将特征名称添加为列:
bigrams = pd.DataFrame(dt_mat.todense(), index=data.index, columns=cv.get_feature_names())
bigrams['number'] = data.number
print(bigrams)
catches tuna farmer plants farmer son fisher catches go fishing \
0 0 1 0 0 0
1 0 0 1 0 1
2 1 0 0 1 0
plants grain son go number
0 1 0 123
1 0 1 234
2 0 0 345
要从宽格式转换为长格式,请使用 melt()
.
然后将结果限制为二元匹配(query()
在这里很有用):
bigrams_long = (pd.melt(bigrams.reset_index(),
id_vars=['index','number'],
value_name='bigram_ct')
.query('bigram_ct > 0')
.sort_values(['index','number']))
index number variable bigram_ct
3 0 123 farmer plants 1
15 0 123 plants grain 1
7 1 234 farmer son 1
13 1 234 go fishing 1
19 1 234 son go 1
2 2 345 catches tuna 1
11 2 345 fisher catches 1
现在为 tfidf
重复这个过程:
tfidf = pd.DataFrame(tfidf_mat.todense(), index=data.index, columns=cv.get_feature_names())
tfidf['number'] = data.number
tfidf_long = pd.melt(tfidf.reset_index(),
id_vars=['index','number'],
value_name='tfidf').query('tfidf > 0')
最后,合并bigrams
和tfidf
:
fulldf = (bigrams_long.merge(tfidf_long,
on=['index','number','variable'])
.set_index('index'))
number variable bigram_ct tfidf
index
0 123 farmer plants 1 0.707107
0 123 plants grain 1 0.707107
1 234 farmer son 1 0.577350
1 234 go fishing 1 0.577350
1 234 son go 1 0.577350
2 345 catches tuna 1 0.707107
2 345 fisher catches 1 0.707107
关于python - 将 CountVectorizer 和 TfidfTransformer 稀疏矩阵转换为单独的 Pandas Dataframe 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43957663/
最近,我开始阅读更多有关 NLP 的内容,并遵循 Python 教程,以进一步了解该主题。在学习其中一个教程时,我观察到他们在每条推文中使用字数统计的稀疏矩阵(使用 CountVectorizer 创
我对 Tfidftransformer 和 Tfidfvectorizer 的使用感到有点困惑,因为它们看起来很相似。一个使用单词将矩阵转换 (Tfidfvectorizer),另一个使用已经转换的文
我对 Tfidftransformer 和 Tfidfvectorizer 的使用感到有点困惑,因为它们看起来很相似。一个使用单词将矩阵转换 (Tfidfvectorizer),另一个使用已经转换的文
下面的代码片段显示了在 scikit-learn 中基于 TF-IDF 的评分测试文档。 如何获得 x_test_tfidf 中每一行的前 5 个词汇元素及其分数? 我知道 count_vect.ge
我正在 sklearn 中处理大量文本数据。首先,我需要向量化文本上下文(字数),然后执行 TfidfTransformer。我有以下代码似乎没有将 CountVectorizer 的输出带到 Tfi
我正在使用 Python 2.7 中 sklearn 包中的 TfidfTransformer。 当我对这些论点感到满意时,我对 use_idf 变得有点困惑,如: TfidfVectorizer(u
我想了解是否可以使用 HashingVectorizer 和 TfidfTransformer 训练在线 SGDClassifier(使用 partial_fit)。简单地将它们加入管道是行不通的,因
问题:将 sklearn 的 CountVectorizer 和 TfidfTransformer 生成的稀疏矩阵转换为 Pandas DataFrame 列的最佳方法是什么,每个二元组及其对应的频率
下面是分类器的一些代码。我使用pickle来保存和加载这个page中指示的分类器.但是,当我加载它使用它时,我无法使用CountVectorizer()和 TfidfTransformer()将原始文
仅使用以下每个功能模板来实现CountVectorizer 和 TfIdTransformer。我有训练、开发、测试数据。 这是我的示例列车数据: Train_dataset = ['This is
我是一名优秀的程序员,十分优秀!