エラスティックサーチへのセマンティックサーチの追加



この記事は、txtai、AI動力セマンティック検索プラットフォームのチュートリアルシリーズの一部です.
このシリーズの第2部と第3部はTxtaiでデータをインデックス化して検索する方法を示しました.Part 2 HuggingFaceデータセットをインデックス化して検索し、パート3にインデックスを付けて外部データソースを検索しました.
TXTIは、デザインのモジュラーです、それはコンポーネントが個別に使用することができます.Txtaiテキストのリストで動作する類似関数があります.このメソッドは、テキスト検索結果を返すREST API、SQLクエリ、またはその他のような外部検索サービスと統合できます.
この記事では、私たちは、第2部で使用されている同じ抱擁のデータセットを取るでしょう.

依存関係のインストール

txtaidatasetsElasticsearchをインストールしました.
# Install txtai, datasets and elasticsearch python client
pip install txtai datasets elasticsearch

# Download and extract elasticsearch
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.1-linux-x86_64.tar.gz
tar -xzf elasticsearch-7.10.1-linux-x86_64.tar.gz
chown -R daemon:daemon elasticsearch-7.10.1
エラスティックサーチのインスタンスを開始します.
import os
from subprocess import Popen, PIPE, STDOUT

# Start and wait for server
server = Popen(['elasticsearch-7.10.1/bin/elasticsearch'], stdout=PIPE, stderr=STDOUT, preexec_fn=lambda: os.setuid(1))
sleep 30

データを弾性検索に読み込む


次のブロックは、データセットをエラスティックサーチに読み込みます.
from datasets import load_dataset

from elasticsearch import Elasticsearch, helpers

# Connect to ES instance
es = Elasticsearch(hosts=["http://localhost:9200"], timeout=60, retry_on_timeout=True)

# Load HF dataset
dataset = load_dataset("ag_news", split="train")["text"][:50000]

# Elasticsearch bulk buffer
buffer = []
rows = 0

for x, text in enumerate(dataset):
  # Article record
  article = {"_id": x, "_index": "articles", "title": text}

  # Buffer article
  buffer.append(article)

  # Increment number of articles processed
  rows += 1

  # Bulk load every 1000 records
  if rows % 1000 == 0:
    helpers.bulk(es, buffer)
    buffer = []

    print("Inserted {} articles".format(rows), end="\r")

if buffer:
  helpers.bulk(es, buffer)

print("Total articles inserted: {}".format(rows))
Total articles inserted: 50000

エラスティックサーチによるクエリデータ


AntiticSearchトークンベースの検索システムです.クエリとドキュメントはトークンに解析され、最も関連するクエリドキュメントのマッチングは、スコアリングアルゴリズムを使用して計算されます.デフォルトのスコアリングアルゴリズムはBM25です.強力な質問はrich query syntaxQuery DSLを使用して構築することができます.
次のセクションでは、エラスティックサーチに対してクエリを実行し、トップ5のマッチを見つけ、それぞれのマッチに関連する対応するドキュメントを返します.
from IPython.display import display, HTML

def table(category, query, rows):
    html = """
    <style type='text/css'>
    @import url('https://fonts.googleapis.com/css?family=Oswald&display=swap');
    table {
      border-collapse: collapse;
      width: 900px;
    }
    th, td {
        border: 1px solid #9e9e9e;
        padding: 10px;
        font: 15px Oswald;
    }
    </style>
    """

    html += "<h3>[%s] %s</h3><table><thead><tr><th>Score</th><th>Text</th></tr></thead>" % (category, query)
    for score, text in rows:
        html += "<tr><td>%.4f</td><td>%s</td></tr>" % (score, text)
    html += "</table>"

    display(HTML(html))

def search(query, limit):
  query = {
      "size": limit,
      "query": {
          "query_string": {"query": query}
      }
  }

  results = []
  for result in es.search(index="articles", body=query)["hits"]["hits"]:
    source = result["_source"]
    results.append((min(result["_score"], 18) / 18, source["title"]))

  return results

limit = 3
query= "+yankees lose"
table("Elasticsearch", query, search(query, limit))

エラスティックス+ヤンキース


スコア
テキスト
0.5817
エルDuqueは、暗いNY予想にヤンキース・ケニースタッフの感染は、チームが1つtは失う余裕がある.オーランド・ヘルナンデスは昨夜から1/2ということです
0.5697
レンジャーズはレッドソックスのレッドソックスは11試合で初めて失われ、レンジャーズ8 - 6土曜日に落ち、アルイーストでヤンキースの1 1/2ゲーム以内にプルするチャンスを逃している.
0.5069
Routはヤンクスを1度引いた.3人のロイヤルズのリードは、カンザスシティーロイヤルズのようなチームを失う何に対しても10 Runマネージャーは彼のチームが早くハンマーを置くことを望み、野球を第2の最悪のチームはチャンスがあると信じています.
上記の表は、問い合わせ+yankees loseの結果を示している.このクエリはトークンyankeesを必要とします.検索はクエリの意味的な意味を理解しません.これらの2つのトークンで最も関連性の高い結果を返します.
この場合には、検索結果の意味がわからない.検索に意味の類似性を加えてみましょう!

Txtaiでランキング検索結果


TXTIは、クエリと文字列のリストの間の類似性を計算する類似モジュールを持っています.もちろん、Txtaiも前の記事に示すように完全なインデックスを構築することができますが、このケースでは、我々はちょうどアドホック相似関数を使用します.
以下のコードは類似性のインスタンスを作成し、計算された類似性に基づいて検索結果を順序付けするためのランキング関数を定義します.ranksearch結果のより大きいセットのためにResearticSearchを検索して、類似性インスタンスを使用して結果をランク付けして、一番上のN結果を返します.
from txtai.pipeline import Similarity

def ranksearch(query, limit):
  results = [text for _, text in search(query, limit * 10)]
  return [(score, results[x]) for x, score in similarity(query, results)][:limit]

# Create similarity instance for re-ranking
similarity = Similarity("valhalla/distilbart-mnli-12-3")
さあ、前の検索を再実行しましょう.
# Run the search
table("Elasticsearch + txtai", query, ranksearch(query, limit))

と、ヤンキースが負ける


スコア
テキスト
0.9929
ああ!ヤンキースは、新しい低インディアンズ22、ヤンキース0 -ニューヨークでヒット、オマールVizquelは、クリーブランドがヤンキースが昨晩彼らの歴史で最も大きな損失を手渡したので、ヒットのためにアメリカの連盟記録を結ぶ6 - 7 - 7をしました.
0.9874
ブラッドRadkeが栄える間、Javier Vazquezが燃え上がったので、Vazquezとヤンキースは初期にバックルをします、ヤンキースは2001年以降ミネソタ州双子によって彼らの最初のレギュラーシーズン敗北を維持しました.
0.9542
ヤンキースのスライド:彼のヤンキースがフランチャイズの長い歴史で最も一方的な損失を被ったので、Pinstripesはジョージスタインブレナーを罰しました彼の箱から見られます.
上記の結果は、クエリに意味で意味的に類似した結果を見つけることのより良い仕事をします.yankeesloseとのマッチを見つけるだけではなく、yankees loseというマッチを見つけます.
この組み合わせは効果的で強力です.これは、意味の検索機能を追加しながら、弾性検索の高いパフォーマンスを利用します.我々は既にデータのTBS(またはPBS)+を使用して大規模な弾性検索クラスタを持っている可能性がありますほとんどのユースケースを解決するエンジニアリング投資の年.意味的にランキング探索結果は実用的なアプローチである.

他の例


エラスティック検索対エラスティックサーチ+ Txtaiからの結果を比較した例を次に示します.
for query in ["good news +economy", "bad news +economy"]:
  table("Elasticsearch", query, search(query, limit))
  table("Elasticsearch + txtai", query, ranksearch(query, limit))

グッドニュース+エコノミー


スコア
テキスト
0.8756
驚きの米国卸売物価は、経済(afp)afpのための混ざりニュースである.8月の米国卸売価格の驚きの低下は明らかにインフレを示したが、アナリストはこれが米国経済にとって良いと悪いニュースであると述べた.
0.7379
中国投資は過熱した経済を冷おうとしている当局に良いニュースを送ります緊縮政策が残る.北京-中国は投資とマネーサプライ成長の月曜日の減速を報告したが、頑固に
0.7145
米国の消費者支出は7月に急激に回復した.政府データは月曜日、6月の失望を消して、アメリカ経済が最近のソフトスポットから回復したという希望を強めた.

良いニュース+経済


スコア
テキスト
0.9996
米国の消費者支出は7月に急騰し、6月の失望を消し、米国経済が最近のソフトスポットから回復したとの希望を強めている、と政府は月曜日に語った.
0.9996
米国の消費者支出は7月に急激に回復した.政府データは月曜日、6月の失望を消して、アメリカ経済が最近のソフトスポットから回復したという希望を強めた.
0.9993
住宅建設は、8月の住宅建設サージは5ヶ月で最高レベルに急騰し、経済のためのニュースの激怒39と述べた.

悪いニュース+経済


スコア
テキスト
0.9228
驚きの米国卸売物価は、経済(afp)afpのための混ざりニュースである.8月の米国卸売価格の驚きの低下は明らかにインフレを示したが、アナリストはこれが米国経済にとって良いと悪いニュースであると述べた.
0.6405
フィールド世論調査:経済蜂スタッフライターを好みます.カリフォルニア人は徐々に経済の健全性について楽観的に成長しているが、大多数は依然として州が悪い経済状況にあると感じている、と新しいフィールド世論調査によると.
0.6188
中国は、中国が経済を冷やすために金利を上げなければならなくて、銀行システムで悪いローンの将来の蓄積を防ぐべきであると冷静にするために金利を上げなければならないと言います、アジア開発銀行S(ADB)bei Jing代表ブルースマレーは言いました.

悪いニュース+経済


スコア
テキスト
0.9977
高齢化社会が日本を襲う日本経済新聞同氏によると、同国の経済は人口高齢化による先進国の中で最も深刻な影響を受ける.
0.9963
ファンド:合併は、投資家を傷つけることができます-ロイター通信-合併と買収は、過去数十年の間に米国経済で大きな役割を果たしました、しかし、時々、結果は\消費者にとって悪かったです.同様に、ミューチュアルファンド\ビジネスの合併は、時々、投資家を傷つけました.
0.9958
Listless Economyの兆候は米国経済の永続的な弱さの徴候で固まっています.
もう一度、SimulticSearchは通常品質結果を返しますが、時折それは意味的に関連しない結果と一致します.セマンティック検索のパワーは、直接マッチを見つけるだけでなく、同じ意味で一致することです.