python实现余弦相似度_Python中N-Gram,tf-idf和余弦相似度的简单实现

I need to compare documents stored in a DB and come up with a similarity score between 0 and 1.

The method I need to use has to be very simple. Implementing a vanilla version of n-grams (where it possible to define how many grams to use), along with a simple implementation of tf-idf and Cosine similarity.

Is there any program that can do this? Or should I start writing this from scratch?

解决方案

Check out NLTK package: http://www.nltk.org it has everything what you need

For the cosine_similarity:

def cosine_distance(u, v):

"""

Returns the cosine of the angle between vectors v and u. This is equal to

u.v / |u||v|.

"""

return numpy.dot(u, v) / (math.sqrt(numpy.dot(u, u)) * math.sqrt(numpy.dot(v, v)))

For ngrams:

def ngrams(sequence, n, pad_left=False, pad_right=False, pad_symbol=None):

"""

A utility that produces a sequence of ngrams from a sequence of items.

For example:

>>> ngrams([1,2,3,4,5], 3)

[(1, 2, 3), (2, 3, 4), (3, 4, 5)]

Use ingram for an iterator version of this function. Set pad_left

or pad_right to true in order to get additional ngrams:

>>> ngrams([1,2,3,4,5], 2, pad_right=True)

[(1, 2), (2, 3), (3, 4), (4, 5), (5, None)]

@param sequence: the source data to be converted into ngrams

@type sequence: C{sequence} or C{iterator}

@param n: the degree of the ngrams

@type n: C{int}

@param pad_left: whether the ngrams should be left-padded

@type pad_left: C{boolean}

@param pad_right: whether the ngrams should be right-padded

@type pad_right: C{boolean}

@param pad_symbol: the symbol to use for padding (default is None)

@type pad_symbol: C{any}

@return: The ngrams

@rtype: C{list} of C{tuple}s

"""

if pad_left:

sequence = chain((pad_symbol,) * (n-1), sequence)

if pad_right:

sequence = chain(sequence, (pad_symbol,) * (n-1))

sequence = list(sequence)

count = max(0, len(sequence) - n + 1)

return [tuple(sequence[i:i+n]) for i in range(count)]

for tf-idf you will have to compute distribution first, I am using Lucene to do that, but you may very well do something similar with NLTK, use FreqDist:

if you like pylucene, this will tell you how to comute tf.idf

# reader = lucene.IndexReader(FSDirectory.open(index_loc))

docs = reader.numDocs()

for i in xrange(docs):

tfv = reader.getTermFreqVector(i, fieldname)

if tfv:

rec = {}

terms = tfv.getTerms()

frequencies = tfv.getTermFrequencies()

for (t,f,x) in zip(terms,frequencies,xrange(maxtokensperdoc)):

df= searcher.docFreq(Term(fieldname, t)) # number of docs with the given term

tmap.setdefault(t, len(tmap))

rec[t] = sim.tf(f) * sim.idf(df, max_doc) #compute TF.IDF

# and normalize the values using cosine normalization

if cosine_normalization:

denom = sum([x**2 for x in rec.values()])**0.5

for k,v in rec.items():

rec[k] = v / denom

### 回答1: TF-IDF算法是一种常用的文本处理算法,可以用于计算文本每个单词的重要程度。在Python,可以使用scikit-learn库来实现TF-IDF算法。为了改进TF-IDF算法的效果,可以考虑以下几点: 1. 去除停用词:停用词是指在文本频繁出现但没有实际意义的词语,如“的”、“是”等。在TF-IDF算法,去除停用词可以减少噪声,提高算法的准确性。 2. 调整权重:TF-IDF算法,词频和逆文档频率的权重默认是相等的,但实际上不同的文本可能需要不同的权重。可以通过调整权重来提高算法的效果。 3. 使用n-gram模型:n-gram模型是指将文本的词语按照一定的顺序组合成n个词语的模型。使用n-gram模型可以更好地捕捉文本的语义信息,提高算法的准确性。 4. 使用词根还原:词根还原是指将单词还原为其原始形式,如将“running”还原为“run”。使用词根还原可以减少单词形态的差异,提高算法的准确性。 以上是TF-IDF算法改进的一些方法,可以根据具体情况选择适合自己的方法来实现算法。 ### 回答2: TF-IDF算法是信息检索常用的一种技术,它能够帮助我们对文本数据进行快速、准确的搜索。它的核心思想是通过计算每个单词在文档集合出现的频率和逆文档频率,来权衡单词的重要程度,从而得出每份文档的关键词。这样,我们就能用这些关键词来快速地判断一份文档与搜索实例的相关性。 Python作为一种广泛使用的编程语言,在实现TF-IDF算法方面具有一定优势。下面就来介绍一下如何改进Python实现TF-IDF算法。 1. 加载数据 首先,需要将文本数据加载到Python。常用的方法是使用pandas库的read_csv函数。 2. 预处理 在计算TF-IDF之前,需要进行一些预处理。首先要将所有文本都转换成小写字母,以避免大小写带来的误差。同时,还需要去除一些停用词,例如“the”、“a”、“an”等等。这些词并不会对文本的相关性产生太大的影响,反而会干扰计算。 3. 分词 将文本进行分词,是TF-IDF算法的一个重要步骤。在Python,可以使用NLTK(自然语言工具包)来进行分词操作。NLTK提供了许多分词方法,例如最简单的word_tokenize函数。此外,还可以使用正则表达式的方法进行分词,更加灵活。 4. 计算词频 计算每个单词在文档集合的频率,是TF-IDF算法的第一部分。在Python,可以使用collections库的Counter函数来计算单词出现的次数。 5. 计算逆文档频率 计算每个单词的逆文档频率,是TF-IDF算法的第二部分。在Python,可以使用math库的log函数来计算自然对数。然后,将所有文档的单词频率除以单词的逆文档频率,即可得到TF-IDF值。 6. 排序 对计算出的TF-IDF值进行排序,并筛选出一定数量的关键词。在Python,可以使用pandas库的sort_values函数进行排序。此外,也可以使用Python自带的sorted函数,更加灵活。 总之,TF-IDF算法在Python实现,需要依次进行数据加载、预处理、分词、计算词频、计算逆文档频率、排序等一系列步骤。通过适当的改进,可以使这些步骤更加高效、精确。这样,就能够为我们提供更加可靠、快速的检索服务。 ### 回答3: tf-idf算法是一种常用的文本挖掘算法,用于计算文档每个词语的重要性,它基于两个统计量:词频(term frequency)和逆文档频率(inverse document frequency)。在实际应用tf-idf算法往往需要与其他算法一起使用,以提高算法的准确性和效率。 为了改进tf-idf算法的python实现,我们可以从以下几个方面入手: 1. 数据预处理:在使用tf-idf算法之前,需要对文本数据进行预处理,包括分词、去停用词、词干提取等。可以使用已有的分词库,如jieba分词库,来对文本进行分词,并使用NLTK库来对文本进行预处理。 2. 选择合适的权重计算方法:如果使用普通的TF-IDF算法,容易忽略一些重要的词语。因此,我们可以使用改进的TF-IDF算法,如Okapi BM25、Full-tF、Bidirectional TF-IDF、Sensitive TF-IDF等,来计算每个词语的权重。 3. 使用稀疏矩阵压缩数据:当文本数据量非常大时,使用稀疏矩阵压缩数据可以减少内存占用,提高算法的运行效率。可以使用Python的SciPy库来实现稀疏矩阵。 4. 优化算法实现tf-idf算法的实现可以使用多线程技术,以提高算法的运行速度。可以使用Python的线程库,如threading和multiprocessing,来实现多线程计算。 总之,改进tf-idf算法的python实现可以通过优化数据预处理、选择合适的权重计算方法、使用稀疏矩阵压缩数据和优化算法实现这几个方面来实现。这些改进可以提高算法的准确性和效率,使得tf-idf算法更加适用于实际应用场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值