L'analyse des sentiments en finance est un outil puissant pour comprendre les tendances du marché et le comportement des investisseurs. Cependant, les modèles généraux d'analyse des sentiments sont souvent insuffisants lorsqu'ils sont appliqués aux textes financiers en raison de leur complexité et de leur nature nuancée. Ce projet propose une solution en réglant GPT-4O Mini, un modèle de langage léger. En utilisant l'ensemble de données TRC2, une collection d'articles de presse financière Reuters étiquetés avec des classes de sentiment par le modèle expert Finbert, nous visons à améliorer la capacité de GPT-4O Mini à capturer des nuances de sentiment financier.
Ce projet fournit une approche efficace et évolutive de l'analyse des sentiments financiers, ouvrant la porte à une analyse plus basée sur le sentiment nuancé en finance. À la fin, nous démontrons que GPT-4O Mini, lorsqu'il est affiné avec des données spécifiques au domaine, peut servir d'alternative viable à des modèles plus complexes comme Finbert dans des contextes financiers.
Cet article a été publié dans le cadre du Blogathon de la science des données.
Pour ce projet, nous utilisons le jeu de données TRC2 (Trec Reuters Corpus, volume 2), une collection d'articles de presse financière organisés par Reuters et mis à disposition par le biais de l'Institut national des normes et de la technologie (NIST). L'ensemble de données TRC2 comprend une sélection complète d'articles de presse financière de Reuters, souvent utilisés dans les modèles de langage financier en raison de sa large couverture et de sa pertinence pour les événements financiers.
Pour obtenir l'ensemble de données TRC2, les chercheurs et les organisations doivent demander l'accès via NIST. L'ensemble de données est disponible chez NIST Trec Reuters Corpus, qui fournit des détails sur les accords de licence et d'utilisation. Vous aurez besoin de:
Une fois que vous avez obtenu l'ensemble de données, prétraitez-vous et segmentez-le en phrases pour l'analyse des sentiments, vous permettant d'appliquer Finbert pour générer des classes de sentiment marquées par des experts.
La méthodologie pour le réglage fin GPT-4O avec des étiquettes de sentiment dérivées de Finbert se compose des étapes principales suivantes:
Pour créer l'ensemble de données à réglage fin, nous tirons parti de Finbert, un modèle de langue financière pré-formée sur le domaine financier. Nous appliquons Finbert à chaque phrase de l'ensemble de données TRC2, générant des étiquettes de sentiment d'experts sur trois classes: positive, négative et neutre. Ce processus produit un ensemble de données étiqueté où chaque phrase de Trc2 est associée à un sentiment, fournissant ainsi une base pour la formation de GPT-4O Mini avec des étiquettes fiables.
Les données étiquetées sont ensuite prétraitées et formatées en une structure JSONL adaptée à l'API à réglage fin d'OpenAI. Nous formons chaque point de données avec la structure suivante:
Après l'étiquetage, nous effectuons des étapes de prétraitement supplémentaires, telles que la conversion d'étiquettes en minuscules pour la cohérence et la stratification des données pour garantir une représentation équilibrée d'étiquette. Nous avons également divisé l'ensemble de données en ensembles de formation et de validation, réservant 80% des données pour la formation et 20% pour la validation, ce qui aide à évaluer la capacité de généralisation du modèle.
En utilisant l'API à réglage fin d'Openai, nous affinons GPT-4O Mini avec l'ensemble de données pré-étiqueté. Les paramètres de réglage fin, tels que le taux d'apprentissage, la taille du lot et le nombre d'époches, sont optimisés pour atteindre un équilibre entre la précision du modèle et la généralisation. Ce processus permet à GPT-4O Mini d'apprendre des données spécifiques au domaine et améliore ses performances sur les tâches d'analyse des sentiments financiers.
Après la formation, les performances du modèle sont évaluées en utilisant des mesures d'analyse des sentiments courants comme la précision et le score F1, permettant une comparaison directe avec les performances de Finbert sur les mêmes données. Cette analyse comparative montre à quel point GPT-4O Mini généralise les classifications des sentiments dans le domaine financier et confirme si elle peut systématiquement surpasser Finbert en précision.
Après avoir confirmé des performances supérieures, GPT-4O Mini est prêt pour le déploiement dans les applications financières du monde réel, telles que l'analyse du marché, le conseil en investissement et le suivi automatisé du sentiment d'information. Ce modèle affiné fournit une alternative efficace aux modèles financiers plus complexes, offrant des capacités d'analyse de sentiment robustes et évolutives adaptées à l'intégration dans les systèmes financiers.
Si vous souhaitez apprendre les bases de l'analyse des sentiments, consultez notre article sur l'analyse des sentiments à l'aide de Python!
Suivez cette approche structurée et étape par étape pour naviguer de manière transparente dans chaque étape du processus. Que vous soyez débutant ou expérimenté, ce guide garantit la clarté et la réussite de la mise en œuvre du début à la fin.
Chargez les bibliothèques requises et configurez l'environnement.
De Transformers Import Autotokenzizer, AutomodeforsequenceClassification Importer une torche Importer des pandas en tant que PD à partir de TQDM IMPORT TQDM tokenizer = autotokenizer.from_pretraind ("PROSUSAI / FINBERT") modèle = AutomodelorsEquenceClassification.from_pretraind ("Prosusai / Finbert") Device = torch.device ('cuda' if torch.cuda.is_available () else 'CPU') Model.To (Device)
def get_sentiment (texte): entrées = tokenizer (texte, return_tensers = "pt", troncature = true, max_length = 512) .to (périphérique) avec torch.no_grad (): sorties = modèle (** entrées) Logits = sorties.logits Sentiment = torch.argmax (Logits, dim = 1) .item () Sentiment_Label = ["positif", "négatif", "neutre"] [Sentiment] Retour Sentiment_Label
Vous devez prévoir soigneusement l'ensemble de données TRC2 pour conserver uniquement les phrases pertinentes pour le réglage fin. Les étapes suivantes décrivent comment lire, nettoyer, diviser et filtrer les données de l'ensemble de données TRC2.
Compte tenu des contraintes de non-divulgation, cette section fournit un aperçu de haut niveau du flux de travail de prétraitement des données avec lepseudocode.
# Chargez l'ensemble de données compressé à partir du fichier ouvrir compresser_file en tant que fichier: # Lisez le contenu du fichier en mémoire data = read_file (fichier) # Extraire des sections pertinentes de chaque document Pour chaque document dans les données: Extraire Document_ID Date d'extraction extraire main_text_content # Définir une fonction pour nettoyer et segmenter le contenu du texte fonction Clean_and_segment_text (texte): # Supprimer les caractères indésirables et les espaces blancs Cleaned_text = retire_special_characters (texte) Cleaned_text = standardize_whitespace (Cleaned_text) # Divisez le texte nettoyé en phrases ou en segments de texte Sentences = Split_into_Sentences (Cleaned_text) phrases de retour # Appliquer la fonction de nettoyage et de segmentation au contenu de chaque document Pour chaque document dans les données: Sentures = Clean_and_segment_text (document ['main_text_content']) Enregistrer les phrases au format structuré # Créez un stockage de données structuré pour les phrases individuelles Initialiser la liste vide de Structured_data Pour chaque phrase en phrases: # Ajouter la phrase aux données structurées Structured_data.append (phrase) # Définissez une fonction pour filtrer les phrases indésirables en fonction de critères spécifiques fonction filter_sences (phrase): Si la phrase est trop courte: retourner faux Si la phrase contient des modèles spécifiques (par exemple, dates ou symboles excessifs): retourner faux Si la phrase correspond aux caractéristiques de formatage indésirables: retourner faux Retour vrai # Appliquer le filtre aux données structurées filtered_data = [phrase pour la phrase dans Structured_data si filter_sences (phrase)] # Filtrez en outre les phrases en fonction de la longueur minimale ou d'autres critères final_data = [phrase pour la phrase dans filtered_data si rencontre_minimum_length (phrase)] # Enregistrer la structure de données finale pour la formation du modèle Enregistrer final_data comme structuré_file
df_sampled = df.sample (n = 1000000, random_state = 42) .reset_index (drop = true)
Importer JSON JSONL_DATA = [] Pour _, Row in TQDM (df_sampled.ITERROWS (), Total = df_sampled.shape [0]): contenu = row ['phrase'] Sentiment = get_sentiment (contenu) jsonl_entry = { "Messages": [ {"rôle": "système", "contenu": "L'assistant est un expert financier."}, {"rôle": "utilisateur", "contenu": contenu}, {"Role": "Assistant", "Content": Sentiment} ]] } JSONL_DATA.APPEND (JSONL_ENTRY) avec open ('finetuning_data.jsonl', 'w') comme jsonl_file: Pour l'entrée dans JSONL_DATA: jsonl_file.write (json.dumps (entrée) '\ n')
avec open ('finetuning_data.jsonl', 'r') comme jsonl_file: data = [json.loads (ligne) pour la ligne dans JSONL_FILE] Pour l'entrée dans les données: entrée ["Messages"] [2] ["Content"] = entrée ["Messages"] [2] ["Content"]. Lower () avec open ('finetuning_data_lowercase.jsonl', 'w') comme new_jsonl_file: Pour l'entrée dans les données: new_jsonl_file.write (json.dumps (entrée) '\ n')
Importer au hasard Random.seed (42) Random.shuffle (données) Split_ratio = 0,8 Split_index = int (len (data) * Split_ratio) Training_Data = Data [: Split_index] validation_data = data [Split_index:] avec Open ('Training_data.jsonl', 'W') comme train_file: Pour l'entrée dans Training_Data: Train_file.write (json.dumps (entrée) '\ n') avec open ('validation_data.jsonl', 'w') comme val_file: pour l'entrée dans validation_data: val_file.write (json.dumps (entrée) '\ n')
de sklearn.model_selection import train_test_split data_df = pd.dataframe ({{ 'contenu': [entrée ["messages"] [1] ["Contenu"] pour la saisie dans les données], 'Label': [entrée ["Messages"] [2] ["Content"] pour la saisie dans les données] }) df_sampled, _ = Train_test_split (data_df, stratify = data_df ['label'], test_size = 0.9, random_state = 42) Train_df, val_df = Train_test_split (df_sampled, stratify = df_sampled ['label'], test_size = 0.2, random_state = 42) def df_to_jsonl (df, nom de fichier): JSONL_DATA = [] pour _, ligne dans df.Iterrows (): jsonl_entry = { "Messages": [ {"rôle": "système", "contenu": "L'assistant est un expert financier."}, {"rôle": "utilisateur", "contenu": row ['contenu']}, {"Role": "Assistant", "Content": Row ['Label']} ]] } JSONL_DATA.APPEND (JSONL_ENTRY) avec ouvert (nom de fichier, 'w') comme jsonl_file: Pour l'entrée dans JSONL_DATA: jsonl_file.write (json.dumps (entrée) '\ n') DF_TO_JSONL (Train_DF, 'Reduced_training_data.jsonl') df_to_jsonl (val_df, 'reduction_validation_data.jsonl')
Pour évaluer les performances du modèle GPT-4O à réglage fin, nous l'avons testée sur un ensemble de données de sentiment financier étiqueté disponible sur Kaggle. Cet ensemble de données contient 5 843 phrases étiquetées dans des contextes financiers, ce qui permet une comparaison significative entre le modèle affiné et Finbert.
Finbert a marqué une précision de 75,81%, tandis que le modèle GPT-4O affiné a atteint 76,46%, démontrant une légère amélioration.
Voici le code utilisé pour les tests:
Importer des pandas en tant que PD Importer un système d'exploitation Importer Openai à partir de Dotenv Import Load_Dotenv # Chargez le fichier CSV csv_file_path = 'data.csv' # Remplacez par votre chemin de fichier réel df = pd.read_csv (csv_file_path) # Convertir DataFrame au format texte avec open ('phrases.txt', 'w', encoding = 'utf-8') comme f: pour index, ligne dans df.Iterrows (): phrase = ligne ['phrase']. strip () # phrase propre Sentiment = Row ['Sentiment']. Strip (). Lower () # Assurez-vous que le sentiment est minuscule et propre f.write (f "{phrase} @ {Sentiment} \ n") # Variables d'environnement de chargement load_dotenv () # Définissez votre clé API Openai openai.api_key = os.getenv ("openai_api_key") # Assurez-vous que Openai_API_KEY est défini dans vos variables d'environnement # Chemin vers le fichier texte de l'ensemble de données file_path = 'Sentences.txt' # Fichier texte contenant des phrases et des étiquettes # Lire les phrases et les véritables étiquettes de l'ensemble de données phrases = [] true_labels = [] avec open (file_path, 'r', encoding = 'utf-8') en tant que fichier: Lines = file.readlines () # Extraire les phrases et les étiquettes Pour la ligne en lignes: line = line.strip () Si '@' en ligne: phrase, label = line.rsplit ('@', 1) phrases.append (phrase.strip ()) true_labels.append (label.strip ()) # Fonction pour obtenir des prédictions du modèle affiné def get_openai_predictions (phrase, modèle = "your_finetuned_model_name"): # remplacer par le nom de votre modèle essayer: réponse = openai.chatcompletion.create ( modèle = modèle, messages = [ {"rôle": "système", "contenu": "Vous êtes un expert en analyse des sentiments financiers."}, {"rôle": "utilisateur", "contenu": phrase} ], max_tokens = 50, Température = 0,5 ) retour de réponse ['choix'] [0] ['message'] ['contenu']. strip () sauf exception comme e: print (f "Erreur de génération de prédiction pour la phrase: '{phrase}'. Erreur: {e}") retourner "inconnu" # Générer des prédictions pour l'ensemble de données prédit_labels = [] pour la phrase en phrases: prédiction = get_openai_predictions (phrase) # Normalisez les prédictions vers «positif», «neutre», «négatif» Si «positif» dans Prediction.Lower (): prédit_labels.append ('positif') elif 'neutre' dans Prediction.Lower (): prédit_labels.append ('neutre') elif 'négatif' dans Prediction.Lower (): prédit_labels.append («négatif») autre: prédit_labels.append ('inconnu') # Calculez la précision du modèle correct_count = sum ([pred == true for Pred, true in zip (prédit_labels, true_labels)])) précision = correct_count / len (phrases) Imprimer (f'Agiatie: {Précision: .4f} ') # Sortie attendue: 0,7646
En combinant l'expertise des étiquettes du domaine financier de Finbert avec la flexibilité de GPT-4O Mini, ce projet réalise un modèle de sentiment financier haute performance qui dépasse Finbert en précision. Ce guide et cette méthodologie ouvrent la voie à l'analyse des sentiments reproductibles, évolutifs et interprétables, spécifiquement adapté à l'industrie financière.
A. GPT-4O Mini fournit une alternative légère et flexible et peut surpasser Finbert sur des tâches spécifiques avec un réglage fin. En affinant des données spécifiques au domaine, GPT-4O Mini peut capturer des modèles de sentiment nuancées dans les textes financiers tout en étant plus efficace et plus facile à déployer.
Q2. Comment demander l'accès à l'ensemble de données TRC2?A. Pour accéder à l'ensemble de données TRC2, soumettez une demande par le biais de l'Institut national des normes et de la technologie (NIST) sur ce lien. Passez en revue les instructions du site Web pour conclure des accords de licence et d'utilisation, généralement requis pour la recherche et l'utilisation commerciale.
Q3. Puis-je utiliser un ensemble de données différent pour l'analyse des sentiments financiers?A. Vous pouvez également utiliser d'autres ensembles de données comme la phrase financière ou des ensembles de données personnalisés contenant des textes financiers étiquetés. Le jeu de données TRC2 convient particulièrement bien aux modèles de sentiment de formation, car il inclut le contenu des actualités financières et couvre un large éventail de sujets financiers.
Q4. Comment Finbert génère-t-il les étiquettes de sentiment?A. Finbert est un modèle linguistique spécifique au domaine financier qui préfère les données financières et les amendes pour l'analyse des sentiments. Lorsqu'il est appliqué aux phrases TRC2, il classe chaque phrase en un sentiment positif, négatif ou neutre en fonction du contexte linguistique dans les textes financiers.
Q5. Pourquoi devons-nous convertir les étiquettes en minuscules en JSONL?A. La conversion des étiquettes en minuscules garantit une cohérence avec les exigences de réglage d'ouverture d'Openai, qui s'attendent souvent à ce que les étiquettes soient sensibles à la casse. Il aide également à prévenir les décalages pendant l'évaluation et maintient une structure uniforme dans l'ensemble de données JSONL.
Les médias présentés dans cet article ne sont pas détenus par l'analytique vidhya et sont utilisés à la discrétion de l'auteur.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!