使用相关和随机语料库计算 TF-IDF 单词得分
Compute TF-IDF word score with relevant and random corpus
给定一个相关文档语料库 (CORPUS) 和一个随机文档语料库 (ran_CORPUS) 我想计算 CORPUS 中所有单词的 TF-IDF 分数,使用 ran_CORPUS 作为基础线。在我的项目中,ran_CORPUS 的文档数量大约是 CORPUS 的 10 倍。
CORPUS = ['this is a relevant document',
'this one is a relevant text too']
ran_CORPUS = ['the sky is blue',
'my cat has a furry tail']
我的计划是对文档进行规范化,将CORPUS中的所有文档都归为一个文档(CORPUS现在是一个包含一个长字符串元素的列表)。我将所有 ran_CORPUS 文档附加到 CORPUS。然后使用 sklearn's TfidfTransformer
计算语料库的 TF-IDF 矩阵(现在由 CORPUS 和 ran_CORPUS 组成)。最后 select 该语料库的第一行获得我最初相关语料库的 TF-IDF 分数。
有人知道这种方法是否可行吗?是否有一种简单的编码方法?
当您说 "whether this approach could work" 时,我想您的意思是将所有相关文档合并为一个文档并矢量化呈现一个有效模型。我想这取决于你打算用那个模型做什么。
我算不上数学家,但我想这就像将所有文档的得分平均到一个向量中 space,所以你丢失了 [=32] 的一些形状=] 原始向量 space 被各个相关文档占用。所以你试图制作一个 "master" 或 "prototype" 文档来表示一个主题?
如果您随后要进行类似与测试文档的相似性匹配或通过距离比较进行分类的操作,那么您可能已经失去了原始文档矢量化的一些微妙之处。总体主题的方面可能比平均值所代表的要多。
更具体地说,假设您的原始 "relevant corpus" 有两组文档,因为实际上有两个主要的子主题,由不同的重要特征组表示。稍后在进行分类时,测试文档可以单独匹配这些集群中的任何一个——同样是因为它们接近两个子主题之一。在这种情况下,通过对整个 "relevant corpus" 进行平均,您最终会得到一个介于这两个集群之间的文档,但不能准确地表示任何一个。因此,测试演示文稿可能根本不匹配 - 取决于分类技术。
我认为如果不在适当的特定语料库上进行试验就很难说。
不管有效性如何,下面是如何实现的。
请注意,您还可以使用 TfidfVectorizer 将矢量化和 Tfidf'ing 步骤合二为一。结果并不总是完全相同,但在这种情况下是完全相同的。
此外,您说对文档进行规范化 - 通常,您可能会在输入需要规范化分布的分类算法(如 SVM)之前对向量表示进行规范化。然而,我认为 TFIDF 自然正常化,因此它似乎没有任何进一步的影响(我在这里可能是错的)。
import logging
from sklearn import preprocessing
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer, TfidfTransformer
CORPUS = ['this is a relevant document',
'this one is a relevant text too']
ran_CORPUS = ['the sky is blue',
'my cat has a furry tail']
doc_CORPUS = ' '.join([str(x) for x in CORPUS])
ran_CORPUS.append(doc_CORPUS)
count_vect = CountVectorizer()
X_counts = count_vect.fit_transform(ran_CORPUS)
tfidf_transformer = TfidfTransformer()
X_tfidf = tfidf_transformer.fit_transform(X_counts)
logging.debug("\nCount + TdidfTransform \n%s" % X_tfidf.toarray())
# or do it in one pass with TfidfVectorizer
vectorizer = TfidfVectorizer()
X_tfidf = vectorizer.fit_transform(ran_CORPUS)
logging.debug("\nTdidfVectoriser \n%s" % X_tfidf.toarray())
# normalising doesn't achieve much as tfidf is already normalised.
normalizer = preprocessing.Normalizer()
X_tfidf = normalizer.transform(X_tfidf)
logging.debug("\nNormalised:\n%s" % X_tfidf.toarray())
Count + TdidfTransform
[[0.52863461 0. 0. 0. 0. 0.40204024
0. 0. 0. 0.52863461 0. 0.
0.52863461 0. 0. ]
[0. 0.4472136 0. 0.4472136 0.4472136 0.
0.4472136 0. 0. 0. 0.4472136 0.
0. 0. 0. ]
[0. 0. 0.2643173 0. 0. 0.40204024
0. 0.2643173 0.52863461 0. 0. 0.2643173
0. 0.52863461 0.2643173 ]]
TdidfVectoriser
[[0.52863461 0. 0. 0. 0. 0.40204024
0. 0. 0. 0.52863461 0. 0.
0.52863461 0. 0. ]
[0. 0.4472136 0. 0.4472136 0.4472136 0.
0.4472136 0. 0. 0. 0.4472136 0.
0. 0. 0. ]
[0. 0. 0.2643173 0. 0. 0.40204024
0. 0.2643173 0.52863461 0. 0. 0.2643173
0. 0.52863461 0.2643173 ]]
Normalised:
[[0.52863461 0. 0. 0. 0. 0.40204024
0. 0. 0. 0.52863461 0. 0.
0.52863461 0. 0. ]
[0. 0.4472136 0. 0.4472136 0.4472136 0.
0.4472136 0. 0. 0. 0.4472136 0.
0. 0. 0. ]
[0. 0. 0.2643173 0. 0. 0.40204024
0. 0.2643173 0.52863461 0. 0. 0.2643173
0. 0.52863461 0.2643173 ]]
给定一个相关文档语料库 (CORPUS) 和一个随机文档语料库 (ran_CORPUS) 我想计算 CORPUS 中所有单词的 TF-IDF 分数,使用 ran_CORPUS 作为基础线。在我的项目中,ran_CORPUS 的文档数量大约是 CORPUS 的 10 倍。
CORPUS = ['this is a relevant document',
'this one is a relevant text too']
ran_CORPUS = ['the sky is blue',
'my cat has a furry tail']
我的计划是对文档进行规范化,将CORPUS中的所有文档都归为一个文档(CORPUS现在是一个包含一个长字符串元素的列表)。我将所有 ran_CORPUS 文档附加到 CORPUS。然后使用 sklearn's TfidfTransformer
计算语料库的 TF-IDF 矩阵(现在由 CORPUS 和 ran_CORPUS 组成)。最后 select 该语料库的第一行获得我最初相关语料库的 TF-IDF 分数。
有人知道这种方法是否可行吗?是否有一种简单的编码方法?
当您说 "whether this approach could work" 时,我想您的意思是将所有相关文档合并为一个文档并矢量化呈现一个有效模型。我想这取决于你打算用那个模型做什么。
我算不上数学家,但我想这就像将所有文档的得分平均到一个向量中 space,所以你丢失了 [=32] 的一些形状=] 原始向量 space 被各个相关文档占用。所以你试图制作一个 "master" 或 "prototype" 文档来表示一个主题?
如果您随后要进行类似与测试文档的相似性匹配或通过距离比较进行分类的操作,那么您可能已经失去了原始文档矢量化的一些微妙之处。总体主题的方面可能比平均值所代表的要多。
更具体地说,假设您的原始 "relevant corpus" 有两组文档,因为实际上有两个主要的子主题,由不同的重要特征组表示。稍后在进行分类时,测试文档可以单独匹配这些集群中的任何一个——同样是因为它们接近两个子主题之一。在这种情况下,通过对整个 "relevant corpus" 进行平均,您最终会得到一个介于这两个集群之间的文档,但不能准确地表示任何一个。因此,测试演示文稿可能根本不匹配 - 取决于分类技术。
我认为如果不在适当的特定语料库上进行试验就很难说。
不管有效性如何,下面是如何实现的。
请注意,您还可以使用 TfidfVectorizer 将矢量化和 Tfidf'ing 步骤合二为一。结果并不总是完全相同,但在这种情况下是完全相同的。
此外,您说对文档进行规范化 - 通常,您可能会在输入需要规范化分布的分类算法(如 SVM)之前对向量表示进行规范化。然而,我认为 TFIDF 自然正常化,因此它似乎没有任何进一步的影响(我在这里可能是错的)。
import logging
from sklearn import preprocessing
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer, TfidfTransformer
CORPUS = ['this is a relevant document',
'this one is a relevant text too']
ran_CORPUS = ['the sky is blue',
'my cat has a furry tail']
doc_CORPUS = ' '.join([str(x) for x in CORPUS])
ran_CORPUS.append(doc_CORPUS)
count_vect = CountVectorizer()
X_counts = count_vect.fit_transform(ran_CORPUS)
tfidf_transformer = TfidfTransformer()
X_tfidf = tfidf_transformer.fit_transform(X_counts)
logging.debug("\nCount + TdidfTransform \n%s" % X_tfidf.toarray())
# or do it in one pass with TfidfVectorizer
vectorizer = TfidfVectorizer()
X_tfidf = vectorizer.fit_transform(ran_CORPUS)
logging.debug("\nTdidfVectoriser \n%s" % X_tfidf.toarray())
# normalising doesn't achieve much as tfidf is already normalised.
normalizer = preprocessing.Normalizer()
X_tfidf = normalizer.transform(X_tfidf)
logging.debug("\nNormalised:\n%s" % X_tfidf.toarray())
Count + TdidfTransform
[[0.52863461 0. 0. 0. 0. 0.40204024
0. 0. 0. 0.52863461 0. 0.
0.52863461 0. 0. ]
[0. 0.4472136 0. 0.4472136 0.4472136 0.
0.4472136 0. 0. 0. 0.4472136 0.
0. 0. 0. ]
[0. 0. 0.2643173 0. 0. 0.40204024
0. 0.2643173 0.52863461 0. 0. 0.2643173
0. 0.52863461 0.2643173 ]]
TdidfVectoriser
[[0.52863461 0. 0. 0. 0. 0.40204024
0. 0. 0. 0.52863461 0. 0.
0.52863461 0. 0. ]
[0. 0.4472136 0. 0.4472136 0.4472136 0.
0.4472136 0. 0. 0. 0.4472136 0.
0. 0. 0. ]
[0. 0. 0.2643173 0. 0. 0.40204024
0. 0.2643173 0.52863461 0. 0. 0.2643173
0. 0.52863461 0.2643173 ]]
Normalised:
[[0.52863461 0. 0. 0. 0. 0.40204024
0. 0. 0. 0.52863461 0. 0.
0.52863461 0. 0. ]
[0. 0.4472136 0. 0.4472136 0.4472136 0.
0.4472136 0. 0. 0. 0.4472136 0.
0. 0. 0. ]
[0. 0. 0.2643173 0. 0. 0.40204024
0. 0.2643173 0.52863461 0. 0. 0.2643173
0. 0.52863461 0.2643173 ]]