给出以下代码:
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
import urllib.request # the lib that handles the url stuff
from bs4 import BeautifulSoup
import unicodedata
def remove_control_characters(s):
base = ""
for ch in s:
if unicodedata.category(ch)[0]!="C":
base = base + ch.lower()
else:
base = base + " "
return base
moby_dick_url='http://www.gutenberg.org/files/2701/2701-0.txt'
soul_of_japan = 'http://www.gutenberg.org/files/12096/12096-0.txt'
def extract_body(url):
with urllib.request.urlopen(url) as s:
data = BeautifulSoup(s).body()[0].string
stripped = remove_control_characters(data)
return stripped
moby = extract_body(moby_dick_url)
bushido = extract_body(soul_of_japan)
corpus = [moby,bushido]
vectorizer = TfidfVectorizer(use_idf=False, smooth_idf=True)
tf_idf = vectorizer.fit_transform(corpus)
df_tfidf = pd.DataFrame(tf_idf.toarray(), columns=vectorizer.get_feature_names(), index=["Moby", "Bushido"])
df_tfidf[["the", "whale"]]
我希望“鲸鱼”在“白鲸记”中获得较高的tf-idf,而在“武士道:日本的灵魂”中得分较低,而“ the”在两者中得分都较低。但是,我却相反。计算结果为:
| | the | whale |
|-------|-----------|----------|
|Moby | 0.707171 | 0.083146 |
|Bushido| 0.650069 | 0.000000 |
这对我来说毫无意义。有人能指出我在思考或编码时所犯的错误吗?
最佳答案
您观察此有两个原因。
首先是由于您传递给Tfidf Vectorizer的参数。您应该执行TfidfVectorizer(use_idf=True, ...)
,因为它是tfidf的idf部分(请记住tf-idf是词频和反向文档频率的乘积),将惩罚所有文档中出现的单词。通过设置 TfidfVectorizer(use_idf=False, ..)
,您只是在考虑词频部分,这显然会导致停用词的得分更高
第二是因为您的数据。假设您解决了上面的代码问题,您的语料库仍然很小,只有两个文档。这意味着两本书中出现的任何单词都会以相同的方式受到惩罚。 “勇气”可能会像“ the”一样出现在两本书中,因此鉴于它们都出现在语料库的每个文档中,因此它们的idf值将相同,从而由于停用词的用语较大,因此停用词的得分也再次增加-频率
关于python - TfidfVectorizer赋予高权重停用词,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59845939/