问题描述
在完成星座运势function的编写中,面临着用户不知道其星座的场景。此时用户将回答出生月日。bot需要把月和日的数字提取出来,换算到对应星座。
出现的问题:
1.无法将同为entities的两个数字提取出来 [7,15] -> [7]
2.无法将中文识别出来
初始代码
nlu中:
这里把month和day分开写的
- [1](month)月[2](day)日
- [3](month)月[9](day)日
- [4](month)月[12](day)日
- [5](month)月[27](day)号
- [7](month)月[2](day)日
- [11](month)月[12](day)号
- [八](month)月[十二](day)日
- [九](month)月[二十一](day)日
- [三](month)月[五](day)日
- [十一](month)月[七](day)日
- [七](month)月[六](day)号
- [八](month)月[十五](day)日
- [1](month)
- [2](month)
- [3](month)
- [4](month)
- [5](month)
- [6](month)
- [7](month)
story中:
- story: 用户询问星座+用户不知道自己星座+月份星座匹配
steps:
- intent: ask_horoscope_vague
- action: utter_for_starsign
- intent: user_not_know_starsign
- action: utter_for_month_and_day
- intent: inform
entities:
- month: "五"
- day: "十二"
- action: action_return_star
- action: action_report_horoscope
action中:
引入pycnnum对中文数字和阿拉伯数字进行转换
注意isnumeric()
是对字符串中是否含有数字(中文阿拉伯均可)进行判断,isdigit()
是判断是字符串还是数字
class ReturnStarAction(Action):
def name(self) -> Text:
return "action_return_star"
def checkdate(self, tracker):
month = tracker.get_slot("month")
day = tracker.get_slot("day")
date_accurate = False
if month.isdigit() == False:
month = pycnnum.cn2num(month)
if int(month) > 0 and int(month) < 13:
date_accurate = True
if day.isdigit() == False:
day = pycnnum.cn2num(day)
if int(day) > 0 and int(day) < 32:
date_accurate = True
return month, day, date_accurate
def findstar(self, month, day):
daylist = [20, 19, 21, 20, 21, 22, 23, 23, 23, 24, 23, 22]
starlist = ['摩羯座', '水瓶座', '双鱼座', '白羊座', '金牛座', '双子座', '巨蟹座', '狮子座', '处女座', '天秤座', '天蝎座', '射手座']
if int(day) < daylist[int(month) - 1]:
return starlist[int(month) - 1]
else:
return starlist[int(month)]
def run(self, dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
month, day, checkdate_status = self.checkdate(tracker)
if checkdate_status == False:
dispatcher.utter_message(text=f"我寻思着这日期只应天上有,要不您说个靠谱的?")
return []
else:
star = self.findstar(month, day)
dispatcher.utter_message(text=f"原来你是{star}~!")
return [SlotSet('starsign_type', star)]
解决方案一
修改pipeline
因为中文字体不存在空格,有一些专门为英文设计的模型就不能使用,token出现错位的情况。可以通过修改pipeline中的模型来改善这个问题。
但在rasa论坛中找了一圈,也没找到合适的pipeline,这个跑通的版本是段老师给的。
在config文件中
language: "zh"
pipeline:
- name: zh_rasa.TFNLUClassifier
epochs: 10
encoder_path: https://code.aliyun.com/qhduan/bert_part/raw/508f4beacff09890d60fbaf273dff6c0d4932863/roberta_wwm_1.tar.gz
- name: zh_rasa.TFNLUExtractor
epochs: 30
encoder_path: https://code.aliyun.com/qhduan/bert_part/raw/508f4beacff09890d60fbaf273dff6c0d4932863/roberta_wwm_1.tar.gz
policies:
- name: MemoizationPolicy
- name: RulePolicy
- name: TEDPolicy
max_history: 5
epochs: 200
constrain_similarities: true
model_confidence: linear_norm
解决方案二
把用户的整句话放到action中,然后用python正则表达式识别日期。
message = tracker.latest_message.text
:用来返回用户的整句话
关于python正则表达提取日期