При попытке воспроизвести пример TFIDF умножение возвращает неправильный номер - PullRequest
0 голосов
/ 09 мая 2018

Я пытаюсь воспроизвести пример 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, что портит мой код?

1 Ответ

0 голосов
/ 09 мая 2018

Во второй последней части перед приведением к df измените эти две строки -

tfidfBowA = computeTF(tfBowA, idfs)
tfidfBowB = computeTF(tfBowB, idfs)

TO -

tfidfBowA = computeTFIDF(tfBowA, idfs)
tfidfBowB = computeTFIDF(tfBowB, idfs)

Для вычисления Tfidf необходимо вызвать функцию computeTFIDF() вместо computeTF()

выход

tfidfBowA
{'bed': 0.0,
 'cat': 0.11552453009332421,
 'dog': 0.0,
 'face': 0.11552453009332421,
 'my': 0.0,
 'on': 0.0,
 'sat': 0.0,
 'the': 0.0}

tfidfBowB
{'bed': 0.11552453009332421,
 'cat': 0.0,
 'dog': 0.11552453009332421,
 'face': 0.0,
 'my': 0.0,
 'on': 0.0,
 'sat': 0.0,
 'the': 0.0}

Надеюсь, это поможет!

...