# Index de recherche

[FAISS](https://github.com/facebookresearch/faiss) et [Elasticsearch](https://www.elastic.co/elasticsearch/) permettent de rechercher des exemples dans un jeu de données. Cela peut être utile lorsque vous souhaitez récupérer des exemples spécifiques d'un jeu de données pertinents pour votre tâche de NLP. Par exemple, si vous travaillez sur une tâche de réponse à des questions en domaine ouvert, vous pouvez vouloir ne renvoyer que les exemples pertinents pour répondre à votre question.

Ce guide vous montre comment construire un index pour votre jeu de données afin de vous permettre de l’interroger.

## FAISS

FAISS récupère des documents en fonction de la similarité de leurs représentations vectorielles. Dans cet exemple, vous générerez les représentations vectorielles avec le modèle [DPR](https://huggingface.co/transformers/model_doc/dpr.html).

1. Téléchargez le modèle DPR depuis 🤗 Transformers :

```py
>>> from transformers import DPRContextEncoder, DPRContextEncoderTokenizer
>>> import torch
>>> torch.set_grad_enabled(False)
>>> ctx_encoder = DPRContextEncoder.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base")
>>> ctx_tokenizer = DPRContextEncoderTokenizer.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base")
```

2. Chargez votre jeu de données et calculez les représentations vectorielles :

```py
>>> from datasets import load_dataset
>>> ds = load_dataset('community-datasets/crime_and_punish', split='train[:100]')
>>> ds_with_embeddings = ds.map(lambda example: {'embeddings': ctx_encoder(**ctx_tokenizer(example["line"], return_tensors="pt"))[0][0].numpy()})
```

3. Créez l’index avec [Dataset.add_faiss_index()](/docs/datasets/v5.2.0/fr/package_reference/main_classes#datasets.Dataset.add_faiss_index) :

```py
>>> ds_with_embeddings.add_faiss_index(column='embeddings')
```

4. Vous pouvez maintenant interroger votre jeu de données avec l’index `embeddings`. Chargez le DPR Question Encoder et recherchez une question avec [Dataset.get_nearest_examples()](/docs/datasets/v5.2.0/fr/package_reference/main_classes#datasets.Dataset.get_nearest_examples) :

```py
>>> from transformers import DPRQuestionEncoder, DPRQuestionEncoderTokenizer
>>> q_encoder = DPRQuestionEncoder.from_pretrained("facebook/dpr-question_encoder-single-nq-base")
>>> q_tokenizer = DPRQuestionEncoderTokenizer.from_pretrained("facebook/dpr-question_encoder-single-nq-base")

>>> question = "Is it serious ?"
>>> question_embedding = q_encoder(**q_tokenizer(question, return_tensors="pt"))[0][0].numpy()
>>> scores, retrieved_examples = ds_with_embeddings.get_nearest_examples('embeddings', question_embedding, k=10)
>>> retrieved_examples["line"][0]
'_that_ serious? It is not serious at all. It’s simply a fantasy to amuse\r\n'
```

5. Vous pouvez accéder à l’index avec [Dataset.get_index()](/docs/datasets/v5.2.0/fr/package_reference/main_classes#datasets.Dataset.get_index) et l’utiliser pour des opérations spéciales, par exemple l’interroger à l’aide de `range_search` :

```py
>>> faiss_index = ds_with_embeddings.get_index('embeddings').faiss_index
>>> limits, distances, indices = faiss_index.range_search(x=question_embedding.reshape(1, -1), thresh=0.95)
```

6. Une fois vos requêtes terminées, enregistrez l’index sur le disque à l’aide de [Dataset.save_faiss_index()](/docs/datasets/v5.2.0/fr/package_reference/main_classes#datasets.Dataset.save_faiss_index) :

```py
>>> ds_with_embeddings.save_faiss_index('embeddings', 'my_index.faiss')
```

7. Rechargez-le à un moment ultérieur avec [Dataset.load_faiss_index()](/docs/datasets/v5.2.0/fr/package_reference/main_classes#datasets.Dataset.load_faiss_index) :

```py
>>> ds = load_dataset('community-datasets/crime_and_punish', split='train[:100]')
>>> ds.load_faiss_index('embeddings', 'my_index.faiss')
```

## Elasticsearch

Contrairement à FAISS, Elasticsearch récupère les documents sur la base de correspondances exactes.

Démarrer Elasticsearch sur votre machine, ou consulter le [guide d'installation d'Elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/current/setup.html) si vous ne l'avez pas encore installé.

1. Chargez le jeu de données que vous souhaitez indexer :

```py
>>> from datasets import load_dataset
>>> squad = load_dataset('rajpurkar/squad', split='validation')
```

2. Construisez l’index avec [Dataset.add_elasticsearch_index()](/docs/datasets/v5.2.0/fr/package_reference/main_classes#datasets.Dataset.add_elasticsearch_index) :

```py
>>> squad.add_elasticsearch_index("context", host="localhost", port="9200")
```

3. Vous pouvez ensuite interroger l'index `context` avec [Dataset.get_nearest_examples()](/docs/datasets/v5.2.0/fr/package_reference/main_classes#datasets.Dataset.get_nearest_examples) :

```py
>>> query = "machine"
>>> scores, retrieved_examples = squad.get_nearest_examples("context", query, k=10)
>>> retrieved_examples["title"][0]
'Computational_complexity_theory'
```

4. Si vous souhaitez réutiliser l'index, définissez le paramètre `es_index_name` lors de la construction de l'index :

```py
>>> from datasets import load_dataset
>>> squad = load_dataset('rajpurkar/squad', split='validation')
>>> squad.add_elasticsearch_index("context", host="localhost", port="9200", es_index_name="hf_squad_val_context")
>>> squad.get_index("context").es_index_name
hf_squad_val_context
```

5. Rechargez-le plus tard avec le nom de l’index lors de l’appel de [Dataset.load_elasticsearch_index()](/docs/datasets/v5.2.0/fr/package_reference/main_classes#datasets.Dataset.load_elasticsearch_index) :

```py
>>> from datasets import load_dataset
>>> squad = load_dataset('rajpurkar/squad', split='validation')
>>> squad.load_elasticsearch_index("context", host="localhost", port="9200", es_index_name="hf_squad_val_context")
>>> query = "machine"
>>> scores, retrieved_examples = squad.get_nearest_examples("context", query, k=10)
```

Pour une utilisation plus avancée d'Elasticsearch, vous pouvez spécifier votre propre configuration avec des paramètres personnalisés :

```py
>>> import elasticsearch as es
>>> import elasticsearch.helpers
>>> from elasticsearch import Elasticsearch
>>> es_client = Elasticsearch([{"host": "localhost", "port": "9200"}])  # default client
>>> es_config = {
...     "settings": {
...         "number_of_shards": 1,
...         "analysis": {"analyzer": {"stop_standard": {"type": "standard", " stopwords": "_english_"}}},
...     },
...     "mappings": {"properties": {"text": {"type": "text", "analyzer": "standard", "similarity": "BM25"}}},
... }  # default config
>>> es_index_name = "hf_squad_context"  # name of the index in Elasticsearch
>>> squad.add_elasticsearch_index("context", es_client=es_client, es_config=es_config, es_index_name=es_index_name)
```

