Rasa學(xué)習(xí)筆記2--Rasa Core

[TOC]

Rasa學(xué)習(xí)筆記2--Rasa Core

1. 概念介紹

首先引出Rasa的設(shè)計理念:
Learning from real conversations is more important than designing hypothetical ones饭玲,我覺得這是非常重要的事情塘雳,我們在構(gòu)建自己的bot的時候 钞啸,我們往往想絞盡腦汁來排列組合出各種意圖的story培漏,但是在實際應(yīng)用中蚯姆,我們發(fā)現(xiàn)不管我們的story庫有多豐富沧侥,還是會有大量的unhappy path無法處理瞎疼,所以我們應(yīng)該想方設(shè)法從真實的對話中來抽象sotry工窍。

1.1 Stories

sotry就是Rasa用來訓(xùn)練對話管理模型的數(shù)據(jù)集割卖。格式如下:*開頭的表示某一輪用戶輸入的intent和slot信息。-開頭的表示分配給bot對應(yīng)的action患雏。

## greet + location/price + cuisine + num people    <!-- name of the story - just for debugging -->
* greet
   - action_ask_howcanhelp
* inform{"location": "rome", "price": "cheap"}  <!-- user utterance, in format intent{entities} -->
   - action_on_it
   - action_ask_cuisine
* inform{"cuisine": "spanish"}
   - action_ask_numpeople        <!-- action that the bot should execute -->
* inform{"people": "six"}
   - action_ack_dosearch

1.2 Domains

定義了整個系統(tǒng)需要操作的所有元素鹏溯,包括:intent,slot,entity,template,actions。

1.3 Actions

定了了bot具體執(zhí)行動作纵苛。在Rasa中定了四種action剿涮,包括:

  1. Utterance actions,直接返回template中定義的話術(shù)攻人。
  2. Retrieval actions取试,閑聊(small talk)和FAQ(small questions)的方式。
  3. Custom actions怀吻,用戶自定義瞬浓。用戶自定義的action,需要發(fā)布action server,然后通過HTTP請求來獲取執(zhí)行action的答案蓬坡。
  4. Defailt actions,比如:action_listen, action_restart, action_default_fallback等

1.4 Policies

所謂policy就是bot在對話中的每一步?jīng)Q定要執(zhí)行哪一個action猿棉。我們可以在config.yml中配置多個policies磅叛,Agent會根據(jù)policy的執(zhí)行優(yōu)先級來選擇最終的action。
Max_history 萨赁,bot再決定action時會向前考慮的對話輪數(shù)弊琴。
Data Augmentation, 在訓(xùn)練模型是杖爽,Rasa會從stories.md中隨機取出sotry拼接一起看作一個story敲董,用來做數(shù)據(jù)擴(kuò)充。

agent決定action的一般原則是選擇這些policy給的得分最大的action慰安,但是當(dāng)兩個policy給出了相同的最高得分腋寨,這時候就需要根據(jù)policy的priority來下決定采取哪一個policy的結(jié)果。在Rasa中推薦的設(shè)置是:

5. FormPolicy
4. FallbackPolicy and TwoStageFallbackPolicy
3. MemoizationPolicy and AugmentedMemoizationPolicy
2. MappingPolicy
1. EmbeddingPolicy, KerasPolicy, and SklearnPolicy

1.4.1 KarasPolicy

構(gòu)造訓(xùn)練數(shù)據(jù)和模型輸入:

  1. 對于每個story化焕,會先封裝成一個TrackerWithCachedStates對象實例萄窜,里面包括:
    sender_id: story標(biāo)識
    _states: 這個story可以生成的所有對話狀態(tài)的組合,內(nèi)容是[最大max_history的狀態(tài)+一下個狀態(tài)]
    domain
    slots,此story包含的slots和值
    latest_message撒桨,
    latest_action_name查刻,
    latest_bot_utterance,
    event,包括ActionExcuted,UserUttered,SlotSet等,封裝domain中的所有內(nèi)容

  2. 構(gòu)造對話狀態(tài)與預(yù)測action
    分別是:trackers_as_states和trackers_as_actions元莫,他們是一一對應(yīng)的關(guān)系赖阻,去重之后會有n個組合。其中:
    trackers_as_states踱蠢,所有max_history狀態(tài)的組合火欧,比如:



    trackers_as_actions,預(yù)測的action茎截,比如對應(yīng)上面005:


  3. 將上述結(jié)果編碼苇侵,構(gòu)造模型輸入X,Y
    X:shape(n, max_history, feature_num),其中feature_num=envent的數(shù)量企锌,使用one-hot編碼榆浓,為1的位置,表示當(dāng)前state的Event撕攒。因為Event的定義就是用來描述對話中的所有內(nèi)容陡鹃。

Y: shape(n, actins_num),因為policy只預(yù)測action抖坪,所以Y的one-hot用來表示預(yù)測的actin來萍鲸。

1.4.2 Embedding Policy (Transformer Embedding Dialogue Policy)

1.5 Forms

現(xiàn)看一個使用Form實現(xiàn)的對話情形:


所謂form就是slot filling擦俐,是我們在實現(xiàn)任務(wù)型對話的一般思路,及:首先定義一些必須槽位,每個槽位會構(gòu)建一個反問話術(shù)品擎,然后bot會順序反問用戶,收集信息备徐,直到填滿所有槽位萄传。FormAction就是來實現(xiàn)這個功能蜜猾。

名詞解釋:happy path就是指你問用戶什么信息瓣铣,用戶就配個回答給bot這個信息。

比如下面這個happy path:

## happy path
* greet
    - utter_greet
* request_restaurant
    - restaurant_form
    - form{"name": "restaurant_form"}
    - form{"name": null}
    - utter_slots_values
* thankyou
    - utter_noworries

當(dāng)用戶意圖是request_restaurant贷揽,bot會接著執(zhí)行restaurant_form action棠笑。form{"name": "restaurant_form"}會激活這個form禽绪,form{"name": null}會關(guān)閉這個form。對于unhappy path的情形循捺,bot可以執(zhí)行任意其他的action雄人,只要這個form還是active的。

我們可以使用Rasa提供的sdk來定制自己的FormAction础钠,需要實現(xiàn)下面三個方法:

  • name(),aciton的名字
  • required_slots()旗吁,列出來所有必須的槽位
  • submit()方法,當(dāng)所有槽位被填充很钓,此action產(chǎn)生的結(jié)果或者執(zhí)行的動作。

一旦form action被激活企孩,FormPolicy會對應(yīng)的被激活叹洲,FormPolicy非常簡單,它預(yù)測的一下個動作永遠(yuǎn)還是form action蝗柔。

定制化slot mapping
有時候我們填充槽位不一定只是用抽取到的slot value,也可以是多種形式的回答槽畔。比如當(dāng)bot問:"您是要坐在外面嗎?"胁编,用戶可能的回答有:“是的”/"不是"/“我更喜歡坐在里面”。這幾個回答都是不同的意圖或者是相同實體中的其他value早直,但卻都是正確的回答市框,所以,我們要將這些答案mapping到這一輪的槽位上喻圃。
FormAction可以支持將yes/no以或者自由文本映射到slot中,只需要實現(xiàn)slot_mappings()方法粪滤。

def slot_mappings(self):
    # type: () -> Dict[Text: Union[Dict, List[Dict]]]
    return { "outdoor_seating": [self.from_entity(entity="seating"),
                      self.from_intent(intent='affirm', value=True),
                      self.from_intent(intent='deny', value=False)]}

如上所示,我們將所有mapping策略函數(shù)封裝在list中肆汹,賦值給目的槽位"outdoor_seating"予权。詳細(xì)來講:

  1. from_entity,將抽取出來的"seating"(seating表示實體)的value填充到outdoor_seating
  2. from_intent硼啤,如果識別的意圖是affirm斧账,True填充到outdoor_seating,反之嗓袱,F(xiàn)alse填充到outdoor_seating习绢。
    還有其他的復(fù)制策略函數(shù)蝙昙,from_trigger_intent梧却,from_text放航。

slot value validation
有時候我們需要對用戶輸入的slot value進(jìn)行個性化的確認(rèn),我們可以在FormAction中使用 validate_{slot-name} 方法來實現(xiàn)荆几。當(dāng)然赊时,我們也可以在validate的過程中來終止form,即放validate方法返回self.deactivate()焊傅,或者重新反問狈涮。

處理unhappy path
在FormAction執(zhí)行過程中鸭栖,如果用戶不配合,比如:問其他問題松却、閑聊或者改變了主意溅话,這時候form會引起ActionExecutionRejection,所以砚哆,你需要采取措施不讓這種情形產(chǎn)生屑墨。比如,
處理閑聊情形的story如下:

## chitchat
* request_restaurant
    - restaurant_form
    - form{"name": "restaurant_form"}
* chitchat
    - utter_chitchat
    - restaurant_form
    - form{"name": null}

當(dāng)用戶改變注意战转,不在詢問最初的需求以躯,這時候bot就不能繼續(xù)詢問最初form的槽位。便可以使用action_deactivate_form來關(guān)閉此form:

## chitchat
* request_restaurant
    - restaurant_form
    - form{"name": "restaurant_form"}
* stop
    - utter_ask_continue
* deny
    - action_deactivate_form
    - form{"name": null}

處理待條件的slot的邏輯
這個功能是為了讓對話更加靈活和有個性化刁标,比如某個人回答要吃希臘菜命雀,bot可以反問他是不是需要露天的座位±羯埃可以在FormAction中通過required_slots()來實現(xiàn):

@staticmethod
def required_slots(tracker) -> List[Text]:
   """A list of required slots that the form has to fill"""

   if tracker.get_slot('cuisine') == 'greek':
     return ["cuisine", "num_people", "outdoor_seating",
             "preferences", "feedback"]
   else:
     return ["cuisine", "num_people",
             "preferences", "feedback"]

1.6 檢索動作(retrieval action)

這個是Rasa在實驗的新功能狐血,主要作用是為了在解決閑聊(small talk)和Faq(simple question)問題時,可以簡化構(gòu)建story浪默,因為這些都是單輪的對話缀匕,可以嘗試通過一個aciton解決掉。

比如阔加,我們可以不在使用下面這些story:

## weather
* ask_weather
   - utter_ask_weather

## introduction
* ask_name
   - utter_introduce_myself

...

而是用一個chitchat意圖來將上面所有意圖包裝起來:

## chitchat
* chitchat
   - respond_chitchat

然后retrival action使用NLU組件中的response selector模型來學(xué)習(xí)和預(yù)測結(jié)果满钟。

訓(xùn)練數(shù)據(jù)

準(zhǔn)備NLU訓(xùn)練數(shù)據(jù):

## intent: chitchat/ask_name
- what's your name
- who are you?
- what are you called?

## intent: chitchat/ask_weather
- how's weather?
- is it sunny where you are?

首先所有上面的sample將被放在一起用來訓(xùn)練意圖識別模型用來預(yù)測chitchat類別湃番。然后通過一個'/'符號來分隔出來的后綴就是對應(yīng)的答案,將作為訓(xùn)練模型的label吠撮,這其實就是一個問題-答案的qq模型。

然后泥兰,在另外一個response.md文件中準(zhǔn)備response語料:

## ask name
* chitchat/ask_name
    - my name is Sara, Rasa's documentation bot!
    
## ask weather
* chitchat/ask_weather
    - it's always sunny where I live

1.7 interactive actions

1.8 Fallback Action

當(dāng)NLU得分低于某個閾值或者policy預(yù)測低于某個閾值逾条,需要進(jìn)行對話回退,也就是嘗試讓用戶重新表達(dá)师脂。有下面兩種用法:

  • 使用FallbackPolicy
policies:
 - name: "FallbackPolicy"
    nlu_threshold: 0.4
    core_threshold: 0.3
    fallback_action_name: "action_default_fallback"

action_default_fallback這個action會對應(yīng)執(zhí)行模板中定義的utter_default來反問客戶。

  • 使用TwoStageFallbackPolicy
policies:
 - name: TwoStageFallbackPolicy
    nlu_threshold: 0.3
    core_threshold: 0.3
    fallback_core_action_name: "action_default_fallback"
    fallback_nlu_action_name: "action_default_fallback"
    deny_suggestion_intent_name: "out_of_scope"

當(dāng)用戶輸入低于nlu閾值啄育,TwoStageFallbackPolicy會采用多個階段來處理:

  • 如果用戶輸入低于nlu閾值拌消,bot執(zhí)行 action_default_ask_affirmation讓用戶確認(rèn)輸入: 如果用戶說yes,則把輸入看作大于閾值的輸入, sotry繼續(xù)氓英。如果用戶否認(rèn)鹦筹,讓用戶重新輸入。
  • 執(zhí)行action_default_ask_rephrase讓用戶重新輸入:如果用戶用戶重新輸入的句子大于閾值徘键,則sotry繼續(xù)遍蟋。如果用戶輸入再一次低于閾值,再次讓用戶確定意圖它呀。
  • 執(zhí)行action_default_ask_affirmation讓用戶二次確認(rèn):如果用戶確認(rèn)挟憔,則story繼續(xù)烟号。如果用戶否認(rèn)汪拥,用戶輸入會被認(rèn)定為'deny_suggestion_intent_name',就會執(zhí)行最終的召回動作fallback_nlu_action_name(比如轉(zhuǎn)人工)。

1.8 Knowledge Base Actions

目前Rasa使用這個action主要解決兩個問題:

  • 當(dāng)用戶需要具體問某個實體的信息和屬性
  • 解決指代問題
    如下面這個例子:


1.8.1 Knowledge Base

rasa_sdk中提供數(shù)據(jù)庫加載的抽象類:InMemoryKnowledgeBase宪赶,直接:knowledge_base = InMemoryKnowledgeBase("knowledge_base_data.json")來構(gòu)造實例脯燃。文檔中提供的一個數(shù)據(jù)庫例子如下:

{
    "restaurant": [
        {
            "id": 0,
            "name": "Donath",
            "cuisine": "Italian",
            "outside-seating": true,
            "price-range": "mid-range"
        },
        {
            "id": 1,
            "name": "Berlin Burrito Company",
            "cuisine": "Mexican",
            "outside-seating": false,
            "price-range": "cheap"
        },
        {
            "id": 2,
            "name": "I due forni",
            "cuisine": "Italian",
            "outside-seating": true,
            "price-range": "mid-range"
        }
    ],
    "hotel": [
        {
            "id": 0,
            "name": "Hilton",
            "price-range": "expensive",
            "breakfast-included": true,
            "city": "Berlin",
            "free-wifi": true,
            "star-rating": 5,
            "swimming-pool": true
        },
        {
            "id": 1,
            "name": "Hilton",
            "price-range": "expensive",
            "breakfast-included": true,
            "city": "Frankfurt am Main",
            "free-wifi": true,
            "star-rating": 4,
            "swimming-pool": false
        },
        {
            "id": 2,
            "name": "B&B",
            "price-range": "mid-range",
            "breakfast-included": false,
            "city": "Berlin",
            "free-wifi": false,
            "star-rating": 1,
            "swimming-pool": false
        },
    ]}

這是一個餐館的數(shù)據(jù)辕棚,其中id和name一般都是要配置的邓厕。當(dāng)然我們也可以定制自己的數(shù)據(jù)庫扁瓢。

1.8.2 準(zhǔn)備NLU data

首先定義一個新的意圖query_knowledge_base來表示“查詢數(shù)據(jù)庫”的用戶意圖引几,然后bot對應(yīng)的執(zhí)行``ActionQueryKnowledgeBase `動作,目前rasa中可以解決的兩種分類是:1. 列舉出用戶指定屬性的所有對象敞掘。2. 用戶想知道某個對象的某個屬性贿讹。對于上述的餐館領(lǐng)域,可以構(gòu)造如下的nlu數(shù)據(jù):

## intent:query_knowledge_base
- what [restaurants](object_type:restaurant) can you recommend?
- list some [restaurants](object_type:restaurant)
- can you name some [restaurants](object_type:restaurant) please?
- can you show me some [restaurant](object_type:restaurant) options
- list [German](cuisine) [restaurants](object_type:restaurant)
- do you have any [mexican](cuisine) [restaurants](object_type:restaurant)?
- do you know the [price range](attribute:price-range) of [that one](mention)?
- what [cuisine](attribute) is [it](mention)?
- do you know what [cuisine](attribute) the [last one](mention:LAST) has?
- does the [first one](mention:1) have [outside seating](attribute:outside-seating)?
- what is the [price range](attribute:price-range) of [Berlin Burrito Company](restaurant)?
- what about [I due forni](restaurant)?
- can you tell me the [price range](attribute) of [that restaurant](mention)?
- what [cuisine](attribute) do [they](mention) have?
 ...

其中:
object_type: 標(biāo)注數(shù)據(jù)庫中的某個實體茄菊。
mention: 標(biāo)注指代赊堪。
attribute: 數(shù)據(jù)庫中包含的屬性哭廉。
另外,使用synonyms來將數(shù)據(jù)中標(biāo)記的單詞映射到數(shù)據(jù)庫中使用的標(biāo)準(zhǔn)格式遵绰,比如:'restaurants'->'restaurant'椿访。
上面有提到目前rasa可以解決的兩種情景:

  1. 從數(shù)據(jù)庫中查詢用戶指定屬性的所有對象。
    當(dāng)用戶想要從數(shù)據(jù)庫中查詢對象成玫,問句中必須包含某個對象哭当,即'object_type',同時需要指定某些屬性钦勘。
    比如:
    What Italian restaurant options in Berlin do I have?
    用戶想得到'object_type'='restaurant'彻采, 條件是{'cuisine'='Italian'朵栖,'city'='Berlin'}柴梆,然后action就通過這兩個條件來篩選符合的對象。
    當(dāng)然想要解析上面的問句需要如下的標(biāo)注:
    What [Italian](cuisine) [restaurant](object_type) options in [Berlin](city) do I have?.
  2. 用戶想知道某個對象的某個屬性门扇。
    這種情形偿渡,比如:
    What is the cuisine of Berlin Burrito Company?
    用戶想知道'Berlin Burrito Company'的'cuisine'溜宽。需要的標(biāo)注如下:
    What is the [cuisine](attribute) of [Berlin Burrito Company](restaurant)?

1.8.3 解決指代

rasa中定義兩種指代,1. 順序指代(ordinal mentions),比如:'the first one'适揉,2. 普通指代嫉嘀,比如'it'。

  • 順序指代
    在bot輸出輪剪侮,當(dāng)給用戶是一系列象列瓣俯,可在解析用戶回答的時候,可以使用一個順序指代映射來解決用戶問題中的指代詞腔剂。這個順序指代映射需要在KnowledgeBase類中定義:
{
    "1": lambda l: l[0],
    "2": lambda l: l[1],
    "3": lambda l: l[2],
    "4": lambda l: l[3],
    "5": lambda l: l[4],
    "6": lambda l: l[5],
    "7": lambda l: l[6],
    "8": lambda l: l[7],
    "9": lambda l: l[8],
    "10": lambda l: l[9],
    "ANY": lambda l: random.choice(list),
    "LAST": lambda l: l[-1],
}

key就是對應(yīng)到nlu標(biāo)注數(shù)據(jù)中的mention后面的值推掸,比如:does the [first one](mention:1) have [outside seating](attribute:outside-seating)?

  • 普通指代
    rasa的處理方案是將上文識最近別到的對象作為指代的對象驻仅。

  • 編寫ActionQueryKnowledgeBase

2. 代碼結(jié)構(gòu)分析和源碼學(xué)習(xí)

  • DialogueStateTracker 保存對話狀態(tài),包括:
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市粘优,隨后出現(xiàn)的幾起案子呻顽,更是在濱河造成了極大的恐慌廊遍,老刑警劉巖贩挣,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件王财,死亡現(xiàn)場離奇詭異,居然都是意外死亡绒净,警方通過查閱死者的電腦和手機挂疆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恃疯,“玉大人墨闲,你說我怎么就攤上這事《芰郏” “怎么了瞻离?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵套利,是天一觀的道長。 經(jīng)常有香客問我验辞,道長喊衫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任壳贪,我火速辦了婚禮,結(jié)果婚禮上互纯,老公的妹妹穿的比我還像新娘磕蒲。我一直安慰自己,他們只是感情好愤兵,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布秆乳。 她就那樣靜靜地躺著钻哩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪扯键。 梳的紋絲不亂的頭發(fā)上珊肃,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機與錄音厉亏,去河邊找鬼烈和。 笑死,一個胖子當(dāng)著我的面吹牛恬试,可吹牛的內(nèi)容都是我干的疯暑。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼畦粮,長吁一口氣:“原來是場噩夢啊……” “哼乖阵!你這毒婦竟也來了瞪浸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤钩蚊,失蹤者是張志新(化名)和其女友劉穎蹈矮,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝠咆,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡刚操,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年再芋,在試婚紗的時候發(fā)現(xiàn)自己被綠了济赎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡华蜒,死狀恐怖豁遭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情捂蕴,我是刑警寧澤闪幽,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布盯腌,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏舌劳。R本人自食惡果不足惜玫荣,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一捅厂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧焙贷,春花似錦辙芍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至捐晶,卻和暖如春惑灵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背英支。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工干花, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抡驼。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓致盟,卻偏偏與公主長得像碎税,于是被迫代替她去往敵國和親馏锡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348