我下面的教程是可利用的在第1部分和第2部分 。 不幸的是,作者没有使用余弦相似地找到两个文件之间的距离,这涉及到最后一节的时间。 我注视着从以下链接的帮助下,本文中的例子计算器 ,包括在上面的链接提到的代码(就只是为了让生活更轻松)
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from nltk.corpus import stopwords
import numpy as np
import numpy.linalg as LA
train_set = ["The sky is blue.", "The sun is bright."] # Documents
test_set = ["The sun in the sky is bright."] # Query
stopWords = stopwords.words('english')
vectorizer = CountVectorizer(stop_words = stopWords)
#print vectorizer
transformer = TfidfTransformer()
#print transformer
trainVectorizerArray = vectorizer.fit_transform(train_set).toarray()
testVectorizerArray = vectorizer.transform(test_set).toarray()
print 'Fit Vectorizer to train set', trainVectorizerArray
print 'Transform Vectorizer to test set', testVectorizerArray
transformer.fit(trainVectorizerArray)
print
print transformer.transform(trainVectorizerArray).toarray()
transformer.fit(testVectorizerArray)
print
tfidf = transformer.transform(testVectorizerArray)
print tfidf.todense()
如上面的代码的结果我有以下矩阵
Fit Vectorizer to train set [[1 0 1 0]
[0 1 0 1]]
Transform Vectorizer to test set [[0 1 1 1]]
[[ 0.70710678 0. 0.70710678 0. ]
[ 0. 0.70710678 0. 0.70710678]]
[[ 0. 0.57735027 0.57735027 0.57735027]]
我不知道怎么做才能计算余弦相似度使用这个输出,我知道如何实现相对于余弦相似相似长度的两个向量,但在这里我不知道如何识别两个向量。
Answer 1:
首先,如果你想提取计数功能和应用TF-IDF正常化和逐行欧几里德正常化你能做到这一点在一个操作TfidfVectorizer
:
>>> from sklearn.feature_extraction.text import TfidfVectorizer
>>> from sklearn.datasets import fetch_20newsgroups
>>> twenty = fetch_20newsgroups()
>>> tfidf = TfidfVectorizer().fit_transform(twenty.data)
>>> tfidf
<11314x130088 sparse matrix of type '<type 'numpy.float64'>'
with 1787553 stored elements in Compressed Sparse Row format>
我们发现一个文档的余弦距离(例如,在数据集中的第一个)和所有你只需要计算第一向量的点积与所有其他的作为TFIDF向量已经行规格化的其他人。 所述SciPy的稀疏矩阵API是有点怪(不够灵活致密的N维numpy的阵列)。 为了让您需要切片矩阵逐行得到一个单列的子矩阵的第一载体:
>>> tfidf[0:1]
<1x130088 sparse matrix of type '<type 'numpy.float64'>'
with 89 stored elements in Compressed Sparse Row format>
scikit学习已经提供成对的指标(又名机器学习说法的核心)工作载体的集合都疏密表示。 在这种情况下,我们需要一个点的产品,也被称为线性内核:
>>> from sklearn.metrics.pairwise import linear_kernel
>>> cosine_similarities = linear_kernel(tfidf[0:1], tfidf).flatten()
>>> cosine_similarities
array([ 1. , 0.04405952, 0.11016969, ..., 0.04433602,
0.04457106, 0.03293218])
因此,找到前5个相关文件,我们可以使用argsort
和一些负面阵列切片(最相关的文档具有最高余弦相似值,因此在分类指数数组的结尾):
>>> related_docs_indices = cosine_similarities.argsort()[:-5:-1]
>>> related_docs_indices
array([ 0, 958, 10576, 3277])
>>> cosine_similarities[related_docs_indices]
array([ 1. , 0.54967926, 0.32902194, 0.2825788 ])
第一个结果是一个全面的检查:我们找到了查询文档与余弦相似度得分1,它有以下文本最相似的文件:
>>> print twenty.data[0]
From: lerxst@wam.umd.edu (where's my thing)
Subject: WHAT car is this!?
Nntp-Posting-Host: rac3.wam.umd.edu
Organization: University of Maryland, College Park
Lines: 15
I was wondering if anyone out there could enlighten me on this car I saw
the other day. It was a 2-door sports car, looked to be from the late 60s/
early 70s. It was called a Bricklin. The doors were really small. In addition,
the front bumper was separate from the rest of the body. This is
all I know. If anyone can tellme a model name, engine specs, years
of production, where this car is made, history, or whatever info you
have on this funky looking car, please e-mail.
Thanks,
- IL
---- brought to you by your neighborhood Lerxst ----
第二个最相似的文档是引用原邮件,因此有许多常用词的答复:
>>> print twenty.data[958]
From: rseymour@reed.edu (Robert Seymour)
Subject: Re: WHAT car is this!?
Article-I.D.: reed.1993Apr21.032905.29286
Reply-To: rseymour@reed.edu
Organization: Reed College, Portland, OR
Lines: 26
In article <1993Apr20.174246.14375@wam.umd.edu> lerxst@wam.umd.edu (where's my
thing) writes:
>
> I was wondering if anyone out there could enlighten me on this car I saw
> the other day. It was a 2-door sports car, looked to be from the late 60s/
> early 70s. It was called a Bricklin. The doors were really small. In
addition,
> the front bumper was separate from the rest of the body. This is
> all I know. If anyone can tellme a model name, engine specs, years
> of production, where this car is made, history, or whatever info you
> have on this funky looking car, please e-mail.
Bricklins were manufactured in the 70s with engines from Ford. They are rather
odd looking with the encased front bumper. There aren't a lot of them around,
but Hemmings (Motor News) ususally has ten or so listed. Basically, they are a
performance Ford with new styling slapped on top.
> ---- brought to you by your neighborhood Lerxst ----
Rush fan?
--
Robert Seymour rseymour@reed.edu
Physics and Philosophy, Reed College (NeXTmail accepted)
Artificial Life Project Reed College
Reed Solar Energy Project (SolTrain) Portland, OR
Answer 2:
我知道它的旧帖子。 但我试过http://scikit-learn.sourceforge.net/stable/包。 这里是我的代码找到余弦相似。 问题是,你将如何计算余弦相似度这个包,这里是我的代码为
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.feature_extraction.text import TfidfVectorizer
f = open("/root/Myfolder/scoringDocuments/doc1")
doc1 = str.decode(f.read(), "UTF-8", "ignore")
f = open("/root/Myfolder/scoringDocuments/doc2")
doc2 = str.decode(f.read(), "UTF-8", "ignore")
f = open("/root/Myfolder/scoringDocuments/doc3")
doc3 = str.decode(f.read(), "UTF-8", "ignore")
train_set = ["president of India",doc1, doc2, doc3]
tfidf_vectorizer = TfidfVectorizer()
tfidf_matrix_train = tfidf_vectorizer.fit_transform(train_set) #finds the tfidf score with normalization
print "cosine scores ==> ",cosine_similarity(tfidf_matrix_train[0:1], tfidf_matrix_train) #here the first element of tfidf_matrix_train is matched with other three elements
这里假设查询train_set和DOC1,DOC2和doc3的第一个元素是,我想用余弦相似度的帮助下排名的文件。 然后我就可以使用此代码。
此外,在这个问题提供的教程是非常有用的。 这里是所有它的零件部分-I , 部分II , 部分III
输出将是如下:
[[ 1. 0.07102631 0.02731343 0.06348799]]
这里1表示查询与自身匹配,另外三个是匹配与相应的文档查询分数。
Answer 3:
与@ excray的评论的帮助,我设法弄明白答案,我们需要做的实际上是写一个简单的for循环的两个数组表示训练数据和测试数据在迭代什么。
首先实现一个简单的lambda函数保持公式余弦计算:
cosine_function = lambda a, b : round(np.inner(a, b)/(LA.norm(a)*LA.norm(b)), 3)
然后只写一个简单的for循环,以在矢量迭代,逻辑是每个“对于trainVectorizerArray每个向量,你必须要找到与testVectorizerArray向量余弦相似性。”
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from nltk.corpus import stopwords
import numpy as np
import numpy.linalg as LA
train_set = ["The sky is blue.", "The sun is bright."] #Documents
test_set = ["The sun in the sky is bright."] #Query
stopWords = stopwords.words('english')
vectorizer = CountVectorizer(stop_words = stopWords)
#print vectorizer
transformer = TfidfTransformer()
#print transformer
trainVectorizerArray = vectorizer.fit_transform(train_set).toarray()
testVectorizerArray = vectorizer.transform(test_set).toarray()
print 'Fit Vectorizer to train set', trainVectorizerArray
print 'Transform Vectorizer to test set', testVectorizerArray
cx = lambda a, b : round(np.inner(a, b)/(LA.norm(a)*LA.norm(b)), 3)
for vector in trainVectorizerArray:
print vector
for testV in testVectorizerArray:
print testV
cosine = cx(vector, testV)
print cosine
transformer.fit(trainVectorizerArray)
print
print transformer.transform(trainVectorizerArray).toarray()
transformer.fit(testVectorizerArray)
print
tfidf = transformer.transform(testVectorizerArray)
print tfidf.todense()
下面是输出:
Fit Vectorizer to train set [[1 0 1 0]
[0 1 0 1]]
Transform Vectorizer to test set [[0 1 1 1]]
[1 0 1 0]
[0 1 1 1]
0.408
[0 1 0 1]
[0 1 1 1]
0.816
[[ 0.70710678 0. 0.70710678 0. ]
[ 0. 0.70710678 0. 0.70710678]]
[[ 0. 0.57735027 0.57735027 0.57735027]]
Answer 4:
让我给你我写另一个教程。 它回答您的问题,也使得我们为什么这样做的一些事情作出解释。 我还试图使它简洁。
所以,你有一个list_of_documents
这只是一个字符串数组,另一个document
是只是一个字符串。 你需要从找到这样的文件list_of_documents
是最相似的document
。
让我们结合在一起: documents = list_of_documents + [document]
让我们先从依赖。 为什么我们使用他们每个人将变得清晰。
from nltk.corpus import stopwords
import string
from nltk.tokenize import wordpunct_tokenize as tokenize
from nltk.stem.porter import PorterStemmer
from sklearn.feature_extraction.text import TfidfVectorizer
from scipy.spatial.distance import cosine
一个可以使用的方法是一个袋的词的方法,我们在独立于其它的文档对待每一个单词,只是把所有的人都一起在大包。 从一个角度来看,它失去了大量的信息(如字是如何连接的),但是从另一个角度来看这使得模型简单。
在英语和其他任何人类语言有很多的“无用”“在”像“一”,“中”字,这是很常见的,他们不具备很多的意义。 他们被称为停止的话 ,这是一个好主意,将其删除。 人们可以注意到的另一件事是,像“分析”,“分析”,“分析”的话是真的很相似。 他们有一个共同的根,都可以转换成只有一个字。 这个过程被称为词干并且存在其中在速度,攻击性不同,所以在不同的词干。 每个文档的,所以我们要转换列表中不停的单词的茎。 此外,我们放弃所有的标点。
porter = PorterStemmer()
stop_words = set(stopwords.words('english'))
modified_arr = [[porter.stem(i.lower()) for i in tokenize(d.translate(None, string.punctuation)) if i.lower() not in stop_words] for d in documents]
因此,如何将这个袋子的话帮助我们? 假设我们具有3袋: [a, b, c]
[a, c, a]
和[b, c, d]
我们可以将它们转换成矢量的基础 [a, b, c, d]
因此,我们最终与载体: [1, 1, 1, 0]
[2, 0, 1, 0]
和[0, 1, 1, 1]
类似的事情是与我们的文件(仅矢量会的方式来更长)。 现在我们看到,我们删除了大量的词汇和朵朵等也降低载体的尺寸。 这里有刚有趣的现象。 更长的文档会比短多方式积极因素,这就是为什么它是好的,标准化载体。 这就是所谓的词频TF,人们也用这个字是如何经常在其他文件中使用的附加信息 - 逆文档频率IDF。 我们一起有一个指标TF-IDF其中有一对夫妇的口味 。 这可以用在sklearn一条线路可以实现:-)
modified_doc = [' '.join(i) for i in modified_arr] # this is only to convert our list of lists to list of strings that vectorizer uses.
tf_idf = TfidfVectorizer().fit_transform(modified_doc)
其实矢量化允许做很多事情像移除停止字和lowercasing。 我曾在一个单独的步骤中完成他们只是因为sklearn没有非英语停用词,但NLTK了。
因此,我们有所有的向量计算。 最后一步是找到哪一个是最相似的最后一个。 有多种方法来实现这一目标,其中之一是欧氏距离这不是理由如此之大在这里讨论 。 另一种方法是余弦相似 。 我们遍历所有的文件和文档,最后一个计算之间的余弦相似性:
l = len(documents) - 1
for i in xrange(l):
minimum = (1, None)
minimum = min((cosine(tf_idf[i].todense(), tf_idf[l + 1].todense()), i), minimum)
print minimum
现在,最低将有大约最好的文档及其分数信息。
Answer 5:
这会帮助你。
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
tfidf_vectorizer = TfidfVectorizer()
tfidf_matrix = tfidf_vectorizer.fit_transform(train_set)
print tfidf_matrix
cosine = cosine_similarity(tfidf_matrix[length-1], tfidf_matrix)
print cosine
输出将是:
[[ 0.34949812 0.81649658 1. ]]
Answer 6:
这里是您的测试数据对训练数据进行比较,与TF-IDF变压器装有训练数据的功能。 好处是,你可以快速旋转或一组找n个最接近的元素,并且计算下降矩阵明智的。
def create_tokenizer_score(new_series, train_series, tokenizer):
"""
return the tf idf score of each possible pairs of documents
Args:
new_series (pd.Series): new data (To compare against train data)
train_series (pd.Series): train data (To fit the tf-idf transformer)
Returns:
pd.DataFrame
"""
train_tfidf = tokenizer.fit_transform(train_series)
new_tfidf = tokenizer.transform(new_series)
X = pd.DataFrame(cosine_similarity(new_tfidf, train_tfidf), columns=train_series.index)
X['ix_new'] = new_series.index
score = pd.melt(
X,
id_vars='ix_new',
var_name='ix_train',
value_name='score'
)
return score
train_set = pd.Series(["The sky is blue.", "The sun is bright."])
test_set = pd.Series(["The sun in the sky is bright."])
tokenizer = TfidfVectorizer() # initiate here your own tokenizer (TfidfVectorizer, CountVectorizer, with stopwords...)
score = create_tokenizer_score(train_series=train_set, new_series=test_set, tokenizer=tokenizer)
score
ix_new ix_train score
0 0 0 0.617034
1 0 1 0.862012
文章来源: Python: tf-idf-cosine: to find document similarity