gpt4 book ai didi

python - 为Textacy中的单个单词计算TF-IDF

转载 作者:太空宇宙 更新时间:2023-11-04 09:30:57 25 4
gpt4 key购买 nike

我正在尝试使用Textacy计算整个标准语料库中单个单词的TF-IDF分数,但是对于我收到的结果有点不清楚。

我期待一个单一的浮点数,它代表了语料库中单词的出现频率。那么,为什么我会收到包含7个结果的列表(?)?

“ acculer”实际上是法语单词,因此期望英语语料库的结果为0。

word = 'acculer'
vectorizer = textacy.Vectorizer(tf_type='linear', apply_idf=True, idf_type='smooth')
tf_idf = vectorizer.fit_transform(word)
logger.info("tf_idf:")
logger.info(tfidf)


输出量

tf_idf:
(0, 0) 2.386294361119891
(1, 1) 1.9808292530117262
(2, 1) 1.9808292530117262
(3, 5) 2.386294361119891
(4, 3) 2.386294361119891
(5, 2) 2.386294361119891
(6, 4) 2.386294361119891


问题的第二部分是如何为Textacy中的TF-IDF函数提供我自己的语料库。一个用另一种语言?

编辑

如@Vishal所述,我已经使用以下行记录了输出:

logger.info(vectorizer.vocabulary_terms)


所提供的单词 acculer似乎已拆分为字符。

{'a': 0, 'c': 1, 'u': 5, 'l': 3, 'e': 2, 'r': 4}


(1)如何获得针对该词的TF-IDF,而不是每个字符?

(2)我如何提供自己的语料库并将其作为参数?

(3)可以在句子级别使用TF-IDF吗?即:这句话相对于语料库的相对频率是多少?

最佳答案

基本原理

在研究实际问题之前,让我们弄清楚定义。

假设我们的语料库包含3个文档(分别为d1,d2和d3):

corpus = ["this is a red apple", "this is a green apple", "this is a cat"]


词频(tf)

tf(单词的)定义为单词在文档中出现的次数。

tf(word, document) = count(word, document) # Number of times word appears in the document


tf是在文档级别为单词定义的。

tf('a',d1)     = 1      tf('a',d2)     = 1      tf('a',d3)     = 1
tf('apple',d1) = 1 tf('apple',d2) = 1 tf('apple',d3) = 0
tf('cat',d1) = 0 tf('cat',d2) = 0 tf('cat',d3) = 1
tf('green',d1) = 0 tf('green',d2) = 1 tf('green',d3) = 0
tf('is',d1) = 1 tf('is',d2) = 1 tf('is',d3) = 1
tf('red',d1) = 1 tf('red',d2) = 0 tf('red',d3) = 0
tf('this',d1) = 1 tf('this',d2) = 1 tf('this',d3) = 1


使用原始计数存在一个问题,即与较短的文档相比,较长的文档中单词的 tf值较高。通过将原始计数值除以文档长度(相应文档中的单词数)来归一化可以解决此问题。这称为 l1规范化。现在,文档 d1可以由 tf vector表示,并具有语料库中所有单词的所有 tf值。还有一种称为 l2的标准化,可以使文档的tf向量的 l2范数等于1。

tf(word, document, normalize='l1') = count(word, document)/|document|
tf(word, document, normalize='l2') = count(word, document)/l2_norm(document)


|d1| = 5, |d2| = 5, |d3| = 4
l2_norm(d1) = 0.447, l2_norm(d2) = 0.447, l2_norm(d3) = 0.5,


代号:tf

corpus = ["this is a red apple", "this is a green apple", "this is a cat"]
# Convert docs to textacy format
textacy_docs = [textacy.Doc(doc) for doc in corpus]

for norm in [None, 'l1', 'l2']:
# tokenize the documents
tokenized_docs = [
doc.to_terms_list(ngrams=1, named_entities=True, as_strings=True, filter_stops=False, normalize='lower')
for doc in textacy_docs]

# Fit the tf matrix
vectorizer = textacy.Vectorizer(apply_idf=False, norm=norm)
doc_term_matrix = vectorizer.fit_transform(tokenized_docs)

print ("\nVocabulary: ", vectorizer.vocabulary_terms)
print ("TF with {0} normalize".format(norm))
print (doc_term_matrix.toarray())


输出:

Vocabulary:  {'this': 6, 'is': 4, 'a': 0, 'red': 5, 'apple': 1, 'green': 3, 'cat': 2}
TF with None normalize
[[1 1 0 0 1 1 1]
[1 1 0 1 1 0 1]
[1 0 1 0 1 0 1]]

Vocabulary: {'this': 6, 'is': 4, 'a': 0, 'red': 5, 'apple': 1, 'green': 3, 'cat': 2}
TF with l1 normalize
[[0.2 0.2 0. 0. 0.2 0.2 0.2 ]
[0.2 0.2 0. 0.2 0.2 0. 0.2 ]
[0.25 0. 0.25 0. 0.25 0. 0.25]]

Vocabulary: {'this': 6, 'is': 4, 'a': 0, 'red': 5, 'apple': 1, 'green': 3, 'cat': 2}
TF with l2 normalize
[[0.4472136 0.4472136 0. 0. 0.4472136 0.4472136 0.4472136]
[0.4472136 0.4472136 0. 0.4472136 0.4472136 0. 0.4472136]
[0.5 0. 0.5 0. 0.5 0. 0.5 ]]


tf矩阵中的行对应于文档(因此,我们的语料库为3行),列对应于词汇表中的每个单词(词汇表中显示的单词的索引)

反文档频率(idf)

有些单词传达的信息要少于其他单词。例如,像“一个”,“一个”,“一个”,“这个”之类的单词是非常常见的单词,它们传达的信息很少。 idf是对单词重要性的度量。与出现在少数文件中的单词相比,我们认为在许多文件中出现的单词信息较少。

idf(word, corpus) = log(|corpus| / No:of documents containing word) + 1  # standard idf


对于我们的语料库 idf(apple, corpus) < idf(cat,corpus)

idf('apple', corpus) = log(3/2) + 1 = 1.405 
idf('cat', corpus) = log(3/1) + 1 = 2.098
idf('this', corpus) = log(3/3) + 1 = 1.0


代号:idf

textacy_docs = [textacy.Doc(doc) for doc in corpus]    
tokenized_docs = [
doc.to_terms_list(ngrams=1, named_entities=True, as_strings=True, filter_stops=False, normalize='lower')
for doc in textacy_docs]

vectorizer = textacy.Vectorizer(apply_idf=False, norm=None)
doc_term_matrix = vectorizer.fit_transform(tokenized_docs)

print ("\nVocabulary: ", vectorizer.vocabulary_terms)
print ("standard idf: ")
print (textacy.vsm.matrix_utils.get_inverse_doc_freqs(doc_term_matrix, type_='standard'))


输出:

Vocabulary:  {'this': 6, 'is': 4, 'a': 0, 'red': 5, 'apple': 1, 'green': 3, 'cat': 2}
standard idf:
[1. 1.405 2.098 2.098 1. 2.098 1.]


术语频率-反向文档频率(tf-idf):tf-idf是对单词在语料库文档中的重要性的一种度量。用其ID加权的单词的tf给我们单词的tf-idf度量。

tf-idf(word, document, corpus) = tf(word, docuemnt) * idf(word, corpus)


tf-idf('apple', 'd1', corpus) = tf('apple', 'd1') * idf('apple', corpus) = 1 * 1.405 = 1.405
tf-idf('cat', 'd3', corpus) = tf('cat', 'd3') * idf('cat', corpus) = 1 * 2.098 = 2.098


编码:tf-idf

textacy_docs = [textacy.Doc(doc) for doc in corpus]

tokenized_docs = [
doc.to_terms_list(ngrams=1, named_entities=True, as_strings=True, filter_stops=False, normalize='lower')
for doc in textacy_docs]

print ("\nVocabulary: ", vectorizer.vocabulary_terms)
print ("tf-idf: ")

vectorizer = textacy.Vectorizer(apply_idf=True, norm=None, idf_type='standard')
doc_term_matrix = vectorizer.fit_transform(tokenized_docs)
print (doc_term_matrix.toarray())


输出:

Vocabulary:  {'this': 6, 'is': 4, 'a': 0, 'red': 5, 'apple': 1, 'green': 3, 'cat': 2}
tf-idf:
[[1. 1.405 0. 0. 1. 2.098 1. ]
[1. 1.405 0. 2.098 1. 0. 1. ]
[1. 0. 2.098 0. 1. 0. 1. ]]


现在来提问题:


  (1)我如何获得针对该词的TF-IDF反对语料库,而不是
  比每个角色?


如上所述,没有独立定义的 tf-idf,单词的 tf-idf是针对语料库中的文档的。


  (2)如何提供我自己的语料库并将其作为参数?


在上面的示例中显示了它。


使用textacy.Doc api将文本文档转换为textacy Docs
用to_terms_list方法标记textacy.Doc。 (使用此方法,您可以将unigram,bigram或trigram添加到词汇表中,过滤掉停用词,然后对文本进行非名词化等)
使用textacy.Vectorizer从标记化文档中创建术语矩阵。返回的术语矩阵为


tf (raw counts): apply_idf=False, norm=None
tf (l1 normalized): apply_idf=False, norm='l1'
tf (l2 normalized): apply_idf=False, norm='l2'
tf-idf (standard): apply_idf=True, idf_type='standard'




  (3)可以在句子级别使用TF-IDF吗?即:相对是什么
  这句话对语料库的使用频率。


是的,只有当您将每个句子都视为一个单独的文档时,您才可以。在这种情况下,相应文档的 tf-idf矢量(全行)可以视为文档的矢量表示(在您的情况下为单个句子)。

如果是我们的语料库(实际上每个文档只包含一个句子),则与向量d1和d3相比,d1和d2的向量表示应接近。让我们检查余弦相似度,然后看:

cosine_similarity(doc_term_matrix)


输出量

array([[1.        ,     0.53044716,     0.35999211],
[0.53044716, 1. , 0.35999211],
[0.35999211, 0.35999211, 1. ]])


如您所见cosine_similarity(d1,d2)= 0.53和cosine_similarity(d1,d3)= 0.35,因此d1和d2确实比d1和d3更相似(1完全相似而0不相似-正交向量)。

训练 Vectorizer后,您可以将训练后的对象腌制到磁盘上以备后用。

结论

单词的 tf处于文档级别,单词的 idf处于语料库级别,单词的 tf-idf处于相对于主体的文档。它们非常适合于文档(或由单个句子组成的文档中的句子)的矢量表示。如果您对单词的矢量表示感兴趣,请探索单词嵌入(例如word2vec,fasttext,g手套等)。

关于python - 为Textacy中的单个单词计算TF-IDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55764766/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com