繁体   English   中英

我怎样才能使这个python函数更快?

[英]How can I make this python function faster?

我编写的以下代码包含68,000个项目,并尝试根据字符串中的文本位置查找相似的项目。 这个过程在我暂时用来编码的i3 4130上花了点时间-有什么方法可以加快速度吗? 我的意思是“你是说吗?” 功能,因此我需要对用户输入的内容进行排序。

我不是要在已经使用关键字创建的字典中通过相似性进行比较,而是要在用户输入的动态输入与所有现有键之间进行相似性比较。 用户可能会键入错误的键,这就是为什么它会像Google搜索一样显示“您是不是要输入?”的原因。

根据平均测试,排序不会影响时间。

def similar_movies(movie):
    start=time.clock()
    movie=capitalize(movie)
    similarmovies={}
    allmovies=all_movies() #returns set of all 68000 movies
    for item in allmovies:
        '''if similar(movie.lower(),item.lower())>.5 or movie in item: #older algorithm
            similarmovies[item]=similar(movie.lower(),item.lower())'''
        if movie in item: #newer algorithm,
                similarmovies[item]=1.0
                print item
        else:
            similarmovies[item]=similar(movie.lower(),item.lower())
    similarmovieshigh=sorted(similarmovies, key=similarmovies.get, reverse=True)[:10]
    print time.clock()-start
    return similarmovieshigh

使用的其他功能:

from difflib import SequenceMatcher
def similar(a, b):
    output=SequenceMatcher(None, a, b).ratio()
    return output

def all_movies(): #returns set of all keys in sub dicts(movies)
    people=list(ratings.keys())
    allmovies=[]
    for item in people:
        for i in ratings[item]:
            allmovies.append(i)
    allmovies=set(allmovies)
    return allmovies

字典采用这种格式,但有数千个名称:

rating = {'Shane':{'Avatar':4.2,'127 Hours':4.7},'Joe':{'Into The Wild':4.5,'Unstoppable':3.0}}

您的算法将为O(n 2 ),因为在每个标题中, in运算符必须检查标题的每个子字符串,以确定输入的文本是否在其中。 是的,我可以理解为什么您希望它运行得更快。

i3不能提供太多的计算能力,因此唯一的解决方案是尽可能地进行预计算,而再次运行该功能,则运行额外的软件(例如数据库)可能会产生较差的结果。

您可能会考虑使用标题词词典(可能通过预先计算的语音变化来消除最常见的拼写错误-Porter Stemmer算法应提供一些有用的归约规则,例如,允许“不停”匹配“不停”)。

因此,例如,词典中的一个键将是“ wild”(或语音调整),并且与该键关联的值将是包含“ wild”的所有标题的列表; 在68,000个标题列表中,“ the”,“ into”,“ avatar”,“ hours”,“ 127”以及所有其他单词的含义相同。 举例来说,字典的“ wild”条目可能类似于:

"wild": ["Into The Wild", "Wild Wild West", "Wild Things"]

(是的,我只是在IMDB上搜索“ wild”,所以此列表中可能有更多条目-可能不是最佳选择,但是其中没有“ avatar”,“ unstoppable”或“ hours”的标题很少)。

诸如“ the”之类的常用词可能有足够多的条目,您希望将它们排除在外,因此,词典的持久副本可能有助于您进行特定的调整,尽管这不是必需的,并且计算时间应该是启动相对较快。

当用户键入某些文本时,您将文本拆分为多个单词,如果选择使用它们,则应用任何语音简化,然后将用户的所有单词的所有标题列表(包括重复项)串联起来。

然后,计算重复项并按标题匹配的次数排序。 如果用户键入“ The Wild”,则您在“ Into The Wild”中将有两个匹配项(“ the”和“ wild”),因此它的排序应比仅包含“ the”或“ wild”的标题更高,在他们中。

您可以在建立最终排序列表之后搜索等级列表,并将等级附加到每个条目上; 此操作应该很快,因为您的评分已在字典中,并以名称为关键字。

对于输入的每个单词,这会将O(n 2 )搜索转换为O(log(n))搜索,如果适合您的需求,这将在性能上产生很大的不同。

all_movies()不是附加到一个列表中,您可以添加一组,而不是投键()到一个列表:

def all_movies():
    allmovies = set()
    for item in ratings.keys():
        for i in ratings[item]:
            allmovies.add(i)
    return allmovies

编辑:或者只能用一个for循环:

def all_movies():
    result = []
    for rating_dict in ratings.values()
        result += rating_dict.keys()
    return result

我看similar_movies

也可以看看celery: http//docs.celeryproject.org/en/latest/用于多处理,
尤其是chunks的概念: http://docs.celeryproject.org/en/latest/userguide/canvas.html#chunks

如果您正在为生产系统进行开发,建议您使用全文搜索引擎,如Whoosh(Python)Elastic Search(Java)Apache Solr(Java) 全文搜索引擎是一种服务器,它构建索引以有效地实现包括模糊或接近搜索在内的全文搜索。 许多流行的数据库系统还具有完整的搜索文本引擎,例如PostgreSQL FTSMySQL FTS ,如果您已经在使用这些数据库引擎,它们可能是可接受的替代方法。

如果此代码主要是为自学而开发的,并且您想学习如何实现模糊搜索,则可能需要查看将索引和搜索字词中的电影标题标准化。 诸如SoundexMetaphone之类的方法可以根据其在英语中的发音方式对搜索词进行归一化,并且可以使用此归一化的词来创建搜索索引。 PostgreSQL已经实现了这些算法 请注意,这些算法是非常基本的构建块,适当的全文本搜索引擎将考虑拼写错误,同义词,停用词,特定于语言的怪癖以及诸如并行/分布式处理等优化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM