Интерпретация суммы баллов TF-IDF по документам
Сначала давайте выберем баллы TF-IDF за семестр за документ:
from gensim import corpora, models, similarities
documents = ["Human machine interface for lab abc computer applications",
"A survey of user opinion of computer system response time",
"The EPS user interface management system",
"System and human system engineering testing of EPS",
"Relation of user perceived response time to error measurement",
"The generation of random binary unordered trees",
"The intersection graph of paths in trees",
"Graph minors IV Widths of trees and well quasi ordering",
"Graph minors A survey"]
stoplist = set('for a of the and to in'.split())
texts = [[word for word in document.lower().split() if word not in stoplist] for document in documents]
dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts]
tfidf = models.TfidfModel(corpus)
corpus_tfidf = tfidf[corpus]
Распечатка:
for doc in corpus_tfidf:
print doc
[выход]:
[(0, 0.4301019571350565), (1, 0.4301019571350565), (2, 0.4301019571350565), (3, 0.4301019571350565), (4, 0.2944198962221451), (5, 0.2944198962221451), (6, 0.2944198962221451)]
[(4, 0.3726494271826947), (7, 0.27219160459794917), (8, 0.3726494271826947), (9, 0.27219160459794917), (10, 0.3726494271826947), (11, 0.5443832091958983), (12, 0.3726494271826947)]
[(6, 0.438482464916089), (7, 0.32027755044706185), (9, 0.32027755044706185), (13, 0.6405551008941237), (14, 0.438482464916089)]
[(5, 0.3449874408519962), (7, 0.5039733231394895), (14, 0.3449874408519962), (15, 0.5039733231394895), (16, 0.5039733231394895)]
[(9, 0.21953536176370683), (10, 0.30055933182961736), (12, 0.30055933182961736), (17, 0.43907072352741366), (18, 0.43907072352741366), (19, 0.43907072352741366), (20, 0.43907072352741366)]
[(21, 0.48507125007266594), (22, 0.48507125007266594), (23, 0.48507125007266594), (24, 0.48507125007266594), (25, 0.24253562503633297)]
[(25, 0.31622776601683794), (26, 0.31622776601683794), (27, 0.6324555320336759), (28, 0.6324555320336759)]
[(25, 0.20466057569885868), (26, 0.20466057569885868), (29, 0.2801947048062438), (30, 0.40932115139771735), (31, 0.40932115139771735), (32, 0.40932115139771735), (33, 0.40932115139771735), (34, 0.40932115139771735)]
[(8, 0.6282580468670046), (26, 0.45889394536615247), (29, 0.6282580468670046)]
Если мы хотим найти "значимость" или "важность" слов в этом корпусе, можем ли мы просто суммировать оценки tf-idf по всем документам и разделить их на количество документов? Т.е.
>>> tfidf_saliency = Counter()
>>> for doc in corpus_tfidf:
... for word, score in doc:
... tfidf_saliency[word] += score / len(corpus_tfidf)
...
>>> tfidf_saliency
Counter({7: 0.12182694202050007, 8: 0.11121194156107769, 26: 0.10886469856464989, 29: 0.10093919463036093, 9: 0.09022272408985754, 14: 0.08705221175200946, 25: 0.08482488519466996, 6: 0.08143359568202602, 10: 0.07480097322359022, 12: 0.07480097322359022, 4: 0.07411881371164887, 13: 0.07117278898823597, 5: 0.07104525967490458, 27: 0.07027283689263066, 28: 0.07027283689263066, 11: 0.060487023243988705, 15: 0.055997035904387725, 16: 0.055997035904387725, 21: 0.05389680556362955, 22: 0.05389680556362955, 23: 0.05389680556362955, 24: 0.05389680556362955, 17: 0.048785635947490406, 18: 0.048785635947490406, 19: 0.048785635947490406, 20: 0.048785635947490406, 0: 0.04778910634833961, 1: 0.04778910634833961, 2: 0.04778910634833961, 3: 0.04778910634833961, 30: 0.045480127933079706, 31: 0.045480127933079706, 32: 0.045480127933079706, 33: 0.045480127933079706, 34: 0.045480127933079706})
Глядя на результат, можем ли мы предположить, что наиболее "выдающееся" слово в корпусе:
>>> dictionary[7]
u'system'
>>> dictionary[8]
u'survey'
>>> dictionary[26]
u'graph'
Если да, что такое математическая интерпретация суммы TF-IDF множества слов в документах?
Ответы
Ответ 1
Интерпретация TF-IDF в корпусе является самым высоким TF-IDF в корпусе для данного термина.
Найти верхние слова в corpus_tfidf.
topWords = {}
for doc in corpus_tfidf:
for iWord, tf_idf in doc:
if iWord not in topWords:
topWords[iWord] = 0
if tf_idf > topWords[iWord]:
topWords[iWord] = tf_idf
for i, item in enumerate(sorted(topWords.items(), key=lambda x: x[1], reverse=True), 1):
print("%2s: %-13s %s" % (i, dictionary[item[0]], item[1]))
if i == 6: break
Выходная корзина для сравнения:
ПРИМЕЧАНИЕ. Невозможно использовать gensim
, чтобы создать соответствующий dictionary
с corpus_tfidf
.
Может отображать только Word Indizies.
Question tfidf_saliency topWords(corpus_tfidf) Other TF-IDF implentation
---------------------------------------------------------------------------
1: Word(7) 0.121 1: Word(13) 0.640 1: paths 0.376019
2: Word(8) 0.111 2: Word(27) 0.632 2: intersection 0.376019
3: Word(26) 0.108 3: Word(28) 0.632 3: survey 0.366204
4: Word(29) 0.100 4: Word(8) 0.628 4: minors 0.366204
5: Word(9) 0.090 5: Word(29) 0.628 5: binary 0.300815
6: Word(14) 0.087 6: Word(11) 0.544 6: generation 0.300815
Расчет TF-IDF всегда учитывает состав.
Протестировано с помощью Python: 3.4.2
Ответ 2
Существует два контекста, в которых может рассчитываться значимость.
- значимость в корпусе
- значимость в одном документе
значимость в корпусе просто может быть рассчитана путем подсчета появлений конкретного слова в корпусе или путем обратного отсчета документов, в которых появляется слово (IDF = Inverted Document Frequency). Поскольку слова, которые содержат конкретный смысл, не отображаются повсюду.
значимость в документе рассчитывается tf_idf. Потому что это состоит из двух видов информации. Глобальная информация (основанная на корпусе) и локальная информация (основанная на документах). Требование о том, что "слово с большей частотой в документе более важно в текущем документе" не является полностью истинным или ложным, поскольку оно зависит от глобальной значимости слова. В конкретном документе у вас есть много слов типа "это, есть, am, are,..." с большими частотами. Но это слово не важно в каком-либо документе, и вы можете воспринимать их как стоп-слова!
---- edit ---
Знаменатель (= len (corpus_tfidf)) является постоянным значением и может быть проигнорирован, если вы хотите иметь дело с обыденностью, а не с мощностью измерения. С другой стороны, мы знаем, что IDF означает Inverted Document Freqeuncy, поэтому IDF может быть переотложен на 1/DF. Мы знаем, что DF - это значение уровня корпуса, а TF - значение уровня документа. Суммирование TF-IDF превращает TF на уровне документа в TF корпуса. Действительно, суммирование равно этой формуле:
count (word)/count (документы содержат слово)
Это измерение можно назвать значением обратного рассеяния. Когда значение повышается, слова собираются в меньший поднабор документов и наоборот.
Я считаю, что эта формула не так полезна.
Ответ 3
Это отличная дискуссия. Спасибо, что начали эту тему. Идея включения длины документа в @avip кажется интересной. Придется экспериментировать и проверять результаты. Тем временем позвольте мне попытаться задать вопрос несколько иначе. Что мы пытаемся интерпретировать при запросе оценок релевантности TF-IDF?
- Возможно, попытка понять релевантность слова на уровне документа
- Возможно, попытка понять значение слова в классе
-
Возможно, нужно понять общую релевантность слова (в целом
corpus)
# # features, corpus = 6 documents of length 3
counts = [[3, 0, 1],
[2, 0, 0],
[3, 0, 0],
[4, 0, 0],
[3, 2, 0],
[3, 0, 2]]
from sklearn.feature_extraction.text import TfidfTransformer
transformer = TfidfTransformer(smooth_idf=False)
tfidf = transformer.fit_transform(counts)
print(tfidf.toarray())
# lambda for basic stat computation
summarizer_default = lambda x: np.sum(x, axis=0)
summarizer_mean = lambda x: np.mean(x, axis=0)
print(summarizer_default(tfidf))
print(summarizer_mean(tfidf))
Результат:
# Result post computing TF-IDF relevance scores
array([[ 0.81940995, 0. , 0.57320793],
[ 1. , 0. , 0. ],
[ 1. , 0. , 0. ],
[ 1. , 0. , 0. ],
[ 0.47330339, 0.88089948, 0. ],
[ 0.58149261, 0. , 0.81355169]])
# Result post aggregation (Sum, Mean)
[[ 4.87420595 0.88089948 1.38675962]]
[[ 0.81236766 0.14681658 0.2311266 ]]
Если мы внимательно наблюдаем, мы понимаем, что признак, который произошел во всем документе, не игнорируется полностью, потому что добавлена реализация sklearn idf = log [n/df (d, t)] + 1. +1, так что важное слово, которое так происходит во всем документе, не игнорируется. Например. слово "велосипед" происходит очень часто при классификации конкретного документа как "motorcyle" (20_newsgroup dataset).
-
Теперь, касаясь первых двух вопросов, вы пытаетесь интерпретировать и понимать основные общие функции, которые могут возникать в документе. В этом случае агрегирование в какой-либо форме, включая все возможные появления слова в документе, не воспринимает ничего, даже математически. ИМО такой запрос очень полезен, исследуя набор данных и помогая понять, что такое набор данных. Логика может быть применена и к векторизации с использованием Хейшинга.
релевантность_score = среднее (tf (t, d) * idf (t, d)) = среднее ((смещение + inital_wt * F (t, d)/max {F (t ', d)}) * log (N/df (d, t)) + 1))
-
Вопрос 3 очень важен, так как он может также способствовать
функции выбираются для построения модели прогнозирования. Просто использование оценок TF-IDF независимо для выбора функции может вводить в заблуждение на нескольких уровнях. Принятие более теоретического статистического теста, такого как пара "chi2" с оценкой релевантности TF-IDF, может быть лучшим подходом. Такой статистический тест также оценивает важность функции в отношении соответствующего целевого класса.
И, конечно, сочетание этой интерпретации с весовыми характеристиками, полученными с помощью модели, было бы очень полезно для понимания важности текстовых функций полностью.
** Проблема здесь сложнее описать здесь. Но, надеясь, что это помогает. Что чувствуют другие?
Ссылка: https://arxiv.org/abs/1707.05261
Ответ 4
Если мы хотим найти "значимость" или "важность" слов внутри этот корпус, можем ли мы просто суммировать оценки tf-idf по всем документы и делить его на количество документов? Если да, то какой математическая интерпретация суммы баллов TF-IDF через документы?
Если вы суммировали оценки td-idf по документам, термины, которые в противном случае имели бы низкие баллы, могли бы получить повышение, а условия с более высокими баллами могли бы привести к снижению их оценок.
Я не думаю, что простое разделение на общее количество документов будет достаточной нормализацией для решения этой проблемы. Может быть, включение длины документа в коэффициент нормировки? В любом случае, я думаю, что все такие методы все равно должны быть скорректированы для каждого домена.
Итак, в общем, математически я ожидаю, что вы получите нежелательный эффект усреднения.
Ответ 5
Я как-то наткнулся на ту же проблему. Я поделюсь своим решением здесь, но не знаю, насколько оно эффективно.
После вычисления tf-idf мы получаем, как матрицу терминов против документов.
[terms/docs : doc1 , doc2 , doc3..... docn
term1 : tf(doc1)-idf, tf(doc2)-idf , tf(doc3)-idf.....
.
.
.
termn ........ ]
Мы можем представить столбцы doc1, doc2... docn как баллы, присвоенные каждому члену в соответствии с n различными метриками. Если мы суммируем по столбцам, мы просто усредняем оценки, что является наивным способом и не полностью отражает полученную информацию. Мы можем сделать что-то лучше, так как это проблема поиска топ-k. Одним из эффективных алгоритмов является алгоритм Фагина, который работает над этой идеей:
Сортированные списки сканируются до тех пор, пока не будут найдены k элементов данных, которые были замечены во всех списках, тогда алгоритм может остановиться, и гарантируется, что среди всех элементов данных, просмотренных до сих пор, даже те, которые отсутствовали во всех списках, Топ-К элементов данных можно найти.
Отсортированные списки здесь просто означают, что один столбец конкретного документа становится списком, и у нас есть n таких списков. Так что разберитесь с каждым из них, а затем делайте на нем фагин.
Подробнее об этом читайте здесь