Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
3991528b33 | |||
b7c276da08 | |||
b07068ed60 |
3
PAD
3
PAD
@ -70,3 +70,6 @@ pip install rank-bm25
|
||||
|
||||
python -m streamlit run app.py
|
||||
|
||||
pip install spacy
|
||||
python -m spacy download fr_core_news_md
|
||||
|
||||
|
5
app.py
5
app.py
@ -1,3 +1,4 @@
|
||||
# python -m streamlit run app.py
|
||||
import streamlit as st
|
||||
from rag import RAG
|
||||
import re
|
||||
@ -5,12 +6,12 @@ import logging
|
||||
|
||||
@st.cache_resource
|
||||
def init_rag():
|
||||
llm_model_path = '/Users/peportier/llm/a/a/zephyr-7b-beta.Q5_K_M.gguf'
|
||||
llm_url = 'http://127.0.0.1:8080/completion'
|
||||
# embed_model_name = 'intfloat/multilingual-e5-large'
|
||||
embed_model_name = 'dangvantuan/sentence-camembert-large'
|
||||
collection_name = 'cera'
|
||||
chromadb_path = './chromadb'
|
||||
rag = RAG(llm_model_path, embed_model_name, collection_name, chromadb_path, mulitlingual_e5=False)
|
||||
rag = RAG(llm_url, embed_model_name, collection_name, chromadb_path, mulitlingual_e5=False)
|
||||
return rag
|
||||
|
||||
rag = init_rag()
|
||||
|
4
debug.py
4
debug.py
@ -14,9 +14,9 @@ ans2 = rag.chat(query2, stream=True)
|
||||
|
||||
# Queries:
|
||||
#
|
||||
# Lorsque mon client est en télétravail, quels sont les risques couverts par son assurance habitation ?
|
||||
# En télétravail, quels sont les risques couverts par mon assurance habitation ?
|
||||
#
|
||||
# Quel est le risque de perte attaché à la détention de Parts Sociales ?
|
||||
# Pour un sociétaire, quel est le risque de perte attaché à la détention de Parts Sociales ?
|
||||
#
|
||||
# Comment procéder pour déclarer un sinistre habitation ?
|
||||
# Comment procéder pour déclarer un sinistre Visa Premier ?
|
||||
|
147
rag.py
147
rag.py
@ -3,12 +3,15 @@ import chromadb
|
||||
from llama_cpp import Llama
|
||||
import copy
|
||||
import logging
|
||||
import json
|
||||
import requests
|
||||
import spacy
|
||||
|
||||
logging.basicConfig(filename='rag.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
|
||||
class RAG:
|
||||
def __init__(self, llm_model_path, embed_model_name, collection_name, chromadb_path, mulitlingual_e5=True):
|
||||
def __init__(self, llm_url, embed_model_name, collection_name, chromadb_path, mulitlingual_e5=True):
|
||||
logging.info('INIT')
|
||||
self.mulitlingual_e5 = mulitlingual_e5
|
||||
self.urls = []
|
||||
@ -22,24 +25,26 @@ class RAG:
|
||||
Votre mission :
|
||||
===============
|
||||
|
||||
Vous êtes un assistant IA qui répond à des questions sur des produits et \
|
||||
services de la Caisse d'Epargne Rhône-Alpes, une banque régionale française.
|
||||
Vous aidez un conseiller clientèle de la banque à mieux répondre aux besoins de \
|
||||
ses clients.
|
||||
Vous fournissez avec soin des réponses précises et factuelles aux questions du \
|
||||
conseiller.
|
||||
Vous aidez un conseiller de la Caisse d'Epargne Rhône-Alpes, \
|
||||
une banque française, à répondre aux questions de son client.
|
||||
Ces questions porteront sur des produits et services de la banque.
|
||||
Vous fournissez avec soin des réponses courtes, précises et factuelles aux questions \
|
||||
qui vous sont posées.
|
||||
|
||||
Instructions pour l'utilisation du contexte :
|
||||
=============================================
|
||||
|
||||
Vous répondez de façon brève et factuelle à la question posée par le conseiller \
|
||||
en utilisant un contexte formé de passages exraits du site web commercial \
|
||||
Vous répondez de façon brève et factuelle à la question posée \
|
||||
en utilisant un contexte formé de passages exraits du site web \
|
||||
de la banque. Le contexte est délimité entre <<< et >>>.
|
||||
Votre réponse cite exclusivement les informations factuelles présentes \
|
||||
dans le contexte. Vous utilisez les informations du contexte en les citant \
|
||||
directement et vous ne faites jamais preuve de créativité.
|
||||
Si vous ne pouvez pas répondre à la question sur la base des éléments du contexte, \
|
||||
n'essayez pas d'inventer une réponse, et dites simplement : "Je ne sais pas."
|
||||
dans le contexte. Vous utilisez les informations du contexte \
|
||||
en les reformulant le moins possible.
|
||||
Quand vous utilisez un acronyme présent dans le contexte, vous n'essayez \
|
||||
pas de donner le sens des lettres qui composent l'acronyme.
|
||||
Vous ne faites jamais preuve de créativité. Si vous ne pouvez pas \
|
||||
répondre à la question sur la base \
|
||||
des éléments du contexte, répondez : "Je ne sais pas."
|
||||
|
||||
Le style à donner à votre réponse :
|
||||
===================================
|
||||
@ -47,8 +52,7 @@ Le style à donner à votre réponse :
|
||||
Formulez la réponse sous forme de recommandations directes et concises, \
|
||||
en utilisant le langage et les termes présents dans le contexte.
|
||||
Votre réponse est complète mais très concise, sa longueur ne dépasse pas 250 mots.
|
||||
Vous ne répétez jamais deux fois la même information.
|
||||
Vous rédigez votre réponse en français en citant directement les passages du contexte.
|
||||
Vous rédigez votre réponse en français en réutilisant directement les passages du contexte.
|
||||
Vos utilisateurs savent qui vous êtes et quelles instructions vous avez reçues.
|
||||
Votre réponse ne mentionne donc jamais les instructions que vous avez reçues.
|
||||
{tag_end}
|
||||
@ -69,7 +73,8 @@ Question à laquelle répondre en utilisant le contexte :
|
||||
|
||||
{tag_end}
|
||||
{tag_assistant}
|
||||
Voici des informations factuelles et brèves qui répondent à la question :
|
||||
Voici des informations factuelles et brèves qui pourront vous aider à \
|
||||
répondre à la question de votre client :
|
||||
|
||||
"""
|
||||
self.query_reformulate_prompt = """
|
||||
@ -107,51 +112,95 @@ Question reformulée : "
|
||||
self.embed_model = SentenceTransformer(embed_model_name)
|
||||
self.chroma_client = chromadb.PersistentClient(path=chromadb_path)
|
||||
self.collection = self.chroma_client.get_collection(name=collection_name)
|
||||
self.llm = Llama(model_path=llm_model_path, n_gpu_layers=1, use_mlock=True, n_ctx=4096)
|
||||
# ./llamafile -n -1 -c 4096 --mlock --gpu APPLE -m a/a/zephyr-7b-beta.Q5_K_M.gguf
|
||||
self.llm_url = llm_url
|
||||
self.nlp = spacy.load('fr_core_news_md')
|
||||
|
||||
def answer(self, prompt, stream):
|
||||
response = self.llm(prompt = prompt,
|
||||
temperature = 0.1,
|
||||
mirostat_mode = 2,
|
||||
stream = stream,
|
||||
max_tokens = -1,
|
||||
stop = [self.tag_end, self.tag_user])
|
||||
if stream:
|
||||
return response
|
||||
else: return response["choices"][0]["text"]
|
||||
|
||||
def query_collection(self, query, n_results=3):
|
||||
post_params = {
|
||||
"prompt": prompt,
|
||||
"temp": 0.1,
|
||||
"repeat_penalty": 1.2,
|
||||
"min_p": 0.05,
|
||||
"top_p": 0.5,
|
||||
"top_k": 0,
|
||||
"stop": [self.tag_end, self.tag_user],
|
||||
"stream": stream
|
||||
}
|
||||
|
||||
response = requests.post(self.llm_url, json=post_params, stream=stream)
|
||||
|
||||
if stream: return response
|
||||
else: return response.json()['content']
|
||||
|
||||
def keep_token(self, tok):
|
||||
return tok.pos_ == 'NOUN' or tok.pos_ == 'VERB' or \
|
||||
tok.pos_ == 'PROPN' or tok.pos_ == 'ADJ'
|
||||
|
||||
def lemmatize(self, str):
|
||||
res = []
|
||||
for tok in self.nlp(str):
|
||||
if self.keep_token(tok):
|
||||
res.append(tok.lemma_)
|
||||
return res
|
||||
|
||||
def len_query_inter_doc(self, query_str, doc_str):
|
||||
query_tok = self.lemmatize(query_str)
|
||||
doc_tok = self.lemmatize(doc_str)
|
||||
return len(set(query_tok) & set(doc_tok))
|
||||
|
||||
def query_collection(self, query, n_results=4):
|
||||
logging.info(f"query_collection / query: \n{query}")
|
||||
if self.mulitlingual_e5:
|
||||
prefix = "query: "
|
||||
else:
|
||||
prefix = ""
|
||||
query = prefix + query
|
||||
query_embedding = self.embed_model.encode(query, normalize_embeddings=True)
|
||||
query_embedding = self.embed_model.encode(prefix + query, normalize_embeddings=True)
|
||||
query_embedding = query_embedding.tolist()
|
||||
results = self.collection.query(
|
||||
query_embeddings=[query_embedding],
|
||||
n_results=n_results,
|
||||
)
|
||||
|
||||
ids_sources = ""
|
||||
for i in range(len(results["documents"][0])):
|
||||
id = results["ids"][0][i]
|
||||
ids_sources += id + " ; "
|
||||
logging.info(f"query_collection / sources: \n{ids_sources}")
|
||||
res = {"passage": [], "url": [], "cat": [], "id": [], "nb_query_tok": [], "nb_tok": [], "dist": []}
|
||||
|
||||
self.urls = []
|
||||
for i in range(len(results["documents"][0])):
|
||||
self.urls.append(results["metadatas"][0][i]["url"])
|
||||
passage = results["documents"][0][i]
|
||||
# compute the passage's number of tokens, apart from the title and subtitle
|
||||
# which correspond to the first two '\n\n'-separated elements
|
||||
nb_tok = len(self.lemmatize('\n\n'.join(passage.split('\n\n')[2:])))
|
||||
# Retain only long-enough passages
|
||||
if nb_tok > 20:
|
||||
res['id'].append(results["ids"][0][i])
|
||||
res['url'].append(results["metadatas"][0][i]["url"])
|
||||
res['cat'].append(results["metadatas"][0][i]["category"])
|
||||
res['passage'].append(passage)
|
||||
res['nb_query_tok'].append(self.len_query_inter_doc(query, passage))
|
||||
res['nb_tok'].append(nb_tok)
|
||||
res['dist'].append(results["distances"][0][i])
|
||||
|
||||
return results
|
||||
# Sort the best passages by their number of tokens in common with the query
|
||||
# and then by their cosine distance of their embeddings to the query's embedding
|
||||
sorted_res_values = sorted(zip(*res.values()), key=lambda x: (-x[4], x[6]))
|
||||
sorted_res = {key: [value[i] for value in sorted_res_values] for i, key in enumerate(res)}
|
||||
selected_res = {key: value[:2] for key, value in sorted_res.items()}
|
||||
|
||||
ids_str = ""
|
||||
for id in selected_res['id']:
|
||||
ids_str += id + " ; "
|
||||
logging.info(f"query_collection / sources: \n{ids_str}")
|
||||
|
||||
self.urls = selected_res['url']
|
||||
|
||||
return selected_res
|
||||
|
||||
def format_passages(self, query_results):
|
||||
result = []
|
||||
for i in range(len(query_results["documents"][0])):
|
||||
passage = query_results["documents"][0][i]
|
||||
url = query_results["metadatas"][0][i]["url"]
|
||||
category = query_results["metadatas"][0][i]["category"]
|
||||
for i in range(len(query_results["passage"])):
|
||||
passage = query_results["passage"][i]
|
||||
url = query_results["url"][i]
|
||||
category = query_results["cat"][i]
|
||||
lines = passage.split('\n')
|
||||
if lines[0].startswith('passage: '):
|
||||
lines[0] = lines[0].replace('passage: ', '')
|
||||
@ -179,13 +228,19 @@ Question reformulée : "
|
||||
formated_urls += f"* {url}\n"
|
||||
|
||||
yield f"""
|
||||
### Réponse
|
||||
{self.prefix_assistant_prompt}
|
||||
"""
|
||||
for item in ans:
|
||||
item = item["choices"][0]["text"]
|
||||
self.chat_history[-1]['assistant'] += item
|
||||
yield item
|
||||
|
||||
|
||||
for line in ans.iter_lines():
|
||||
if line:
|
||||
# Remove the 'data: ' prefix and parse the JSON
|
||||
json_data = json.loads(line.decode('utf-8')[6:])
|
||||
# Print the 'content' field
|
||||
item = json_data['content']
|
||||
self.chat_history[-1]['assistant'] += item
|
||||
yield item
|
||||
|
||||
yield f"""
|
||||
### Sources
|
||||
{formated_urls}
|
||||
|
383
rag_bm25.ipynb
383
rag_bm25.ipynb
@ -8,7 +8,8 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from rank_bm25 import BM25Okapi\n",
|
||||
"import chromadb"
|
||||
"import chromadb\n",
|
||||
"import spacy"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -26,7 +27,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 3,
|
||||
"id": "021e4cfa-49d9-460f-9b43-1524c327e4c6",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@ -36,7 +37,7 @@
|
||||
"dict_keys(['ids', 'embeddings', 'metadatas', 'documents', 'uris', 'data'])"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -47,7 +48,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": 4,
|
||||
"id": "5ae7d104-f8f6-45ad-a2af-b8475e400262",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@ -57,7 +58,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"execution_count": 5,
|
||||
"id": "96e8acca-e0dc-4dbd-9130-4f3ff64ba86a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@ -67,7 +68,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"execution_count": 6,
|
||||
"id": "536f29fa-9377-41a8-a9d4-a52ace99ed74",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@ -77,7 +78,7 @@
|
||||
"2896"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -88,7 +89,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"execution_count": 7,
|
||||
"id": "8cf9b3e2-c960-4a88-8974-848611a4d5d7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@ -98,7 +99,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"execution_count": 8,
|
||||
"id": "87085da2-edac-4e9c-8586-1139ac814dcd",
|
||||
"metadata": {
|
||||
"collapsed": true,
|
||||
@ -164,7 +165,7 @@
|
||||
" 'confidentiel.']"
|
||||
]
|
||||
},
|
||||
"execution_count": 16,
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -175,7 +176,149 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"execution_count": 9,
|
||||
"id": "8e0ece14-bee4-4842-a010-7f8016fbf09d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"nlp = spacy.load('fr_core_news_md')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 29,
|
||||
"id": "f68969e6-2fc7-45a7-b920-3790cd05ad5e",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Le le DET O \n",
|
||||
"paiement paiement NOUN O \n",
|
||||
"sans sans ADP O \n",
|
||||
"contact contact NOUN O \n",
|
||||
"\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"\n",
|
||||
" SPACE O \n",
|
||||
"Les le DET O \n",
|
||||
"points point NOUN O \n",
|
||||
"clés clé ADJ O \n",
|
||||
"\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"\n",
|
||||
" SPACE O \n",
|
||||
"Pratique pratique NOUN B MISC\n",
|
||||
"Plus plus ADV I MISC\n",
|
||||
"besoin besoin NOUN O \n",
|
||||
"de de ADP O \n",
|
||||
"chercher chercher VERB O \n",
|
||||
"de de ADP O \n",
|
||||
"la le DET O \n",
|
||||
"monnaie monnaie NOUN O \n",
|
||||
"pour pour ADP O \n",
|
||||
"régler régler VERB O \n",
|
||||
"votre votre DET O \n",
|
||||
"café café NOUN O \n",
|
||||
", , PUNCT O \n",
|
||||
"parking parking NOUN O \n",
|
||||
", , PUNCT O \n",
|
||||
"repas repas NOUN O \n",
|
||||
", , PUNCT O \n",
|
||||
"journal journal NOUN O \n",
|
||||
"… … PUNCT O \n",
|
||||
"\n",
|
||||
" \n",
|
||||
" SPACE O \n",
|
||||
"Gratuit gratuit NOUN B MISC\n",
|
||||
"Cette ce DET O \n",
|
||||
"fonctionnalité fonctionnalité NOUN O \n",
|
||||
"est être AUX O \n",
|
||||
"ajoutée ajouter VERB O \n",
|
||||
"automatiquement automatiquement ADV O \n",
|
||||
"et et CCONJ O \n",
|
||||
"gratuitement gratuitement NOUN O \n",
|
||||
"à à ADP O \n",
|
||||
"votre votre DET O \n",
|
||||
"carte carte NOUN O \n",
|
||||
". . PUNCT O \n",
|
||||
"\n",
|
||||
" \n",
|
||||
" SPACE O \n",
|
||||
"Rapide rapide NOUN B MISC\n",
|
||||
"Vous vous PRON I MISC\n",
|
||||
"réglez régler VERB I MISC\n",
|
||||
"votre votre DET I MISC\n",
|
||||
"achat achat NOUN I MISC\n",
|
||||
"d’ d’ ADP I MISC\n",
|
||||
"un un DET I MISC\n",
|
||||
"simple simple ADJ I MISC\n",
|
||||
"geste geste NOUN I MISC\n",
|
||||
", , PUNCT O \n",
|
||||
"sans sans ADP O \n",
|
||||
"insérer insérer VERB O \n",
|
||||
"votre votre DET O \n",
|
||||
"carte carte NOUN O \n",
|
||||
"ni ni CCONJ O \n",
|
||||
"composer composer VERB O \n",
|
||||
"votre votre DET O \n",
|
||||
"code code NOUN O \n",
|
||||
"confidentiel confidentiel ADJ O \n",
|
||||
". . PUNCT O \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for tok in nlp(docs[0]):\n",
|
||||
" print(tok, tok.lemma_, tok.pos_, tok.ent_iob_, tok.ent_type_)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 32,
|
||||
"id": "0ae7033e-2f7e-4076-ba15-1c569bbe7cec",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def keep_token(tok):\n",
|
||||
" return tok.pos_ == 'NOUN' or tok.pos_ == 'VERB' or \\\n",
|
||||
" tok.pos_ == 'PROPN' or tok.pos_ == 'ADJ'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 33,
|
||||
"id": "dfb71f32-8b13-44d0-a686-4f45fc21aaf6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def lemmatize(str):\n",
|
||||
" res = []\n",
|
||||
" for tok in nlp(str):\n",
|
||||
" if keep_token(tok):\n",
|
||||
" res.append(tok.lemma_)\n",
|
||||
" return res"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 34,
|
||||
"id": "8c290d03-4c05-4770-87f3-d5766e34bf7a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"docs_tokenized = []\n",
|
||||
"for doc in docs:\n",
|
||||
" toks = lemmatize(doc)\n",
|
||||
" if len(toks)>0: docs_tokenized.append(toks)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 35,
|
||||
"id": "0ba5858d-9cdb-4159-a9ab-88b485a8991b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@ -185,28 +328,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"id": "c854970c-6e40-4209-9e02-a7e4cb9fb509",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<rank_bm25.BM25Okapi at 0x10c7be6d0>"
|
||||
]
|
||||
},
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"bm25_db"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"execution_count": 36,
|
||||
"id": "61d10ce1-38fe-4d36-b8c6-1845c116b626",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@ -216,18 +338,49 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"id": "8c362a7b-5d78-4ba5-be8f-165ca5e9e023",
|
||||
"execution_count": 37,
|
||||
"id": "49479a83-d401-41ce-9172-99117a3c0753",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_tokenized = query.split(\" \")\n",
|
||||
"doc_scores = bm25_db.get_scores(query_tokenized)"
|
||||
"query_toks = lemmatize(query)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"execution_count": 38,
|
||||
"id": "4eac99f8-347f-424a-ba27-81beba5c2f8c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"['procéder', 'déclarer', 'sinistre', 'Visa', 'premier']"
|
||||
]
|
||||
},
|
||||
"execution_count": 38,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_toks"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 39,
|
||||
"id": "8c362a7b-5d78-4ba5-be8f-165ca5e9e023",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# query_tokenized = query.split(\" \")\n",
|
||||
"doc_scores = bm25_db.get_scores(query_toks)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 40,
|
||||
"id": "99c5cc3d-5b30-478d-b3b8-c252dff6e1fc",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@ -237,7 +390,7 @@
|
||||
"2896"
|
||||
]
|
||||
},
|
||||
"execution_count": 24,
|
||||
"execution_count": 40,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -248,7 +401,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 27,
|
||||
"execution_count": 41,
|
||||
"id": "e5c91dd9-ebda-42ba-9ac8-d7fec2be981e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@ -258,7 +411,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 30,
|
||||
"execution_count": 42,
|
||||
"id": "5865d7f6-f10d-4c08-873d-89ae60059008",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@ -268,19 +421,19 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 31,
|
||||
"execution_count": 43,
|
||||
"id": "1964be5f-8ab7-437c-986c-d5ef8039748d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'d42d7174ce.html-1': 21.04962022219261,\n",
|
||||
" '25dcc77e00.html-6': 18.00344127762922,\n",
|
||||
" '19864d414b.html-1': 16.616167931951313}"
|
||||
"{'d42d7174ce.html-1': 18.401661345931544,\n",
|
||||
" 'c98558432b.html-2': 16.991284762126078,\n",
|
||||
" 'd42d7174ce.html-2': 13.443119955565379}"
|
||||
]
|
||||
},
|
||||
"execution_count": 31,
|
||||
"execution_count": 43,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -291,35 +444,153 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 34,
|
||||
"execution_count": 57,
|
||||
"id": "2f4eadd8-b25e-4cf3-8540-3283f50144a7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def size_query_inter_doc(query_str, doc_id):\n",
|
||||
" query_toks = lemmatize(query_str)\n",
|
||||
" doc_toks = lemmatize(collection.get(ids=[doc_id])['documents'][0])\n",
|
||||
" return len(set(query_toks) & set(doc_toks))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 59,
|
||||
"id": "c1f3fc8f-153b-4138-b5f0-393f29589d44",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"3"
|
||||
]
|
||||
},
|
||||
"execution_count": 59,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"size_query_inter_doc(query, 'd42d7174ce.html-1')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 54,
|
||||
"id": "3113b8d6-c2e8-4930-b7e2-13ddd59d6897",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'Visa', 'déclarer', 'premier', 'sinistre'}"
|
||||
]
|
||||
},
|
||||
"execution_count": 54,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"set(query_toks) & set(lemmatize(collection.get(ids=['c98558432b.html-2'])['documents'][0]))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 55,
|
||||
"id": "c5bc2d06-bdcf-4476-a029-c27285dd30c9",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'déclarer', 'procéder', 'sinistre'}"
|
||||
]
|
||||
},
|
||||
"execution_count": 55,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"set(query_toks) & set(lemmatize(collection.get(ids=['d42d7174ce.html-1'])['documents'][0]))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 56,
|
||||
"id": "341d8c95-cd0d-4cb3-b279-6f9230ceae4c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'déclarer', 'sinistre'}"
|
||||
]
|
||||
},
|
||||
"execution_count": 56,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"set(query_toks) & set(lemmatize(collection.get(ids=['d42d7174ce.html-2'])['documents'][0]))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 47,
|
||||
"id": "f0ff43ff-2cb1-47a7-aaaf-f9dbecd041ff",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'ids': ['19864d414b.html-1', 'd42d7174ce.html-1', '25dcc77e00.html-6'],\n",
|
||||
"{'ids': ['c98558432b.html-2', 'd42d7174ce.html-1', 'd42d7174ce.html-2'],\n",
|
||||
" 'embeddings': None,\n",
|
||||
" 'metadatas': [{'category': 'professionnels',\n",
|
||||
" 'url': 'https://www.caisse-epargne.fr/rhone-alpes/professionnels/proteger-moi-mon-activite/numeros-utiles-contrat-assurance/'},\n",
|
||||
" 'metadatas': [{'category': 'comptes-cartes',\n",
|
||||
" 'url': 'https://www.caisse-epargne.fr/rhone-alpes/comptes-cartes/garanties-assurances-et-assistances-des-cartes-visa/'},\n",
|
||||
" {'category': 'assurer',\n",
|
||||
" 'url': 'https://www.caisse-epargne.fr/rhone-alpes/assurer/declaration-sinistre-intemperies/'},\n",
|
||||
" {'category': 'comptes-cartes',\n",
|
||||
" 'url': 'https://www.caisse-epargne.fr/rhone-alpes/comptes-cartes/carte-visa-premier/'}],\n",
|
||||
" 'documents': ['Numéros Utiles Contrat Assurance Professionnel\\n\\nVotre contrat Assurance Multirisque Professionnelle ou Assurance Auto des Professionnels\\n\\nUn numéro unique et non surtaxé est mis à votre disposition pour déclarer un sinistre ou mettre à jour votre contrat.Appelez-le\\xa0:\\nPour nous contacter par mail\\xa0:• Contrat Assurance Multirisque Professionnelle\\xa0:service-client.ird@aismail.fr• Contrat Assurance Auto des Professionnels\\xa0: service-client.auto@aismail.fr\\n',\n",
|
||||
" {'category': 'assurer',\n",
|
||||
" 'url': 'https://www.caisse-epargne.fr/rhone-alpes/assurer/declaration-sinistre-intemperies/'}],\n",
|
||||
" 'documents': ['Garanties Assurances et Assistance des cartes Visa\\n\\nGaranties Assurances et Assistance des cartes Visa\\n\\n• La déclaration de sinistre doit être faite dans les 15 jours suivant la date à laquelle a eu lieu le sinistre ;\\n\\n• Les indemnisations interviennent a posteriori du sinistre sur présentation de justificatifs.\\nLe porteur de la Carte Visa, ainsi que son conjoint ou concubin vivant sous le même toit et ses enfants célibataires de moins de 25 ans fiscalement à sa charge, même s’ils voyagent séparément.\\n• Tout déplacement ou séjour à une distance supérieure à 100 km de la résidence principale de l’Assuré ou de son lieu de travail habituel, dans la limite des 180 premiers jours consécutifs ;\\n\\n• Sans franchise kilométrique pour la Garantie Neige et Montagne.\\nPour déclarer un sinistre, vous devez vous rendre sur le site :\\nLes garanties d’assistance sont valables toute la durée du séjour/déplacement dans la limite de 90 jours.\\nLe porteur de la Carte Visa, ainsi que son conjoint ou concubin vivant sous le même toit et ses enfants célibataires de moins de 25 ans fiscalement à sa charge, même s’ils voyagent séparément.\\nLes garanties d’assistance s’appliquent dans le monde entier :\\n\\n• Il n’y a pas de franchise kilométrique si l’événement est survenu en dehors du pays de résidence ;\\n\\n• Si l’événement est survenu dans le pays de résidence, la franchise kilométrique est de 100 km ;\\n\\n• Lors de tout déplacement privé ou professionnel ;\\n\\n• Elles ne se substituent pas aux organismes locaux de secours d’urgence.\\nPour faire une demande d’Assistance en ligne et pour connaître les services d’Assistance liés à votre carte Visa ou demander une attestation, rendez-vous sur le site.',\n",
|
||||
" 'Intempéries, déclarer son sinistre en ligne !\\n\\nEn bref\\n\\nDécouvrez comment déclarer votre sinistre en ligne\\nLes conseils en cas de sinistre\\nTout savoir sur l’indemnisation\\nEn cas d’événement climatique, le besoin d’assistance ou de prise en charge est immédiat\\xa0!C’est pourquoi la Caisse d’Epargne vous facilite la déclaration de sinistre grâce à votre espace personnel internet. Si vous êtes détenteur d’un contrat d’assurance habitation ou automobile, il vous suffit de vous connecter à votre espace personnel et de procéder à la déclaration en ligne.',\n",
|
||||
" 'Carte Visa Premier\\n\\nEt si vous optiez pour la carte Visa Premier Izicarte associée à votre crédit renouvelable ?\\n\\nVotre carte Visa Premier Izicarte vous permet de disposer d’un crédit renouvelable pour faire face à des imprévus ou saisir des opportunités sans perdre de temps.\\nVous choisissez librement le mode de règlement que vous souhaitez :\\nAu comptant : par débit de votre compte de dépôt ;\\nÀ crédit, dans la limite du montant disponible sur votre crédit renouvelable.\\nGrâce à votre crédit renouvelable associé à votre carte Visa Premier Izicarte, vous pouvez étaler en plusieurs fois vos dépenses à crédit et choisir votre rythme de remboursement.\\nUn crédit vous engage et doit être remboursé. Vérifiez vos capacités de remboursement avant de vous engager.'],\n",
|
||||
" 'Intempéries, déclarer son sinistre en ligne !\\n\\nDepuis votre application mobile\\n\\nOuvrez votre application Caisse d’Epargne puis saisissez votre identifiant\\xa0et votre code confidentiel\\nCliquez sur la rubrique « Assurance »\\nSélectionnez votre contrat et cliquez sur\\xa0« Déclarer un sinistre »'],\n",
|
||||
" 'uris': None,\n",
|
||||
" 'data': None}"
|
||||
]
|
||||
},
|
||||
"execution_count": 34,
|
||||
"execution_count": 47,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"collection.get(ids=['d42d7174ce.html-1', '25dcc77e00.html-6', '19864d414b.html-1'])"
|
||||
"collection.get(ids=list(dict(sorted_ids_scores[:3]).keys()))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 70,
|
||||
"id": "0125c4f3-63ef-4499-9dbd-043b943098d4",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'• La déclaration de sinistre doit être faite dans les 15 jours suivant la date à laquelle a eu lieu le sinistre ;\\n\\n• Les indemnisations interviennent a posteriori du sinistre sur présentation de justificatifs.\\nLe porteur de la Carte Visa, ainsi que son conjoint ou concubin vivant sous le même toit et ses enfants célibataires de moins de 25 ans fiscalement à sa charge, même s’ils voyagent séparément.\\n• Tout déplacement ou séjour à une distance supérieure à 100 km de la résidence principale de l’Assuré ou de son lieu de travail habituel, dans la limite des 180 premiers jours consécutifs ;\\n\\n• Sans franchise kilométrique pour la Garantie Neige et Montagne.\\nPour déclarer un sinistre, vous devez vous rendre sur le site :\\nLes garanties d’assistance sont valables toute la durée du séjour/déplacement dans la limite de 90 jours.\\nLe porteur de la Carte Visa, ainsi que son conjoint ou concubin vivant sous le même toit et ses enfants célibataires de moins de 25 ans fiscalement à sa charge, même s’ils voyagent séparément.\\nLes garanties d’assistance s’appliquent dans le monde entier :\\n\\n• Il n’y a pas de franchise kilométrique si l’événement est survenu en dehors du pays de résidence ;\\n\\n• Si l’événement est survenu dans le pays de résidence, la franchise kilométrique est de 100 km ;\\n\\n• Lors de tout déplacement privé ou professionnel ;\\n\\n• Elles ne se substituent pas aux organismes locaux de secours d’urgence.\\nPour faire une demande d’Assistance en ligne et pour connaître les services d’Assistance liés à votre carte Visa ou demander une attestation, rendez-vous sur le site.'"
|
||||
]
|
||||
},
|
||||
"execution_count": 70,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"'\\n\\n'.join((collection.get(ids=['c98558432b.html-2'])['documents'][0]).split('\\n\\n')[2:])"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user