{"id":31581466,"url":"https://github.com/k-sel/semantic-search-engine","last_synced_at":"2025-10-05T21:58:46.558Z","repository":{"id":317371620,"uuid":"1065993452","full_name":"K-sel/semantic-search-engine","owner":"K-sel","description":"Un moteur de recherche sémantique avec calcule de similarité cosinus entre les docs et la query utilisant la libraire vectorielle FAISS ainsi que Python et une API Flask","archived":false,"fork":false,"pushed_at":"2025-09-30T14:04:26.000Z","size":151,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-30T14:27:03.879Z","etag":null,"topics":["faiss-vector-database","flask","python","search-engine"],"latest_commit_sha":null,"homepage":"","language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/K-sel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-28T20:56:54.000Z","updated_at":"2025-09-30T14:04:30.000Z","dependencies_parsed_at":"2025-09-30T14:38:51.132Z","dependency_job_id":null,"html_url":"https://github.com/K-sel/semantic-search-engine","commit_stats":null,"previous_names":["k-sel/semantic-search-engine"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/K-sel/semantic-search-engine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/K-sel%2Fsemantic-search-engine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/K-sel%2Fsemantic-search-engine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/K-sel%2Fsemantic-search-engine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/K-sel%2Fsemantic-search-engine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/K-sel","download_url":"https://codeload.github.com/K-sel/semantic-search-engine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/K-sel%2Fsemantic-search-engine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278526224,"owners_count":26001327,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["faiss-vector-database","flask","python","search-engine"],"created_at":"2025-10-05T21:58:45.091Z","updated_at":"2025-10-05T21:58:46.549Z","avatar_url":"https://github.com/K-sel.png","language":"Vue","readme":"# Semantic Search Engine - Mon premier projet IA avec Python\n\n## 📋 Vue d'ensemble\n\nApplication de **recherche sémantique** qui comprend le sens des requêtes plutôt que de faire une simple correspondance de mots-clés. Par exemple, chercher \"voiture rapide\" trouvera aussi des documents contenant \"automobile sportive\" ou \"véhicule performant\".\n\nCe projet a été développé pour apprendre et comprendre comment fonctionne un moteur de recherche moderne et a par la même occasion servi de projet final soumis à Harvard pour valider mon cours CS50.\n\n\n## 📚 Table des matières\n\n- [📋 Vue d'ensemble](#-vue-densemble)\n- [🚀 Démarrage](#-démarrage)\n- [🧠 Comment fonctionne la recherche sémantique ?](#-comment-fonctionne-la-recherche-sémantique-)\n  - [Le problème avec la recherche classique](#le-problème-avec-la-recherche-classique)\n  - [La solution : les embeddings vectoriels](#la-solution--les-embeddings-vectoriels)\n- [🔬 Architecture du moteur de recherche](#-architecture-du-moteur-de-recherche)\n  - [Étape 1 : Préparation des données](#étape-1--préparation-des-données-datasetpy)\n  - [Étape 2 : Indexation](#étape-2--indexation-indexerpy)\n  - [Étape 3 : Recherche en temps réel](#étape-3--recherche-en-temps-réel-apppy)\n- [🎯 Pourquoi c'est puissant ?](#-pourquoi-cest-puissant-)\n- [🔍 FAISS : Le cœur du système](#-faiss--le-cœur-du-système)\n  - [Comparaison des index FAISS](#comparaison-des-index-faiss)\n- [🎨 Flux complet d'une recherche](#-flux-complet-dune-recherche)\n- [🧪 Exemple concret](#-exemple-concret)\n- [🔧 API Endpoints](#-api-endpoints)\n\n--- \n\n### Technologies principales\n- **Backend** : Flask + FAISS + Sentence Transformers\n- **Frontend** : Vue.js 3 + Vite\n- **Orchestration** : Docker Compose\n\n---\n\n## 🚀 Démarrage\n\n```bash\n# Cloner et lancer\ngit clone \u003crepo\u003e\ncd semantic-search\n\ncd backend\npython dataset.py\npython indexer.py\n\ncd ..\ndocker-compose up --build\n\n# Puis ouvrir dans votre navigateur\n# Frontend : http://localhost:5173\n# API : http://localhost:5000\n```\n\n---\n\n## 🧠 Comment fonctionne la recherche sémantique ?\n\n### Le problème avec la recherche classique\n\nUne recherche traditionnelle cherche des **correspondances exactes** :\n- Requête : \"voiture rapide\"\n- Trouve : documents contenant exactement \"voiture\" ET \"rapide\"\n- Rate : \"automobile sportive\", \"véhicule performant\", \"bolide\"\n\n### La solution : les embeddings vectoriels\n\nAu lieu de comparer des mots, on compare des **vecteurs mathématiques** qui représentent le **sens** du texte.\n\n```\n\"machine learning\"          →  [0.2, 0.8, 0.1, ..., 0.5]  (384 dimensions)\n\"apprentissage automatique\" →  [0.21, 0.79, 0.11, ..., 0.49]\n\nSimilarité cosinus élevée → textes similaires !\n```\n\n---\n\n## 🔬 Architecture du moteur de recherche\n\n### Étape 1 : Préparation des données (`dataset.py`)\n\n```python\ndocuments = [\n    \"Machine learning is a subset of AI\",\n    \"Deep learning uses neural networks\",\n    \"Python is great for data science\"\n]\n```\n\nGénère :\n- **`data/`** : Fichiers sources bruts\n- **`docs.db`** : Base SQLite avec métadonnées (id, titre, texte)\n\n### Étape 2 : Indexation (`indexer.py`)\n\n```python\n# 1. Charger le modèle\nmodel = SentenceTransformer(\"all-MiniLM-L6-v2\")\n\n# 2. Encoder tous les documents\nembeddings = model.encode(documents)\n# → Matrice de vecteurs normalisés pour la similarité cosinus\n\n# 3. Créer l'index FAISS avec similarité cosinus\nindex = faiss.IndexFlatIP(384)  # IP = Inner Product (cosinus sur vecteurs normalisés)\n\n# 4. Ajouter les vecteurs\nindex.add(embeddings)\n\n# 5. Sauvegarder\nfaiss.write_index(index, \"indexes.faiss\")\n```\n\n**Résultat :** `indexes.faiss` - Index optimisé pour la recherche rapide\n\n### Étape 3 : Recherche en temps réel (`app.py`)\n\n```python\n# 1. Utilisateur cherche : \"deep learning\"\nquery_vector = model.encode(query)\n\n# 2. Chercher les 5 vecteurs les plus similaires\nsimilarities, indices = index.search(query_vector, k=5)\n\n# similarities = [0.95, 0.87, 0.72, 0.65, 0.58]  # Plus élevé = plus similaire\n# indices = [42, 15, 103, 8, 67]\n\n# 3. Récupérer les documents depuis SQLite\nresults = [\n    {\"id\": 42, \"title\": \"...\", \"score\": 0.95},\n    {\"id\": 15, \"title\": \"...\", \"score\": 0.87},\n    ...\n]\n```\n\n---\n\n## 🎯 Pourquoi c'est puissant ?\n\n### 1. Comprend les synonymes\n```\nRequête : \"automobile\"\nTrouve : \"voiture\", \"véhicule\", \"car\"\n```\n\n### 2. Comprend le contexte\n```\nRequête : \"apple fruit\"\nTrouve : documents sur les pommes (fruit)\nPas : documents sur Apple (entreprise)\n```\n\n### 3. Fonctionne en multilingue\n```\nRequête : \"machine learning\"\nTrouve aussi : \"apprentissage automatique\"\n```\n\n### 4. Rapide et scalable\n- **10 000 documents** : ~5-10ms\n- **1 million de documents** : ~50-100ms\n\n---\n\n## 🔍 FAISS : Le cœur du système\n\n**FAISS** (Facebook AI Similarity Search) permet la recherche vectorielle ultra-rapide.\n\n### IndexFlatIP vs IndexFlatL2\n\nNotre projet utilise `IndexFlatIP` qui calcule le **produit scalaire** :\n\n```python\nindex = faiss.IndexFlatIP(384)\n```\n\n**Quand utiliser IndexFlatIP :**\n- **Vecteurs normalisés** (comme Sentence Transformers) : équivalent à la similarité cosinus\n- **Score intuitif** : valeurs 0-1, plus élevé = meilleur\n- **Recherche sémantique** : on compare l'orientation (le sens), pas la magnitude\n- **Recommandations** : \"cet article est similaire à celui-ci\"\n\n**Quand utiliser IndexFlatL2 :**\n- **Vecteurs non normalisés** où la magnitude compte\n- **Embeddings d'images** avec des modèles qui ne normalisent pas\n- **Distance physique** : coordonnées GPS, données spatiales\n- **Données numériques brutes** : température, prix, mesures\n\n**Note importante :** Avec Sentence Transformers, les vecteurs sont automatiquement normalisés. Dans ce cas, **IndexFlatIP et IndexFlatL2 donnent des classements identiques** (seule l'échelle des scores diffère). On préfère IP pour l'interprétabilité du score.\n\n### Comparaison des index FAISS\n\n| Index | Vitesse | Précision | RAM | Meilleur pour |\n|-------|---------|-----------|-----|---------------|\n| **FlatIP/L2** | Lent (O(n)) | 100% | Élevée | \u003c 100k vecteurs, précision critique |\n| **IVFFlat** | Rapide (O(log n)) | 90-95% | Moyenne | 100k-10M vecteurs, bon équilibre |\n| **IVFPQ** | Très rapide | 85-90% | Faible | 10M+ vecteurs, RAM limitée |\n| **HNSW** | Très rapide | 95-99% | Élevée | Meilleure qualité approximative |\n\n**Notre choix :** IndexFlatIP car précision maximale pour un dataset de taille modérée (~1k-100k documents).\n\n---\n\n## 📊 Sentence Transformers : Le cerveau\n\n### Le modèle : all-MiniLM-L6-v2\n\n**Caractéristiques :**\n- **Dimension** : 384\n- **Taille** : ~80 MB\n- **Vitesse** : ~14 000 phrases/seconde (CPU)\n- **Qualité** : Excellent équilibre performance/précision\n\n```python\nmodel = SentenceTransformer(\"all-MiniLM-L6-v2\")\n\nmodel.encode(\"chat\")  # → [0.12, -0.54, ...]\nmodel.encode(\"J'aime les chats\")  # → [0.15, -0.52, ...]\n```\n\nLe modèle a été entraîné sur des millions de paires de phrases pour capturer le sens sémantique.\n\n---\n\n## 🎨 Flux complet d'une recherche\n\n```\n1. Utilisateur : \"python data science\"\n   ↓\n2. Frontend → GET /search?q=python data science\n   ↓\n3. Flask encode la requête\n   → [0.23, 0.67, -0.12, ..., 0.89]\n   ↓\n4. FAISS calcule les similarités cosinus\n   → [doc_42: 0.89, doc_15: 0.82, doc_103: 0.75]\n   ↓\n5. SQLite récupère les métadonnées\n   ↓\n6. JSON → Frontend\n   [{id: 42, title: \"...\", score: 0.89}, ...]\n```\n\n---\n\n## 🧪 Exemple concret\n\n### Documents indexés :\n```\n[1] \"Python est un langage de programmation\"\n[2] \"JavaScript est utilisé pour le web\"\n[3] \"Le machine learning utilise Python\"\n[4] \"Les pandas mangent du bambou\"\n```\n\n### Requête : \"programmation python\"\n\n**Similarités cosinus calculées :**\n```\ndoc[1] : 0.92  ← Très similaire !\ndoc[2] : 0.35\ndoc[3] : 0.78  ← Assez similaire\ndoc[4] : 0.12  ← Peu similaire\n```\n\n**Résultats (triés par score décroissant) :**\n```json\n[\n  {\n    \"id\": 1,\n    \"title\": \"Python est un langage de programmation\",\n    \"score\": 0.92\n  },\n  {\n    \"id\": 3,\n    \"title\": \"Le machine learning utilise Python\",\n    \"score\": 0.78\n  }\n]\n```\n\n---\n\n## 🔧 API Endpoints\n\n### `GET /`\nInformations sur l'index\n\n```json\n{\n  \"message\": \"FAISS API ready\",\n  \"index_size\": 1000,\n  \"dimension\": 384\n}\n```\n\n### `GET /search?q=votre requête`\nRecherche sémantique\n\n**Réponse :**\n```json\n[\n  {\n    \"id\": 42,\n    \"title\": \"Introduction to Machine Learning\",\n    \"snippet\": \"Machine learning is a subset...\",\n    \"score\": 0.89\n  }\n]\n```\n\n**Note :** Avec `IndexFlatIP`, **plus le score est élevé, meilleur est le résultat** (contrairement à L2 où un score bas est meilleur).\n\n---\n\n## 📖 Ressources\n\n- [FAISS](https://faiss.ai/) - Bibliothèque de recherche vectorielle\n- [Sentence Transformers](https://www.sbert.net/) - Modèles d'embeddings\n- [Flask](https://flask.palletsprojects.com/) - Framework web Python\n- [Hugging Face Models](https://huggingface.co/models?library=sentence-transformers) - Modèles alternatifs\n\n---\n\n**Le principe :** Transformer du texte en vecteurs, calculer leur similarité cosinus pour trouver ce qui est sémantiquement proche. Simple et puissant ! 🚀\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fk-sel%2Fsemantic-search-engine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fk-sel%2Fsemantic-search-engine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fk-sel%2Fsemantic-search-engine/lists"}