[英]Calculating TF-IDF from a Pandas DataFrame (without sklearn)
所以我有一个 Pandas DataFrame:这里
正如您所看到的,我已将其标记为使其更清晰(书名只是书名,数字是它们各自的频率)。
要计算 TF-IDF,我必须实现一个名为“choice”的 function,其签名如下:
def choice(term, documents):
其中“term”是 dataframe 中存在的任何有效词,“documents”是 pandas dataframe 本身。 function 计算 dataframe 中所有书籍的 TF-IDF(因此,行,因为每本书都是一个新行),然后返回具有最高 TF-IDF 值的书籍的名称,例如:
choice('the', mydataframe)
# output: pg16238.txt
我遇到的问题是我无法从 dataframe 中提取特定频率,因为已将索引从标准编号(0、1、2 等)重命名为书名,如您在呈现内置的“.str.contains”function 不知何故无用(它不起作用)。
我搜索了很多,发现它以某种方式变成了“多索引”dataframe? (我是初学者,所以我不知道如何解决这个问题)。
我遇到的另一个问题是计算完成后我不知道如何返回书名。 就像,我是否应该列出索引,然后创建一个看起来像这样的字典:
{'book-title': tf-idf-value}
然后返回最高值? 请帮助我找出解决此问题的适当方法。
我已经成功编写了一个有效的 IDF 计算 function:
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(术语)
注意:我提供的 DataFrame 屏幕截图只是完整 dataframe 的一部分。 此外,书名可能会有所不同,书籍的数量不仅是6本,而且可以是N本。 因此,我打算对 function 进行编码,它可以考虑上述条件。
编辑:如果我们使用 Pandas,我们可以创建 lambda function -
choice = lambda term, documents: documents[documents[term] == documents[term].max()].index[0]
输入:
choice('accept', documents=df)
Output:
'1661-0.txt'
***对于想要重新创建(上半部分)此示例的任何人:
import pandas as pd
index = ['11-0.txt','1342-0.txt','1661-0.txt','1952-0.txt','84-0.txt','pg16328.txt',]
cols = ['accept','acceptance','accepted','accepting','access','accessed']
df = pd.DataFrame(index=index, columns=cols)
### Un-comment to print formatted pairs
#for i in index:
#for j in cols:
#print(f'df.loc[\'{i}\', \'{j}\'] = ')
df.loc['11-0.txt', 'accept'] = 0.000034
df.loc['11-0.txt', 'acceptance'] = 0.000034
df.loc['11-0.txt', 'accepted'] = 0.000067
df.loc['11-0.txt', 'accepting'] = 0.000034
df.loc['11-0.txt', 'access'] = 0.000336
df.loc['11-0.txt', 'accessed'] = 0.000034
df.loc['1342-0.txt', 'accept'] = 0.000051
df.loc['1342-0.txt', 'acceptance'] = 0.000013
df.loc['1342-0.txt', 'accepted'] = 0.000026
df.loc['1342-0.txt', 'accepting'] = 0.000013
df.loc['1342-0.txt', 'access'] = 0.000153
df.loc['1342-0.txt', 'accessed'] = 0.000013
df.loc['1661-0.txt', 'accept']= 0.000144
df.loc['1661-0.txt', 'acceptance'] = 0.000032
df.loc['1661-0.txt', 'accepted'] =0.000144
df.loc['1661-0.txt', 'accepting'] = 0.000040
df.loc['1661-0.txt', 'access'] = 0.000080
df.loc['1661-0.txt', 'accessed'] = 0.000008
df.loc['1952-0.txt', 'accept'] = 0.000046
df.loc['1952-0.txt', 'acceptance'] = 0.000009
df.loc['1952-0.txt', 'accepted'] = 0.000037
df.loc['1952-0.txt', 'accepting'] = 0.000009
df.loc['1952-0.txt', 'access'] = 0.000092
df.loc['1952-0.txt', 'accessed'] = 0.000009
df.loc['84-0.txt', 'accept'] = 0.000109
df.loc['84-0.txt', 'accepted'] = 0.000218
df.loc['84-0.txt', 'accepting'] =0.000109
df.loc['84-0.txt', 'access'] = 0.001089
df.loc['84-0.txt', 'accessed'] = 0.000109
df.loc['pg16328.txt', 'accept'] = 0.000045
df.loc['pg16328.txt', 'accepted'] = 0.000361
df.loc['pg16328.txt', 'accepting'] =0.000090
df.loc['pg16328.txt', 'access'] = 0.000293
df.loc['pg16328.txt', 'accessed'] = 0.000023
我对您的实现做了一些修改,我假设您已经计算了 IDF DataFrame。 让我们创建一个虚拟的一些统一值:
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'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.