著者はCOVID-19救済基金を選択し、 Write forDOnationsプログラムの一環として寄付を受け取りました。

序章

多くの機能がある場合、ソフトウェアとの対話は困難な作業になる可能性があります。 場合によっては、同様のアクションを実行するには、アクションを実行するたびにメニューをナビゲートしたり、フォームに入力したりするなどの手順を繰り返す必要があります。 チャットボットは、ソフトウェアシステムのユーザーが長いプロセスを経ることなく情報にアクセスしたり、アクションを実行したりするのに役立つ仮想アシスタントです。 これらのアシスタントの多くは会話型であり、システムと対話するためのより自然な方法を提供します。

会話型チャットボットを作成するには、Dialogflowなどのプラットフォームを使用してチャットボットを高レベルで設計できます。 または、 spaCy のようなライブラリを使用して自分でビルドすることもできます。これは、高速で堅牢なPythonベースの自然言語処理(NLP)ライブラリです。 spaCyは、ステートメント内の単語が属する品詞の判別、2つのステートメントの意味の類似性の検出などの便利な機能を提供します。

このチュートリアルでは、ユーザーがソフトウェアシステムとの対話を簡素化するのに役立つだけでなく、自然言語(このチュートリアルではアメリカ英語)でユーザーと通信するのに十分インテリジェントなチャットボットを作成します。 チャットボットはOpenWeatherAPI を使用して、世界のどの都市の現在の天気もユーザーに通知しますが、チャットボットを実装して別のAPIのユースケースを処理することもできます。

前提条件

始める前に、次のものが必要になります。

このチュートリアルは、既に Python に精通していることを前提としています。Pythonの知識を深めたい場合は、 Python3シリーズのコーディング方法を確認してください。 このチュートリアルでは、自然言語処理の知識は必要ありません。

ステップ1—環境を設定する

このステップでは、をインストールします spaCy チャットボットがユーザーの文章を理解するのに役立つライブラリ。

前提条件に従ってPythonを設定すると、仮想環境ができあがります。 その環境を活性化しましょう。

環境を設定したディレクトリにいることを確認してから、次のコマンドを実行します。

  1. source my_env/bin/activate

次に、spaCyをインストールします。

  1. pip install -U spacy

最後に、言語モデルをダウンロードします。 spaCyの言語モデルは、事前にトレーニングされたNLPモデルであり、ステートメントを処理して意味を抽出するために使用できます。 英語モデルを使用するので、それをダウンロードします。

次のコマンドを実行します。

  1. python -m spacy download en_core_web_md

次のようなエラーが発生した場合:

Output
ERROR: Failed building wheel for en-core-web-md

インストールする必要があります wheel:

  1. pip install -U wheel

次に、英語モデルを再度ダウンロードします。

spaCyが正しくインストールされていることを確認するには、Pythonインタープリターを開きます。

  1. python

次に、spaCyをインポートし、英語モデルをロードします。

>>> import spacy
>>> nlp = spacy.load("en_core_web_md")

これらの2つのステートメントがエラーなしで実行される場合は、spaCyがインストールされています。

次に、Pythonインタープリターを閉じます。

>>> exit()

これで、チャットボットでの作業を開始するために必要なすべてのものが揃いました。 次のセクションでは、都市の現在の天気についてOpenWeatherAPIにクエリを実行するスクリプトを作成します。

ステップ2—都市気象プログラムの作成

このセクションでは、ユーザーから都市名を受け取り、OpenWeather APIにその都市の現在の天気を照会し、応答を表示するスクリプトを作成します。

まず、Pythonファイルを作成して開きます。 weather_bot.py お好みのエディターで:

  1. nano weather_bot.py

次に、関数を作成して、OpenWeatherAPIから都市の現在の天気を取得します。 この関数は、都市名をパラメーターとして受け取り、都市の天気の説明を返します。

次のコードをに追加します weather_bot.py ファイル:

Weather_bot.py
import requests

api_key = "your_api_key"

def get_weather(city_name):
	api_url = "http://api.openweathermap.org/data/2.5/weather?q={}&appid={}".format(city_name, api_key)

	response = requests.get(api_url)
	response_dict = response.json()

    weather = response_dict["weather"][0]["description"]

	if response.status_code == 200:
		return weather
	else:
		print('[!] HTTP {0} calling [{1}]'.format(response.status_code, api_url))
		return None

まず、インポートします requests ライブラリを使用して、HTTPリクエストを操作および作成できます。 必ず交換してください your_api_key 独自のAPIキーを使用します。 次の行は、関数の定義を開始します get_weather() 指定した都市の天気を取得します。

この関数では、OpenWeatherAPIのURLを作成します。 このURLは、都市の天気情報(気温、天気の説明、湿度など)を返し、結果をJSON形式で提供します。 その後、APIエンドポイントにGETリクエストを行い、結果を response 変数を入力し、応答をPython dictionaryに変換してアクセスしやすくします。

次の行では、天気の説明だけを抽出して weather 変数を入力し、API応答のステータスコードが次のようになっていることを確認します 200 (リクエストに問題がなかったことを意味します)。 最後に、天気の説明を返します。

リクエストに問題がある場合は、ステータスコードがコンソールに出力され、 None.

スクリプトをテストするには、 get_weather() 選択した都市(たとえば、ロンドン)で機能し、結果を印刷します。 関数の後に強調表示されたコードを追加します。

〜/ Weather_bot.py
import requests

def get_weather(city_name):

  ...

  return weather

weather = get_weather("London")
print(weather)

スクリプトを保存して実行します。

  1. python weather_bot.py

次のような結果が表示されます。

Output
scattered clouds

これが正常に完了すると、スクリプトから最後の2行を削除できます。

それを開く:

  1. nano weather_bot.py

次に、ファイルの最後にある強調表示された2行を削除します。

〜/ Weather_bot.py
import requests

def get_weather(city_name):

  ...

  return weather

weather = get_weather("London")
print(weather)

ファイルを保存して閉じます。

これで、特定の都市の天気の説明を返す関数ができました。

次のステップでは、ユーザーが都市の現在の天気を取得したいかどうかを判断できるチャットボットを作成します。取得したい場合は、チャットボットは get_weather() 適切に対応する機能。

ステップ3—チャットボットを作成する

前の2つの手順では、spaCyをインストールし、特定の都市の天気を取得するための関数を作成しました。 次に、チャットボットを作成して、を使用して自然言語でユーザーと対話します。 weather_bot.py 脚本。

あなたは書くでしょう chatbot() ユーザーのステートメントを都市の天気のチェックを表すステートメントと比較する関数。 この比較を行うには、spaCy 類似性()メソッドを使用します。 このメソッドは、2つのステートメントの意味的類似性、つまり、それらの意味がどの程度類似しているかを計算します。 これは、ユーザーが天気をチェックしようとしているかどうかを判断するのに役立ちます。

まず、スクリプトを開きます。

  1. nano weather_bot.py

次に、spaCyをインポートし、英語モデルをロードします。

〜/ Weather_bot.py
import spacy
import requests

nlp = spacy.load("en_core_web_md")

. . .

後に get_weather() ファイルで関数を作成し、 chatbot() ユーザーのステートメントを受け入れて応答を返すチャットボットを表す関数。

定義に従って、強調表示されたコードを追加して、比較する2つのステートメントのトークンを作成します。 トークンは、単語や句読点など、ステートメントのさまざまな意味のあるセグメントです。 これは、spaCyが意味的類似性を計算できるようにするために必要です。

〜/ Weather_bot.py
import spacy

. . .

def chatbot(statement):
  weather = nlp("Current weather in a city")
  statement = nlp(statement)

ここに weatherstatement 対応する各文字列を nlp() 関数。

ファイルを保存して閉じます。

次に、spaCyを紹介します similarity() あなたへの方法 chatbot() 関数。 The similarity() メソッドは、2つのステートメントの意味的類似性を間の値として計算します 01、ここで、数値が大きいほど類似性が高くなります。 ユーザーが天気を確認したいことを確信するために、類似性が持つ必要のある最小値を指定する必要があります。

たとえば、ステートメント2と3の類似性を次のステートメント1とチェックすると、次のようになります。

  1. 都市の現在の天気
  2. ロンドンの天気は? (類似度= 0.86)
  3. ピーナッツバターとゼリー(類似度= 0.31)

これを自分で試すには、Pythonインタープリターを開きます。

  1. python

次に、spaCyをインポートし、英語モデルをロードします。

>>> import spacy
>>> nlp = spacy.load("en_core_web_md")

次に、ステートメント1と2からトークンを作成しましょう。

>>> statement1 = nlp("Current weather in a city")
>>> statement2 = nlp("What is the weather in London?")

最後に、2つのステートメントの意味的類似性を取得しましょう。

>>> print(statement1.similarity(statement2))

次のような結果が表示されます。

Output
0.8557684354027663

低い最小値(たとえば、0.1)を設定すると、チャットボットはステートメント1と同様にステートメント(ステートメント3など)を使用してユーザーを誤って解釈しますが、これは正しくありません。 最小値を高く設定しすぎると(0.9など)、ステートメント2などのステートメント1に実際に類似している一部のステートメントが除外されます。

このチュートリアルでは0.75を任意に選択しますが、プロジェクトで作業するときにさまざまな値をテストすることをお勧めします。

この値をスクリプトに追加してみましょう。 まず、ファイルを開きます。

  1. nano weather_bot.py

次に、次の強調表示されたコードを追加して、最小値を導入します。

〜/ Weather_bot.py
import spacy

. . .

def chatbot(statement):
  weather = nlp("Current weather in a city")
  statement = nlp(statement)
  min_similarity = 0.75

次に、ユーザーのステートメントと天気に関するステートメントとの類似性が、指定した最小類似性値以上であるかどうかを確認します。 以下の強調表示を追加します if これをチェックするステートメント:

〜/ Weather_bot.py
import spacy

. . .

def chatbot(statement):
  weather = nlp("Current weather in a city")
  statement = nlp(statement)
  min_similarity = 0.75

  if weather.similarity(statement) >= min_similarity:
    pass

最後のステップは、ユーザーのステートメントから都市を抽出して、都市をに渡すことができるようにすることです。 get_weather() API呼び出しから天気を取得する関数。 これを実装するには、次の強調表示された forloopを追加します。

〜/ Weather_bot.py
import spacy

...

def chatbot(statement):
  weather = nlp("Current weather in a city")
  statement = nlp(statement)
  min_similarity = 0.75

  if weather.similarity(statement) >= min_similarity:
    for ent in statement.ents:
      if ent.label_ == "GPE": # GeoPolitical Entity
        city = ent.text
        break

これを行うには、spaCyの名前付きエンティティ認識機能を使用しています。 名前付きエンティティは、人、この場合は都市などの名前を持つ実世界の名詞です。 ユーザーのステートメントから都市の名前を抽出したいとします。

都市名を抽出するには、ユーザーのステートメントですべての名前付きエンティティを取得し、そのうちのどれが地政学的エンティティ(国、州、都市)であるかを確認します。 これを行うには、spaCyがステートメントから抽出したすべてのエンティティをループします。 ents 次に、エンティティラベル(またはクラス)が地政学的エンティティを表す「GPE」であるかどうかを確認します。 そうである場合は、エンティティの名前(そのテキスト)をという変数に保存します city.

また、都市が入力されていない場合をキャッチする必要があります else ブロック:

〜/ Weather_bot.py
import spacy

...

def chatbot(statement):
  weather = nlp("Current weather in a city")
  statement = nlp(statement)
  min_similarity = 0.75

  if weather.similarity(statement) >= min_similarity:
    for ent in statement.ents:
      if ent.label_ == "GPE": # GeoPolitical Entity
        city = ent.text
        break
      else:
        return "You need to tell me a city to check."

これで都市ができたので、 get_weather() 関数:

〜/ Weather_bot.py
import spacy

...

def chatbot(statement):
  weather = nlp("Current weather in a city")
  statement = nlp(statement)
  min_similarity = 0.75

  if weather.similarity(statement) >= min_similarity:
    for ent in statement.ents:
      if ent.label_ == "GPE": # GeoPolitical Entity
        city = ent.text
        break
      else:
        return "You need to tell me a city to check."

    city_weather = get_weather(city)
    if city_weather is not None:
      return "In " + city + ", the current weather is: " + city_weather
    else:
      return "Something went wrong."
  else:
    return "Sorry I don't understand that. Please rephrase your statement."

OpenWeather APIによってエラーが返された場合は、エラーコードをターミナルに出力し、 get_weather() 関数は戻ります None. このコードでは、最初に get_weather() 関数は戻ります None. そうでない場合は、都市の天気を返しますが、そうでない場合は、問題が発生したことを示す文字列を返します。 最終 else ブロックは、ユーザーのステートメントの類似性の値がしきい値に達しない場合を処理するためのものです。 そのような場合、あなたはユーザーに彼らの声明を言い換えるように頼みます。

これらすべてを完了すると、都市の天気をユーザーに会話で伝えることができるチャットボットができました。 このボットとルールベースのチャットボットの違いは、ユーザーが毎回同じステートメントを入力する必要がないことです。 代わりに、さまざまな方法でリクエストを表現したり、タイプミスをしたりすることもできますが、spaCyのNLP機能により、チャットボットはリクエストを理解できます。

ボットをテストしてみましょう。 電話する chatbot() 関数を実行し、都市の天気を尋ねるステートメントを渡します。次に例を示します。

〜/ Weather_bot.py
import spacy

. . .

def chatbot(statement):

. . .

response = chatbot("Is it going to rain in Rome today?")
print(response)

ファイルを保存して閉じてから、ターミナルでスクリプトを実行します。

  1. python3 weather_bot.py

次のような出力が表示されます。

Output
In Rome, the current weather is: clear sky

これで、動的なユーザーリクエストに応答できるインテリジェントなチャットボットが正常に作成されました。 さらに多くの例を試して、ボットの全機能を見つけることができます。 これを行うには、OpenWeatherおよびその他のソースから他のAPIエンドポイントを取得できます。 チャットボットを拡張するもう1つの方法は、より多くのユーザーリクエストに応答できるようにすることです。 このために、ユーザーのステートメントを複数のオプションと比較して、意味的類似性が最も高いものを見つけることができます。

結論

ユーザーがさまざまな方法でステートメントを表現している場合でも、ユーザーのステートメントに応答するのに十分インテリジェントなチャットボットを作成しました。 チャットボットはOpenWeatherAPIを使用して、ユーザーが指定した都市の現在の天気を取得します。

チャットボットをさらに改善するには、次のことができます。

このチュートリアルの最終的なコードは、このDigitalOceanリポジトリにあります。