Bixby Developer Center

Guides
References

Training 모범 사례(best practice)

자연어 Training에서 Bixby가 사용 사례를 이해하도록 학습시키기 위해 캡슐에 자연어 발화를 추가하는 방법을 알아보았습니다.

이 가이드에서는 자연어 Training의 제약 사항과 더 효과적인 Training을 위한 원칙 그리고 모범 사례(best practice)를 설명합니다.

플랫폼과 학습 관련 제약 사항

Bixby는 강력하고 고유한 툴이지만 약간의 제약 사항도 있습니다.

  • Bixby는 누구라도 학습시킬 수 있습니다. 그러나 결과를 정교하게 만들고 싶어하는 NL 전문가가 미세하게 수정한다거나 할 수는 없습니다.
  • Bixby는 소량의 깔끔한(small and clean) 데이터를 사용할 때 가장 잘 동작합니다. 대규모의 지저분한(big and messy) 데이터에는 제대로 작동하지 않을 수도 있습니다.
  • Bixby는 한 가지 기능을 깊이 있게(deep) 동작하는 것보다는 다양한 기능을 수평적으로 확장하는 데 더 잘 동작하도록 설계되었습니다.

이러한 제약 속에서 어떻게 하면 가장 효과적으로 학습시킬 수 있을지 궁금하실 겁니다. 기본적으로 반복적인 테스트를 통해 경험치를 높이고 상식을 활용하는 것이 중요합니다. 동작하는 것과 그렇지 않은 것을 파악하기 위해서는 시행착오(trial and error)가 가장 좋은 방법입니다. 그렇다고 해서 무턱대고 반복에만 의존한다면 너무 많은 시간이 낭비될 수 있습니다. 개발자 커뮤니티와 유용한 예제를 참고하는 것도 도움이 됩니다.

Training의 기본 원칙

효과적인 training을 위해서는 기본적으로는 다음 3가지 기본 원칙을 따르는 것이 좋습니다.

일반적으로 "빅데이터"를 사용하면 많은 자연어 문제를 해결할 수 있지만, Bixby 플랫폼의 경우 위 세 가지 원칙을 잘 따르는 작고 대표성을 갖는 "스마트한" 데이터만으로도 충분히 잘 동작합니다.

지원 범위 최소화(Tightly-Scoped)

효과적인 캡슐은 노출 범위를 최소화합니다.

캡슐의 범위가 해당 도메인의 노출 범위인 경우 이 범위를 최소화해야 합니다. NL과 연관된 feature가 추가되면 될수록 처리에 필요한 데이터 양과 종류도 늘어나기 마련입니다.

이 부분을 해결하기 위해서는 최소한으로 모델링하고 학습하되, 해당 기능을 잘 지원하는 탄탄한 기반을 다져 우수한 사용자 경험을 제공할 수 있어야 합니다.

Tightly-Scoped

Note

캡슐의 범위를 좁게 유지하면 캡슐의 범위를 벗어난 발화에 대해 신경 쓸 필요가 없습니다. Bixby는 발화가 속한 NL 범위를 파악해 해당 캡슐 범위에 들지 않는 발화는 캡슐로 보내지 않습니다. 예를 들어 레시피 캡슐을 생성했는데 사용자가 "사과 칼로리는 얼마야?"라고 물을 경우 Bixby에게 "모릅니다"라고 말하도록 학습시켜서는 안 됩니다. Bixby가 사용자의 발화를 더 적절한 캡슐로 보낼 것이기 때문입니다. 마찬가지로, 레시피 캡슐을 만들 때 캡슐의 지원 범위를 완전히 벗어난 "타지마할은 어디에 있어?", "오늘 날씨 어때?" 같은 발화를 학습시킬 필요가 없습니다.

그러나 이 상황은 category를 도입하면 달라질 수 있습니다. 캡슐이 특정 category에 들어왔지만 특정 요청을 처리하지 않는 경우 그러한 상황에 적절하게 동작하도록 Bixby에게 몇 가지 발화를 학습시켜야 할 수 있습니다.

캡슐이 지원하는 도메인 범위를 벗어나면 다음과 같은 문제가 생길 수 있습니다.

  • query, goal, signal을 분류하기가 더 어려워집니다.
  • 일관된 결과가 나오지 않아 실제 사용 시의 전반적인 사용자 경험을 예측하기가 어렵습니다.
  • 음성 인식 에러, 예기치 않은 단어, out-of-vocabulary signal에 대한 동작이 보장되지 않을 수 있습니다.
  • 사용자에게 비현실적인 기대치를 갖게 할 수 있습니다. 캡슐의 지원 범위가 고르지 않으면 사용자는 실제 사용하기 전에는 Bixby가 어떤 기능을 제공하는지 예측하기가 어렵습니다.

Setting up unrealistic expectations when not tightly scoped

한마디로, 반복적으로 사용할 수 있는 캡슐을 설계하고 빌드해야 합니다. 이렇게 해야 캡슐을 신뢰하고(무엇을 하는 캡슐인지 예측 가능) 이해할 수 있습니다(캡슐이 어떻게 동작하는지를 예측 가능).

다양한 사용 사례를 해결하기 위해 여러 가지 캡슐을 빌드해야 할 수 있습니다. 예를 들어 레시피를 반환하는 캡슐은 지원 범위를 최소로 하고, 음식과 관련된 질문(예: "요거트 칼로리는 얼마야?")과 답변을 처리하는 캡슐을 별도로 만들 수 있습니다. 이렇게 하면 사용 사례가 그다지 좁은 범위가 아니더라도 Bixby에게 더 많은 것을 학습시킬 수 있습니다.

분명하게 구분될 것(Well-Discriminated)

효과적인 캡슐은 처리해야 하는 쿼리를 분명하게 구분할 수 있습니다.

사용자의 쿼리에 적합한 캡슐을 찾는 것이 때로는 어려울 수 있습니다. 캡슐의 모든 사용자 쿼리가 해당 캡슐에 분명하게 매핑되는 경우 이를 분명하게 구분된(well-discriminated) 캡슐이라고 합니다. 캡슐이 분명하게 구분되지 않으면 비일관적인 에러가 계속해서 발생하게 되고, 따라서 쿼리 결과의 신뢰도가 떨어질 뿐 아니라 더 많은 training 데이터가 필요하게 됩니다.

일반적으로 다음 두 가지 권장 사항을 따라 모호성을 줄여야 합니다.

분명하게 구분된 training 쿼리 만들기

가능하면 non-signal 텍스트만으로도 training 쿼리가 분명하게 구분되도록 합니다. 이렇게 하면 Bixby가 캡슐을 잘 분류할 수 있고 특히 음성 인식에서 잘 동작하도록 할 수 있습니다. 아래 예제에서 볼 수 있듯, signal 텍스트(대괄호 안의 텍스트)를 삭제해도 해당 쿼리가 어느 캡슐에 속하는지를 쉽게 파악할 수 있어야 합니다.

  • [Greek Hummus] 레시피
  • [AA] 항공편 [1530] 현재 상태 보여줘
  • [$50]의 팁은 얼마야?
분명하게 구분되는 Vocabulary 만들기

Vocabulary를 사용해야 할 경우에는 다른 vocabulary와 중복되지 않고 명확하게 구분되도록 만들어야 합니다. 아래의 예에는 vocabulary(대괄호 안)가 모호하고 혼동되는 것들은 삭제되고 명확한 것으로만 정의되어 있습니다.

  • 스타벅스를 찾아줘 [Starbucks, The, Spot, Walmart]
  • SFO 찾아줘 [FOR, SFO, SJC, THE, LAX]
  • AA 1530 찾아줘 [AA, NO, UA, B6, OF, WN]
  • 비가 올까? [rain, nice, snow, bad, sunny]

Bixby는 이러한 training entry에서 사용자 쿼리를 일반화한 후, 공항 코드 THE 또는 항공사 코드 NO와 같이 혼동될 수 있는 인스턴트를 캐치할 수 있어야 합니다. Bixby가 이렇게 하지 못하는 경우에는 out-of-vocabulary으로 학습을 추가해야 합니다. 이렇게 하면 Bixby는 이러한 단어가 공항이나 식당과 같은 것을 의미하는 경우와 그렇지 않은 경우를 구분해 낼 수 있습니다.

Vocabulary 사용에 대한 자세한 내용은 자연어 Training 개발자 가이드의 vocabulary 추가하기를 참조하세요.

명확한 태깅(Obviously-Annotated)

효과적인 캡슐은 인식하기 쉬운 signal을 사용합니다.

음성 인식 에러나 새로운 단어나 문구를 인식하기 위해서는 value labeling이 명확하게 되는 것이 좋습니다. 이해를 돕기 위해 명확한 태깅이 이루어지지 않은 예를 살펴보겠습니다.

명확하게 태깅되지 않은 Signal의 예

다음 예제에서는 명확하게 태깅되지 않은 발화를 보여주고, 각 예제의 이슈를 설명하며, 이러한 이슈를 방지하기 위한 권장 사항을 제시합니다.

예제 1: 팁 계산기

다음 발화에서 문제가 무엇인지 한번 살펴보세요.

Split[r:ChangeBillSplit] the bill.
What is the total split 4[v:SplitAmount] ways?

이 예제에는 아래와 같은 이슈가 있습니다.

  • 단어가 도메인 전체에서 일관된 의미를 가져야 합니다. 이 예제의 첫 번째 문장에서는 split이 ChangeBillSplit에 매핑되어 있고 두 번째 문장에서는 4가 SplitAmount에 매핑되었는데 split 자체에는 태깅되지 않았습니다.
  • 동사에는 태깅하지 않습니다. 동사를 태깅하는 것은 좋은 방법이 아니며, 동사는 goal에 매핑되도록 합니다.
  • 명확한 경우에만 텍스트에 태깅합니다. 여기서는 "split"에 태깅이 필요할까요? 사람이 판단하기 어려운 부분은 Bixby에게도 마찬가지입니다.

예제 2: 날씨

다음 발화에서 문제가 무엇인지 한번 살펴보세요.

Do I (need an umbrella)[v:WeatherCondition:rain] today? 
Will it rain[v:WeatherCondition:rain] today?

이 예제에는 크게 두 가지 이슈가 있습니다. 우선, enum이 무분별하게 사용되었습니다. vocabulary에 있는 단어와 정확히 일치되지 않는 경우에는 enum을 사용하지 않습니다. 매치되는 단어가 많을수록 vocabulary의 신뢰성이 떨어집니다. 또한 이 예에서 training entry가 명확하지 않습니다. 구체적으로 보면, "need", "an", "umbrella"가 다 가능할 것 같아 보이는데 어디서부터 어디까지 태깅해야 할지가 명확하지 않습니다. 사람에게 명확하지 않다면 Bixby에게도 마찬가지입니다.

예제 3: 레시피

다음 발화에서 문제가 무엇인지 한번 살펴보세요.

Butter[v:IngredientName] recipes
(Pot roast)[v:FoodName] recipes

이 예제에는 컨텍스트 이슈가 있습니다. 즉, vocabulary를 사용하지 않고서는 "Butter"가 IngredientName이고 "Pot roast"가 FoodName이라는 것을 구분하기가 어렵습니다. 또한 다음 사항에 유의해주세요.

  • vocabulary에 없는 Name을 value로 태깅하면 Bixby가 어느 것을 사용할지 알지 못합니다.
  • vocabulary를 작성할 때는 최대한 깔끔하고(clean) 완전하게(complete) 작성할 수 있어야 합니다. 예를 들어 모든 IngredientName 항목을 나열한다는 것은 현실적으로 불가능합니다.
  • 근본적으로 IngredientFood의 구분 자체가 명확하지는 않습니다. 예를 들어 "chicken recipes"를 묻는 경우 닭고기 요리를 의미할 수도 있고 닭고기를 재료로 사용하는 레시피를 의미할 수도 있습니다.

이러한 모호함을 해결하기 위해서는 모든 음식 항목을 FoodName으로 모델링하고, 모든 out-of-vocabulary 인스턴스도 FoodName으로 태깅합니다. 그리고 "including Butter"와 같이 의미가 명확한 발화는 role을 사용하여 구분합니다.

구조체(structure) concept이 아닌 원시(primitives) concept 태깅하기

학습을 할 때에는 구조체(structure) concept이 아닌 원시(primitive) concept을 태깅해야 합니다. "find shirts under $40"와 같은 발화에는 CurrencySymbolCurrencyValue를 포함하는 Currency 구조체가 있을 수 있습니다. "$40"를 Currency로 태깅하지 말고 "$"를 CurrencySymbol로, "40"을 CurrencyValue로 각각 태깅합니다.

find shirts under ($)[v:CurrencySymbol](40)[v:CurrencyValue]

캡슐에 이 두 가지 원시(primitive) concept을 구조체(structure) concept으로 결합하는 action을 제공합니다. 이렇게 하면 Bixby는 실제 수행 시 필요할 때 이 action을 사용하게 됩니다.

Note

viv.time.DateTimeExpression과 같이 패턴으로 학습된 구조체(structure) concept은 이 규칙에 대한 예외가 적용됩니다. 패턴은 구조체(structure) concept을 해석하는 방법을 알려주는 vocabulary를 가질 수 있으므로 NL Training에서 구조체(structure) concept을 직접 사용할 수 있습니다.

일반 권장 사항 및 모범 사례(best practice)

Training 예제가 많다고 좋은 것은 아닙니다. 개수는 적지만 좋은 예제가 있어야 합니다. Bixby가 최대한 많은 일을 하도록 만들어야 합니다. goal을 설정하고, value를 식별하고, plan을 확인합니다.

다음은 몇 가지 모범 사례(best practice)입니다.

권장 사항:

  • 의도적으로 캡슐을 설계하고 학습시킵니다.
    캡슐을 설계할 때는 사용 사례에 중점을 두어야 합니다. 일반적으로 모든 사용자 요청을 충족시키기 보다는 중요한 사용 사례에 집중하는 것이 좋습니다. 모델링 뿐 아니라 학습할 때도 마찬가지입니다.
  • 사용자에게 가장 유용한 goal을 선택합니다.
    때로는 사용자가 요청하는 것 이상을 제공해야 할 수도 있습니다. 사용자가 “근처에 멕시코 음식점 있어?”라고 물을 경우 “네” 또는 “아니오”로 답하는 것은 별로 도움이 되지 않습니다. 이 경우 단순한 대답보다는 goal을 restaurant로 설정하여 어떤 멕시코 음식점이 있는지를 알려주는 것이 좋습니다. 또 다른 예로, 사용자가 "내일 우산 필요할까?”라고 물을 경우에는 질문에 답할 뿐 아니라 내일 일기 예보를 추가로 보여주는 goal을 선택하는 것이 좋습니다.
  • action보다는 concept을 goal로 사용합니다.
    일반적으로 concept을 goal로 잡는 것이 더 유연합니다. 그러나 예외적으로 제품을 주문하거나 서비스를 예약하는 발화에서는 action을 goal로 사용하는 것이 더 적합합니다.
  • 되도록이면 명사와 명사구에 태깅합니다.
    동사를 signal로 태깅하여 처리해야 하는 경우에는 아예 새로운 goal을 만드는 것이 좋습니다. 이 경우 문장의 주어가 변경되기 때문입니다.
  • 사용자의 인텐트(intent)에만 태깅합니다. 달성하는 방법에 대한 추가 정보에는 태깅하지 않습니다.
    실제로 사용자의 의도가 명백히 드러나는 경우에만 concept 또는 action으로 태깅합니다.
  • 지원되는 각 언어에 대한 training 예제를 별도로 생성합니다.
    캡슐과 training 데이터를 로컬라이제이션하는 방법에 대한 자세한 내용은 캡슐을 로컬라이제이션하는 방법을 참조하세요.
  • 해당 도메인에서 발화가 어떻게 태깅되어야 하는지를 다른 사람에게 쉽게 설명할 수 있는지 스스로 확인해봅니다.
    설명하기 쉽지 않다면 모델링을 변경하는 것이 좋습니다.
  • Submission reports의 Training Evaluation 섹션을 검토하여 Not Learned training이 없도록 합니다.
    일반적으로 Not Learned training 예제는 vocabulary가 누락되었거나, training에 일관성이 없다거나, 원시 타입(primitive type)을 잘못 사용했다거나 하는 중요한 이슈가 있는 것입니다. 그러한 이슈는 사용자 수준의 쿼리에 실제로 상당한 영향을 미칩니다. Submission이 성공했다 하더라도 Not Learned training 예제는 비정상이므로 꼭 확인하시기 바랍니다. 캡슐의 training 예제는 거의 항상 100% Learned여야 합니다.

주의 사항:

  • 원하는 인텐트(intent)를 강제로 충족시키기 위해 억지로 태깅하지 않도록 합니다. 필요한 경우에 제대로 동작하지 않을 수 있습니다!
    이렇게 강제로 학습된 training entry는 그 signal 인스턴스에는 동작할지 몰라도 이 type의 모든 쿼리에 대해 동작하지는 않을 수 있기 때문입니다. 기능을 동작시키기 위해서 training을 의도에 맞지 않게 강제로 태깅하지는 않아야 합니다.
  • vocabulary를 지나치게 확장하지 않도록 주의하세요!
    특히 다음 팁을 기억하세요.
    • closed-type의 vocabulary training은 절대적으로 필요한 경우에만 학습하도록 하세요! symbol value가 태깅된 텍스트와 비슷하거나 무리 없이 대체할 수 있는 경우에만 enum을 학습해야 합니다. 라우트(route)는 절대로 사용하지 않도록 합니다.
    • open-vocab input type은 적게 유지하세요!
      한 발화 내에서 여러 개의 type을 사용하게 될 경우, 각 단어의 의미가 잘 구분되는지 반드시 확인하도록 합니다.