リランキングは、検索結果の並べ替えを行うアプローチです。リランキングにはいくつかの手法が存在します。
本ラボでは、クロスエンコーダーモデルによるセマンティックリランキングを活用した検索の改善効果を確認していきます。
本ラボの実施にあたっては、以下のラボを事前に完了している必要があります。これらのラボで作成したインデックスを元にリランキングを行っていきます。
本ラボでは、Apache license 2.0 ライセンスで公開されている BAAI/bge-reranker-v2-m3 を Amazon SageMaker 上にデプロイし、リランキングに使用します。モデルの詳細については Hugging Face 上の解説を参照してください。
!pip install opensearch-py requests-aws4auth --quiet
from IPython.core.magic import register_cell_magic
from IPython import get_ipython
import ipywidgets as widgets
import boto3
import json
import time
import logging
from tqdm import tqdm
from datetime import datetime, timedelta
from functools import lru_cache
import pandas as pd
import numpy as np
from opensearchpy import OpenSearch, RequestsHttpConnection, AWSV4SignerAuth
import sagemaker
from sagemaker.huggingface import HuggingFaceModel, get_huggingface_llm_image_uri
/opt/conda/lib/python3.11/site-packages/pydantic/_internal/_fields.py:192: UserWarning: Field name "json" in "MonitoringDatasetFormat" shadows an attribute in parent "Base" warnings.warn(
sagemaker.config INFO - Not applying SDK defaults from location: /etc/xdg/sagemaker/config.yaml sagemaker.config INFO - Not applying SDK defaults from location: /home/sagemaker-user/.config/sagemaker/config.yaml
以降の処理を実行する際に必要なヘルパー関数を定義しておきます。
def search_cloudformation_output(stackname, key):
cloudformation_client = boto3.client("cloudformation", region_name=default_region)
for output in cloudformation_client.describe_stacks(StackName=stackname)["Stacks"][0]["Outputs"]:
if output["OutputKey"] == key:
return output["OutputValue"]
raise ValueError(f"{key} is not found in outputs of {stackname}.")
def get_huggingface_tei_image_uri(instance_type, region):
key = "huggingface-tei" if instance_type.startswith("ml.g") or instance_type.startswith("ml.p") else "huggingface-tei-cpu"
return get_huggingface_llm_image_uri(key, version="1.2.3", region=region)
@lru_cache(maxsize=None)
def list_instance_quotas_for_realtime_inference(instance_family, region):
service_quotas_client = boto3.client("service-quotas", region_name=region)
quotas = []
paginator = service_quotas_client.get_paginator('list_service_quotas')
page_iterator = paginator.paginate(ServiceCode='sagemaker',
PaginationConfig={'MaxResults': 100})
for page in page_iterator:
for quota in page['Quotas']:
if quota["QuotaName"].endswith("endpoint usage") and quota["Value"] > 0 and quota["QuotaName"].startswith("ml."+instance_family):
quotas.append(quota)
return quotas
def list_instance_usages(region):
sagemaker_client = boto3.client("sagemaker", region_name=region)
response = sagemaker_client.list_endpoints(
)
instances = []
for endpoint in response["Endpoints"]:
response = sagemaker_client.describe_endpoint(EndpointName=endpoint["EndpointName"])
response = sagemaker_client.describe_endpoint_config(EndpointConfigName=response["EndpointConfigName"])
if "InstanceType" in response["ProductionVariants"][0]:
instances.append(response["ProductionVariants"][0]["InstanceType"])
values, counts = np.unique(instances, return_counts=True)
return values,counts
def list_instance_attributes_realtime_inference(instance_family, region):
pricing = boto3.client("pricing", region_name="us-east-1")
instance_types = []
paginator = pricing.get_paginator("get_products")
page_iterator = paginator.paginate(
ServiceCode="AmazonSageMaker",
Filters=[
{
"Type": "TERM_MATCH",
"Field": "productFamily",
"Value": "ML Instance"
},
{
"Type": "TERM_MATCH",
"Field": "regionCode",
"Value": region
},
{
"Type": "TERM_MATCH",
"Field": "platoinstancetype",
"Value": "Hosting"
},
{
"Type": "TERM_MATCH",
"Field": "platoinstancename",
"Value": instance_family
},
],
)
products = []
for page in page_iterator:
for product in page["PriceList"]:
products.append(json.loads(product)["product"]["attributes"])
return products
def list_available_instance_types_for_realtime_inference(instance_family, region):
quotas = list_instance_quotas_for_realtime_inference(instance_family=instance_family, region=region)
quotas_df = pd.json_normalize(quotas).loc[:,["QuotaName","Value"]]
quotas_df["InstanceType"] = quotas_df["QuotaName"].str.removesuffix(" for endpoint usage")
quotas_df = quotas_df.drop(columns=["QuotaName"]).rename(columns={"Value":"Limit"})
quotas_df["Limit"] = quotas_df["Limit"].astype(int)
usage_values,usage_counts = list_instance_usages(region=region)
usages_df = pd.DataFrame({"InstanceType": usage_values, "Usage": usage_counts})
attributes = list_instance_attributes_realtime_inference(instance_family=instance_family, region=region)
attributes_df = pd.json_normalize(attributes)
attributes_df = attributes_df.loc[:,["instanceName","vCpu"]].rename(columns={"instanceName": "InstanceType"})
merged_df = pd.merge(pd.merge(quotas_df, usages_df, how="left", on="InstanceType"), attributes_df, on='InstanceType').fillna(value=0)
filtered_df = merged_df.query("Usage<Limit")
filtered_df["vCpu"] = filtered_df["vCpu"].astype(int)
instance_types = filtered_df.sort_values("vCpu", ascending=True, ignore_index=True).InstanceType
print(instance_types.array)
return instance_types.array
def search_sagemaker_inference_endpoint(endpoint_name, region):
sagemaker_client = boto3.client("sagemaker", region_name=region)
try:
response = sagemaker_client.search(
Resource="Endpoint",
SearchExpression={
"Filters": [
{
"Name": "EndpointName",
"Operator": "Contains",
"Value": endpoint_name
},
],
},
SortBy="LastModifiedTime",
SortOrder="Descending"
)
return response["Results"]
except Exception as e:
print(e)
default_region = boto3.Session().region_name
logging.getLogger().setLevel(logging.ERROR)
Amazon SageMaker にクロスエンコーダーモデル BAAI/bge-reranker-v2-m3 を実行するリアルタイム推論エンドポイントを作成します。
重複してエンドポイントを作成しないように、推論エンドポイントが既に作成されている場合はモデルの作成をスキップし、既存のエンドポイント情報を返します。
try:
sagemaker_region = default_region
reranking_model_id_on_hf = "BAAI/bge-reranker-v2-m3"
reranking_model_name = reranking_model_id_on_hf.lower().replace("/", "-")
realtime_inference_endpoint_type = "instance"
reranking_endpoint_name_prefix = f"{reranking_model_name}-{realtime_inference_endpoint_type}"
response = search_sagemaker_inference_endpoint(reranking_endpoint_name_prefix, sagemaker_region)
if len(response) == 0:
print(f"Model {reranking_model_id_on_hf} is not deployed on a realtime {realtime_inference_endpoint_type} endpoint." )
hub = {
"HF_MODEL_ID": reranking_model_id_on_hf
}
role = sagemaker.get_execution_role()
available_instance_types = list_available_instance_types_for_realtime_inference(instance_family="g5", region=sagemaker_region)
if (len(available_instance_types)) > 0:
instance_type = available_instance_types[0]
else:
print("There is no available gpu instance type. Trying to use cpu instance type.")
available_instance_types = list_available_instance_types_for_realtime_inference(instance_family="c5", region=sagemaker_region)
if (len(available_instance_types)) > 0:
instance_type = available_instance_types[0]
else:
raise ValueException("There is no available instance types. Please change deployment option to on serverless endpoint, and try again.")
print(f"Found an eligable instance type. {instance_type} will be used for a realtime {realtime_inference_endpoint_type} endpoint.")
reranking_model = HuggingFaceModel(
name=sagemaker.utils.name_from_base(reranking_model_name),
env=hub, # configuration for loading model from Hub
role=role, # iam role with permissions to create an Endpoint
image_uri=get_huggingface_tei_image_uri(instance_type=instance_type, region=sagemaker_region)
)
print(f"start deploy {reranking_model_id_on_hf} on a realtime {realtime_inference_endpoint_type} endpoint.")
reranking_model.deploy(
endpoint_name=sagemaker.utils.name_from_base(reranking_endpoint_name_prefix),
initial_instance_count=1,
instance_type=instance_type
)
reranking_endpoint_name = reranking_model.endpoint_name
else:
print(f"Model {reranking_model_id_on_hf} is already deployed on a realtime {realtime_inference_endpoint_type} endpoint.")
reranking_endpoint = response[0]["Endpoint"]
reranking_endpoint_name = reranking_endpoint["EndpointName"]
reranking_endpoint_url = f"https://runtime.sagemaker.{default_region}.amazonaws.com/endpoints/{reranking_endpoint_name}/invocations"
print(f"\nendpoint name: {reranking_endpoint_name}")
print(f"endpoint url: {reranking_endpoint_url}")
except Exception as e:
print(e)
Model BAAI/bge-reranker-v2-m3 is not deployed on a realtime instance endpoint.
/tmp/ipykernel_200/2391943473.py:89: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy filtered_df["vCpu"] = filtered_df["vCpu"].astype(int)
<NumpyExtensionArray> ['ml.g5.2xlarge', 'ml.g5.4xlarge'] Length: 2, dtype: object Found an eligable instance type. ml.g5.2xlarge will be used for a realtime instance endpoint. start deploy BAAI/bge-reranker-v2-m3 on a realtime instance endpoint. ---------------! endpoint name: baai-bge-reranker-v2-m3-instance-2025-03-11-05-24-14-401 endpoint url: https://runtime.sagemaker.us-east-1.amazonaws.com/endpoints/baai-bge-reranker-v2-m3-instance-2025-03-11-05-24-14-401/invocations
推論エンドポイントに対してテスト呼び出しを実行します。推論エンドポイントからは、ドキュメントリストのインデックス番号とスコアが返却されます。結果はスコアの高い順番に返却されます。
%%time
payload = {
"query":"What is the capital city of America?",
"texts":[
"Carson City is the capital city of the American state of Nevada.",
"The Commonwealth of the Northern Mariana Islands is a group of islands in the Pacific Ocean. Its capital is Saipan.",
"Washington, D.C. (also known as simply Washington or D.C., and officially as the District of Columbia) is the capital of the United States. It is a federal district.",
"Capital punishment (the death penalty) has existed in the United States since beforethe United States was a country. As of 2017, capital punishment is legal in 30 of the 50 states."
]
}
body = bytes(json.dumps(payload), 'utf-8')
sagemaker_runtime_client = boto3.client("sagemaker-runtime", region_name=sagemaker_region)
response = sagemaker_runtime_client.invoke_endpoint(
EndpointName=reranking_endpoint_name,
ContentType="application/json",
Accept="application/json",
Body=body
)
result = eval(response['Body'].read().decode('utf-8'))
print(json.dumps(result, indent=2))
[ { "index": 2, "score": 0.9291838 }, { "index": 0, "score": 0.013584392 }, { "index": 1, "score": 0.000593021 }, { "index": 3, "score": 0.00012148176 } ] CPU times: user 16 ms, sys: 0 ns, total: 16 ms Wall time: 123 ms
送信したドキュメントリストと順番を揃える場合は、index でソートする必要があります。
print(json.dumps(sorted(result, key=lambda x: x['index']),indent=2))
[ { "index": 0, "score": 0.013584392 }, { "index": 1, "score": 0.000593021 }, { "index": 2, "score": 0.9291838 }, { "index": 3, "score": 0.00012148176 } ]
ドメイン(クラスター)に接続するためのエンドポイント情報を CloudFormation スタックの出力から取得し、OpenSearch クライアントを作成します。
cloudformation_stack_name = "search-lab-jp"
opensearch_cluster_endpoint = search_cloudformation_output(cloudformation_stack_name, "OpenSearchDomainEndpoint")
credentials = boto3.Session().get_credentials()
service_code = "es"
auth = AWSV4SignerAuth(credentials=credentials, region=default_region, service=service_code)
opensearch_client = OpenSearch(
hosts=[{"host": opensearch_cluster_endpoint, "port": 443}],
http_compress=True,
http_auth=auth,
use_ssl=True,
verify_certs=True,
connection_class = RequestsHttpConnection
)
opensearch_client
<OpenSearch([{'host': 'vpc-opensearchservi-lsy27q89mdpe-ldw2ctnzym3u7iqqrmq36zwftu.us-east-1.es.amazonaws.com', 'port': 443}])>
OpenSearch クラスターへのネットワーク接続性が確保されており、OpenSearch の Security 機能により API リクエストが許可されているかを確認します。 レスポンスに cluster_name や cluster_uuid が含まれていれば、接続確認が無事完了したと判断できます
opensearch_client.info()
{'name': '37fa7880d30e6918860bdb0e18c8e91d', 'cluster_name': '123456789012:opensearchservi-lsy27q89mdpe', 'cluster_uuid': 'yHC8ufTTRdWZqY-0J9kE9A', 'version': {'distribution': 'opensearch', 'number': '2.17.0', 'build_type': 'tar', 'build_hash': 'unknown', 'build_date': '2025-02-14T09:38:50.023788640Z', 'build_snapshot': False, 'lucene_version': '9.11.1', 'minimum_wire_compatibility_version': '7.10.0', 'minimum_index_compatibility_version': '7.0.0'}, 'tagline': 'The OpenSearch Project: https://opensearch.org/'}
SageMaker 上にデプロイしたモデルを呼び出すためのコンポーネントを作成します。
モデルは、コネクタと呼ばれる外部接続を定義したコンポーネントで構成されています。 今回の構成では、モデルは Rerank Processor から呼び出されます。Rerank processor は、リランキングモデルと連携し、クエリと検索結果の組み合わせを元に検索結果の並べ替えを行います。
本セルの実行でエラーが発生する場合は、再度 SageMaker 上でのモデルデプロイをお試しください。
print(f"model name: {reranking_model_name}")
print(f"endpoint name: {reranking_endpoint_name}")
print(f"endpoint url: {reranking_endpoint_url}")
model name: baai-bge-reranker-v2-m3 endpoint name: baai-bge-reranker-v2-m3-instance-2025-03-11-05-24-14-401 endpoint url: https://runtime.sagemaker.us-east-1.amazonaws.com/endpoints/baai-bge-reranker-v2-m3-instance-2025-03-11-05-24-14-401/invocations
OpenSearch コネクタから AWS サービスに接続する際、任意の IAM ロールの権限を引き受ける必要があります。引受対象の IAM ロールを CloudFormation スタックの出力から取得します。
cloudformation_stack_name = "search-lab-jp"
opensearch_connector_role_arn = search_cloudformation_output(cloudformation_stack_name, 'OpenSearchConnectorRoleArn')
opensearch_connector_role_arn
'arn:aws:iam::123456789012:role/workshop/search-lab-jp/search-lab-jp-OpenSearchConnectorRole-Htsh09WLGPGt'
Amazon SageMaker 上のモデルを呼び出す定義を記載したコネクタを作成します。 コネクタは、OpenSearch におけるモデルの一要素です。
コネクタの処理の流れは以下の通りです。
payload = {
"name": reranking_model_name,
"description": "Remote connector for "+ reranking_model_name,
"version": 1,
"protocol": "aws_sigv4",
"credential": {
"roleArn": opensearch_connector_role_arn
},
"parameters": {
"region": default_region,
"service_name": "sagemaker"
},
"actions": [
{
"action_type": "predict",
"method": "POST",
"url": reranking_endpoint_url,
"headers": {
"content-type": "application/json"
},
"pre_process_function": """
def query_text = params.query_text;
def text_docs = params.text_docs;
def textDocsBuilder = new StringBuilder('[');
for (int i=0; i<text_docs.length; i++) {
textDocsBuilder.append('\"');
textDocsBuilder.append(text_docs[i]);
textDocsBuilder.append('\"');
if (i<text_docs.length - 1) {
textDocsBuilder.append(',');
}
}
textDocsBuilder.append(']');
def parameters = '{ \"query\": \"' + query_text + '\", \"texts\": ' + textDocsBuilder.toString() + ' }';
return '{\"parameters\": ' + parameters + '}';
""",
"request_body": "{ \"query\": \"${parameters.query}\", \"texts\": ${parameters.texts} }",
"post_process_function": """
if (params.result == null) {
throw new IllegalArgumentException("Post process function input is empty.");
}
def outputs = params.result;
def scores = new Double[outputs.length];
for (int i=0; i<outputs.length; i++) {
def index = new BigDecimal(outputs[i].index.toString()).intValue();
scores[index] = outputs[i].score;
}
def resultBuilder = new StringBuilder('[');
for (int i=0; i<scores.length; i++) {
resultBuilder.append(' {\"name\": \"similarity\", \"data_type\": \"FLOAT32\", \"shape\": [1],');
resultBuilder.append('\"data\": [');
resultBuilder.append(scores[i]);
resultBuilder.append(']}');
if (i<outputs.length - 1) {
resultBuilder.append(',');
}
}
resultBuilder.append(']');
return resultBuilder.toString();
"""
}
]
}
response = opensearch_client.http.post("/_plugins/_ml/connectors/_create", body=payload)
reranking_connector_id = response['connector_id']
print("reranking connector id: " + reranking_connector_id)
reranking connector id: YM6wg5UB_gYfju7dgedL
コネクタを元に、OpenSearch にモデル情報を登録します。
payload = {
"name": reranking_model_name,
"description": reranking_model_name,
"function_name": "remote",
"connector_id": reranking_connector_id
}
response = opensearch_client.http.post("/_plugins/_ml/models/_register?deploy=true", body=payload)
reranking_model_id = response['model_id']
for i in range(300):
ml_model_status = opensearch_client.http.get("/_plugins/_ml/models/"+ reranking_model_id)
model_state = ml_model_status.get("model_state")
if model_state in ["DEPLOYED", "PARTIALLY_DEPLOYED"]:
break
time.sleep(1)
if model_state == "DEPLOYED":
print("reranking model " + reranking_model_id + " is deployed successfully")
elif model_state == "PARTIALLY_DEPLOYED":
print("reranking model " + reranking_model_id + " is deployed only partially")
else:
raise Exception("reranking model " + reranking_model_id + " deployment failed")
print(ml_model_status)
reranking model Y86wg5UB_gYfju7dgeeO is deployed successfully {'name': 'baai-bge-reranker-v2-m3', 'model_group_id': 'Yc6wg5UB_gYfju7dgedp', 'algorithm': 'REMOTE', 'model_version': '1', 'description': 'baai-bge-reranker-v2-m3', 'model_state': 'DEPLOYED', 'created_time': 1741671137678, 'last_updated_time': 1741671137731, 'last_deployed_time': 1741671137731, 'auto_redeploy_retry_times': 0, 'planning_worker_node_count': 1, 'current_worker_node_count': 1, 'planning_worker_nodes': ['kdnLueFaT0quni1aPfT5-g'], 'deploy_to_all_nodes': True, 'is_hidden': False, 'connector_id': 'YM6wg5UB_gYfju7dgedL'}
OpenSearch 経由で Amazon SageMaker 上の埋め込みモデルを実行できることを確認します。モデルの呼び出し方は 2 パターンあります。
Reranking processor からの呼び出しを想定する場合は、以下パスの API を使用します。 Reranking processor が text_similarity モデルを呼び出す際のパラメーターキーは query_text と text_docs で固定されています。query_text パラメーターには、クライアントのクエリが、text_docs には検索結果のテキストがセットされています。
payload = {
"query_text": "What is the capital city of America?",
"text_docs": [
"Carson City is the capital city of the American state of Nevada.",
"The Commonwealth of the Northern Mariana Islands is a group of islands in the Pacific Ocean. Its capital is Saipan.",
"Washington, D.C. (also known as simply Washington or D.C., and officially as the District of Columbia) is the capital of the United States. It is a federal district.",
"Capital punishment (the death penalty) has existed in the United States since beforethe United States was a country. As of 2017, capital punishment is legal in 30 of the 50 states."
]
}
opensearch_client.http.post("/_plugins/_ml/_predict/text_similarity/" + reranking_model_id, body=payload)
{'inference_results': [{'output': [{'name': 'similarity', 'data_type': 'FLOAT32', 'shape': [1], 'data': [0.013584392]}, {'name': 'similarity', 'data_type': 'FLOAT32', 'shape': [1], 'data': [0.000593021]}, {'name': 'similarity', 'data_type': 'FLOAT32', 'shape': [1], 'data': [0.92905515]}, {'name': 'similarity', 'data_type': 'FLOAT32', 'shape': [1], 'data': [0.00012148176]}], 'status_code': 200}]}
ML モデル配下の predict API を直接呼び出してテストを行うことも可能です。この場合 pre_process_function は呼び出されず、parameters に記載した値が直接コネクタで指定した推論エンドポイントに渡されます。
payload = {
"parameters": {
"query": "What is the capital city of America?",
"texts": [
"Carson City is the capital city of the American state of Nevada.",
"The Commonwealth of the Northern Mariana Islands is a group of islands in the Pacific Ocean. Its capital is Saipan.",
"Washington, D.C. (also known as simply Washington or D.C., and officially as the District of Columbia) is the capital of the United States. It is a federal district.",
"Capital punishment (the death penalty) has existed in the United States since beforethe United States was a country. As of 2017, capital punishment is legal in 30 of the 50 states."
]
}
}
result = opensearch_client.http.post("/_plugins/_ml/models/" + reranking_model_id + "/_predict", body=payload)
print(json.dumps(result, indent=2))
{ "inference_results": [ { "output": [ { "name": "similarity", "data_type": "FLOAT32", "shape": [ 1 ], "data": [ 0.013636836 ] }, { "name": "similarity", "data_type": "FLOAT32", "shape": [ 1 ], "data": [ 0.000593021 ] }, { "name": "similarity", "data_type": "FLOAT32", "shape": [ 1 ], "data": [ 0.9291838 ] }, { "name": "similarity", "data_type": "FLOAT32", "shape": [ 1 ], "data": [ 0.00012148176 ] } ], "status_code": 200 } ] }
テキストとベクトルのハイブリッド検索 (Amazon SageMaker 編) で作成した検索パイプラインをベースに Reranking processor を含むパイプラインを作成します。作成にあたって、過去のパイプラインの設定を流用します。
embedding_model_id_on_hf = "BAAI/bge-m3"
embedding_model_name = embedding_model_id_on_hf.lower().replace("/", "-")
neural_search_pipeline_id = f"{embedding_model_name}_neural_search_query"
sparse_encoding_model_id_on_hf = "hotchpotch/japanese-splade-v2"
sparse_encoding_model_name = sparse_encoding_model_id_on_hf.lower().replace("/", "-")
neural_sparse_search_pipeline_id = f"{sparse_encoding_model_name}_neural_sparse_search_query"
hybrid_search_pipeline_id = f"{embedding_model_name}_{sparse_encoding_model_name}_hybrid_search"
response = opensearch_client.http.get("/_search/pipeline/" + hybrid_search_pipeline_id)
request_processors = response[hybrid_search_pipeline_id]["request_processors"]
phase_results_processors = response[hybrid_search_pipeline_id]["phase_results_processors"]
Reranking を使用するためには、Search pipeline 内に Search response processors の一種である Rerank processor を追加します。
上記で取得した request_processors に加えて、Response processors に Rerank processor を追加したパイプラインを作成します。
payload={
"request_processors": request_processors,
"phase_results_processors": phase_results_processors,
"response_processors": [
{
"rerank": {
"ml_opensearch": {
"model_id": reranking_model_id
},
"context": {
"document_fields": [
"question"
]
}
}
}
]
}
# パイプライン ID の指定
rerank_pipeline_id = "rerank_pipeline"
# パイプライン作成 API の呼び出し
response = opensearch_client.http.put("/_search/pipeline/" + rerank_pipeline_id, body=payload)
print(response)
response = opensearch_client.http.get("/_search/pipeline/" + rerank_pipeline_id)
print(response)
{'acknowledged': True} {'rerank_pipeline': {'request_processors': [{'neural_sparse_two_phase_processor': {'tag': 'neural-sparse', 'description': 'Creates a two-phase processor for neural sparse search.'}}, {'neural_query_enricher': {'default_model_id': '6s6ig5UB_gYfju7duOPf', 'neural_field_default_id': {'question_sparse_embedding': 'Mc6kg5UB_gYfju7dMOSG', 'context_sparse_embedding': 'Mc6kg5UB_gYfju7dMOSG'}}}], 'phase_results_processors': [{'normalization-processor': {'normalization': {'technique': 'min_max'}, 'combination': {'technique': 'arithmetic_mean', 'parameters': {'weights': [0.7, 0.3]}}}}], 'response_processors': [{'rerank': {'ml_opensearch': {'model_id': 'Y86wg5UB_gYfju7dgeeO'}, 'context': {'document_fields': ['question']}}}]}}
従来の全文検索では、フィールドの重みづけの調整など、スコア計算の調整で検索結果の調整を行ってきました。 ベクトル検索単体では全文検索のような重みづけの調整が困難であるため、リランキングサービスと組み合わせることで検索結果の並べ替えを行います。
例えば、context_embedding に対するベクトル検索の上位 30 件を見てみると、質問の意図に沿っていないものも上位のスコアとなっており、検索結果のランキングが妥当とはいえません。
%%time
# search
index_name = "jsquad-neural-search"
query = "日本で梅雨がない場所は?"
payload = {
"size": 30,
"query": {
"neural": {
"context_embedding": {
"query_text": query, # テキストをベクトルに変換し
"k": 30 # クエリベクトルに近いベクトルのうち上位 5 つを返す
}
}
},
"_source" : False,
"fields": ["question", "answers", "context"]
}
# 検索 API を実行
response = opensearch_client.search(
body = payload,
index = index_name,
filter_path = "hits.hits",
search_pipeline = neural_search_pipeline_id #ベクトル変換を行うパイプラインを指定
)
# 結果を表示
pd.json_normalize(response["hits"]["hits"])
CPU times: user 3.95 ms, sys: 0 ns, total: 3.95 ms Wall time: 134 ms
_index | _id | _score | fields.question | fields.answers | fields.context | |
---|---|---|---|---|---|---|
0 | jsquad-neural-search | a10336p0q0 | 0.547599 | [日本で梅雨がないのは北海道とどこか。] | [小笠原諸島, 小笠原諸島を除く日本] | [梅雨 [SEP] 梅雨(つゆ、ばいう)は、北海道と小笠原諸島を除く日本、朝鮮半島南部、中国... |
1 | jsquad-neural-search | a10336p0q1 | 0.547599 | [梅雨とは何季の一種か?] | [雨季] | [梅雨 [SEP] 梅雨(つゆ、ばいう)は、北海道と小笠原諸島を除く日本、朝鮮半島南部、中国... |
2 | jsquad-neural-search | a10336p0q2 | 0.547599 | [梅雨は、世界的にどのあたりで見られる気象ですか?] | [東アジア, 東アジアの広範囲] | [梅雨 [SEP] 梅雨(つゆ、ばいう)は、北海道と小笠原諸島を除く日本、朝鮮半島南部、中国... |
3 | jsquad-neural-search | a10336p0q3 | 0.547599 | [梅雨がみられるのはどの期間?] | [5月から7月, 5月から7月にかけて] | [梅雨 [SEP] 梅雨(つゆ、ばいう)は、北海道と小笠原諸島を除く日本、朝鮮半島南部、中国... |
4 | jsquad-neural-search | a10336p23q2 | 0.545992 | [7月頃に例年ある、長い雨の時期を抜けることを何というか。] | [梅雨明け] | [梅雨 [SEP] 年によっては梅雨入りの時期が特定できなかったり、あるいは発表がされないこ... |
5 | jsquad-neural-search | a10336p23q0 | 0.545968 | [本当の夏が長いのは近畿地方と北陸地方どちらか] | [近畿地方] | [梅雨 [SEP] 年によっては梅雨入りの時期が特定できなかったり、あるいは発表がされないこ... |
6 | jsquad-neural-search | a10336p23q3 | 0.545968 | [年によっては梅雨入りの時期が特定できなかったり、あるいは発表がされないこともある。東・西日... | [数年に一回, 数年に一回の割合, 数年に一回の割合で起こる] | [梅雨 [SEP] 年によっては梅雨入りの時期が特定できなかったり、あるいは発表がされないこ... |
7 | jsquad-neural-search | a10336p23q1 | 0.545957 | [近畿地方における夏は北陸地方よりも長い?短い?] | [長い] | [梅雨 [SEP] 年によっては梅雨入りの時期が特定できなかったり、あるいは発表がされないこ... |
8 | jsquad-neural-search | a10336p42q2 | 0.541177 | [梅雨の期間中ほとんど雨が降らない場合をなんという?] | [空梅雨, 空梅雨(からつゆ)] | [梅雨 [SEP] 梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことを空梅雨... |
9 | jsquad-neural-search | a10336p42q3 | 0.541148 | [ほとんど雨が降らない梅雨を何と呼ぶか] | [空梅雨, 空梅雨(からつゆ)] | [梅雨 [SEP] 梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことを空梅雨... |
10 | jsquad-neural-search | a10336p42q0 | 0.541143 | [梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことをなんというか?] | [空梅雨, 空梅雨(からつゆ)] | [梅雨 [SEP] 梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことを空梅雨... |
11 | jsquad-neural-search | a10336p42q1 | 0.541143 | [梅雨の期間中ほとんど雨が降らない場合を何と呼ぶ?] | [空梅雨, 空梅雨(からつゆ)] | [梅雨 [SEP] 梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことを空梅雨... |
12 | jsquad-neural-search | a10336p42q4 | 0.541143 | [ほとんど雨が降らない梅雨を何という?] | [空梅雨, 空梅雨(からつゆ)] | [梅雨 [SEP] 梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことを空梅雨... |
13 | jsquad-neural-search | a10336p34q3 | 0.529068 | [小笠原諸島が春から夏への遷移期にあたる時期はいつ] | [5月] | [梅雨 [SEP] 小笠原諸島が春から夏への遷移期にあたる5月には、気団同士の中心が離れてい... |
14 | jsquad-neural-search | a10336p34q0 | 0.529054 | [小笠原諸島が春から夏への遷移期にあたるのは何月か?] | [5月] | [梅雨 [SEP] 小笠原諸島が春から夏への遷移期にあたる5月には、気団同士の中心が離れてい... |
15 | jsquad-neural-search | a10336p34q1 | 0.529054 | [小笠原諸島に梅雨はあるか] | [ない] | [梅雨 [SEP] 小笠原諸島が春から夏への遷移期にあたる5月には、気団同士の中心が離れてい... |
16 | jsquad-neural-search | a10336p34q2 | 0.529054 | [小笠原諸島が春から夏への遷移期にあたるのは何月?] | [5月] | [梅雨 [SEP] 小笠原諸島が春から夏への遷移期にあたる5月には、気団同士の中心が離れてい... |
17 | jsquad-neural-search | a10336p32q2 | 0.527241 | [気候学的には梅雨はないとされている場所は?] | [北海道] | [梅雨 [SEP] 実際の気象としては北海道にも道南を中心に梅雨前線がかかることはあるが、平... |
18 | jsquad-neural-search | a10336p32q3 | 0.527231 | [梅雨がないとされている都道府県はどこ?] | [北海道] | [梅雨 [SEP] 実際の気象としては北海道にも道南を中心に梅雨前線がかかることはあるが、平... |
19 | jsquad-neural-search | a10336p32q0 | 0.527228 | [梅雨前線が北海道に到達する梅雨末期は勢力が衰え、北上する速度が速くなっていて、降水が長く続... | [梅雨] | [梅雨 [SEP] 実際の気象としては北海道にも道南を中心に梅雨前線がかかることはあるが、平... |
20 | jsquad-neural-search | a10336p32q1 | 0.527228 | [北海道に梅雨はあるか] | [ない, 梅雨はない] | [梅雨 [SEP] 実際の気象としては北海道にも道南を中心に梅雨前線がかかることはあるが、平... |
21 | jsquad-neural-search | a10336p24q0 | 0.524144 | [立秋を境にして、立秋以降の長雨のことを何雨と呼ぶか] | [秋雨] | [梅雨 [SEP] 年によっては梅雨明けの時期が特定できなかったり、あるいは発表がされないこ... |
22 | jsquad-neural-search | a10336p24q1 | 0.524144 | [梅雨が日本の中でない地域はどこか。] | [北海道, 東北地方] | [梅雨 [SEP] 年によっては梅雨明けの時期が特定できなかったり、あるいは発表がされないこ... |
23 | jsquad-neural-search | a10336p24q2 | 0.524144 | [東北地方における夏は北海道よりも長い?短い?] | [短い] | [梅雨 [SEP] 年によっては梅雨明けの時期が特定できなかったり、あるいは発表がされないこ... |
24 | jsquad-neural-search | a10336p31q0 | 0.513337 | [梅雨の期間はどれくらいか?] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
25 | jsquad-neural-search | a10336p31q1 | 0.513337 | [梅雨の期間はだいたいどれぐらいか?] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
26 | jsquad-neural-search | a10336p31q2 | 0.513337 | [日本付近の梅雨期の雨量が最も多い地区は] | [九州南部] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
27 | jsquad-neural-search | a10336p31q3 | 0.513337 | [梅雨の期間はどれくらいか] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
28 | jsquad-neural-search | a10336p31q4 | 0.513337 | [梅雨の期間は?] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
29 | jsquad-neural-search | a10336p27q0 | 0.503760 | [毎年梅雨入り・梅雨明けの発表をするのはどの機関か] | [各地の地方気象台・気象庁] | [梅雨 [SEP] 日本では各地の地方気象台・気象庁が、数個の都府県をまとめた地域ごとに毎年... |
リランキングを挟むことで、_score が補正され、順位が妥当となることが確認できました。
%%time
# search
index_name = "jsquad-neural-search"
query = "日本で梅雨がない場所は?"
payload = {
"size": 30,
"query": {
"neural": {
"context_embedding": {
"query_text": query, # テキストをベクトルに変換し
"k": 30 # クエリベクトルに近いベクトルのうち上位 3 つを返す
}
}
},
"ext": {
"rerank": {
"query_context": {
"query_text_path": "query.neural.context_embedding.query_text"
}
}
},
"_source" : False,
"fields": ["question", "answers", "context"]
}
# 検索 API を実行
response = opensearch_client.search(
body = payload,
index = index_name,
filter_path = "hits.hits",
search_pipeline = rerank_pipeline_id #ベクトル変換を行うパイプラインを指定
)
# 結果を表示
pd.json_normalize(response["hits"]["hits"])
CPU times: user 5.11 ms, sys: 0 ns, total: 5.11 ms Wall time: 119 ms
_index | _id | _score | fields.question | fields.answers | fields.context | |
---|---|---|---|---|---|---|
0 | jsquad-neural-search | a10336p24q1 | 0.999338 | [梅雨が日本の中でない地域はどこか。] | [北海道, 東北地方] | [梅雨 [SEP] 年によっては梅雨明けの時期が特定できなかったり、あるいは発表がされないこ... |
1 | jsquad-neural-search | a10336p0q0 | 0.997809 | [日本で梅雨がないのは北海道とどこか。] | [小笠原諸島, 小笠原諸島を除く日本] | [梅雨 [SEP] 梅雨(つゆ、ばいう)は、北海道と小笠原諸島を除く日本、朝鮮半島南部、中国... |
2 | jsquad-neural-search | a10336p32q3 | 0.948823 | [梅雨がないとされている都道府県はどこ?] | [北海道] | [梅雨 [SEP] 実際の気象としては北海道にも道南を中心に梅雨前線がかかることはあるが、平... |
3 | jsquad-neural-search | a10336p32q2 | 0.893867 | [気候学的には梅雨はないとされている場所は?] | [北海道] | [梅雨 [SEP] 実際の気象としては北海道にも道南を中心に梅雨前線がかかることはあるが、平... |
4 | jsquad-neural-search | a10336p32q1 | 0.303525 | [北海道に梅雨はあるか] | [ない, 梅雨はない] | [梅雨 [SEP] 実際の気象としては北海道にも道南を中心に梅雨前線がかかることはあるが、平... |
5 | jsquad-neural-search | a10336p32q0 | 0.072112 | [梅雨前線が北海道に到達する梅雨末期は勢力が衰え、北上する速度が速くなっていて、降水が長く続... | [梅雨] | [梅雨 [SEP] 実際の気象としては北海道にも道南を中心に梅雨前線がかかることはあるが、平... |
6 | jsquad-neural-search | a10336p31q2 | 0.035679 | [日本付近の梅雨期の雨量が最も多い地区は] | [九州南部] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
7 | jsquad-neural-search | a10336p42q3 | 0.029479 | [ほとんど雨が降らない梅雨を何と呼ぶか] | [空梅雨, 空梅雨(からつゆ)] | [梅雨 [SEP] 梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことを空梅雨... |
8 | jsquad-neural-search | a10336p42q4 | 0.028490 | [ほとんど雨が降らない梅雨を何という?] | [空梅雨, 空梅雨(からつゆ)] | [梅雨 [SEP] 梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことを空梅雨... |
9 | jsquad-neural-search | a10336p23q3 | 0.015425 | [年によっては梅雨入りの時期が特定できなかったり、あるいは発表がされないこともある。東・西日... | [数年に一回, 数年に一回の割合, 数年に一回の割合で起こる] | [梅雨 [SEP] 年によっては梅雨入りの時期が特定できなかったり、あるいは発表がされないこ... |
10 | jsquad-neural-search | a10336p34q1 | 0.009898 | [小笠原諸島に梅雨はあるか] | [ない] | [梅雨 [SEP] 小笠原諸島が春から夏への遷移期にあたる5月には、気団同士の中心が離れてい... |
11 | jsquad-neural-search | a10336p42q2 | 0.009634 | [梅雨の期間中ほとんど雨が降らない場合をなんという?] | [空梅雨, 空梅雨(からつゆ)] | [梅雨 [SEP] 梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことを空梅雨... |
12 | jsquad-neural-search | a10336p42q1 | 0.007816 | [梅雨の期間中ほとんど雨が降らない場合を何と呼ぶ?] | [空梅雨, 空梅雨(からつゆ)] | [梅雨 [SEP] 梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことを空梅雨... |
13 | jsquad-neural-search | a10336p0q2 | 0.006050 | [梅雨は、世界的にどのあたりで見られる気象ですか?] | [東アジア, 東アジアの広範囲] | [梅雨 [SEP] 梅雨(つゆ、ばいう)は、北海道と小笠原諸島を除く日本、朝鮮半島南部、中国... |
14 | jsquad-neural-search | a10336p42q0 | 0.004281 | [梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことをなんというか?] | [空梅雨, 空梅雨(からつゆ)] | [梅雨 [SEP] 梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことを空梅雨... |
15 | jsquad-neural-search | a10336p31q4 | 0.002663 | [梅雨の期間は?] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
16 | jsquad-neural-search | a10336p0q3 | 0.001008 | [梅雨がみられるのはどの期間?] | [5月から7月, 5月から7月にかけて] | [梅雨 [SEP] 梅雨(つゆ、ばいう)は、北海道と小笠原諸島を除く日本、朝鮮半島南部、中国... |
17 | jsquad-neural-search | a10336p31q0 | 0.000718 | [梅雨の期間はどれくらいか?] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
18 | jsquad-neural-search | a10336p31q3 | 0.000561 | [梅雨の期間はどれくらいか] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
19 | jsquad-neural-search | a10336p31q1 | 0.000507 | [梅雨の期間はだいたいどれぐらいか?] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
20 | jsquad-neural-search | a10336p0q1 | 0.000469 | [梅雨とは何季の一種か?] | [雨季] | [梅雨 [SEP] 梅雨(つゆ、ばいう)は、北海道と小笠原諸島を除く日本、朝鮮半島南部、中国... |
21 | jsquad-neural-search | a10336p24q2 | 0.000409 | [東北地方における夏は北海道よりも長い?短い?] | [短い] | [梅雨 [SEP] 年によっては梅雨明けの時期が特定できなかったり、あるいは発表がされないこ... |
22 | jsquad-neural-search | a10336p23q0 | 0.000229 | [本当の夏が長いのは近畿地方と北陸地方どちらか] | [近畿地方] | [梅雨 [SEP] 年によっては梅雨入りの時期が特定できなかったり、あるいは発表がされないこ... |
23 | jsquad-neural-search | a10336p34q2 | 0.000182 | [小笠原諸島が春から夏への遷移期にあたるのは何月?] | [5月] | [梅雨 [SEP] 小笠原諸島が春から夏への遷移期にあたる5月には、気団同士の中心が離れてい... |
24 | jsquad-neural-search | a10336p34q3 | 0.000175 | [小笠原諸島が春から夏への遷移期にあたる時期はいつ] | [5月] | [梅雨 [SEP] 小笠原諸島が春から夏への遷移期にあたる5月には、気団同士の中心が離れてい... |
25 | jsquad-neural-search | a10336p34q0 | 0.000138 | [小笠原諸島が春から夏への遷移期にあたるのは何月か?] | [5月] | [梅雨 [SEP] 小笠原諸島が春から夏への遷移期にあたる5月には、気団同士の中心が離れてい... |
26 | jsquad-neural-search | a10336p27q0 | 0.000069 | [毎年梅雨入り・梅雨明けの発表をするのはどの機関か] | [各地の地方気象台・気象庁] | [梅雨 [SEP] 日本では各地の地方気象台・気象庁が、数個の都府県をまとめた地域ごとに毎年... |
27 | jsquad-neural-search | a10336p23q2 | 0.000060 | [7月頃に例年ある、長い雨の時期を抜けることを何というか。] | [梅雨明け] | [梅雨 [SEP] 年によっては梅雨入りの時期が特定できなかったり、あるいは発表がされないこ... |
28 | jsquad-neural-search | a10336p23q1 | 0.000046 | [近畿地方における夏は北陸地方よりも長い?短い?] | [長い] | [梅雨 [SEP] 年によっては梅雨入りの時期が特定できなかったり、あるいは発表がされないこ... |
29 | jsquad-neural-search | a10336p24q0 | 0.000024 | [立秋を境にして、立秋以降の長雨のことを何雨と呼ぶか] | [秋雨] | [梅雨 [SEP] 年によっては梅雨明けの時期が特定できなかったり、あるいは発表がされないこ... |
リランキングはテキストクエリと組み合わせて使用することも可能です。以下はスコア調整に失敗している例です。context フィールドの結果を重視しているため妥当なランキングではありません。
index_name = "jsquad-neural-search"
query = "日本で梅雨がないのはどこ?"
payload = {
"query": {
"multi_match": {
"query": query,
"fields": ["question", "context^10"],
"operator": "and"
}
},
"_source": False,
"fields": ["question", "answers", "context"],
"size": 10
}
response = opensearch_client.search(
index=index_name,
body=payload
)
pd.json_normalize(response["hits"]["hits"])
_index | _id | _score | fields.question | fields.answers | fields.context | |
---|---|---|---|---|---|---|
0 | jsquad-neural-search | a10336p31q0 | 87.500460 | [梅雨の期間はどれくらいか?] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
1 | jsquad-neural-search | a10336p31q1 | 87.500460 | [梅雨の期間はだいたいどれぐらいか?] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
2 | jsquad-neural-search | a10336p31q2 | 87.500460 | [日本付近の梅雨期の雨量が最も多い地区は] | [九州南部] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
3 | jsquad-neural-search | a10336p31q3 | 87.500460 | [梅雨の期間はどれくらいか] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
4 | jsquad-neural-search | a10336p31q4 | 87.500460 | [梅雨の期間は?] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
5 | jsquad-neural-search | a10336p0q0 | 14.434446 | [日本で梅雨がないのは北海道とどこか。] | [小笠原諸島, 小笠原諸島を除く日本] | [梅雨 [SEP] 梅雨(つゆ、ばいう)は、北海道と小笠原諸島を除く日本、朝鮮半島南部、中国... |
6 | jsquad-neural-search | a10336p24q1 | 14.434446 | [梅雨が日本の中でない地域はどこか。] | [北海道, 東北地方] | [梅雨 [SEP] 年によっては梅雨明けの時期が特定できなかったり、あるいは発表がされないこ... |
Rerank を挟むことでランキングが妥当になったことが確認できました。
index_name = "jsquad-neural-search"
query = "日本で梅雨がないのはどこ?"
payload = {
"query": {
"multi_match": {
"query": query,
"fields": ["question", "context^10"],
"operator": "and"
}
},
"ext": {
"rerank": {
"query_context": {
"query_text_path": "query.multi_match.query"
}
}
},
"_source": False,
"fields": ["question", "answers", "context"],
"size": 10,
}
response = opensearch_client.search(
index=index_name,
body=payload,
search_pipeline = rerank_pipeline_id #ベクトル変換を行うパイプラインを指定
)
pd.json_normalize(response["hits"]["hits"])
_index | _id | _score | fields.question | fields.answers | fields.context | |
---|---|---|---|---|---|---|
0 | jsquad-neural-search | a10336p24q1 | 0.999056 | [梅雨が日本の中でない地域はどこか。] | [北海道, 東北地方] | [梅雨 [SEP] 年によっては梅雨明けの時期が特定できなかったり、あるいは発表がされないこ... |
1 | jsquad-neural-search | a10336p0q0 | 0.998826 | [日本で梅雨がないのは北海道とどこか。] | [小笠原諸島, 小笠原諸島を除く日本] | [梅雨 [SEP] 梅雨(つゆ、ばいう)は、北海道と小笠原諸島を除く日本、朝鮮半島南部、中国... |
2 | jsquad-neural-search | a10336p31q2 | 0.017917 | [日本付近の梅雨期の雨量が最も多い地区は] | [九州南部] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
3 | jsquad-neural-search | a10336p31q4 | 0.002183 | [梅雨の期間は?] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
4 | jsquad-neural-search | a10336p31q0 | 0.000820 | [梅雨の期間はどれくらいか?] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
5 | jsquad-neural-search | a10336p31q3 | 0.000612 | [梅雨の期間はどれくらいか] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
6 | jsquad-neural-search | a10336p31q1 | 0.000503 | [梅雨の期間はだいたいどれぐらいか?] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
リランキングはハイブリッド検索との組み合わせも可能です
index_name = "jsquad-neural-search"
query = "日本で梅雨がないのはどこ?"
payload = {
"query": {
"hybrid": {
"queries": [
{
"multi_match": {
"query": query,
"fields": ["question", "context^10"],
"operator": "and"
}
},
{
"neural": {
"context_embedding": {
"query_text": query, # テキストをベクトルに変換し
"k": 30 # クエリベクトルに近いベクトルのうち上位 30 を返す
}
}
}
]
}
},
"ext": {
"rerank": {
"query_context": {
"query_text": query
}
}
},
"_source": False,
"fields": ["question", "answers", "context"],
"size": 30,
}
response = opensearch_client.search(
index=index_name,
body=payload,
search_pipeline = rerank_pipeline_id #ベクトル変換を行うパイプラインを指定
)
pd.json_normalize(response["hits"]["hits"])
_index | _id | _score | fields.question | fields.answers | fields.context | |
---|---|---|---|---|---|---|
0 | jsquad-neural-search | a10336p24q1 | 0.999053 | [梅雨が日本の中でない地域はどこか。] | [北海道, 東北地方] | [梅雨 [SEP] 年によっては梅雨明けの時期が特定できなかったり、あるいは発表がされないこ... |
1 | jsquad-neural-search | a10336p0q0 | 0.998821 | [日本で梅雨がないのは北海道とどこか。] | [小笠原諸島, 小笠原諸島を除く日本] | [梅雨 [SEP] 梅雨(つゆ、ばいう)は、北海道と小笠原諸島を除く日本、朝鮮半島南部、中国... |
2 | jsquad-neural-search | a10336p32q3 | 0.977799 | [梅雨がないとされている都道府県はどこ?] | [北海道] | [梅雨 [SEP] 実際の気象としては北海道にも道南を中心に梅雨前線がかかることはあるが、平... |
3 | jsquad-neural-search | a10336p32q2 | 0.754553 | [気候学的には梅雨はないとされている場所は?] | [北海道] | [梅雨 [SEP] 実際の気象としては北海道にも道南を中心に梅雨前線がかかることはあるが、平... |
4 | jsquad-neural-search | a10336p32q1 | 0.366136 | [北海道に梅雨はあるか] | [ない, 梅雨はない] | [梅雨 [SEP] 実際の気象としては北海道にも道南を中心に梅雨前線がかかることはあるが、平... |
5 | jsquad-neural-search | a10336p32q0 | 0.112991 | [梅雨前線が北海道に到達する梅雨末期は勢力が衰え、北上する速度が速くなっていて、降水が長く続... | [梅雨] | [梅雨 [SEP] 実際の気象としては北海道にも道南を中心に梅雨前線がかかることはあるが、平... |
6 | jsquad-neural-search | a10336p42q4 | 0.047514 | [ほとんど雨が降らない梅雨を何という?] | [空梅雨, 空梅雨(からつゆ)] | [梅雨 [SEP] 梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことを空梅雨... |
7 | jsquad-neural-search | a10336p42q3 | 0.037750 | [ほとんど雨が降らない梅雨を何と呼ぶか] | [空梅雨, 空梅雨(からつゆ)] | [梅雨 [SEP] 梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことを空梅雨... |
8 | jsquad-neural-search | a10336p23q3 | 0.020924 | [年によっては梅雨入りの時期が特定できなかったり、あるいは発表がされないこともある。東・西日... | [数年に一回, 数年に一回の割合, 数年に一回の割合で起こる] | [梅雨 [SEP] 年によっては梅雨入りの時期が特定できなかったり、あるいは発表がされないこ... |
9 | jsquad-neural-search | a10336p31q2 | 0.017917 | [日本付近の梅雨期の雨量が最も多い地区は] | [九州南部] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
10 | jsquad-neural-search | a10336p34q1 | 0.011029 | [小笠原諸島に梅雨はあるか] | [ない] | [梅雨 [SEP] 小笠原諸島が春から夏への遷移期にあたる5月には、気団同士の中心が離れてい... |
11 | jsquad-neural-search | a10336p42q2 | 0.008348 | [梅雨の期間中ほとんど雨が降らない場合をなんという?] | [空梅雨, 空梅雨(からつゆ)] | [梅雨 [SEP] 梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことを空梅雨... |
12 | jsquad-neural-search | a10336p0q2 | 0.008156 | [梅雨は、世界的にどのあたりで見られる気象ですか?] | [東アジア, 東アジアの広範囲] | [梅雨 [SEP] 梅雨(つゆ、ばいう)は、北海道と小笠原諸島を除く日本、朝鮮半島南部、中国... |
13 | jsquad-neural-search | a10336p42q1 | 0.006145 | [梅雨の期間中ほとんど雨が降らない場合を何と呼ぶ?] | [空梅雨, 空梅雨(からつゆ)] | [梅雨 [SEP] 梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことを空梅雨... |
14 | jsquad-neural-search | a10336p42q0 | 0.004556 | [梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことをなんというか?] | [空梅雨, 空梅雨(からつゆ)] | [梅雨 [SEP] 梅雨の期間中ほとんど雨が降らない場合がある。このような梅雨のことを空梅雨... |
15 | jsquad-neural-search | a10336p31q4 | 0.002183 | [梅雨の期間は?] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
16 | jsquad-neural-search | a10336p0q3 | 0.001585 | [梅雨がみられるのはどの期間?] | [5月から7月, 5月から7月にかけて] | [梅雨 [SEP] 梅雨(つゆ、ばいう)は、北海道と小笠原諸島を除く日本、朝鮮半島南部、中国... |
17 | jsquad-neural-search | a10336p31q0 | 0.000820 | [梅雨の期間はどれくらいか?] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
18 | jsquad-neural-search | a10336p24q2 | 0.000732 | [東北地方における夏は北海道よりも長い?短い?] | [短い] | [梅雨 [SEP] 年によっては梅雨明けの時期が特定できなかったり、あるいは発表がされないこ... |
19 | jsquad-neural-search | a10336p31q3 | 0.000612 | [梅雨の期間はどれくらいか] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
20 | jsquad-neural-search | a10336p0q1 | 0.000612 | [梅雨とは何季の一種か?] | [雨季] | [梅雨 [SEP] 梅雨(つゆ、ばいう)は、北海道と小笠原諸島を除く日本、朝鮮半島南部、中国... |
21 | jsquad-neural-search | a10336p23q0 | 0.000564 | [本当の夏が長いのは近畿地方と北陸地方どちらか] | [近畿地方] | [梅雨 [SEP] 年によっては梅雨入りの時期が特定できなかったり、あるいは発表がされないこ... |
22 | jsquad-neural-search | a10336p31q1 | 0.000503 | [梅雨の期間はだいたいどれぐらいか?] | [40日から50日前後] | [梅雨 [SEP] 梅雨の期間はどの地方でも40日から50日前後と大差はないが、期間中の降水... |
23 | jsquad-neural-search | a10336p34q3 | 0.000111 | [小笠原諸島が春から夏への遷移期にあたる時期はいつ] | [5月] | [梅雨 [SEP] 小笠原諸島が春から夏への遷移期にあたる5月には、気団同士の中心が離れてい... |
24 | jsquad-neural-search | a10336p34q2 | 0.000111 | [小笠原諸島が春から夏への遷移期にあたるのは何月?] | [5月] | [梅雨 [SEP] 小笠原諸島が春から夏への遷移期にあたる5月には、気団同士の中心が離れてい... |
25 | jsquad-neural-search | a10336p27q0 | 0.000092 | [毎年梅雨入り・梅雨明けの発表をするのはどの機関か] | [各地の地方気象台・気象庁] | [梅雨 [SEP] 日本では各地の地方気象台・気象庁が、数個の都府県をまとめた地域ごとに毎年... |
26 | jsquad-neural-search | a10336p34q0 | 0.000089 | [小笠原諸島が春から夏への遷移期にあたるのは何月か?] | [5月] | [梅雨 [SEP] 小笠原諸島が春から夏への遷移期にあたる5月には、気団同士の中心が離れてい... |
27 | jsquad-neural-search | a10336p23q1 | 0.000085 | [近畿地方における夏は北陸地方よりも長い?短い?] | [長い] | [梅雨 [SEP] 年によっては梅雨入りの時期が特定できなかったり、あるいは発表がされないこ... |
28 | jsquad-neural-search | a10336p23q2 | 0.000049 | [7月頃に例年ある、長い雨の時期を抜けることを何というか。] | [梅雨明け] | [梅雨 [SEP] 年によっては梅雨入りの時期が特定できなかったり、あるいは発表がされないこ... |
29 | jsquad-neural-search | a10336p24q0 | 0.000023 | [立秋を境にして、立秋以降の長雨のことを何雨と呼ぶか] | [秋雨] | [梅雨 [SEP] 年によっては梅雨明けの時期が特定できなかったり、あるいは発表がされないこ... |
検索結果を外部のモデルを活用することで並べ替えできることが確認できました。