コード例 #1
0
def response_matrix(last_utterance, chatbot, conversation):
    with open("../data/da_matrix.csv") as f_matrix:
        mat = np.loadtxt(f_matrix,
                         delimiter=",",
                         skiprows=1,
                         usecols=range(1, 27))
        mat = mat / np.sum(mat, axis=0)

        da_names = [
            da.name for da in DA
            if da.name not in ["statement", "question", "response_action"]
        ]
        response_col = da_names.index(last_utterance.dialogue_act.name)

        sentiment = np.random.normal(chatbot.personality.mood, 2)
        while sentiment < 1 or sentiment > 10:
            sentiment = np.random.normal(chatbot.personality.mood, 2)

        assertiveness = np.random.normal(chatbot.personality.mood, 2)
        while assertiveness < 1 or assertiveness > 10:
            assertiveness = np.random.normal(chatbot.personality.mood, 2)

        utterance = Utterance(
            chatbot.name, DA[np.random.choice(da_names, p=mat[:,
                                                              response_col])],
            last_utterance.topic, int(sentiment), int(assertiveness))

        text = nlg.generate_response_text(utterance, chatbot, conversation)
        utterance.set_text(text)
        return utterance
コード例 #2
0
def query_user_general(conversation,
                       chatbot,
                       user,
                       personas=None,
                       sentiment=None,
                       formal=None):
    """
    General questions of user to find a topic of discussion.
    :param sentiment: Inferred sentiment from chatbot, unless explicitly given
    :param formal: Inferred formality from chatbot, unless explicitly given
    """
    if sentiment is None:
        sentiment = chatbot.personality.mood

    da = random.choice([DA.question_experience, DA.question_information])

    text = generic_response.query_user_information(
            persona,
            conversation,
            sentiment
        ) if da is DA.question_information else \
        generic_response.query_user_experience(
            persona,
            conversation,
            sentiment
        )

    utterance = Utterance(chatbot.name, da, "self_user", sentiment,
                          chatbot.personality.assertiveness, text)
    return utterance
コード例 #3
0
def new_conversation(conversation,
                     chatbot,
                     user,
                     personas=None,
                     last_utterance=None):
    # New conversation started
    # prev = greeting, then greeting, query, etc.
    if last_utterance.dialogue_act == DA.greeting:
        #TODO overcome limitation of not making text here. (use meta text)
        # Ideal, would be able to be assertive and make
        # greeting + question_ or statement_
        # call nlg module here, from IA.

        assertiveness = response_assertiveness(chatbot)

        if respond_passively(assertiveness):
            # if passive response, then only greeting.
            utterance = Utterance(chatbot.name, DA.greeting, "self_user",
                                  chatbot.personality.mood,
                                  chatbot.personality.assertiveness)

            text = nlg.generate_response_text(utterance, chatbot, conversation)
            utterance.set_text(text)
            return utterance
        else:  # respond with greeting AND something else.
            # else: query user general
            greeting_text = generic_response.greeting(chatbot, conversation,
                                                      chatbot.personality.mood)
            greeting_text = greeting_text[0].upper() + greeting_text[1:]
            greeting_text = (greeting_text +
                             "." if chatbot.personality.mood < 8
                             and chatbot.personality.assertiveness < 8 else
                             greeting_text + "!")

            utterance = tactic.query_user_general(conversation, chatbot, user,
                                                  personas)

            text = greeting_text + " " + utterance.text
            utterance.set_text(text)
            return utterance
    elif (not topic_is_self(last_utterance.topic)
          and not topic_is_user(last_utterance.topic)
          and is_question(last_utterance.dialogue_act)):
        return Utterance(chatbot.name,
                         question_to_statement(last_utterance.dialogue_act),
                         last_utterance.topic, chatbot.personality.mood,
                         chatbot.personality.assertiveness)
    elif (not topic_is_self(last_utterance.topic)
          and not topic_is_user(last_utterance.topic)
          and is_statement(last_utterance.dialogue_act)):
        return Utterance(chatbot.name,
                         statement_to_question(last_utterance.dialogue_act),
                         last_utterance.topic, chatbot.personality.mood,
                         chatbot.personality.assertiveness)
    else:
        return tactic.psychiatrist(last_utterance, chatbot.name)
コード例 #4
0
def change_topic_passive(conversation, chatbot, user, mood_magnitude,
                         topic_magnitude, personas):
    choice = np.random.choice(3, 1)
    if choice == 0:
        # silence or no response or minimal response
        return Utterance(chatbot.name, DA.silence, last_utterance.topic,
                         chatbot.personality.mood,
                         chatbot.persoality.assertiveness)
    elif chocie == 1:
        # ask to change topic, no expression of sent, not alternatives
        return Utterance(chatbot.name, DA.question_information,
                         last_utterance.topic, chatbot.personality.mood,
                         chatbot.persoality.assertiveness)
    # express sent, no alternatives
    return Utterance(chatbot.name, DA.statement_opinion, last_utterance.topic,
                     chatbot.personality.mood,
                     chatbot.persoality.assertiveness)
コード例 #5
0
def decide_response(conversation_history, chatbot_id, persona_dict):
    """
    Main interface for intelligent agent to decide how to response. With the NLU
    information and the persona making this decision, generates the metadata of
    the persona's response utterance. This metadata matches the type and format
    of the NLU information.
    """
    chatbot = persona_dict[chatbot_id]
    participants = conversation_history.participants
    participants.remove(chatbot_id)
    user = persona_dict[next(iter(participants))]
    last_utterance = conversation_history.last_utterance

    # Assess mood and magnitude of change to mood necessary
    mood_magnitude = chatbot.personality.mood - user.personality.mood

    # Assess topic sentiment in relation to desired mood
    topic_magnitude = chatbot.topic_magnitude(last_utterance.topic,
                                              chatbot.personality.mood)
    # TODO give first utterance, should never occur in prototype

    return static_matrix(conversation_history, chatbot, user, persona_dict)

    #return decision_tree_static(conversation_history, chatbot, user, persona_dict)

    # static reactions:
    if last_utterance.dialogue_act == DA.farewell:
        return Utterance(chatbot_id, DA.farewell, "self_user",
                         chatbot.personality.mood,
                         chatbot.personality.assertiveness)
    #elif last_utterance.dialogue_act == DA.greeting:
    #    return Utterance(
    #        chatbot_id,
    #        DA.greeting,
    #        "self_user",
    #        chatbot.personality.mood,
    #        chatbot.personality.assertiveness
    #    )

    # TODO remove this, this is just to stop code from crashing until IA finished
    return Utterance(chatbot_id, DA.other, "None", 5, 5)
コード例 #6
0
def response_matrix(last_utterance, chatbot):
    mat = np.loadtxt(open("../data/da_matrix.csv"),
                     delimiter=",",
                     skiprows=1,
                     usecols=range(1, 27))
    mat = mat / np.sum(mat, axis=0)

    da_names = [
        da.name for da in DA
        if da.name not in ["statement", "question", "response_action"]
    ]
    response_col = da_names.index(last_utterance.dialogue_act.name)
    return Utterance(
        chatbot.name, DA[np.random.choice(da_names, p=mat[:, response_col])],
        last_utterance.topic,
        min(max(np.random.normal(chatbot.personality.mood, 2), 10), 1),
        min(max(np.random.normal(chatbot.personality.assertiveness, 2), 10),
            1))
コード例 #7
0
def static_matrix(conversation, chatbot, user, personas=None):
    """
    A manually constructed decision tree to implement a rule based system as a
    baseline.

    :param conversation: current Conversation
    :param chatbot: Persona of chatbot
    :param user: Persona of user
    :param personas: Dictionary of str "persona_id" to Persona
    """
    last_utterance = conversation.last_utterance

    # Assess mood and magnitude of change to mood necessary
    mood_magnitude = chatbot.personality.mood - user.personality.mood

    # Assess topic sentiment in relation to desired mood
    topic_magnitude = user.topic_magnitude(last_utterance.topic,
                                           chatbot.personality.mood)

    # static reactions:
    if last_utterance.dialogue_act == DA.farewell:
        utterance = Utterance(chatbot.name, DA.farewell, "self_user",
                              chatbot.personality.mood,
                              chatbot.personality.assertiveness)

        text = nlg.generate_response_text(utterance, chatbot, conversation)
        utterance.set_text(text)
        return utterance

    #if len(conversation.topic_to_utterances.keys()) <= 0:
    if conversation.new_convo:
        conversation.new_convo = False
        # New conversation started
        if last_utterance.dialogue_act == DA.greeting:
            utterance = Utterance(chatbot.name, DA.greeting, "self_user",
                                  chatbot.personality.mood,
                                  chatbot.personality.assertiveness)
            text = nlg.generate_response_text(utterance, chatbot, conversation)
            utterance.set_text(text)
            return utterance
        elif (not topic_is_self(last_utterance.topic)
              and not topic_is_user(last_utterance.topic)
              and is_question(last_utterance.dialogue_act)):
            utterance = Utterance(
                chatbot.name,
                question_to_statement(last_utterance.dialogue_act),
                last_utterance.topic, chatbot.personality.mood,
                chatbot.personality.assertiveness)
            text = nlg.generate_response_text(utterance, chatbot, conversation)
            utterance.set_text(text)
            return utterance
        elif (not topic_is_self(last_utterance.topic)
              and not topic_is_user(last_utterance.topic)
              and is_statement(last_utterance.dialogue_act)):
            utterance = Utterance(
                chatbot.name,
                statement_to_question(last_utterance.dialogue_act),
                last_utterance.topic, chatbot.personality.mood,
                chatbot.personality.assertiveness)
            text = nlg.generate_response_text(utterance, chatbot, conversation)
            utterance.set_text(text)
            return utterance
        else:
            return tactic.psychiatrist(last_utterance, chatbot.name)
    else:  # Ongoing Conversation
        # topics have been discussed, and conversation ongoing
        if topic_is_self(last_utterance.topic) \
                or topic_is_user(last_utterance.topic):
            return tactic.psychiatrist(last_utterance, chatbot.name)
        else:
            return response_matrix(last_utterance, chatbot, conversation)
コード例 #8
0
def farewell(chatbot):
    return Utterance(chatbot.name, DA.farewell, "self_user",
                     chatbot.personality.mood,
                     chatbot.personality.assertiveness)
コード例 #9
0
def psychiatrist(utterance, responder_id):
    """ Use ELIZA to generate response utterances when the topic is on user. """
    return Utterance(responder_id, DA.other, "self_user", 5, 5,
                     eliza_chatbot.respond(utterance.text))
コード例 #10
0
def nlu_cli(default_mood, user_id):
    """ Command line interface for user to give all NLU data of utterance. """
    mood = -1  # TODO currently superfulous while loop given default mood.
    while mood not in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
        mood = input(
            "Enter your current mood on a scale of 1 to 10 where " +
            "1 is negative, 5 is neutral, and 10 is positive (default is " +
            str(default_mood) + "): ")
        if mood == "" or not mood.isdigit():
            mood = default_mood
        else:
            mood = int(mood)
        mood = default_mood if mood == "" else int(mood)

    topic = ""
    while topic == "":
        topic = input("Enter Topic: ").strip().lower()

    #loop until they select correct dialogue act, show help after first fail
    dialogue_act = ""
    first = True
    da_names = [
        da.name for da in DA
        if da.name not in ['statement', 'question', 'response_action']
    ]
    while dialogue_act not in da_names:
        dialogue_act = input("Enter dialogue Act: ").strip().lower()

        # TODO add help print out descriptions
        if first and dialogue_act not in da_names:
            first = False
            # Help, details what each dialogue act means.
            print("Enter a dialogue act from list below:\n", da_names)

    question_type = None
    if is_question(DA[dialogue_act]):
        question_type = ""
        first = True
        question_types = [qt.name for qt in QT]
        while question_type not in question_types:
            question_type = input("Enter question type: ").strip().lower()

            # TODO add help print out descriptions
            if first and question_type not in question_types:
                first = False
                # Help, details what each dialogue act means.
                print("Enter a question type from list below:\n",
                      question_types)

    text = input("Enter utterance text: ").strip()

    sentiment = -1
    while sentiment not in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
        sentiment = input("Enter utterance sentiment 1 to 10. " +
                          "1 negative, 5 neutral, and 10 positive: ")
        sentiment = -1 if sentiment == "" else int(sentiment)

    assertiveness = -1
    while assertiveness not in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
        assertiveness = input("Enter utterance assertiveness 1 to 10. " +
                              "1 passive/listening oriented, 5 neutral, and " +
                              "10 assertive/leading conversation: ")
        assertiveness = -1 if assertiveness == "" else int(assertiveness)

    return Utterance(user_id, DA[dialogue_act], topic, sentiment,
                     assertiveness, text, question_type), mood