![](/img/trans.png)
[英]Python: How can I make this function for calculating distances faster?
[英]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 FTS和MySQL FTS ,如果您已經在使用這些數據庫引擎,它們可能是可接受的替代方法。
如果此代碼主要是為自學而開發的,並且您想學習如何實現模糊搜索,則可能需要查看將索引和搜索字詞中的電影標題標准化。 諸如Soundex和Metaphone之類的方法可以根據其在英語中的發音方式對搜索詞進行歸一化,並且可以使用此歸一化的詞來創建搜索索引。 PostgreSQL已經實現了這些算法 。 請注意,這些算法是非常基本的構建塊,適當的全文本搜索引擎將考慮拼寫錯誤,同義詞,停用詞,特定於語言的怪癖以及諸如並行/分布式處理等優化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.