Я пытаюсь воспроизвести пример TFIDF из этого видео: Использование TF-IDF для преобразования неструктурированного текста в полезные функции
Насколько я могу судить, код такой же, как в примере, за исключением того, что я использую .items (python 3) вместо .iteritems (python 2):
docA = "the cat sat on my face"
docB = "the dog sat on my bed"
bowA = docA.split(" ")
bowB = docB.split(" ")
wordSet= set(bowA).union(set(bowB))
wordDictA = dict.fromkeys(wordSet, 0)
wordDictB = dict.fromkeys(wordSet, 0)
for word in bowA:
wordDictA[word]+=1
for word in bowB:
wordDictB[word]+=1
import pandas as pd
bag = pd.DataFrame([wordDictA, wordDictB])
print(bag)
def computeTF(wordDict,bow):
tfDict = {}
bowCount = len(bow)
for word, count in wordDict.items():
tfDict[word] = count / float(bowCount)
return tfDict
tfBowA = computeTF(wordDictA, bowA)
tfBowB = computeTF(wordDictB, bowB)
def computeIDF(docList):
import math
idfDict = {}
N = len(docList)
#Count N of docs that contain word w
idfDict = dict.fromkeys(docList[0].keys(),0)
for doc in docList:
for word, val in doc.items():
if val > 0:
idfDict[word] +=1
for word, val in idfDict.items():
idfDict[word] = math.log(N/ float(val))
return idfDict
idfs = computeIDF([wordDictA, wordDictB])
def computeTFIDF(tfBow,idfs):
tfidf = {}
for word, val in tfBow.items():
tfidf[word] = val * idfs[word]
return tfidf
tfidfBowA = computeTF(tfBowA, idfs)
tfidfBowB = computeTF(tfBowB, idfs)
TF = pd.DataFrame([tfidfBowA, tfidfBowB])
print(TF)
Полученная таблица должна выглядеть примерно так: обычные слова (on, my, sat, the) имеют оценку 0:
bed cat dog face my on sat the
0 0.000000 0.115525 0.000000 0.115525 0.000000 0.000000 0.000000 0.000000
1 0.115525 0.000000 0.115525 0.000000 0.000000 0.000000 0.000000 0.000000
Но вместо этого мой итоговый фрейм данных выглядит следующим образом: все слова имеют одинаковую оценку, кроме тех, которые встречаются в одном из документов (bed \ dog, cat \ face):
bed cat dog face my on sat the
0 0.000000 0.020833 0.000000 0.020833 0.020833 0.020833 0.020833 0.020833
1 0.020833 0.000000 0.020833 0.000000 0.020833 0.020833 0.020833 0.020833
если я печатаю (idfs), я получаю
{'my': 0.0, 'sat': 0.0, 'dog': 0.6931, 'cat': 0.6931, 'on': 0.0, 'the': 0.0, 'face': 0.6931, 'bed': 0.6931}
Здесь слова, включенные в оба документа, имеют значение 0, которое затем будет использоваться для оценки их важности, поскольку они являются общими для всех документов. Перед использованием функции computeTFIDF данные выглядят так:
{'my': 0.1666, 'sat': 0.1666, 'dog': 0.0, 'cat': 0.1666, 'on': 0.1666, 'the': 0.1666, 'face': 0.1666, 'bed': 0.0}
Поскольку функция будет умножать два числа, «my» (с idfs 0) должно быть 0, а «dog» (с idfs 0.6931) должно быть (0,6931 * 0,1666 = 0, 11) согласно примеру. Вместо этого я получаю номер 0.02083 для всех, кроме слов, которых нет в документе. Есть ли что-то кроме синтаксиса iter \ iteritems между python 2 и 3, что портит мой код?