如何从sklearn输出中正确提取tf、tfidf的数值?
问题根因
你得到的数组仅包含0和1属于符合工具逻辑的输出,并非代码异常:你将原始行按weight重复得到df2后,sklearn的文本向量化工具默认将df2的每一行视为独立文档,你的每个url用\S+作为分词规则仅会分出1个token,所以单篇文档对应token的词频固定为1,其余位置为0,最终输出全为0/1。你出现预期不符的核心原因是统计粒度不匹配:你需要的是按原始url类别聚合后的全局统计值,而非单条重复行的统计值。
正确获取TF值的方案
核心逻辑是对相同url对应的所有行的计数结果做聚合,示例代码如下:
import pandas as pd import numpy as np from sklearn.feature_extraction.text import CountVectorizer # 你的原始数据构造逻辑 df = pd.DataFrame({"person":['A','B','C'],"url":["google.kr","stackoverflow.com","yahoo.us"],"weight":[5,10,15]}) df2 = df.loc[np.repeat(df.index.values,df.weight)] # 初始化计数向量化器 v_count = CountVectorizer(token_pattern='\S+') x_count = v_count.fit_transform(df2['url']) # 按url聚合得到总词频 tf_array = x_count[df2['url'] == df['url'][0]].sum(axis=0) for url in df['url'].unique()[1:]: tf_array = np.vstack([tf_array, x_count[df2['url'] == url].sum(axis=0)]) # 转换为带语义的DataFrame方便查看 tf_df = pd.DataFrame(tf_array, columns=v_count.get_feature_names_out(), index=df['person']) print(tf_df)
如果你的url分词后可能出现多个token,该方法同样适用。如果单url固定对应1个分词,你也可以直接用weight列作为对应token的TF值,无需构造重复的df2。
正确获取TF-IDF值的方案
首先需要注意:如果你预期IDF基于原始的3个独立url(3篇文档)计算,不要用重复后的df2拟合向量化器,否则文档总数会被识别为30,IDF计算结果不符合业务逻辑。正确实现代码如下:
from sklearn.feature_extraction.text import TfidfVectorizer # 用原始的3个url作为文档集拟合,得到正确的IDF值 v_tfidf = TfidfVectorizer(token_pattern='\S+', smooth_idf=False, norm=None) v_tfidf.fit(df['url']) idf_s = pd.Series(v_tfidf.idf_, index=v_tfidf.get_feature_names_out()) # 总TF * IDF得到最终TF-IDF值 tfidf_df = tf_df * idf_s print(tfidf_df)
如果你确实需要基于重复后的30篇文档计算IDF,只需将拟合输入改为df2['url']即可,其余逻辑不变。
内容的提问来源于stack exchange,提问作者Johnny
相关产品推荐
相关产品推荐

