我正在使用搜索引擎搜索存储在Solr中的文档。
在用户查询中,我要检测命名实体(人员,组织,城市...)。
示例查询是:
巴拉克奥巴马的妻子年龄
在此查询中,我要检测“奥巴马”是一个人。
由于查询不是真实短语,因此经典NER(Spacy,Stanford NER ...)很难正常工作。因此,我采用了[[此方法:
def find_entities(query,entities_dict):
entities=[]
new_query=query.lower()
for entity in entities_dict:
if find_substring(entity,new_query):
entities.append({entity:entities_dict[entity]})
new_query = re.sub(r'\b{}\b'.format(entity), '', new_query)
return(new_query,entities)
:创建字典需要几分钟;加载后,此方法运行良好,快速且不占用内存。[[在不久的将来,我将拥有50到1亿个实体。目前,我的Solr索引中有大约20万个实体
我认为将这些实体存储在内存中是不可能的。
我该如何改变我的方法?
我正在寻找要使用的算法,内存管理和数据结构的建议。
trie)或Aho-Corasick图中。这些数据结构大大加快了子字符串搜索的速度,因为它们利用了许多实体中具有相同子字符串的事实,试图通过
single遍历将all实体与您的查询进行匹配。
实际上,我已经使用pyahocorasick在短查询中查找了几百万个实体(电影,歌曲,演员等),并且它似乎很好地扩展了。形式上,Aho-Corasick的时间复杂度不取决于实体总数,而仅取决于具体查询中匹配实体的数量。因此,如果搜索变慢(这不太可能),则有必要查看哪些实体产生大量误报匹配并将其从索引中删除。以我为例,在删除非常常见的实体(例如“ It”(这是电影名称!))之后,匹配器的速度甚至更快了。