多意图自然语言处理和分类
Multi-intent natural language processing and classification
所以,我正在制作我自己的家庭助理,我正在尝试制作一个多意图分类系统。但是,我找不到将用户所说的查询拆分为查询中的多个不同意图的方法。
例如:
I have my data for one of my intents (same format for all)
{"intent_name": "music.off" , "examples": ["turn off the music" , "kill
the music" , "cut the music"]}
用户所说的查询将是:
'dim the lights, cut the music and play Black Mirror on tv'
我想把句子分成他们各自的意图,例如:
['dim the lights', 'cut the music', 'play black mirror on tv']
但是,我不能只在带有 and
和 ,
的句子中使用 re.split
作为分隔符,就好像用户问的那样:
'turn the lights off in the living room, dining room, kitchen and bedroom'
这将拆分为
['turn the lights off in the living room', 'kitchen', 'dining room', 'bedroom']
我的意图检测无法使用它
这是我的问题,提前谢谢你
更新
好的,我的代码已经走到这一步了,它可以从我的数据中获取示例并按照我的意愿识别内部的不同意图,但是它并没有将原始查询的各个部分拆分为各自的意图和只是匹配。
import nltk
import spacy
import os
import json
#import difflib
#import substring
#import re
#from fuzzysearch import find_near_matches
#from fuzzywuzzy import process
text = "dim the lights, shut down the music and play White Collar"
commands = []
def get_matches():
for root, dirs, files in os.walk("./data"):
for filename in files:
f = open(f"./data/{filename}" , "r")
file_ = f.read()
data = json.loads(file_)
choices.append(data["examples"])
for set_ in choices:
command = process.extract(text, set_ , limit=1)
commands.append(command)
print(f"all commands : {commands}")
这个 returns [('dim the lights') , ('turn off the music') , ('play Black Mirror')]
这是正确的意图,但我无法知道查询的哪一部分与每个意图相关 - 这是主要问题
我的数据如下,暂时很简单,直到我想出一个方法:
play.json
{"intent_name": "play.device" , "examples" : ["play Black Mirror" , "play Netflix on tv" , "can you please stream Stranger Things"]}
music.json
{"intent_name": "music.off" , "examples": ["turn off the music" , "cut the music" , "kill the music"]}
lights.json
{"intent_name": "lights.dim" , "examples" : ["dim the lights" , "turn down the lights" , "lower the brightness"]}
看来你的问题中混合了两个问题:
- 单个查询中的多个独立意图(例如
shut down the music and play White Collar
)
- 多个 slots(使用 form-filling 框架)在一个意图中(例如
turn the lights off in the living room bedroom and kitchen
)。
这些问题是完全不同的。然而,两者都可以表述为单词标记问题(类似于 POS-tagging)并通过机器学习解决(例如 CRF 或 bi-LSTM 在预训练的单词嵌入上,预测每个单词的标签)。
可以使用 BIO 符号创建每个单词的意图标签,例如
shut B-music_off
down I-music_off
the I-music_off
music I-music_off
and O
play B-tv_on
White I-tv_on
Collar I-tv_on
turn B-light_off
the I-light-off
lights I-light-off
off I-light-off
in I-light-off
the I-light-off
living I-light-off
room I-light-off
bedroom I-light-off
and I-light-off
kitchen I-light-off
模型会读取句子并预测标签。它应该接受至少数百个示例的训练——你必须生成或挖掘它们。
使用在此类标签上训练的模型拆分意图后,您将拥有对应于每个独特意图的短文本。然后对于每一个短文本你都需要运行进行二次切分,寻找槽位。例如。关于光的句子可以表示为
turn B-action
the I-action
lights I-action
off I-action
in O
the B-place
living I-place
room I-place
bedroom B-place
and O
kitchen B-place
现在 BIO 标记非常有用:the B-place
标记将 bedroom
与 the living room
分开。
两种分割原则上都可以由一个分层 end-to-end 模型执行(google 语义解析,如果你想要的话),但我觉得两个更简单的标注器也可以工作。
所以,我正在制作我自己的家庭助理,我正在尝试制作一个多意图分类系统。但是,我找不到将用户所说的查询拆分为查询中的多个不同意图的方法。
例如:
I have my data for one of my intents (same format for all)
{"intent_name": "music.off" , "examples": ["turn off the music" , "kill
the music" , "cut the music"]}
用户所说的查询将是:
'dim the lights, cut the music and play Black Mirror on tv'
我想把句子分成他们各自的意图,例如:
['dim the lights', 'cut the music', 'play black mirror on tv']
但是,我不能只在带有 and
和 ,
的句子中使用 re.split
作为分隔符,就好像用户问的那样:
'turn the lights off in the living room, dining room, kitchen and bedroom'
这将拆分为
['turn the lights off in the living room', 'kitchen', 'dining room', 'bedroom']
我的意图检测无法使用它
这是我的问题,提前谢谢你
更新
好的,我的代码已经走到这一步了,它可以从我的数据中获取示例并按照我的意愿识别内部的不同意图,但是它并没有将原始查询的各个部分拆分为各自的意图和只是匹配。
import nltk
import spacy
import os
import json
#import difflib
#import substring
#import re
#from fuzzysearch import find_near_matches
#from fuzzywuzzy import process
text = "dim the lights, shut down the music and play White Collar"
commands = []
def get_matches():
for root, dirs, files in os.walk("./data"):
for filename in files:
f = open(f"./data/{filename}" , "r")
file_ = f.read()
data = json.loads(file_)
choices.append(data["examples"])
for set_ in choices:
command = process.extract(text, set_ , limit=1)
commands.append(command)
print(f"all commands : {commands}")
这个 returns [('dim the lights') , ('turn off the music') , ('play Black Mirror')]
这是正确的意图,但我无法知道查询的哪一部分与每个意图相关 - 这是主要问题
我的数据如下,暂时很简单,直到我想出一个方法:
play.json
{"intent_name": "play.device" , "examples" : ["play Black Mirror" , "play Netflix on tv" , "can you please stream Stranger Things"]}
music.json
{"intent_name": "music.off" , "examples": ["turn off the music" , "cut the music" , "kill the music"]}
lights.json
{"intent_name": "lights.dim" , "examples" : ["dim the lights" , "turn down the lights" , "lower the brightness"]}
看来你的问题中混合了两个问题:
- 单个查询中的多个独立意图(例如
shut down the music and play White Collar
) - 多个 slots(使用 form-filling 框架)在一个意图中(例如
turn the lights off in the living room bedroom and kitchen
)。
这些问题是完全不同的。然而,两者都可以表述为单词标记问题(类似于 POS-tagging)并通过机器学习解决(例如 CRF 或 bi-LSTM 在预训练的单词嵌入上,预测每个单词的标签)。
可以使用 BIO 符号创建每个单词的意图标签,例如
shut B-music_off
down I-music_off
the I-music_off
music I-music_off
and O
play B-tv_on
White I-tv_on
Collar I-tv_on
turn B-light_off
the I-light-off
lights I-light-off
off I-light-off
in I-light-off
the I-light-off
living I-light-off
room I-light-off
bedroom I-light-off
and I-light-off
kitchen I-light-off
模型会读取句子并预测标签。它应该接受至少数百个示例的训练——你必须生成或挖掘它们。
使用在此类标签上训练的模型拆分意图后,您将拥有对应于每个独特意图的短文本。然后对于每一个短文本你都需要运行进行二次切分,寻找槽位。例如。关于光的句子可以表示为
turn B-action
the I-action
lights I-action
off I-action
in O
the B-place
living I-place
room I-place
bedroom B-place
and O
kitchen B-place
现在 BIO 标记非常有用:the B-place
标记将 bedroom
与 the living room
分开。
两种分割原则上都可以由一个分层 end-to-end 模型执行(google 语义解析,如果你想要的话),但我觉得两个更简单的标注器也可以工作。