基本的な否定表現
ユーザーが「〇〇は嫌だ」というように、望まないものを伝えてくることはよくあります。これを正確に理解することはとても重要です。 否定表現の処理は、一般的に自然言語処理(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])