Commit d46f3e20 authored by Delvallez Delvallez's avatar Delvallez Delvallez

élements complémentaires et traces de raisonnement

parent 69859c8a
# Main V1
Dataset issu des données du Challenge RAG de EvalLLM2026.
## Construction
- Extraction du texte des pdf à l'aide de `pymupdf4llm`
- Découpe avec `MarkdownTextSplitter` de `langchain_text_splitter` (chunk_size=500, chunk_overlap=150)
- Documents extraits automatiquement à l'aide E5 et ChromaDB
- Selection des questions et documents à la main à partir des extraction automatiques
## Format
3 fichiers:
- paires_mainV1.csv
- docs_mainV1.csv
- queries_mainV1.csv
### paires_mainV1.csv
- q_id (int) : identifiant de question
- question (str) : texte de la question
- doc_id (int) : identifiant de ducument
- doc_name (str) : nom du fichier pdf d'origine
- page_number (int) : numéro (absolu) de la page d'origine
- chunk_id (int) : identifiant de l'extrait
- text (str) : texte de l'extrait
- pertinent (bool) : pertinent du document pour la question
Infos:
- 52 entrées
- Autant de documents pertinents que non pertinents
- 1 document pertinent/ non-pertinent par question
- 52 extraits
- 26 questions
### docs_mainV1.csv
- doc_id (int) : identifiant de ducument
- doc_name (str) : nom du fichier pdf d'origine
- page_number (int) : numéro (absolu) de la page d'origine
- chunk_id (int) : identifiant de l'extrait
- text (str) : texte de l'extrait
### queries_mainV1.csv
- q_id (int) : identifiant de question
- question (str) : texte de la question
# Main V2
Dataset issu des données du Challenge RAG de EvalLLM2026.
## Construction
- Extraction du texte des pdf à l'aide de `pymupdf4llm`
- Découpe avec `MarkdownTextSplitter` de `langchain_text_splitter` (chunk_size=500, chunk_overlap=150)
- Documents extraits automatiquement à l'aide E5 et ChromaDB
- Selection des questions et documents à la main à partir des extraction automatiques
## Format
3 fichiers:
- paires_mainV2.csv
- docs_mainV2.csv
- queries_mainV2.csv
### paires_mainV2.csv
- q_id (int) : identifiant de question
- question (str) : texte de la question
- doc_id (int) : identifiant de document
- doc_name (str) : nom du fichier pdf d'origine
- page_number (int) : numéro (absolu) de la page d'origine
- chunk_id (int) : identifiant de l'extrait
- text (str) : texte de l'extrait
- pertinent (bool) : pertinent du document pour la question
Infos:
- 27 entrées
- Autant de documents pertinents que non pertinents
- Textes issus de 3 pdfs
- 28 extraits
- 1 question
### docs_mainV2.csv
- doc_id (int) : identifiant de ducument
- doc_name (str) : nom du fichier pdf d'origine
- page_number (int) : numéro (absolu) de la page d'origine
- chunk_id (int) : identifiant de l'extrait
- text (str) : texte de l'extrait
### queries_mainV2.csv
- q_id (int) : identifiant de question
- question (str) : texte de la question
## Contenu/ Stats
Construction des données:
- 1 question, 3 pdf (limitations matérielles du drone, code de la défense - matériel de guerre, fausses infos pdt les JO/JP)
- 50% de textes pertinents
- 28 paires
Question :
> Quelles sont les trois principales catégories de limitations techniques affectant les systèmes de drones, et comment chacune influence-t-elle l'efficacité opérationnelle de ces vecteurs ?
|word | freq | TF-IDF |
|----------|---|------------------|
|**matériel** |16 |0.0627430130086598|
|**système** |11 |0.0542242908052481|
|**limitation**|6 |0.0495565089630139|
|**drone** |10 |0.0441649020535004|
|défense |10 |0.0440955901918619|
|prendre |6 |0.0425658179515979|
|compte |5 |0.0404563824330286|
|action |8 |0.0401684995180441|
|article |9 |0.0400092952253956|
|ministre |8 |0.03913497111578 |
|aérien |7 |0.0366033210120314|
|acteur |6 |0.0337084867312698|
|guerre |8 |0.0336043799517422|
# Main V3
Dataset issu des données du Challenge RAG de EvalLLM2026.
## Construction
- Extraction du texte des pdf à l'aide de `pymupdf4llm`
- Découpe avec `MarkdownTextSplitter` de `langchain_text_splitter` (chunk_size=500, chunk_overlap=150)
- Documents extraits automatiquement à l'aide E5 et ChromaDB
- Selection des questions et documents à la main à partir des extraction automatiques
## Format
3 fichiers:
- paires_mainV3.csv
- docs_mainV3.csv
- queries_mainV3.csv
### paires_mainV3.csv
- q_id (int) : identifiant de question
- question (str) : texte de la question
- doc_id (int) : identifiant de ducument
- doc_name (str) : nom du fichier pdf d'origine
- page_number (int) : numéro (absolu) de la page d'origine
- chunk_id (int) : identifiant de l'extrait
- text (str) : texte de l'extrait
- pertinent (bool) : pertinent du document pour la question
Infos:
- 20 entrées
- Autant de documents pertinents que non pertinents
- Textes issus de 3 pdfs
- 20 extraits
- 1 question
### docs_mainV3.csv
- doc_id (int) : identifiant de ducument
- doc_name (str) : nom du fichier pdf d'origine
- page_number (int) : numéro (absolu) de la page d'origine
- chunk_id (int) : identifiant de l'extrait
- text (str) : texte de l'extrait
### queries_mainV3.csv
- q_id (int) : identifiant de question
- question (str) : texte de la question
## Analyse
### Question
1 question :
> Quels sont les défis majeurs liés à l’utilisation d’une intelligence artificielle auto-apprenante dans les systèmes d’armes, et en quoi ces défis remettent-ils en cause les méthodes traditionnelles de développement et de validation des technologies militaires ?
### Thématique
Sujet pas spécifique à la défense mais appliqué à la défense : Intelligence Artificielle appliquée aux outils et pratiques de la défense et notamment à la guerre.
Thèmatique des 3 pdf:
- IA pour la défense : enjeux
- Aviation civile
- usage des ballons (aérostats et dirigeables) dans l'histoire et rebond de l'usage
### Statistique
| Mot | Fréquence| TF-IDF |
|------------|---|--------------------|
|système |13 |0.06480086088326986 |
|transport |9 |0.05957370634266266 |
|militaire |9 |0.0488148141908528 |
|force |8 |0.048789708865220195|
|aérien |8 |0.05223144426877953 |
|automatiser |7 |0.04028923862758367 |
|artificiel |6 |0.04046189336007796 |
|intelligence|6 |0.04046189336007796 |
|emploi |6 |0.03775763430881781 |
|domaine |6 |0.03862181838643274 |
_Système_ est essentielement issu de l'expression _système autonome_ dans les documents positofs (issus du numéro sur l'emploi des Ia et systèmes automatisés du Centre interarmées de concepts, de doctrines et d’expérimentations). La seule exception est pour _système High Altitude pseudo-satellite (HAPS)_ issu du document sur les ballons.
L'entièreté des occurences de _transport_ sont issues du document sur l'aviation civile.
Les occurences de _militaire_ sont issues des documents sur les sytèmes autonomes et les ballons.
\ No newline at end of file
This diff is collapsed.
#!/usr/bin/env python
# coding: utf-8
# # Construction à la min d'un petit dataset maitrisé issu de challenge
# In[48]:
import pandas as pd
# In[49]:
docsV2 = pd.read_csv("../docsV2.csv")
# In[30]:
tmp = docsV2[ docsV2.doc_name.str.contains("Guide_sensi")]
tmp #[tmp.page_number==3]
#docsV2.iloc[9200].text
# ## Creation DB
# In[64]:
db = pd.DataFrame(columns=["q_id", "question", "doc_id", "doc_name", "page_number", "chunk_id", "text", "pertinent"])
# In[65]:
tmp = pd.DataFrame({
"q_id" : [100]*(27679 - 27665),
"question" : ["Quelles sont les trois principales catégories de limitations techniques affectant les systèmes de drones, et comment chacune influence-t-elle l'efficacité opérationnelle de ces vecteurs ?"]*(27679 - 27665),
"doc_id" : list(docsV2.iloc[27665:27679].doc_id),
"doc_name" : list(docsV2.iloc[27665:27679].doc_name),
"page_number" :list(docsV2.iloc[27665:27679].page_number),
"chunk_id" :list(docsV2.iloc[27665:27679].chunk_number),
"text" : list(docsV2.iloc[27665:27679].text),
"pertinent" : [True]*(27679 - 27665)
})
db = pd.concat([db,tmp], axis=0)
db
# In[66]:
tmp = pd.DataFrame({
"q_id" : [100]*(37065 - 37059),
"question" : ["Quelles sont les trois principales catégories de limitations techniques affectant les systèmes de drones, et comment chacune influence-t-elle l'efficacité opérationnelle de ces vecteurs ?"]*(37065 - 37059),
"doc_id" : list(docsV2.iloc[37059:37065].doc_id),
"doc_name" : list(docsV2.iloc[37059:37065].doc_name),
"page_number" :list(docsV2.iloc[37059:37065].page_number),
"chunk_id" :list(docsV2.iloc[37059:37065].chunk_number),
"text" : list(docsV2.iloc[37059:37065].text),
"pertinent" : [False]*(37065 - 37059)
})
db = pd.concat([db,tmp], axis=0)
db
# In[67]:
tmp = pd.DataFrame({
"q_id" : [100]*(3606 - 3598),
"question" : ["Quelles sont les trois principales catégories de limitations techniques affectant les systèmes de drones, et comment chacune influence-t-elle l'efficacité opérationnelle de ces vecteurs ?"]*(3606 - 3598),
"doc_id" : list(docsV2.iloc[3598:3606].doc_id),
"doc_name" : list(docsV2.iloc[3598:3606].doc_name),
"page_number" :list(docsV2.iloc[3598:3606].page_number),
"chunk_id" :list(docsV2.iloc[3598:3606].chunk_number),
"text" : list(docsV2.iloc[3598:3606].text),
"pertinent" : [False]*(3606 - 3598)
})
db = pd.concat([db,tmp], axis=0)
db
# In[70]:
db.reset_index(drop=True, inplace=True)
# In[71]:
db.to_csv("paires_mainV2.csv", index=True)
# ## Generation docs et queries
# In[73]:
new_paires = pd.read_csv("paires_mainV2.csv", index_col=0)
new_paires
# In[74]:
docs = new_paires[["doc_id", "doc_name", "page_number", "chunk_id", "text"]]
docs.head()
# In[75]:
queries = new_paires[["q_id", "question"]]
queries.drop_duplicates(inplace=True, ignore_index=True)
queries.head()
# In[76]:
docs.to_csv("docs_mainV2.csv", index=True)
queries.to_csv("queries_mainV2.csv", index=True)
#!/usr/bin/env python
# coding: utf-8
# # Construction à la min d'un petit dataset maitrisé issu de challenge
# In[1]:
import pandas as pd
# In[2]:
docsV2 = pd.read_csv("../docsV2.csv")
# In[18]:
tmp = docsV2[ docsV2.doc_name.str.contains("20180719")]
tmp[tmp.page_number==19]
docsV2.iloc[13620].text
# ## Creation DB
# In[8]:
db = pd.DataFrame(columns=["q_id", "question", "doc_id", "doc_name", "page_number", "chunk_id", "text", "pertinent"])
# In[ ]:
tmp = pd.DataFrame({
"q_id" : [200]*(2),
"question" : ["Quels sont les défis majeurs liés à l’utilisation d’une intelligence artificielle auto-apprenante dans les systèmes d’armes, et en quoi ces défis remettent-ils en cause les méthodes traditionnelles de développement et de validation des technologies militaires ?"]*2,
"doc_id" : list(docsV2.iloc[13591:13593].doc_id),
"doc_name" : list(docsV2.iloc[13591:13593].doc_name),
"page_number" :list(docsV2.iloc[13591:13593].page_number),
"chunk_id" :list(docsV2.iloc[13591:13593].chunk_number),
"text" : list(docsV2.iloc[13591:13593].text),
"pertinent" : [True]*(2)
})
db = pd.concat([db,tmp], axis=0)
db
# In[12]:
tmp = pd.DataFrame({
"q_id" : [200]*(2),
"question" : ["Quels sont les défis majeurs liés à l’utilisation d’une intelligence artificielle auto-apprenante dans les systèmes d’armes, et en quoi ces défis remettent-ils en cause les méthodes traditionnelles de développement et de validation des technologies militaires ?"]*2,
"doc_id" : list(docsV2.iloc[13593:13595].doc_id),
"doc_name" : list(docsV2.iloc[13593:13595].doc_name),
"page_number" :list(docsV2.iloc[13593:13595].page_number),
"chunk_id" :list(docsV2.iloc[13593:13595].chunk_number),
"text" : list(docsV2.iloc[13593:13595].text),
"pertinent" : [True]*(2)
})
db = pd.concat([db,tmp], axis=0)
db
# In[14]:
tmp = pd.DataFrame({
"q_id" : [200]*4,
"question" : ["Quels sont les défis majeurs liés à l’utilisation d’une intelligence artificielle auto-apprenante dans les systèmes d’armes, et en quoi ces défis remettent-ils en cause les méthodes traditionnelles de développement et de validation des technologies militaires ?"]*4,
"doc_id" : list(docsV2.iloc[13609:13613].doc_id),
"doc_name" : list(docsV2.iloc[13609:13613].doc_name),
"page_number" :list(docsV2.iloc[13609:13613].page_number),
"chunk_id" :list(docsV2.iloc[13609:13613].chunk_number),
"text" : list(docsV2.iloc[13609:13613].text),
"pertinent" : [True]*4
})
db = pd.concat([db,tmp], axis=0)
db
# In[16]:
tmp = pd.DataFrame({
"q_id" : [200],
"question" : ["Quels sont les défis majeurs liés à l’utilisation d’une intelligence artificielle auto-apprenante dans les systèmes d’armes, et en quoi ces défis remettent-ils en cause les méthodes traditionnelles de développement et de validation des technologies militaires ?"],
"doc_id" : [docsV2.iloc[13616].doc_id],
"doc_name" : [docsV2.iloc[13616].doc_name],
"page_number" :[docsV2.iloc[13616].page_number],
"chunk_id" :[docsV2.iloc[13616].chunk_number],
"text" : [docsV2.iloc[13616].text],
"pertinent" : [True]
})
db = pd.concat([db,tmp], axis=0)
db
# In[19]:
tmp = pd.DataFrame({
"q_id" : [200],
"question" : ["Quels sont les défis majeurs liés à l’utilisation d’une intelligence artificielle auto-apprenante dans les systèmes d’armes, et en quoi ces défis remettent-ils en cause les méthodes traditionnelles de développement et de validation des technologies militaires ?"],
"doc_id" : [docsV2.iloc[13620].doc_id],
"doc_name" : [docsV2.iloc[13620].doc_name],
"page_number" :[docsV2.iloc[13620].page_number],
"chunk_id" :[docsV2.iloc[13620].chunk_number],
"text" : [docsV2.iloc[13620].text],
"pertinent" : [True]
})
db = pd.concat([db,tmp], axis=0)
db
# In[ ]:
tmp = pd.DataFrame({
"q_id" : [200]*(2),
"question" : ["Quels sont les défis majeurs liés à l’utilisation d’une intelligence artificielle auto-apprenante dans les systèmes d’armes, et en quoi ces défis remettent-ils en cause les méthodes traditionnelles de développement et de validation des technologies militaires ?"]*2,
"doc_id" : list(docsV2.iloc[13591:13593].doc_id),
"doc_name" : list(docsV2.iloc[13591:13593].doc_name),
"page_number" :list(docsV2.iloc[13591:13593].page_number),
"chunk_id" :list(docsV2.iloc[13591:13593].chunk_number),
"text" : list(docsV2.iloc[13591:13593].text),
"pertinent" : [False]*(2)
})
db = pd.concat([db,tmp], axis=0)
db
# In[70]:
db.reset_index(drop=True, inplace=True)
# In[71]:
db.to_csv("paires_mainV2.csv", index=True)
# ## Generation docs et queries
# In[73]:
new_paires = pd.read_csv("paires_mainV2.csv", index_col=0)
new_paires
# In[74]:
docs = new_paires[["doc_id", "doc_name", "page_number", "chunk_id", "text"]]
docs.head()
# In[75]:
queries = new_paires[["q_id", "question"]]
queries.drop_duplicates(inplace=True, ignore_index=True)
queries.head()
# In[76]:
docs.to_csv("docs_mainV2.csv", index=True)
queries.to_csv("queries_mainV2.csv", index=True)
# Récupération et mise en forme des données pour le challenge RAG @ evalLLM¶
import pymupdf4llm
import pandas as pd
from langchain_text_splitters import MarkdownTextSplitter
from os import listdir
from os.path import isfile, join
from tqdm import tqdm
md_splitter = MarkdownTextSplitter(chunk_size=500, chunk_overlap=150) # le choix de la taille et de l'overlap est justifié par les contraintes de E5 (entrée de 512 token) affiner ces hyperparamètres pourrait parfaire le modèle
doc_df = pd.DataFrame( columns=["doc_id","doc_name", "page_number", "chunk_number", "text"])
mypath = "./data_challenge/Corpus_raw"
onlyfiles = [f for f in listdir(mypath) if (isfile(join(mypath, f)) and ".pdf" in f)]
doc_id = 0
for file in tqdm(onlyfiles):
chunk_number = 0
doc = pymupdf4llm.to_markdown(
join(mypath,file),
page_chunks = True, # "output will be a list of Document.page_count dictionaries (one per page)"
# header = False, # ne traite pas le header
# footer = False, # ne traite pas le footer
#pages = range(1)
)
for page in doc:
textes = md_splitter.split_text(text=page["text"])
n = len(textes)
doc_df = pd.concat([doc_df,
pd.DataFrame({
"doc_id" : [int(doc_id)]*n,
"doc_name" : [page["metadata"]["file_path"]]*n,
"page_number" : [int(page["metadata"]["page"])]*n,
"chunk_number" : [int(i+chunk_number) for i in range(n)],
"text" : textes
})], ignore_index=True)
chunk_number += len(textes)
doc_id+=1
doc_id_str = [str(doc_id) for doc_id in doc_df["doc_id"]]
page_nb_str = [str(page_nb) for page_nb in doc_df["page_number"]]
chunk_nb_str = [str(chunk_nb) for chunk_nb in doc_df["chunk_number"]]
ids = ["#".join([doc_id_str[i], page_nb_str[i], chunk_nb_str[i]]) for i in range(len(doc_id_str))]
doc_id_str = [str(doc_id) for doc_id in doc_df["doc_id"]]
page_nb_str = [str(page_nb) for page_nb in doc_df["page_number"]]
chunk_nb_str = [str(chunk_nb) for chunk_nb in doc_df["chunk_number"]]
ids = ["#".join([doc_id_str[i], page_nb_str[i], chunk_nb_str[i]]) for i in range(len(doc_id_str))]
doc_df.insert(0,"id",pd.Series(ids))
doc_df.to_csv("data_challenge/docs.csv")
\ No newline at end of file
This diff is collapsed.
# Spécification du CLI associé à GenericAutomatedPerturbation.py
## Action 1 : Calcul des valeurs (`values`)
Arguments obligatoires :
- modele (str) : nom du modèle (chemin ou adresse HuggingFace)
- dataset (str) : nom du dataset dans irdataset ou chemin dans l'arborescence
- dataset_origin (choices = ["irdatasets", "file"]) : Origine du dataset. indique comment obtenir le dataset
- perturbation (str) : chemin vers le fichier descriptif des perturbations
Arguments optionnels :
- query_field (str, default="question") : champ du fichier des paires correspondant aux questions
- docs_field (str, default="text") : champ du fichier des paires correspondant aux documents
- subdataset_condition (str, default=None) : critère de sélection d'une sous-partie du dataset
- gen_mean (bool, action = "store_true") : déclenche le calcul des matrices de moyennes de sensibilité
- gen_std (bool, action = "store_true") : déclenche le calcul des matrices d'écarts-types de sensibilité
- output (str, default=None) : spécifie le nom du fichier de sauvegarde des valeurs (Par défaut, le dossier des perturbations est utilisé et le fichier est nommé perts_values.json)
## Action 2 : Génération des graphiques (`graphs`)
Arguments obligatoires :
- input (str) : Fichier contenant les données à mettre sous graphe
Arguments optionnels:
- output (str, default=None) : spécifie le nom du dossier de sauvegarde des graphiques (Par défaut, le dossier de l'input)
\ No newline at end of file
...@@ -2,12 +2,10 @@ ...@@ -2,12 +2,10 @@
import json import json
import numpy as np import numpy as np
import sys
import seaborn as sns import seaborn as sns
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import argparse import argparse
from pathlib import Path from pathlib import Path
from itertools import combinations
def compter_noeuds_sensibles(json_path, pert_type): def compter_noeuds_sensibles(json_path, pert_type):
...@@ -32,33 +30,33 @@ def compter_noeuds_sensibles(json_path, pert_type): ...@@ -32,33 +30,33 @@ def compter_noeuds_sensibles(json_path, pert_type):
with open(json_path, "r", encoding="utf-8") as f: with open(json_path, "r", encoding="utf-8") as f:
data = json.load(f) data = json.load(f)
premiere_perturbation = next(iter(data.values())) premiere_perturbation = data[0]
shape = np.array(premiere_perturbation["patching_mean"]).shape shape = np.array(premiere_perturbation["results"]["patching_mean"]).shape
compteurs = np.zeros(shape, dtype=int) compteurs = np.zeros(shape, dtype=int)
compteur_pert = {} compteur_pert = {}
for perturbation, valeurs in data.items(): for perturbation in data:
if pert_type == "all" or pert_type == perturbation_type(perturbation): if pert_type == "all" or pert_type == perturbation["type"]:
mean = np.array(valeurs["patching_mean"]) mean = np.array(perturbation["results"]["patching_mean"])
std = np.array(valeurs["patching_std"]) std = np.array(perturbation["results"]["patching_std"])
resc_mean = (np.sign(mean) / np.absolute(mean).max()) * np.absolute(mean) resc_mean = (np.sign(mean) / np.absolute(mean).max()) * np.absolute(mean)
resc_std = (np.sign(std) / np.absolute(std).max()) * np.absolute(std) resc_std = (np.sign(std) / np.absolute(std).max()) * np.absolute(std)
compteur_pert[perturbation] ={} compteur_pert[perturbation["pert"]["name"]] ={}
compteur_pert[perturbation]["carte"] = ((np.abs(mean) > 0.1) & (np.abs(resc_mean) > 0.5)) | ((np.abs(std) > 0.1) & (np.abs(resc_std) > 0.5)) compteur_pert[perturbation["pert"]["name"]]["carte"] = ((np.abs(mean) > 0.1) & (np.abs(resc_mean) > 0.5)) | ((np.abs(std) > 0.1) & (np.abs(resc_std) > 0.5))
compteur_pert[perturbation]["noeuds_sensibles"] = [] compteur_pert[perturbation["pert"]["name"]]["noeuds_sensibles"] = []
for i in range(mean.shape[0]): for i in range(mean.shape[0]):
for j in range(mean.shape[1]): for j in range(mean.shape[1]):
if compteur_pert[perturbation]["carte"][i,j]: if compteur_pert[perturbation["pert"]["name"]]["carte"][i,j]:
compteur_pert[perturbation]["noeuds_sensibles"].append((i,j,mean[i,j], std[i,j], resc_mean[i,j], resc_std[i,j])) compteur_pert[perturbation["pert"]["name"]]["noeuds_sensibles"].append((i,j,mean[i,j], std[i,j], resc_mean[i,j], resc_std[i,j]))
compteur_pert[perturbation]["total"] = np.sum(compteur_pert[perturbation]["carte"]) compteur_pert[perturbation["pert"]["name"]]["total"] = np.sum(compteur_pert[perturbation["pert"]["name"]]["carte"])
compteurs += compteur_pert[perturbation]["carte"] compteurs += compteur_pert[perturbation["pert"]["name"]]["carte"]
return compteurs, compteur_pert return compteurs, compteur_pert
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment