2008-09-10 22 views
32

Tôi muốn xây dựng một bot hỏi một vài câu hỏi và nhánh đơn giản dựa trên câu trả lời. Tôi nhận ra phân tích cú pháp ý nghĩa từ những phản ứng của con người sẽ là thử thách, nhưng làm thế nào để bạn thiết lập chương trình để đối phó với "trạng thái" của cuộc trò chuyện?Tôi có thể lập trình AI bot trò chuyện đơn giản như thế nào?

Đây sẽ là cuộc trò chuyện trực tiếp giữa con người và bot.

+4

Tôi không hoàn toàn tin rằng các bot trò chuyện hiện tại thậm chí có một thứ như 'trạng thái'. Câu trả lời của họ dường như chỉ phụ thuộc vào câu hỏi cuối cùng bạn hỏi. Chỉ là trùng hợp ngẫu nhiên mà con người sẽ hỏi một loạt các câu hỏi liên quan. –

+0

http://search.cpan.org/search?query=bot&mode=all –

+5

Có các bot có trạng thái, tôi tự làm việc với một chương trình. Đó là một bot phân tích cú pháp dựa vào cơ sở tri thức sử dụng mạng thần kinh. –

Trả lời

22

Bạn có thể muốn xem xét Markov Chains làm cơ sở cho AI bot. Tôi đã viết một cái gì đó một thời gian dài trước đây (mã mà tôi không tự hào chút nào, và cần một số mod để chạy trên Python> 1.5) có thể là một nơi bắt đầu hữu ích cho bạn: http://sourceforge.net/projects/benzo/

EDIT: Dưới đây là một ví dụ tối thiểu trong Python của một chuỗi Markov chấp nhận đầu vào từ stdin và kết quả đầu ra văn bản dựa trên xác suất của các từ thành công lẫn nhau trong đầu vào. Nó được tối ưu hóa cho IRC kiểu bản ghi chat, nhưng chạy bất kỳ văn bản đàng hoàng cỡ qua nó phải chứng minh các khái niệm:

import random, sys 

NONWORD = "\n" 
STARTKEY = NONWORD, NONWORD 
MAXGEN=1000 

class MarkovChainer(object): 
    def __init__(self): 
     self.state = dict() 

    def input(self, input): 
     word1, word2 = STARTKEY 
     for word3 in input.split(): 
      self.state.setdefault((word1, word2), list()).append(word3) 
      word1, word2 = word2, word3 
     self.state.setdefault((word1, word2), list()).append(NONWORD) 

    def output(self): 
     output = list() 
     word1, word2 = STARTKEY 
     for i in range(MAXGEN): 
      word3 = random.choice(self.state[(word1,word2)]) 
      if word3 == NONWORD: break 
      output.append(word3) 
      word1, word2 = word2, word3 
     return " ".join(output) 

if __name__ == "__main__": 
    c = MarkovChainer() 
    c.input(sys.stdin.read()) 
    print c.output() 

Nó khá dễ dàng từ đây đến cắm vào sự kiên trì và một thư viện IRC và có cơ sở các loại bot bạn đang nói đến.

0

Tôi khuyên bạn nên xem xét xác suất Bayesian. Sau đó, chỉ cần theo dõi phòng trò chuyện trong một khoảng thời gian để tạo cây xác suất của bạn.

3

Tôi nghĩ bạn có thể xem mã cho Kooky và IIRC nó cũng sử dụng chuỗi Markov.

Ngoài ra, hãy xem kooky quotes, chúng đã được giới thiệu trên Hoding Horror cách đây không lâu và một số rất vui nhộn.

2

Tôi nghĩ rằng để bắt đầu dự án này, nó sẽ là tốt để có một cơ sở dữ liệu với các câu hỏi (được tổ chức như một cây. Trong mỗi nút một hoặc nhiều câu hỏi). Những câu hỏi này sẽ được trả lời bằng "có" hoặc "không".

Nếu bot bắt đầu đặt câu hỏi, nó có thể bắt đầu với bất kỳ câu hỏi nào từ cơ sở dữ liệu yuor của các câu hỏi được đánh dấu là câu hỏi bắt đầu. Câu trả lời là cách để nút tiếp theo trong cây.

Edit: Đây là một somple một viết bằng ruby ​​bạn có thể bắt đầu với: rubyBOT

0

Tôi không chắc chắn đây là những gì bạn đang tìm kiếm, nhưng có một chương trình cũ gọi ELIZA mà có thể tổ chức một cuộc đối thoại bằng cách lấy những gì bạn nói và nhổ nó lại cho bạn sau khi thực hiện một số biến đổi văn bản đơn giản.

Nếu tôi nhớ chính xác, nhiều người đã bị thuyết phục rằng họ "đang nói chuyện" với một người thực và đã có những cuộc trò chuyện dài với nó.

14

Folks đã đề cập đã statefulness đó không phải là một thành phần lớn của chatbot tiêu biểu:

  • một hiện thực Markov tinh khiết có thể bày tỏ một loại rất lỏng lẻo của nhà nước nếu nó được phát triển từ vựng và bảng của mình trong thời gian thực — những phát biểu trước đó của người đối thoại người có thể bị hối hận sau này trong cuộc trò chuyện — nhưng mô hình Markov không có bất kỳ cơ chế cố hữu nào để chọn hoặc tạo ra các phản ứng như vậy.

  • bot dựa trên phân tích cú pháp (ví dụ:ELIZA) thường cố gắng trả lời (một số) nội dung ngữ nghĩa của đầu vào gần đây nhất từ ​​người dùng mà không quan tâm đáng kể đến các trao đổi trước đó.

Điều đó nói rằng, bạn chắc chắn có thể thêm một số lượng nhà nước đến một chatbot, không phụ thuộc vào mô hình đầu vào phân tích cú pháp và tuyên bố tổng hợp bạn đang sử dụng. Làm thế nào để làm điều đó phụ thuộc rất nhiều vào những gì bạn muốn thực hiện với trạng thái của bạn, và điều đó không thực sự rõ ràng từ câu hỏi của bạn. Tuy nhiên, một vài ý tưởng chung chung:

  • Tạo ngăn xếp từ khóa. Khi con người cung cấp thông tin đầu vào, hãy phân tích các từ khóa từ các câu hỏi/câu hỏi của họ và ném các từ khóa đó vào một chồng xếp loại nào đó. Khi chatbot của bạn không đưa ra thứ gì đó hấp dẫn để phản hồi trong lần nhập gần đây nhất — hoặc, có thể, chỉ ngẫu nhiên, để trộn mọi thứ lên — quay lại ngăn xếp của bạn, lấy từ khóa trước và sử dụng từ khóa đó để gieo hạt tiếp theo của bạn tổng hợp. Đối với điểm thưởng, có bot xác nhận rõ ràng rằng nó quay trở lại chủ đề trước, ví dụ: "Đợi đã, HUMAN, trước đó anh đã đề cập đến foo. [Câu hỏi được gieo bởi foo]".

  • Tạo logic đối thoại RPG giống như bot. Là đầu vào của phân tích cú pháp của con người, hãy chuyển đổi cờ cho lời nhắc hoặc nội dung cuộc hội thoại cụ thể từ người dùng và thay đổi có điều kiện nội dung chatbot có thể nói hoặc cách giao tiếp. Ví dụ, một chatbot bristling (hoặc la hét, hoặc cười) ở ngôn ngữ hôi là khá phổ biến; một chatbot mà sẽ nhận được het lên, và điều kiện vẫn như vậy cho đến khi xin lỗi, sẽ là một biến thể stateful thú vị về điều này. Chuyển đổi đầu ra thành TẤT CẢ CÁC CAPS, vứt bỏ những lời lẽ đối đầu hoặc yêu cầu hoặc thổn thức, v.v.

Bạn có thể làm rõ một chút những gì bạn muốn tiểu bang giúp bạn đạt được không?

5

Hãy tưởng tượng mạng nơron có khả năng phân tích cú pháp trong mỗi nút hoặc nơron. Tùy thuộc vào quy tắc và phân tích kết quả, tế bào thần kinh cháy. Nếu một số tế bào thần kinh cháy, bạn sẽ có được một ý tưởng tốt về chủ đề và ngữ nghĩa của câu hỏi và do đó có thể đưa ra một câu trả lời tốt.

Bộ nhớ được thực hiện bằng cách giữ các chủ đề được đề cập trong phiên, thêm vào việc kích hoạt câu hỏi tiếp theo và do đó hướng dẫn quá trình lựa chọn các câu trả lời có thể có ở cuối.

Giữ nguyên tắc và mẫu của bạn trong cơ sở kiến ​​thức, nhưng biên dịch chúng thành bộ nhớ vào thời gian bắt đầu, với một nơ ron theo quy tắc. Bạn có thể thiết kế các khớp thần kinh bằng cách sử dụng một cái gì đó như nghe hoặc chức năng sự kiện.

+0

Hi Ralph Tôi đánh giá cao ý kiến ​​của bạn; Tôi đi lên bản thân mình để một aproach tương tự, đơn giản hơn mỗi "tế bào thần kinh" là một máy nhà nước hữu hạn với phù hợp với mô hình miền hẹp của mình. Tên mã: naif. Sắp có: https://twitter.com/solyarisoftware/status/792258290591858688 –

0

Nếu bạn chỉ đang yêu thích, tôi tin rằng Pidgin cho phép bạn thực hiện hành vi kiểu tập lệnh. Một phần của khung làm việc có thể là trạng thái của người đã gửi thông báo khi nào và bạn muốn giữ một bản ghi trạng thái bên trong của bot cho mỗi thông điệp N cuối cùng. Các quyết định của nhà nước trong tương lai có thể được mã hóa cứng dựa trên việc kiểm tra các quốc gia trước đó và nội dung của một vài thông điệp gần đây nhất. Hoặc bạn có thể làm một cái gì đó giống như chuỗi Markov thảo luận và sử dụng nó cả hai để phân tích và tạo ra.

0

Nếu bạn không yêu cầu bot học, sử dụng AIML (http://www.aiml.net/) rất có thể sẽ tạo ra kết quả bạn muốn, ít nhất là đối với đầu vào phân tích cú pháp và trả lời dựa trên nó.

Bạn sẽ sử dụng lại hoặc tạo "bộ não" làm bằng XML (trong định dạng AIML) và phân tích/chạy chúng trong một chương trình (trình phân tích cú pháp). Có nhiều trình phân tích cú pháp được thực hiện bằng nhiều ngôn ngữ khác nhau để lựa chọn và theo tôi có thể nói mã nguồn dường như là nguồn mở trong hầu hết các trường hợp.

1

chương trình chatbot ngây thơ. Không phân tích cú pháp, không thông minh, chỉ là một tệp đào tạo và đầu ra.

Đầu tiên nó tự đào tạo trên văn bản và sau đó sử dụng dữ liệu từ khóa đào tạo đó để tạo phản hồi cho nội dung nhập của người đối thoại. Quá trình đào tạo tạo ra một từ điển trong đó mỗi khóa là một từ và giá trị là danh sách tất cả các từ theo sau từ đó tuần tự ở bất kỳ đâu trong văn bản đào tạo. Nếu một từ tính năng nhiều hơn một lần trong danh sách này sau đó phản ánh và nó có nhiều khả năng được lựa chọn bởi bot, không cần cho công cụ xác suất chỉ cần làm điều đó với một danh sách.

Bot chọn một từ ngẫu nhiên từ đầu vào của bạn và tạo phản hồi bằng cách chọn một từ ngẫu nhiên khác đã được xem là từ kế thừa từ được giữ. Sau đó, nó lặp lại quá trình này bằng cách tìm người kế thừa từ đó và tiếp tục lặp đi lặp lại cho đến khi nó nghĩ rằng nó đủ nói. Nó đạt đến kết luận đó bằng cách dừng lại ở một từ trước dấu chấm câu trong văn bản huấn luyện. Sau đó, nó sẽ trở lại chế độ đầu vào một lần nữa để cho phép bạn phản hồi, v.v.

Điều này không thực tế nhưng tôi xin thách thức bất kỳ ai làm tốt hơn trong 71 dòng mã !! Đây là một thách thức lớn đối với bất kỳ người viết blog giả mạo nào, và tôi chỉ ước tôi có thể mở thách thức cho một đối tượng rộng hơn số lượng khách truy cập nhỏ mà tôi nhận được vào blog này. Để mã một bot luôn được đảm bảo là ngữ pháp chắc chắn phải gần hơn vài trăm dòng, tôi đơn giản hóa rất nhiều bằng cách chỉ nghĩ đến quy tắc đơn giản nhất để máy tính chỉ đâm vào việc nói gì đó.

Câu trả lời của nó khá ấn tượng khi nói ít nhất! Ngoài ra bạn phải đặt những gì bạn nói trong dấu nháy đơn.

tôi đã sử dụng Chiến tranh và Hòa bình cho “corpus” của tôi mà mất một vài giờ cho các hoạt động đào tạo, sử dụng một tập tin ngắn hơn nếu bạn là thiếu kiên nhẫn ...

đây là huấn luyện viên

#lukebot-trainer.py 
import pickle 
b=open('war&peace.txt') 
text=[] 
for line in b: 
    for word in line.split(): 
     text.append (word) 
b.close() 
textset=list(set(text)) 
follow={} 
for l in range(len(textset)): 
    working=[] 
    check=textset[l] 
    for w in range(len(text)-1): 
     if check==text[w] and text[w][-1] not in '(),.?!': 
      working.append(str(text[w+1])) 
    follow[check]=working 
a=open('lexicon-luke','wb') 
pickle.dump(follow,a,2) 
a.close() 

đây là bot

#lukebot.py 
import pickle,random 
a=open('lexicon-luke','rb') 
successorlist=pickle.load(a) 
a.close() 
def nextword(a): 
    if a in successorlist: 
     return random.choice(successorlist[a]) 
    else: 
     return 'the' 
speech='' 
while speech!='quit': 
    speech=raw_input('>') 
    s=random.choice(speech.split()) 
    response='' 
    while True: 
     neword=nextword(s) 
     response+=' '+neword 
     s=neword 
     if neword[-1] in ',?!.': 
      break 
    print response 

Bạn có xu hướng có cảm giác kỳ lạ khi nói điều gì đó có vẻ hợp lý.