Python et IA : révolutionner l'analyse CSV en rapports exécutifs

Le brief IA que les pros lisent chaque soir
Les 7 actus IA du jour, décryptées en 5 min. Gratuit.
Inclus dès l'inscription : notre sélection des meilleurs guides & comparatifs IA.
Choisis ton rythme
Gratuit · Pas de spam · Désabonnement en 1 clic
Transformer l'analyse manuelle en automatisation intelligente
Chaque analyste a déjà été confronté à cette situation : un fichier CSV atterrit dans votre boîte de réception, accompagné d'une question sur les performances. Vous vous retrouvez alors à passer des heures à nettoyer les colonnes, à générer des graphiques et à rédiger des conclusions. Cependant, grâce aux avancées technologiques, il est désormais possible d'automatiser une grande partie de ce processus. Cet article vous guide dans la création d'un pipeline en Python qui prend un fichier CSV brut de ventes, le nettoie, effectue les calculs nécessaires, génère des graphiques et utilise une IA, en l'occurrence Claude Opus 4.8, pour rédiger les insights. Ce modèle d'IA est capable de produire un premier brouillon de la narration en quelques secondes, bien que la validation finale des faits reste entre les mains humaines.
Avant de se lancer dans l'analyse, il est crucial de définir une question centrale pour le rapport. Dans notre cas, nous cherchons à savoir combien de revenus ont été conservés sur une période de cinq semaines et où le reste a été perdu. Chaque étape du processus contribue à répondre à cette question. Le nettoyage des données identifie quelles transactions comptent comme des revenus, les agrégats révèlent où et quand les pertes ont eu lieu, et l'IA transforme ces résultats en un résumé lisible par les décideurs.
Le code complet est fourni pour permettre la reproduction de ce processus, et les étapes décrites s'appliquent à presque tous les ensembles de données similaires :
- CSV → nettoyage → exploration → graphique → insights IA → recommandations → rapport
Dans cet exemple, nous utilisons le fichier product_sales.csv, qui contient 45 lignes de transactions. Ce fichier est souvent utilisé dans des contextes d'entretien pour illustrer des questions analytiques. Chaque ligne représente un événement de paiement, qu'il s'agisse d'un achat ou d'un remboursement, avec des détails tels que le pays, la date, le montant et le statut de la transaction.
Nettoyage des données
Le nettoyage des données est une étape cruciale qui garantit l'exactitude des totaux. Parmi les 45 lignes initiales, trois sont marquées comme en attente ou échouées, ce qui signifie qu'elles ne peuvent pas être considérées comme des revenus. Nous procédons à la correction des types de données et ne conservons que les transactions complétées :
import pandas as pd
df = pd.read_csv("product_sales.csv")
df["transaction_date"] = pd.to_datetime(df["transaction_date"])
df["amount"] = pd.to_numeric(df["amount"], errors="coerce")
Les transactions en attente et échouées sont exclues du calcul des revenus.
settled = df[df["status"] == "completed"].copy()
settled["is_refund"] = settled["type"].eq("refund")
Cela élimine 3 des 45 lignes, laissant 42 transactions complétées. Si nous avions utilisé le fichier brut, nous aurions faussement comptabilisé un paiement échoué comme une vente.
Analyse exploratoire
La première partie de notre question porte sur le montant conservé. En séparant les achats des remboursements, les chiffres clés émergent. Les remboursements étant déjà enregistrés comme négatifs, le revenu net est simplement la somme des montants.
gross = settled.loc[~settled["is_refund"], "amount"].sum()
refunds = settled.loc[settled["is_refund"], "amount"].sum() # négatif
net = settled["amount"].sum()
refund_rate = -refunds / gross
print(f"gross {gross:,.0f}")
print(f"refunds {refunds:,.0f}")
print(f"net {net:,.0f}")
print(f"refund rate (value) {refund_rate:.0%}")
Taux de remboursement (valeur) : 38%
En résumé, nous avons vendu environ 13 000 $ et remboursé 4 875 $, ce qui donne un revenu net de 8 100 $. Un taux de remboursement de 38% est notablement élevé, ce qui ne serait pas évident si l'on se contentait de sommer les montants positifs.
Pour comprendre où l'argent a été perdu, nous analysons les données par pays et par semaine. Par pays, nous identifions les marchés qui contribuent au chiffre net :
by_country = (settled.groupby("country")["amount"]
.agg(net_revenue="sum", transactions="count")
.sort_values("net_revenue", ascending=False))
print(by_country)
Le Canada se distingue de manière surprenante avec deux commandes complétées, toutes deux remboursées, ce qui signifie que son revenu net est nul.
Ensuite, nous analysons les données par semaine, en distinguant les achats des remboursements :
settled["week"] = settled["transaction_date"].dt.to_period("W").dt.start_time
weekly = settled.pivot_table(index="week", columns="is_refund",
values="amount", aggfunc="sum").fillna(0)
weekly.columns = ["purchases", "refunds"]
weekly["net"] = weekly.sum(axis=1)
Les trois premières semaines montrent un solde net positif, tandis que les trois dernières sont négatives. Les achats cessent début mai, mais les remboursements continuent.
Un chiffre supplémentaire éclaire cet écart. En utilisant original_transaction_id, nous mesurons le délai entre un achat et son remboursement :
purch_dates = (settled.loc[~settled["is_refund"], ["transaction_id", "transaction_date"]]
.set_index("transaction_id")["transaction_date"])
ref = settled[settled["is_refund"]].copy()
ref["lag_days"] = (ref["transaction_date"]
- ref["original_transaction_id"].map(purch_dates)).dt.days
print(ref["lag_days"].median()) # 20.0
Le remboursement médian intervient 20 jours après la vente, indiquant que les revenus d'avril continuent d'être remboursés en mai.
Création des graphiques
Nous utilisons Matplotlib pour générer trois graphiques, enregistrés en tant que fichiers PNG.
import matplotlib.pyplot as plt
weekly[["purchases", "refunds"]].plot(kind="bar", color=["#2a9d8f", "#e76f51"])
plt.axhline(0, color="black", linewidth=0.8)
plt.title("Achats bruts hebdomadaires vs remboursements")
plt.tight_layout(); plt.savefig("chart_weekly.png")
Le graphique hebdomadaire montre clairement le schéma : de grandes barres vertes en avril, suivies par les barres de remboursement en mai.
settled.groupby("transaction_date")["amount"].sum().sort_index().cumsum().plot()
plt.title("Revenu net cumulé au fil du temps")
plt.tight_layout(); plt.savefig("chart_cumulative.png")
by_country["net_revenue"].plot(kind="barh", color="#2a9d8f")
plt.title("Revenu net par pays")
plt.tight_layout(); plt.savefig("chart_country.png")
Génération des insights IA
Nous transmettons maintenant les chiffres au modèle d'IA. Un résumé textuel des découvertes est construit et présenté comme une invite. Vous collez cette invite dans Claude et insérez la réponse dans le carnet.
weekly_net = {d.date().isoformat(): round(v) for d, v in weekly["net"].items()}
summary = f"""Ventes de produits, {settled['transaction_date'].min().date()} à {settled['transaction_date'].max().date()}.
Brut : ${gross:,.0f} Remboursements : ${-refunds:,.0f} Net : ${net:,.0f}
Taux de remboursement par valeur : {refund_rate:.0%}
Revenu net par pays : {by_country['net_revenue'].round(0).to_dict()}
Net hebdomadaire : {weekly_net}
Jours médians entre achat et remboursement : 20"""
Vous êtes un analyste de données écrivant pour des dirigeants.
Sur la base de ce résumé, rédigez 3 insights et 3 recommandations commerciales. Soyez spécifique et prudent quant à la petite taille de l'échantillon.
Le modèle ne voit que les chiffres résumés. Il raisonne sur des agrégats propres, et aucune donnée au niveau des lignes ne quitte votre machine. Voici ce que Claude Opus 4.8 a retourné :
C'est ici qu'un humain doit rester impliqué. Le modèle a bien lu le résumé, mais il ne sait pas qu'il s'agit d'un produit unique sur cinq semaines et de 42 lignes. La prudence concernant la taille de l'échantillon est justifiée, et nous ne prendrions aucun de ces chiffres à une réunion du conseil sans plus d'historique.
Assemblage du rapport exécutif
La dernière étape assemble un fichier rapport.html autonome avec les indicateurs principaux sous forme de cartes, les trois graphiques et le texte de l'IA. Le constructeur complet est ici.
Voici un aperçu du rapport :
Si vous souhaitez voir le rapport complet, téléchargez ce fichier HTML et ouvrez-le dans votre navigateur.
Le pipeline est court : nettoyer les données, calculer quelques agrégats honnêtes, dessiner trois graphiques, et laisser le modèle rédiger la narration. L'étape de nettoyage et les agrégats déterminent si le rapport est correct. L'IA vous fait gagner l'heure que vous auriez passée à le rédiger.
Claude Opus 4.8 a rédigé des insights clairs et prudents à partir du résumé, et il a correctement signalé la petite taille de l'échantillon. Il ne peut pas vérifier les données ni connaître le contexte commercial, donc les recommandations sont un premier brouillon que nous éditons. Exécutez le script compagnon sur votre propre CSV, changez les noms de colonnes, et vous disposez d'un outil de reporting que vous pouvez diriger vers le prochain fichier qui arrive dans votre boîte de réception.
Nate Rosidi est un scientifique des données et dans la stratégie produit. Il est également professeur adjoint enseignant l'analytique, et est le fondateur de StrataScratch, une plateforme aidant les scientifiques des données à se préparer pour leurs entretiens avec de vraies questions d'entretien provenant de grandes entreprises. Nate écrit sur les dernières tendances du marché de l'emploi, donne des conseils d'entretien, partage des projets de science des données, et couvre tout ce qui concerne SQL.
Brief IA — L'actualité IA en français
L'essentiel de l'actualité de l'intelligence artificielle, décrypté et expliqué chaque jour.