给出以下代码:

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/

10-12 17:53