Нормализация результатов TF-IDF

Я хотел бы нормализовать результаты tfidf, которые я получил из этого кода:

for (int docNum = 0; docNum < ir.numDocs(); docNum++) {
            TermFreqVector tfv = ir.getTermFreqVector(docNum, "contents");
            if (tfv == null) {
                // ignore empty fields
                continue;
            }
            String[] tterms = tfv.getTerms();
            int termCount = tterms.length;
            int[] freqs = tfv.getTermFrequencies();
            for (int t = 0; t < termCount; t++) {
                double idf = ir.numDocs() / ir.docFreq(new Term("contents", tterms[t]));
                System.out.println(" " + tterms[t] + " " + freqs[t]*Math.log(idf));
            }
        }

вывод для этого кода:

area 0.0
areola 5.877735781779639
ari 3.9318256327243257
art 1.6094379124341003
artifici 1.0986122886681098
assign 2.1972245773362196
associ 3.295836866004329
assur 1.9459101490553132
averag 1.0986122886681098
avoid 0.6931471805599453
.
.
.

Любая помощь приветствуется. благодарю вас


person John    schedule 01.07.2012    source источник
comment
Я хотел бы нормализовать результаты tfidf, которые я получил из этого кода:   -  person John    schedule 05.07.2012
comment
TF-IDF является нормализацией.   -  person Has QUIT--Anony-Mousse    schedule 05.07.2012
comment
ха-ха, извините, я имею в виду преобразование в диапазон от 0 до 1. Результаты TF-IDF больше 1.   -  person John    schedule 05.07.2012


Ответы (1)


Распространенным подходом является нормализация по размеру документа. то есть вместо использования количества терминов (или абсолютных частот) вы используете относительные частоты.

Пусть freqsum будет суммой по вашему массиву частот. Затем используйте

freqs[t]/(double)freqsum*Math.log(idf)

Чтобы избежать такого рода путаницы, я рекомендую использовать терминологию:

  • количество терминов для "абсолютной частоты"
  • относительная частота соотношения слова в документе

вместо двусмысленного термина "частота терминов".

Я знаю, что исторически, если вы посмотрите Солтон, Ян, «О спецификации значений терминов в автоматическом индексировании» (1973), они относятся к абсолютным значениям. Косинусное подобие будет убирать масштаб, так что там это все равно не имеет значения. Современные системы, такие как Lucene, будут стараться лучше контролировать влияние документа.

person Has QUIT--Anony-Mousse    schedule 05.07.2012
comment
Просто чтобы прояснить ситуацию — значит, вы имеете в виду, что freqsum в соответствии с моим кодом выше — это termCount? Я просто хочу разъяснений, извини, братан. - person John; 05.07.2012
comment
Нет, termCount — это количество различных терминов, не так ли? Я говорю об общей сумме. Подумайте об частоте относительных терминов, и это должно быть ясно. - person Has QUIT--Anony-Mousse; 05.07.2012
comment
это правильно г-н Anony? int[] freqs = tfv.getTermFrequencies(); double freqsum = Math.sqrt(freqs[i]) / tterms.length; - person John; 05.07.2012
comment
Нет. Вычисление суммы не требует извлечения квадратного корня. - person Has QUIT--Anony-Mousse; 06.07.2012
comment
Не может ли это также привести к отрицательному значению? - person Leo; 13.07.2017
comment
Когда это произойдет? - person Has QUIT--Anony-Mousse; 13.07.2017