From 76aacadcc980b336c7030ade7ebf778194330c13 Mon Sep 17 00:00:00 2001 From: KeerthiGadiparthy Date: Sat, 3 Jan 2026 12:07:58 +0530 Subject: [PATCH 1/2] Initialize README with project details and methodology Added project overview, dataset details, tech stack, methodology, models used, and evaluation results. --- README.md | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..fd3260c3 --- /dev/null +++ b/README.md @@ -0,0 +1,80 @@ +# 📊 Financial News Sentiment Classifier + + Problem Statement +The objective of this project is to classify financial news headlines or sentences into +**Positive**, **Negative**, or **Neutral** sentiment to understand market context. + +Financial sentiment analysis plays an important role in: +- Stock market analysis +- Risk assessment +- Investment decision support systems + + + + Dataset +- **Dataset Name:** Sentiment Analysis for Financial News +- **Source:** Kaggle +- **Link:** https://www.kaggle.com/datasets/ankurzing/sentiment-analysis-for-financial-news + + Dataset Description +The dataset contains short financial news sentences manually labeled into three sentiment categories: +- Positive +- Negative +- Neutral + +--- + +🧰 Tech Stack +- **Programming Language:** Python +- **Libraries & Tools:** + - Pandas, NumPy + - Scikit-learn + - HuggingFace Transformers (FinBERT – optional) + - Matplotlib / Seaborn + - LangChain (for evaluation prompts) +- **Development Environment:** Google Colab + +--- + + Methodology + + 1️⃣ Data Preprocessing +- Loaded and explored the dataset +- Analyzed sentiment class distribution +- Split data into training and testing sets (80:20) + + 2️⃣ Baseline Classical Model +- Applied **TF-IDF vectorization** for text representation +- Trained a **Logistic Regression** classifier +- Evaluated performance using accuracy, precision, recall, and F1-score + + 3️⃣ LLM Zero-Shot Sentiment Classification +- Used a pretrained **FinBERT** model from HuggingFace +- Performed zero-shot sentiment classification without fine-tuning +- Compared predictions with the classical model + +--- + + 🤖 Models Used + +| Model Type | Description | +|-----------|------------| +| Classical ML | TF-IDF + Logistic Regression | +| LLM | FinBERT (Zero-Shot Transformer Model) | + +--- + + Evaluation & Results + +- Generated **classification report** +- Visualized **confusion matrix** for sentiment classes +- Compared classical ML model with LLM zero-shot predictions + +Key Observations: +- Classical ML model performed strongly on structured financial text +- LLM struggled slightly with **neutral sentiment detection** +- Neutral and short headlines caused most misclassifications + +--- + + From 67b4f706ea3b083ca35ba4a86da50c7024e68f51 Mon Sep 17 00:00:00 2001 From: abhinayareddy14 <221fa04714@gmail.com> Date: Sat, 3 Jan 2026 07:38:34 +0000 Subject: [PATCH 2/2] Added dataset documentation and text preprocessing pipeline --- src/preprocess.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/preprocess.py diff --git a/src/preprocess.py b/src/preprocess.py new file mode 100644 index 00000000..c647ded4 --- /dev/null +++ b/src/preprocess.py @@ -0,0 +1,49 @@ +import re +import pandas as pd +from sklearn.model_selection import train_test_split +import nltk +from nltk.corpus import stopwords + +# Download stopwords if not already present +try: + stopwords.words("english") +except LookupError: + nltk.download("stopwords") +stop_words = set(stopwords.words("english")) + +def clean_text(text): + text = text.lower() + text = re.sub(r"[^a-zA-Z\s]", "", text) + text = text.split() + text = [word for word in text if word not in stop_words] + return " ".join(text) + +def load_and_preprocess(csv_path): + df = pd.read_csv(csv_path, encoding="latin-1") + df.columns = ["sentiment", "sentence"] + + # Apply cleaning steps from notebook + df = df.drop_duplicates(subset="sentence") + df = df.dropna() + + # Apply label mapping from notebook + label_mapping = { + "negative": 0, + "neutral": 1, + "positive": 2 + } + df["label"] = df["sentiment"].map(label_mapping) + + # Apply clean_text + df["clean_sentence"] = df["sentence"].apply(clean_text) + + # Use the cleaned sentence and mapped label for splitting + X_train, X_test, y_train, y_test = train_test_split( + df["clean_sentence"], + df["label"], + test_size=0.2, + random_state=42, + stratify=df["label"] + ) + + return X_train, X_test, y_train, y_test