始める無料で始める

基本的な否定表現

ユーザーが「〇〇は嫌だ」というように、望まないものを伝えてくることはよくあります。これを正確に理解することはとても重要です。 否定表現の処理は、一般的に自然言語処理(NLP)における難しい問題のひとつです。ここでは、多くのケースに対応できるシンプルなアプローチを取り上げます。

tests というテストのリストがあらかじめ定義されています。シェルで中身を確認してみましょう。各テストは次の要素からなるタプルになっています。

  • エンティティを含むメッセージの文字列
  • エンティティをキー、そのエンティティが否定されているかどうかを示すブール値を値とする辞書

ここでの課題は、メッセージ内の否定されたエンティティを検出する negated_ents() 関数を定義することです。

この演習はコースの一部です

Python でチャットボットを作る

コースを見る

演習の手順

  • リスト内包表記を使って、メッセージ中に "south" または "north" という単語が含まれているかを確認し、該当するエンティティを抽出します。
  • 各エンティティで文を区切ったチャンクに分割します。具体的には以下のように行います。
    • phrase.index() メソッドを使って各エンティティ e の開始インデックスを取得し、そこにエンティティの長さを足してエンティティの終端インデックスを求めます。
    • start=0 から始め、各 end に対して start から end までの文字列をスライスします。スライスしたものをリスト chunks に追加し、ループのたびに開始位置を更新します。
  • 各エンティティについて、そのチャンクに "not" または "n't" が含まれている場合、そのエンティティは否定されていると判断します。

実践的なインタラクティブ演習

このサンプルコードを完成させて、この演習に挑戦してみましょう。

# Define negated_ents()
def negated_ents(phrase):
    # Extract the entities using keyword matching
    ents = [e for e in ["____", "____"] if e in phrase]
    # Find the index of the final character of each entity
    ends = sorted([____ + ____ for e in ents])
    # Initialise a list to store sentence chunks
    chunks = []
    # Take slices of the sentence up to and including each entitiy
    start = 0
    for end in ends:
        chunks.____(phrase[____:____])
        start = end
    result = {}
    # Iterate over the chunks and look for entities
    for chunk in chunks:
        for ent in ents:
            if ent in chunk:
                # If the entity contains a negation, assign the key to be False
                if "not" in chunk or "n't" in chunk:
                    result[ent] = ____
                else:
                    result[ent] = ____
    return result  

# Check that the entities are correctly assigned as True or False
for test in tests:
    print(negated_ents(test[0]) == test[1])
コードを編集して実行