簡體   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