
Здравствуйте дорогие читатели!В этой статье я хочу показать реализованные неким автором By torselllo c сайта nlpx.net http://nlpx.net/archives/57
tf-idf (term frequency-inverse document frequency или на рус., частотность терминов-обратная частотность документов) и и их же реализацию на
sklearn(пакет sklearn.feature_extraction.text) а также bag of words (мешок слов) или count vector(вектор счета)-тот же пакет.
Итак,
Term Frequency
TF — это частотность термина, которая измеряет, насколько часто термин встречается в документе.
Формула:
| Bash | 1
| TF термина а = (Количество раз, когда термин а встретился в тексте / количество всех слов в тексте) |
|
Реализация:
| Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
| import collections
def compute_tf(text):
#На вход берем текст в виде списка (list) слов
#Считаем частотность всех терминов во входном массиве с помощью
#метода Counter библиотеки collections
tf_text = collections.Counter(text)
for i in tf_text:
#для каждого слова в tf_text считаем TF путём деления
#встречаемости слова на общее количество слов в тексте
tf_text[i] = tf_text[i]/float(len(text))
#возвращаем объект типа Counter c TF всех слов текста
return tf_text |
|
| Bash | 1
2
3
4
| text = ['hasta', 'la', 'vista', 'baby', 'la', 'vista', 'la']
print compute_tf(text)
Out: Counter({'la': 0.42857142857142855, 'vista': 0.2857142857142857,
'hasta': 0.14285714285714285, 'baby': 0.14285714285714285}) |
|
Inverse Document Frequency
IDF — это обратная частотность документов. Она измеряет непосредственно важность термина. То есть, когда мы считали TF, все термины считаются как бы равными
по важности друг другу. Но всем известно, что, например, предлоги встречаются очень часто, хотя практически не влияют на смысл текста.
И что с этим поделать? Ответ прост — посчитать IDF.
Формула:
| Bash | 1
| IDF термина а = логарифм(Общее количество документов / Количество документов, в которых встречается термин а) |
|
Реализация:
| Python | 1
2
3
4
5
6
7
8
| import math
def compute_idf(word, corpus):
#на вход берется слово, для которого считаем IDF
#и корпус документов в виде списка списков слов
#количество документов, где встречается искомый термин
#считается как генератор списков
return math.log10(len(corpus)/sum([1.0 for i in corpus if word in i])) |
|
| Bash | 1
2
3
4
5
6
|
texts = [['pasta', 'la', 'vista', 'baby', 'la', 'vista'],
['hasta', 'siempre', 'comandante', 'baby', 'la', 'siempre'],
['siempre', 'comandante', 'baby', 'la', 'siempre']]
print compute_idf('pasta', texts)
Out: 0.47712125472 |
|
Term Frequency — Inverse Document Frequency
А затем мы умножаем TF на IDF и получаем — TF-IDF!
| Bash | 1
| TF-IDF термина а = (TF термина а) * (IDF термина а) |
|
(реализацию пропустил).
Итак поработаем с sklearn для корпуса
| Python | 1
2
3
4
| corpus = [
"I like this movie, it`s funny", "I hate this movie.",
"This was awersome!I like it.", "Nice one, I love it."
] |
|
Bag of words:
| Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| from sklearn.feature_extraction.text import CountVectorizer
corpus = [
"I like this movie, it`s funny", "I hate this movie.",
"This was awersome!I like it.", "Nice one, I love it."
]
cv = CountVectorizer()
word_count_vector = cv.fit_transform(corpus)
print(word_count_vector.toarray())
"""
->
[[0 1 0 1 1 0 1 0 0 1 0]
[0 0 1 0 0 0 1 0 0 1 0]
[1 0 0 1 1 0 0 0 0 1 1]
[0 0 0 1 0 1 0 1 1 0 0]]
""" |
|
Tf-idf:
| Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
corpus = [
"I like this movie, it`s funny", "I hate this movie.",
"This was awersome!I like it.", "Nice one, I love it."
]
cv = CountVectorizer()
word_count_vector = cv.fit_transform(corpus)
print(word_count_vector.toarray())
"""
->
[[0 1 0 1 1 0 1 0 0 1 0]
[0 0 1 0 0 0 1 0 0 1 0]
[1 0 0 1 1 0 0 0 0 1 1]
[0 0 0 1 0 1 0 1 1 0 0]]
"""
tfidf_transformer = TfidfTransformer(smooth_idf=True, use_idf=True)
tfidf_transformer.fit(word_count_vector)
print(tfidf_transformer.idf_)
"""
->
[1.91629073 1.91629073 1.91629073 1.22314355 1.51082562 1.91629073
1.51082562 1.91629073 1.91629073 1.22314355 1.91629073]
""" |
|
|