この記事は機械翻訳されたものです。

作業プログラマ

相談室 (第 2 回): ELIZA (機械翻訳)

Ted Neward

 

Ted Neward最後に会ったとき、私たち Tropo、雲の主催の音声および SMS サービスを使用して電話で音声入力するを応答、シンプルなシステムを構築しました。 我々 は音声入力に対応し、応答を提供することができますされる限りうまくいけば、お湯であまりにも多くの時間には、Xbox は、休暇で支出の重要な他の救済です。 いくつかの残念ながら、その日を実施しない可能性があり、ものはまだ緊張との間。 思いやりのある人間として、私は、アマチュアのセラピストとしての私のサービスを提供することができますしたいのですが、このとき。 残念ながら、しかし、私は非常にうまくスケールしないし、あなたの各 1 つに話をすることはできません。 ので、代わりに、代替を見てみましょう。 私は、もちろん、イライザーの話します。

イライザー:歴史

イライザーになじみのない、「彼女」は人工無脳です — と人工知能 (AI) に向けての最初と最も有名な手順の 1 つ。 戻って 60 年代にジョセフ ・ ワイゼンバウム、Lisp で書かれたイライザー ユーザー入力の「キー」を分析し、これらのキーに基づく人間のような応答を生成 (今日の基準) で比較的シンプルな入力応答プロセッサです。 あなたが言った場合は、したがって、たとえば、「悲しい、私」イライザー彼女が応答可能性があります、「なぜか、悲しい」または「私に話して、悲しいものですか。」またはも「悲しいされて停止 !」実際には、応答時しばらく、それこのチューリング テストに合格するためのプログラムを得るための方法かもしれないと思っただった、従って本格的なことができます。

四十年後で、しかし、私たちまだ会話私たちのコンピューターにはアーサー c. ないことです。 クラークの想像で「2001年。宇宙の旅、」が、わけ私たち私たちのプログラム「人間のような「通信無視する必要があります。 我々 は、自然言語処理 (NLP) 微妙によりコンピューター システムに、スリップし、テキストへの音声認識エンジンを組み合わせると、人間とコンピューターの相互作用の完全に新しい道を開く参照してくださいし始めています。 たとえば、単純イライザーのようなキー認識システムも、非常にイライラすることがなく役立つ人間支援システム Web サイトを作成しようとしました。 またはルーティングの顧客大企業内の右の部門にことができます"顧客サービスのための 1 キーを押します、人材の 2 キーを押します、3 を押す.」のコール ツリー。

あなたは、簡単な NLP でも手を出して、ただし、このような何かをしようとしては少し大変なすることができます。 幸いにも、我々 も、いくつかの非常に基本的な試みからいくつかの良い結果を得ることができます。 偉大なチュートリアルでは bit.ly/uzBSM9、イライザーの実装 f# で記述するには、私たちが次をしているのインスピレーションとして機能します。 F# の選択肢をここでは 2 つです。最初、Lisp では ELIZA の使用へのオマージュとして私の中で列サンプルで F # を行っていないため両方機能の言語と第二に、あります。 当然のことながら、私たち彼女の F # 呼ぶ-イライザー、または (よりエキゾチックな感じがするので) を短いと彼女は、さまざまな異なるプログラムで埋め込むことができるので彼女は F # ライブラリとして実装の Feliza の。

Feliza:バージョン 0

Feliza へのインターフェイスをする必要があります短い、甘い、簡単- と、全体の束の複雑さを隠します。 古典的なギャングの 4 パターン カタログから、これはファサード パターンです (「」)、および F # 簡単ファサードは、「モジュール」機能を使用してを作成します。

module Feliza
open System
let respond input =
  "Hi, I'm Feliza"
Using Feliza in a console-mode program, for example, would then be as easy as this:
open Feliza
open System
let main =
  Console.WriteLine("Hello!")
  while true do
    Console.Write("> ")
      let input = Console.ReadLine()
      let responseText = respond input
      Console.WriteLine(responseText)
      if (input.ToLower().Equals("bye")) then
        Environment.Exit(0)
  ()

これは、その後、テストベッドを形成します。 それもそれを私たちはこのユーバー-シンプルな API にスティックことができます他の環境で Feliza を埋め込むやすくなります。

私たちはいくつかの作業実装、ところで、建物行くを取得を覚えて Feliza 汎用 NLP エンジンをするものではないこと-は、私はこのコラムのための部屋があるよりもより多くの作業がかかります。 実際には、Microsoft Research に NLP を専用部門全体が (を参照してください research.microsoft.com/groups/nlp 何が彼らを調査している詳細について)。 私はそれらのいずれかのないようにしてください。

Feliza:バージョン 1

「作業」のバージョン Feliza に 1 を取得する最も簡単な方法は、可能な応答の簡単なリストを作成しそれら間ランダムに選択するです。

let respond input =
  let rand = new Random()
  let responseBase =
    [| "I heard you!";
      "Hmm.
I'm not sure I know what you mean.";
      "Continue, I'm listening...";
      "Very interesting.";
      "Tell me more..."
    |]
  responseBase.[rand.Next(responseBase.Length - 1)]

ここに配列ではない慣用的」F #-っぽい、」がそれは簡単にからの可能な応答をランダムに選択します。 時にコードを記述しようとしているプログラマに話をしようとしている人にはおなじみかもしれませんがそれは特にエキサイティングな会話ではないです。 まだ、少しの間、それは実際に実際の会話のようなを感じるかもしれない。 我々 よりも行うことができます。

Feliza:バージョン 2

缶詰の応答を特定の入力、ユーザーからの「サポート技術情報」を作成するには、次の明白な実装をです。 これは簡単に f# 組を対応する入力のフレーズをされている組の最初の要素と応答されている 2 番目の要素を使用してモデル化されます。 や、それについて人間に (レスポンスで明白な繰り返しを避けるために) は、私たちすることができます 2 番目の要素を可能な応答のリストをランダムには、リストから 1 つのように表示図 1

図 1 サポート技術情報 Feliza

let knowledgeBase =
  [
    ( "Bye",
      [ "So long!
Thanks for chatting!";
        "Please come back soon, I enjoyed talking with you";
        "Eh, I didn't like you anyway" ] );
    ( "What is your name", 
      [ "My name is Feliza";
        "You can call me Feliza";
        "Who's asking?" ] );
    ( "Hi",
      [ "Hi there";
        "Hello!";
        "Hi yourself" ] );
    ( "How are you",
      [ "I'm fine, how are you?";
        "Just peachy";
        "I've been better" ] );
    ( "Who are you",
      [ "I'm an artificial intelligence";
        "I'm a collection of silicon chips";
        "That is a very good question" ] );
    ( "Are you intelligent",
      [ "But of course!";
        "What a stupid question!";
        "That depends on who's asking." ] );
    ( "Are you real",
      [ "Does that question really matter all that much?";
        "Do I seem real to you?";
        "Are you?" ] );
    ( "Open the pod bay doors",
      [ "Um...
No.";
        "My name isn't HAL, you dork.";
        "I don't know...
That didn't work so well last time." ] );
  ]
let unknownResponses =
  [ "I'm sorry, could you repeat that again?";
    "Wait, what?";
    "Huh?" ]
let randomResponse list =
  let listLength list = (List.toArray list).Length
  List.
nth list (rand.Next(listLength list))
let cleanInput (incoming : string) =
  incoming.
Replace(".", "").
Replace(",", "").
Replace("?", "").
Replace("!", "").
ToLower()
let lookup =
  (List.tryFind
    (fun (it : string * string list) ->
      (fst it).Equals(cleanInput input))
    knowledgeBase)
randomResponse (if Option.isSome lookup then
                    (snd (Option.get lookup))
                else
                    unknownResponses)

このバージョンはいくつか簡単なクリーンアップでは、入力の組 (「知識ベース」)、のリストの最初の部分に一致するように努めるしリストからの応答をランダムに選択。 再び「キー ・ フレーズ」、知識ベース、"不明"の応答が生成されますがない場合リストからランダムに選択。 (確かに、クリーンアップ、特に非効率的な方法で行われますが、私たち人間のコミュニケーションについて話しているときは、遅延は問題ではないです。 実際には、いくつかの人工無脳実装意図的に、応答が遅くなるし、-誰か、キーボードで入力を模倣する文字で、印刷します。)

必要入力のフレーズの応答をトリガーに一致する必要がありますのでこの何らかの現実世界のシナリオで使用した場合は、明らかに、我々 ははるかより大きい技術、あらゆる可能な順列の人間の音声を組み込むがあります。 うーん — スケーラブルなソリューションではないです。 さらに、我々 は本当に多くとき Feliza へのユーザー入力をより有意義な方法で応答しないを失います。 イライザーのオリジナルの強みの 1 つあなたが言った場合は、「ジャガイモ、好き」彼女と応答は、「ジャガイモをすること重要ですか?」— 会話はより「パーソナライズ」を

Feliza:バージョン 3

このバージョンは、もう少し複雑になるを取得しますが、それもより多くの柔軟性とパワーを提供しています。 本質的に、正確な一致アルゴリズムを有効に、柔軟な 1 つの組の一覧がそれぞれ評価され、応答を作成するには、チャンスを与え関数の一覧に変換に。 これはオプションの入力では、Feliza がどのように相互作用することができますとどのように彼女は、入力からの単語を特定の応答を生成するために選ぶことができますの巨大なリストを開きます。

それ「処理ルール」の単純なリストではの下にある彼女は、「unknownResponses」リストから、以前のバージョンの道徳的な等量に応答する方法で示してように知っている didn't 示す汎用応答が開始図 2.

図 2 汎用ルール応答

let processingRules =
  [
    // ...
// Catchall rule for when nothing else matches before
    // this point; consider this the wildcard case.
This
    // must always be the last case considered!
(
      (fun (it : string) ->
        Some(randomResponse
          [
          "That didn't make sense.";
          "You cut out for a second there.
What did you say?";
          "Wait--the Seahawks are about to...
Never mind.
They lost.";
          "I'm sorry, could you repeat that again?";
          "Wait, what?";
          "Huh?"
          ]))
    )
  ]
List.head (List.choose (fun (it) -> it (cleanInput input)) processingRules)

このバージョンのコア、最後の行には-List.choose 関数各 processingRule を受け取り、入力に対して実行し、processingRule、いくつかの値を返す場合、その値を呼び出し元に返される一覧に追加を取得します。 だから我々 は新しいルールを追加することができます今は、各 1 つの戻り値、して [いずれか、最初の 1 つを取る (よう図 2、List.head を使用して) かもランダムに選択。 将来のバージョンでは、テキスト応答との妥当性は正しい応答を選択するには、「重量」両方は、いくつか値を生成可能性があります。

新しいルールの作成が容易になります。 F # のパターン マッチングを使用して一致するように簡単に私たちはちょうどキー入力のルールを持つことができます。

(fun (it : string) ->
  match it with
  | "Hi" | "Howdy" | "Greetings" ->
    Some(randomResponse
      [
      "Hello there yourself!";
      "Greetings and salutations!";
      "Who goes there?"
      ])
  | _ -> None
);

または「機能」構築にも同じことを示すように、省略形を使用することができます図 3.

図 3 は、関数構文

(function
  | "How are you?" ->
    Some(randomResponse
      [
      "I'm fine, how are you?";
      "Just peachy";
      "I've been better"
      ])
  | "open the pod bay doors" ->
    Some(randomResponse
      [
      "Um ...
No.";
      "My name isn't HAL, you dork.";
      "I don't know ...
That didn't work so well last time."
            ])
  | _ -> None
);

我々 はむしろのでほとんどの場合、にもかかわらず、Feliza それら缶詰のフレーズ、得ることはできません彼女が彼女のキュー、ユーザーの入力、キーワードからとして取る図 4 を指定します。

図 4 へキーワードを結ぶ

(fun (it : string) ->
  if it.Contains("hate") || it.Contains("despise") then
    Some(randomResponse
      [ "Why do you feel so strongly about this?";
        "Filled with hate you are, young one.";
        "Has this always bothered you so much?" ])
  else
    None
);
(fun (it : string) ->
  if it.StartsWith("what is your") then
    let subject =
      it.Substring(it.IndexOf("what is your") +
                         "what is your".Length).Trim()
    match subject with
      | "name" ->
        Some(randomResponse
          [ "Feliza."; "Feliza.
What's yours?";
            "Names are labels.
Why are they so important to you?" ])
      | "age" ->
        Some(randomResponse
          [ "Way too young for you, old man."; "Pervert!";
            "I was born on December 6th, 2011" ])
      | "quest" ->
        Some("To find the Holy Grail!")
      | "favorite color" ->
        Some("It's sort of green but more dimensions")
      | _ ->
        Some("Enough about me.
What's yours?")
  else
    None
);

F # ベテラン F #「アクティブ パターン」にぴったりいくつかのこのことに注意する; f# アクティブ パターン構造と (または、F # パターン マッチング構文で一般的な) に精通していない人からジェシカ カーの優れた 2 部シリーズでは、件名に見つけることができます bit.ly/ys4jtobit.ly/ABQkSN

進む :Feliza に接続します。

Feliza は素晴らしいですが、キーボード以外に達する、入力チャネルなし、彼女は非常に遠くまで行かない。 Feliza は、人々 だけでは、キーボードの前に座っているよりも多くの人々 を助けたい-彼女は、携帯電話やインターネット接続とのだれでもアクセスできるように望んでいるし、次の分割払いでは、我々「彼女をフックします」。

コーディングを楽しんで !

Ted Neward Neudesic LLC、建築コンサルタントです。 彼は 100 以上の記事を書いている、c# MVP、INETA のスピーカーとが作成あり、最近発表された「プロ F # 2.0」を含む、数十本を共著 (Wrox、2010年).彼は相談し、定期的にメンターします。彼の仕事をチームには、または自分のブログで読むことに興味があれば彼に ted@tedneward.com に達する blogs.tedneward.com

この記事のレビュー、技術スタッフに感謝:Matthew Podwysocki