Warisamm748 commited on
Commit
30aacba
·
verified ·
1 Parent(s): f1ab02b

Create utils.py

Browse files
Files changed (1) hide show
  1. utils.py +191 -0
utils.py ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Importing libraries
2
+ from bs4 import BeautifulSoup
3
+ import requests
4
+ from langchain.schema import HumanMessage
5
+ from langchain_groq import ChatGroq
6
+ import json
7
+ from dotenv import load_dotenv
8
+ import os
9
+ from transformers import pipeline
10
+
11
+ # Load environment variables
12
+ load_dotenv()
13
+ GROQ_API_KEY = os.getenv('GROQ_API_KEY')
14
+
15
+ # Initialize the LLM model
16
+ llm = ChatGroq(api_key=GROQ_API_KEY, model="llama-3.1-8b-instant")
17
+
18
+ # Function to extract news titles and summaries from Economic Times
19
+ def extract_titles_and_summaries(company_name, num_articles=10):
20
+ url = f"https://economictimes.indiatimes.com/topic/{company_name}/news"
21
+ try:
22
+ response = requests.get(url)
23
+ if response.status_code != 200:
24
+ print(f"Failed to fetch the webpage. Status code: {response.status_code}")
25
+ return []
26
+
27
+ soup = BeautifulSoup(response.content, "html.parser")
28
+ articles = soup.find_all('div', class_='clr flt topicstry story_list', limit=num_articles)
29
+ extracted_articles = []
30
+
31
+ for article in articles:
32
+ title_tag = article.find('h2')
33
+ if title_tag:
34
+ link_tag = title_tag.find('a')
35
+ title = link_tag.get_text(strip=True) if link_tag else "No Title Found"
36
+ else:
37
+ title = "No Title Found"
38
+
39
+ summary_tag = article.find('p')
40
+ summary = summary_tag.get_text(strip=True) if summary_tag else "No Summary Found"
41
+
42
+ extracted_articles.append({
43
+ "Title": title,
44
+ "Summary": summary
45
+ })
46
+
47
+ return {
48
+ "Company": company_name,
49
+ "Articles": extracted_articles
50
+ }
51
+ except Exception as e:
52
+ print(f"An error occurred: {e}")
53
+ return []
54
+
55
+ # Function to perform sentiment analysis on extracted news articles
56
+ def perform_sentiment_analysis(news_data):
57
+ from transformers import pipeline
58
+ articles = news_data.get("Articles", [])
59
+ pipe = pipeline("text-classification", model="tabularisai/multilingual-sentiment-analysis", device=1)
60
+ sentiment_counts = {"Positive": 0, "Negative": 0, "Neutral": 0}
61
+
62
+ for article in articles:
63
+ content = f"{article['Title']} {article['Summary']}"
64
+ sentiment_result = pipe(content)[0]
65
+
66
+ sentiment_map = {
67
+ "positive": "Positive",
68
+ "negative": "Negative",
69
+ "neutral": "Neutral",
70
+ "very positive": "Positive",
71
+ "very negative": "Negative"
72
+ }
73
+
74
+ sentiment = sentiment_map.get(sentiment_result["label"].lower(), "Unknown")
75
+ score = float(sentiment_result["score"])
76
+
77
+ article["Sentiment"] = sentiment
78
+ article["Score"] = score
79
+
80
+ if sentiment in sentiment_counts:
81
+ sentiment_counts[sentiment] += 1
82
+
83
+ return news_data, sentiment_counts
84
+
85
+ # Function to extract topics from articles using Hugging Face model
86
+ def extract_topics_with_hf(news_data):
87
+ structured_data = {
88
+ "Company": news_data.get("Company", "Unknown"),
89
+ "Articles": []
90
+ }
91
+ topic_pipe = pipeline("text-classification", model="valurank/distilroberta-topic-classification", device=1)
92
+ articles = news_data.get("Articles", [])
93
+
94
+ for article in articles:
95
+ content = f"{article['Title']} {article['Summary']}"
96
+ topics_result = topic_pipe(content, top_k=3)
97
+ topics = [topic["label"] for topic in topics_result] if topics_result else ["Unknown"]
98
+
99
+ structured_data["Articles"].append({
100
+ "Title": article["Title"],
101
+ "Summary": article["Summary"],
102
+ "Sentiment": article.get("Sentiment", "Unknown"),
103
+ "Score": article.get("Score", 0.0),
104
+ "Topics": topics
105
+ })
106
+ return structured_data
107
+
108
+ # Function to generate a final sentiment summary using LLM
109
+ def generate_final_sentiment(news_data, sentiment_counts):
110
+ company_name = news_data["Company"]
111
+ total_articles = sum(sentiment_counts.values())
112
+ combined_summaries = " ".join([article["Summary"] for article in news_data["Articles"]])
113
+
114
+ prompt = f"""
115
+ Based on the analysis of {total_articles} articles about the company "{company_name}":
116
+ - Positive articles: {sentiment_counts['Positive']}
117
+ - Negative articles: {sentiment_counts['Negative']}
118
+ - Neutral articles: {sentiment_counts['Neutral']}
119
+ The following are the summarized key points from the articles: "{combined_summaries}".
120
+ Provide a single, concise summary that integrates the overall sentiment analysis and key news highlights while maintaining a natural flow. Explain its implications for the company's reputation, stock potential, and public perception.
121
+ Respond **ONLY** with a well-structured very concise and short paragraph in plain text, focusing on overall sentiment.
122
+ """
123
+
124
+ response = llm.invoke([HumanMessage(content=prompt)], max_tokens=200)
125
+ final_sentiment = response if response else "Sentiment analysis summary not available."
126
+ return final_sentiment.content # returns a string
127
+
128
+ # Function to extract JSON response from LLM output
129
+ def extract_json(response):
130
+ try:
131
+ return json.loads(response)
132
+ except json.JSONDecodeError:
133
+ return {}
134
+
135
+ # Function to compare articles based on common topics and sentiment variations
136
+ def compare_articles(news_data, sentiment_counts):
137
+ articles = news_data.get("Articles", [])
138
+ all_topics = [set(article["Topics"]) for article in articles]
139
+ common_topics = set.intersection(*all_topics) if all_topics else set()
140
+
141
+ topics_prompt = f"""
142
+ Analyze the following article topics and identify **only three** key themes that are common across multiple articles,
143
+ even if they are phrased differently. The topics from each article are:
144
+ {all_topics}
145
+ Respond **ONLY** with a JSON format:
146
+ {{"CommonTopics": ["topic1", "topic2", "topic3"]}}
147
+ """
148
+
149
+ response = llm.invoke([HumanMessage(content=topics_prompt)]).content
150
+ contextual_common_topics = extract_json(response).get("CommonTopics", list(common_topics))[:3] # Limit to 3 topics
151
+
152
+ total_articles = sum(sentiment_counts.values())
153
+
154
+ comparison_prompt = f"""
155
+ Provide a high-level summary comparing {total_articles} news articles about "{news_data['Company']}":
156
+ - Sentiment distribution: {sentiment_counts}
157
+ - Commonly discussed topics across articles: {contextual_common_topics}
158
+ Consider the following:
159
+ 1. Notable contrasts between articles (e.g., major differences in topics and perspectives).
160
+ 2. Overall implications for the company's reputation, stock potential, and public perception.
161
+ 3. How sentiment varies across articles and its impact.
162
+ Respond **ONLY** with a concise and insightful summary in this JSON format:
163
+ {{
164
+ "Coverage Differences": [
165
+ {{"Comparison": "Brief contrast between Articles 1 & 2", "Impact": "Concise impact statement"}},
166
+ {{"Comparison": "Brief contrast between Articles 3 & 4", "Impact": "Concise impact statement"}}
167
+ ]
168
+ }}
169
+ """
170
+
171
+ response = llm.invoke([HumanMessage(content=comparison_prompt)]).content
172
+ coverage_differences = extract_json(response).get("Coverage Differences", [])
173
+
174
+ final_sentiment = generate_final_sentiment(news_data, sentiment_counts)
175
+
176
+ return {
177
+ "Company": news_data["Company"],
178
+ "Articles": articles,
179
+ "Comparative Sentiment Score": {
180
+ "Sentiment Distribution": sentiment_counts,
181
+ "Coverage Differences": coverage_differences,
182
+ "Topic Overlap": {
183
+ "Common Topics": contextual_common_topics,
184
+ "Unique Topics": {
185
+ f"Article {i+1}": list(topics - set(contextual_common_topics))
186
+ for i, topics in enumerate(all_topics)
187
+ }
188
+ }
189
+ },
190
+ "Final Sentiment Analysis": final_sentiment
191
+ }