Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Spacy短语匹配器-匹配字符串中的所有关键字,而不是其中一个关键字_Python_Spacy - Fatal编程技术网

Python Spacy短语匹配器-匹配字符串中的所有关键字,而不是其中一个关键字

Python Spacy短语匹配器-匹配字符串中的所有关键字,而不是其中一个关键字,python,spacy,Python,Spacy,我试图解决根据关键字将文本分类到桶中的任务。当我需要将文本与一个或多个关键字(因此其中一个关键字应在文本中)进行匹配时,这是相当容易的,但是当我需要确保字符串中存在多个关键字时,我很难理解如何进行匹配 下面是一个小样本。假设我的dfArticles是一个pandas数据框架,它有一列Text,与我尝试匹配的文本文章: dfArticles['Text'] Out[2]: 0 (Reuters) - Major Middle Eastern markets ended... 1

我试图解决根据关键字将文本分类到桶中的任务。当我需要将文本与一个或多个关键字(因此其中一个关键字应在文本中)进行匹配时,这是相当容易的,但是当我需要确保字符串中存在多个关键字时,我很难理解如何进行匹配

下面是一个小样本。假设我的
dfArticles
是一个pandas数据框架,它有一列
Text
,与我尝试匹配的文本文章:

dfArticles['Text']
Out[2]: 
0       (Reuters) - Major Middle Eastern markets ended...
1       MIDEAST STOCKS-Oil price fall hurts major Gulf...
2       DUBAI, 21st September, 2020 (WAM) -- The Minis...
3       DUBAI, (UrduPoint / Pakistan Point News / WAM ...
4       Brent crude was down 99 cents or 2.1% at $42.2.
我们还可以说,我的dataframe
dfTopics
包含我试图匹配的关键字列表以及与关键字关联的bucket:

dfTopics
Out[3]: 
            Topic              Keywords
0     Regulations                   law
1     Regulations            regulatory
2     Regulations            regulation
3     Regulations           legislation
4     Regulations                 rules
5          Talent            capability
6          Talent             workforce
def textToTopic(text, topics):
    t = []
    for k,v in topics.items():
        if all([topic in text.split() for topic in v]):
            t.append(k)
    return t
当我只需要检查文本是否匹配其中一个关键字时,很简单:

def prep_match_patterns(dfTopics):
    
    matcher = PhraseMatcher(nlp.vocab, attr="LOWER")
    
    for topic in dfTopics['Topic'].unique():
        keywords = dfTopics.loc[dfTopics['Topic'] == topic, 'Keywords'].to_list()
        patterns_topic = [nlp.make_doc(text) for text in keywords]
        matcher.add(topic, None, *patterns_topic)
    return matcher
然后,我可以很容易地用一个镜头检查文本属于哪个桶:

nlp = spacy.load("en_core_web_lg")
nlp.disable_pipes(["parser"])
# extract the sentences from the documents
nlp.add_pipe(nlp.create_pipe('sentencizer'))

matcher = prep_match_patterns(dfTopics)


dfResults = pd.DataFrame([],columns=['ArticleID', 'Topic'])


articles = []
topics = []


for index, row in tqdm(dfArticles.iterrows(), total=len(dfArticles)):
    doc = nlp(row['Text'])
    matches = matcher(doc)
    if len(matches)<1:
        continue
    else:
        for match_id, start, end in matches:
            string_id = nlp.vocab.strings[match_id]  # Get string representation
            articles.append(row['ID'])
            topics.append(string_id)
    
dfResults['ArticleID'] = articles
dfResults['Topic'] = topics


dfResults.drop_duplicates(inplace=True)
nlp=spacy.load(“en_core\u web\u lg”)
nlp.禁用_管道([“解析器”])
#从文件中摘录句子
nlp.add_管道(nlp.create_管道(“判刑器”))
匹配器=准备匹配模式(dfTopics)
dfResults=pd.DataFrame([],列=['ArticleID','Topic'])
条款=[]
主题=[]
对于索引,TQM中的行(dfArticles.iterrows(),total=len(dfArticles)):
doc=nlp(第['Text']行)
匹配=匹配器(文档)

如果len(匹配)我认为你太复杂了。您可以使用简单的python实现您想要的

假设我们有:

df_topics
    Topic   Keywords
0   Regulations law
1   Regulations regulatory
2   Regulations regulation
3   Regulations legislation
4   Regulations rules
5   Talent  capability
6   Talent  workforce
然后,您可以将主题关键字组织到词典中:

topics = df_topics.groupby("Topic")["Keywords"].agg(lambda x: x.to_list()).to_dict()
topics
{'Regulations': ['law', 'regulatory', 'regulation', 'legislation', 'rules'],
 'Talent': ['capability', 'workforce']}
最后,定义一个func以匹配关键字:

dfTopics
Out[3]: 
            Topic              Keywords
0     Regulations                   law
1     Regulations            regulatory
2     Regulations            regulation
3     Regulations           legislation
4     Regulations                 rules
5          Talent            capability
6          Talent             workforce
def textToTopic(text, topics):
    t = []
    for k,v in topics.items():
        if all([topic in text.split() for topic in v]):
            t.append(k)
    return t
演示:



您可以将此函数应用于
df

中的文本,如果您的文本中不是确切的关键字,而是它的派生词呢?如果你说5场比赛中有4场怎么办?如果部分列表同时匹配两个类别会怎样?有什么特别的理由和斯帕西一起做吗?@SergeyBushmanov她的Sergey。想法是,对于每一个桶,我有几个匹配模式,如果文本匹配任何模式,我认为这是一个匹配。如果文本匹配多个类别-就这样吧,我将捕获两个匹配项。精确或导数不重要,实际上我在进行词干分析后运行所有操作,这里只是一个简化的示例。我根本不想使用spacy,我只是相信我现有的代码Hey Sergey。抱歉耽搁了。是的,看起来很整洁!我有点惊讶,尽管spacy似乎比纯python方法快(在我的例子中,PhraseMatcher几乎快2倍)。但它让我绕过了查找“文本中的所有关键字”的问题,所以谢谢!不客气!如果首选2X
PhraseMatcher
,您可以使用
all()
遵循相同的逻辑,将短语匹配器输入到
all
。但逻辑仍然是一样的:无法直接加载此逻辑,请使用变通方法。