Un analyste financier IA local analyse vos relevés bancaires sur votre machine en combinant preprocessing Python, modèles ML légers et LLMs locaux (ex. Ollama, Llama.cpp), garantissant confidentialité et rapports en langage naturel. Voir documentation Ollama pour déploiement local (https://ollama.com).
Pourquoi un analyste financier IA local ?
Un analyste financier IA local conserve vos données bancaires sur votre machine, évitant tout transfert vers des services cloud et facilitant des analyses interprétables et auditées. Cette approche vise d’abord la confidentialité, puis la conformité, la maîtrise des risques fournisseurs et le contrôle intégral des modèles et pipelines.
Motivations et bénéfices pratiques :
- Confidentialité — Le traitement local élimine le besoin d’envoyer des relevés ou des identifiants vers des tiers, réduisant significativement la surface d’exposition en cas de fuite ou de mauvaise configuration.
- Conformité et minimisation des données — La minimisation consiste à ne collecter et conserver que le strict nécessaire; cette exigence est détaillée par la CNIL (voir https://www.cnil.fr/fr/la-minimisation-des-donnees).
- Réduction des risques fournisseurs — Le contrôle local limite la dépendance aux API externes, aux changements de tarification ou aux interruptions de service d’un fournisseur cloud.
- Contrôle et auditabilité — Le code, les modèles et les pipelines restent sous votre responsabilité, ce qui facilite les audits, la traçabilité des décisions et l’explicabilité (interprétabilité) des analyses.
Comparaison concrète : cloud vs local
| Critère | Cloud | Local |
| Confidentialité | Traitement hors site nécessitant chiffrement et contrats, exposé aux politiques du fournisseur. | Données restent sur la machine, contrôle total sur le stockage et les sauvegardes. |
| Latence / Coût | Latence réseau et coûts opérationnels récurrents selon usage et taille modèle. | Latence réseau quasi nulle pour l’inférence et coûts matériels uniques mais investissements CPU/GPU à prévoir. |
| Maintenance | Mise à jour et scalabilité gérées par le fournisseur, dépendance aux SLA. | Maintenance et mises à jour sous votre responsabilité, mais liberté totale sur versions et audits. |
Exemples d’outils locaux — Ollama et Llama.cpp permettent d’exécuter des modèles LLM en local selon vos ressources matérielles.
Checklist rapide pour décider si le local vous convient :
- Vos données sont sensibles ou soumises à régulation stricte (KYC, bancaire) ? Si oui, privilégiez le local.
- Disposez-vous de ressources matérielles et d’une équipe pour maintenir modèles et sécurité ? Si non, évaluez un hybride.
- Avez-vous besoin d’auditabilité complète et de contrôle des versions des modèles ? Si oui, le local est recommandé.
Quelle architecture pour l’application ?
Architecture simple, modulaire et locale pour transformer des CSV financiers en analyses et rapports générés par un LLM local.
Chaque composant joue un rôle précis dans le flux de données. L’interface Streamlit (app.py) est le point d’entrée utilisateur, responsable du chargement du CSV et du pilotage des étapes. Le module preprocessing.py détecte les types de colonnes, gère les valeurs manquantes et normalise les devises et dates. Le module ml_models.py exécute le feature engineering (ratios, lags, agrégations) puis produit scores et détections d’anomalies (ex : isolation forest, thresholds). Le module visualizations.py construit des figures interactives (plots, tables de synthèse) consommées par Streamlit. Le module llm_integration.py orchestre l’envoi du résumé et des données au runtime LLM local (ex : Ollama) et récupère le rendu en streaming pour une génération de rapport progressive. Le fichier config.py centralise chemins et clés. Le répertoire sample_data contient jeux d’exemple pour tests. Le fichier requirements.txt verrouille les dépendances Python.
Flux end-to-end : import CSV → détection/normalisation → feature engineering → scoring/anomalies → visualisations interactives → génération de rapport par LLM local.
| app.py | Point d’entrée Streamlit, UI et orchestration. |
| preprocessing.py | Détection des types, nettoyage, normalisation. |
| ml_models.py | Feature engineering, scoring, anomalie. |
| visualizations.py | Graphes interactifs et tables pour Streamlit. |
| llm_integration.py | Hooks pour modèle local en streaming (Ollama/http). |
| config.py | Chemins, host/port modèle, options de streaming. |
| requirements.txt | Dépendances Python verrouillées. |
| sample_data/ | Exemples CSV pour tests et démo. |
Exemple minimal de config :
LLM_RUNTIME = "ollama"
LLM_HOST = "http://localhost"
LLM_PORT = 11434
MODEL_NAME = "finance-analyst"
STREAMING = True
DATA_PATH = "sample_data/finance.csv"
Hook streaming (extrait) :
def stream_llm(prompt):
import requests
url = f"{LLM_HOST}:{LLM_PORT}/api/generate"
for chunk in requests.post(url, json={"model": MODEL_NAME, "prompt": prompt}, stream=True).iter_lines():
if chunk:
yield chunk.decode()
Recommandations de déploiement local :
- Prérequis système : 4+ CPU, 8+ Go RAM pour usage léger; GPU recommandé pour modèles lourds.
- Gestion dépendances : utiliser venv/virtualenv puis pip install -r requirements.txt; pinner les versions.
- Sécurité fichiers : stocker secrets dans .env non versionné; restreindre permissions (chmod 600) et éviter de committer sample_data sensible.
- Monitoring : journaliser appels LLM et erreurs pour debug et audit.
Comment construire un pipeline de preprocessing robuste ?
Pipeline robuste commence par détecter et normaliser tôt les colonnes hétérogènes afin d’éviter la dette technique et les erreurs downstream.
Voici un jeu de motifs regex représentatifs pour détecter les colonnes courantes (date, description, amount, debit, credit, currency, reference).
COLUMN_PATTERNS = {
"date": [r"(^date$)", r"date[_\s]?(posted|transaction|txn|val)?", r"\d{4}-\d{2}-\d{2}", r"\d{2}/\d{2}/\d{4}"],
"description": [r"(description|libellé|label|narrative|memo|beneficiaire|payee)", r"(details|remark)s?"],
"amount": [r"(^amount$)", r"(montant|amount|amt|value)"],
"debit": [r"(debit|dr|withdrawal|retir(e|é))", r"(outflow|debit_am?t)"],
"credit": [r"(credit|cr|deposit|versement|inflow)"],
"currency": [r"(currency|curr|devise|iso_currency|monnaie|€|\$|USD|EUR)"],
"reference": [r"(ref|réf|reference|id|transaction_id)"]
}
Fonction detect_column_mapping(df) — logique étape par étape.
- Prendre d’abord les noms de colonnes et comparer chaque nom avec les motifs; attribuer un score si le nom matche.
- Si ambiguïté, échantillonner 100 valeurs non-nulles et tester les motifs de contenu (dates par parsing, montants par regex numérique, codes devise).
- Prioriser correspondance par score combiné nom+contenu; retourner mapping dict {standard_name: column_name}.
def detect_column_mapping(df):
import re
mapping = {}
for std, patterns in COLUMN_PATTERNS.items():
best_col, best_score = None, 0
for col in df.columns:
score = 0
name = col.lower()
for p in patterns:
if re.search(p, name):
score += 2
sample = df[col].dropna().astype(str).head(100).tolist()
for val in sample:
for p in patterns:
if re.search(p, val, re.IGNORECASE):
score += 1
if score > best_score:
best_score, best_col = score, col
if best_col:
mapping[std] = best_col
return mapping
Algorithme merge_debit_credit.
- Si colonne amount présente, la normaliser en float et standardiser les signes (parenthèses => négatif).
- Sinon, si debit et credit présentes, calculer amount = (credit.fillna(0)) – (debit.fillna(0)).
- Si seule debit présente, amount = -debit. Si seule credit présente, amount = credit.
- Gérer valeurs manquantes, milliers/virgule décimale et multi-devises en conservant colonne currency pour conversion ultérieure.
def _to_float_series(s):
s = s.astype(str).str.replace(r"[^\d\-\.,\(\)]", "", regex=True)
s = s.str.replace(r"\(", "-", regex=True).str.replace(r"\)", "", regex=True)
s = s.str.replace(r"\s+", "", regex=True)
s = s.str.replace(",", ".", regex=True)
return pd.to_numeric(s, errors="coerce")
def merge_debit_credit(df, mapping):
amt_col = mapping.get("amount")
debit_col = mapping.get("debit")
credit_col = mapping.get("credit")
if amt_col in df.columns:
df["amount"] = _to_float_series(df[amt_col])
else:
d = _to_float_series(df[debit_col]) if debit_col in df.columns else 0
c = _to_float_series(df[credit_col]) if credit_col in df.columns else 0
df["amount"] = c.fillna(0) - d.fillna(0)
return df
Normaliser tôt réduit la dette technique en rendant les transformations idempotentes, testables et traçables; cela diminue les bugs de 30–70% selon la complexité des jeux de données.
| Étape | Action | Risque couvert |
| Détection colonnes | Regex nom+contenu | Colonnes mal nommées ou traduites |
| Normalisation types | Dates ISO, floats signés | Format incohérent, décimales |
| Fusion débit/crédit | Règles signées | Montants dupliqués ou opposés |
| Edge cases | Multi-devises, lignes total | Lignes récapitulatives, encodages |
Comment intégrer ML et LLM locaux pour analyses et rapports ?
Comment combiner signaux ML structurés et génération en langage naturel par un LLM local (Large Language Model) pour produire des rapports financiers exploitables.
J’utilise d’abord une ingénierie des features robuste pour transformer les transactions brutes en signaux : agrégats glissants (rolling sums sur 7/30 jours), fréquence par catégorie (transactions par jour/semaine), montant médian et écart-type, ratio crédits/débits, heures d’activité. Les features doivent être anonymisées (hash d’identifiant, suppression PII) avant tout traitement.
- Stratégies pour peu de données : Utiliser transfer learning quand possible (embeddings pré-entraînés), construire featurization robuste (features agrégées), valider via cross-validation à K folds, et corriger le déséquilibre par oversampling (SMOTE) ou class weights.
- Sélection de modèles : RandomForest ou LightGBM pour classification (catégorisation de transaction), IsolationForest (Breunig et al., 2000) pour détection d’anomalies.
Exemple d’entraînement RandomForest et IsolationForest en scikit-learn :
from sklearn.ensemble import RandomForestClassifier, IsolationForest
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split, cross_val_score
# Préparez X (features) et y (labels)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
clf = Pipeline([
('scaler', StandardScaler()),
('rf', RandomForestClassifier(n_estimators=200, class_weight='balanced', random_state=42))
])
clf.fit(X_train, y_train)
print("CV accuracy:", cross_val_score(clf, X_train, y_train, cv=5).mean())
iso = IsolationForest(n_estimators=100, contamination=0.01, random_state=42)
iso.fit(X_train) # sur features sans label d'anomalie
Fonctions d’inférence qui enrichissent le DataFrame :
def infer_and_annotate(df, feature_cols, clf, iso):
X = df[feature_cols]
df['pred_category'] = clf.predict(X) # ou predict_proba pour scores
df['anomaly_score'] = -iso.decision_function(X) # plus haut => plus anormal
return df
Pour la synthèse, intégrer un LLM local (ex : Ollama) en streaming et respecter la confidentialité : ne pas envoyer de PII, transmettre seulement agrégats anonymisés. Exemple de template de prompt (system + user) :
System: "Vous êtes un analyste financier synthétique. Répondez en français clair, neutre et précis. Ne révélez aucune donnée sensible."
User: "Contexte anonymisé: période=2026-03, total_transactions=1,234, total_volume=€124,500, top_categories=[('Food', 320, €24,000), ('Salary', 10, €90,000)], anomalies=[{id:'a1',score:0.85,reason:'montant élevé'}]. Rédigez un rapport mensuel de 6-8 phrases avec actionables."
- Bonnes pratiques de prompt engineering : Limiter le contexte (max 1-2 pages d’agrégats), instructions system précises, temperature basse (0.0–0.3) pour fiabilité, demander structure (résumé, anomalies, recommandations).
Tableau comparatif des sorties ML vs LLM et orchestration :
| ML (signaux) | LLM (texte) |
| Prédiction catégorielle, score d’anomalie, métriques chiffrées | Résumé narratif, interprétation, recommandations actionnables |
| Déterministe, auditable, explicable (features importances) | Flexible, lisible, nécessite validation factuelle |
| Utilisé pour déclencheurs automatiques | Utilisé pour rapports destinés aux décideurs |
Orchestration recommandée : Générer d’abord signaux ML, stocker résultats structurés, puis appeler le LLM local avec contexte restreint pour générer le rapport; conserver logs et hash des entrées pour traçabilité.
Prêt à analyser vos finances en local et garder le contrôle ?
J’ai montré comment concevoir un analyste financier IA 100% local : motivations (confidentialité et contrôle), architecture pratique (Streamlit + modules Python + LLM local), pipeline de preprocessing robuste pour CSV hétérogènes, modèles ML pour catégorisation et détection d’anomalies, et intégration d’un LLM local pour générer des rapports en langage naturel. En appliquant ces étapes vous obtenez des analyses exploitables tout en conservant vos données chez vous. Bénéfice pour vous : insights précis, traçabilité complète et confidentialité garantie.
FAQ
A propos de l’auteur
Franck Scandolera — expert & formateur en Tracking avancé server-side, Analytics Engineering, Automatisation No/Low Code (n8n) et intégration de l’IA en entreprise. Responsable de l’agence webAnalyste et de l’organisme de formation Formations Analytics. Références : Logis Hôtel, Yelloh Village, BazarChic, Fédération Française de Football, Texdecor. Dispo pour aider les entreprises => contactez moi.
⭐ Analytics engineer, Data Analyst et Automatisation IA indépendant ⭐
- Ref clients : Logis Hôtel, Yelloh Village, BazarChic, Fédération Football Français, Texdecor…
Mon terrain de jeu :
- Data Analyst & Analytics engineering : tracking avancé (GTM server, e-commerce, CAPI, RGPD), entrepôt de données (BigQuery, Snowflake, PostgreSQL, ClickHouse), modèles (Airflow, dbt, Dataform), dashboards décisionnels (Looker, Power BI, Metabase, SQL, Python).
- Automatisation IA des taches Data, Marketing, RH, compta etc : conception de workflows intelligents robustes (n8n, App Script, scraping) connectés aux API de vos outils et LLM (OpenAI, Mistral, Claude…).
- Engineering IA pour créer des applications et agent IA sur mesure : intégration de LLM (OpenAI, Mistral…), RAG, assistants métier, génération de documents complexes, APIs, backends Node.js/Python.






