Deepvest/ProfilingAI
0
1import pandas as pd2import numpy as np3from typing import List, Dict4import random5 6class InvestmentDataGenerator:7 """Générateur de données pour l'entraînement du modèle d'investissement"""8 9 def __init__(self, num_samples: int = 1000):10 self.num_samples = num_samples11 12 # Définition des valeurs possibles13 self.risk_levels = ["Prudent", "Modéré", "Dynamique"]14 self.goals = [15 "Retraite", 16 "Achat immobilier", 17 "Études des enfants",18 "Épargne de précaution",19 "Création d'entreprise",20 "Voyage",21 "Patrimoine"22 ]23 24 def generate_data(self) -> pd.DataFrame:25 """Génère un DataFrame avec des profils et recommandations"""26 data = []27 28 for _ in range(self.num_samples):29 # Générer un profil30 age = random.randint(18, 70)31 income = random.randint(20, 200) * 100 # 2000€ à 20000€32 savings = random.randint(5, 50) * 100 # 500€ à 5000€33 34 # Sélectionner 1-3 objectifs aléatoires35 num_goals = random.randint(1, 3)36 selected_goals = ", ".join(random.sample(self.goals, num_goals))37 38 # Déterminer le niveau de risque en fonction de l'âge39 risk_tolerance = self._determine_risk_tolerance(age)40 41 # Calculer l'allocation recommandée42 allocation = self._calculate_allocation(age, risk_tolerance)43 44 # Calculer l'investissement mensuel recommandé45 monthly_investment = self._calculate_monthly_investment(income, age)46 47 # Générer l'explication de la stratégie48 strategy = self._generate_strategy_explanation(49 age, risk_tolerance, selected_goals, allocation50 )51 52 data.append({53 "age": age,54 "income": income,55 "savings": savings,56 "goals": selected_goals,57 "risk_tolerance": risk_tolerance,58 "stocks_allocation": allocation["stocks"],59 "bonds_allocation": allocation["bonds"],60 "cash_allocation": allocation["cash"],61 "monthly_investment": monthly_investment,62 "strategy_explanation": strategy63 })64 65 return pd.DataFrame(data)66 67 def _determine_risk_tolerance(self, age: int) -> str:68 """Détermine le niveau de risque en fonction de l'âge"""69 if age < 30:70 weights = [0.1, 0.3, 0.6] # Plus de chance d'être dynamique71 elif age < 50:72 weights = [0.2, 0.5, 0.3] # Plus de chance d'être modéré73 else:74 weights = [0.6, 0.3, 0.1] # Plus de chance d'être prudent75 76 return random.choices(self.risk_levels, weights=weights)[0]77 78 def _calculate_allocation(self, age: int, risk_tolerance: str) -> Dict[str, int]:79 """Calcule l'allocation d'actifs recommandée"""80 # Base d'allocation selon le risque81 base_allocations = {82 "Prudent": {"stocks": 30, "bonds": 60, "cash": 10},83 "Modéré": {"stocks": 60, "bonds": 30, "cash": 10},84 "Dynamique": {"stocks": 80, "bonds": 15, "cash": 5}85 }86 87 # Ajustement selon l'âge88 allocation = base_allocations[risk_tolerance].copy()89 90 if age > 50:91 # Réduire l'exposition aux actions avec l'âge92 reduction = (age - 50) * 1 # 1% de réduction par année après 50 ans93 allocation["stocks"] = max(20, allocation["stocks"] - reduction)94 allocation["bonds"] += reduction95 96 return allocation97 98 def _calculate_monthly_investment(self, income: int, age: int) -> int:99 """Calcule l'investissement mensuel recommandé"""100 # Base: 20% du revenu101 base_investment = income * 0.2102 103 # Ajustement selon l'âge104 if age < 30:105 # Les jeunes ont plus de temps mais moins de moyens106 multiplier = 0.8107 elif age < 50:108 # Phase d'accumulation principale109 multiplier = 1.2110 else:111 # Phase de préparation à la retraite112 multiplier = 1.5113 114 return int(base_investment * multiplier)115 116 def _generate_strategy_explanation(self, 117 age: int, 118 risk_tolerance: str,119 goals: str,120 allocation: Dict[str, int]) -> str:121 """Génère une explication personnalisée de la stratégie"""122 # Templates d'explications123 age_context = {124 "young": "Votre jeune âge vous permet d'adopter une vision long terme et de privilégier la croissance.",125 "mid": "Vous êtes dans une phase idéale pour équilibrer croissance et sécurité.",126 "senior": "La préservation du capital devient prioritaire à l'approche de la retraite."127 }128 129 risk_context = {130 "Prudent": "Une approche prudente qui privilégie la sécurité",131 "Modéré": "Une stratégie équilibrée entre rendement et sécurité",132 "Dynamique": "Une stratégie orientée vers la croissance"133 }134 135 # Construire l'explication136 if age < 35:137 age_text = age_context["young"]138 elif age < 55:139 age_text = age_context["mid"]140 else:141 age_text = age_context["senior"]142 143 explanation = f"""144 {age_text} Compte tenu de votre profil {risk_context[risk_tolerance].lower()}, 145 nous recommandons une allocation de {allocation['stocks']}% en actions pour la croissance, 146 {allocation['bonds']}% en obligations pour la stabilité, et {allocation['cash']}% en liquidités 147 pour les opportunités. Vos objectifs de {goals} seront servis par cette répartition qui 148 {self._get_strategy_benefit(risk_tolerance)}.149 """150 151 return explanation.strip()152 153 def _get_strategy_benefit(self, risk_tolerance: str) -> str:154 """Retourne les avantages de la stratégie selon le profil"""155 benefits = {156 "Prudent": "minimise les fluctuations tout en maintenant un potentiel de croissance modéré",157 "Modéré": "offre un bon équilibre entre potentiel de croissance et maîtrise du risque",158 "Dynamique": "maximise le potentiel de croissance à long terme en acceptant plus de volatilité"159 }160 return benefits[risk_tolerance]161 162def main():163 # Créer le générateur164 generator = InvestmentDataGenerator(num_samples=1000)165 166 # Générer les données167 df = generator.generate_data()168 169 # Sauvegarder en CSV170 df.to_csv("investment_data.csv", index=False)171 print(f"Données générées et sauvegardées dans investment_data.csv")172 173 # Afficher quelques statistiques174 print("\nAperçu des données générées:")175 print(f"Nombre d'entrées: {len(df)}")176 print("\nDistribution des niveaux de risque:")177 print(df['risk_tolerance'].value_counts())178 print("\nStatistiques d'âge:")179 print(df['age'].describe())180 print("\nStatistiques de revenu:")181 print(df['income'].describe())182 183 # Afficher quelques exemples184 print("\nExemples de données générées:")185 print(df.head())186 187if __name__ == "__main__":188 main()