从 Pandas DataFrame 计算 TF-IDF(不带 sklearn)



所以我有一个Pandas DataFrame: 这里

正如你所看到的,我给它贴上了标签,让它更清晰一点(书名只是书名,数字是它们各自的频率(。

要计算 TF-IDF,我必须实现一个名为"choice"的函数,其签名如下:

def choice(term, documents):

其中"term"是数据帧中存在的任何有效单词,"文档"是 pandas 数据帧本身。该函数计算数据帧中所有书籍的 TF-IDF(因此,行,因为每本书都是新行(,然后返回具有最高 TF-IDF 值的书籍的名称,如下所示:

choice('the', mydataframe)
# output: pg16238.txt

我遇到的问题是,由于将索引从标准编号(0、1、2 等(重命名为书名,我无法从数据帧中提取特定频率,如您在图像中看到的那样,该图像使内置的".str.contains"函数以某种方式无用(它不起作用(。

我搜索了很多关于它的信息,发现它以某种方式变成了一个"多索引"数据帧?(我是初学者,所以我对如何解决这个问题没有好主意(。

我遇到的另一个问题是,我不知道计算完成后如何返回书名。比如,我应该列出索引,然后创建一个字典,看起来像这样:

{'book-title': tf-idf-value}

然后返回最大值?请帮助我找出解决此问题的适当方法。

我已经成功地编写了一个有效的 IDF 计算函数:

def get_IDF(self, term):
N = 0
D = len(self.files_list)
for file in self.files_list:
with open(file, 'r', encoding='utf-8-sig', errors='replace') as f:
temp_cleaned_data = ''.join(i.lower() for i in f.read() if ord(i) < 128).translate(str.maketrans('', '', string.punctuation)).replace('n', ' ')
if self.contains_word(temp_cleaned_data, term):
N += 1
return 1 + (math.log(D / (1 + N)))

"files_list"是存储在当前目录中的文件列表。

另外,请原谅我糟糕的编码"temp_cleaned_data",我稍后会重构它,对此感到抱歉。(我知道使用".isalnum(("确实有更简单的方法可以做到这一点,但我也在尝试学习一些列表理解和函数式编程,所以我尝试了不同的东西并将其拼凑在一起看看它是如何工作的(。

无论如何,我真的很感激任何帮助来解决这个问题,谢谢。TF-IDF 的公式为:

术语

频率(术语( x IDF(术语(

注意:我提供的数据帧屏幕截图只是完整数据帧的一部分。此外,书名可能会有所不同,书籍的数量不仅仅是 6 本,而且数量可以是 N。因此,我打算编写可以考虑上述条件的函数。

我对你的实现做了一些修改,我假设你已经计算了 IDF 数据帧。让我们创建一个包含一些统一值的虚拟值:

IDF = pd.DataFrame([1.0/len(df.index)]*len(df.index), index = df.index)
print(IDF)

0
11-0.txt     0.166667
1342-0.txt   0.166667
1661-0.txt   0.166667
1952-0.txt   0.166667
84-0.txt     0.166667
pg16328.txt  0.166667

我还将您的df名称更改为TF

TF = df.copy()

def choice(term, TF, impute_val=0.000001):
TF = TF.fillna(impute_val)
# Based on the formula provided, calculate the TFIDF score for all documents of this term
tfidf_score = TF[term].values.ravel() * IDF.values.ravel()
doc_names = TF.index.tolist()
# sort by TFIDF score and return the doc name that has max tfidf value
return sorted(zip(doc_names,tfidf_score),key=lambda x: x[1])[-1][0]
print(choice(term='accept', TF=TF))
'1661-0.txt'

最新更新