Rundstedtz commited on
Commit
ad85bde
β€’
1 Parent(s): 8354dab

Upload first version

Browse files
Files changed (2) hide show
  1. app.py +234 -0
  2. requirements.txt +9 -0
app.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import streamlit as st
2
+ # import pandas as pd
3
+ # import numpy as np
4
+ # import matplotlib.pyplot as plt
5
+
6
+ # # Placeholder for loading models
7
+ # def load_models():
8
+ # # In a real scenario, you would load your pre-trained models here.
9
+ # return {"model_placeholder": "Loaded Model"}
10
+
11
+ # # Placeholder function to classify news as ESG-related
12
+ # def classify_esg(text, models, api_key):
13
+ # # Simulate ESG classification logic
14
+ # # This is where you would use your model to classify the text.
15
+ # return np.random.choice(["Yes", "No"])
16
+
17
+ # # Placeholder function to determine sentiment
18
+ # def determine_sentiment(text, models, api_key):
19
+ # # Simulate sentiment analysis logic
20
+ # # This is where you would use your model to determine the sentiment.
21
+ # return np.random.choice(["Positive", "Neutral", "Negative"])
22
+
23
+ # # Placeholder function to run Alphalens analysis
24
+ # def run_alphalens_analysis(data, models, api_key):
25
+ # # Simulate some metrics
26
+ # metrics = {"alpha": np.random.rand(), "beta": np.random.rand()}
27
+
28
+ # # Generate a simple plot
29
+ # fig, ax = plt.subplots()
30
+ # ax.plot([1, 2, 3], [1, 2, 3], 'r') # Example plot
31
+ # ax.set_title('Example Plot')
32
+
33
+ # return metrics, [fig]
34
+
35
+ # # Streamlit app code
36
+ # models = load_models()
37
+
38
+ # st.title('NLP Project: ESG News Analysis and Financial Impact')
39
+
40
+ # api_key = st.sidebar.text_input("OpenAI API Key", type="password")
41
+
42
+ # uploaded_file = st.file_uploader("Choose a CSV file", type="csv")
43
+ # if uploaded_file is not None:
44
+ # data = pd.read_csv(uploaded_file)
45
+ # st.write("Uploaded News Data:")
46
+ # st.dataframe(data)
47
+
48
+ # if st.button('Classify News as ESG-related'):
49
+ # data['ESG'] = data['news'].apply(lambda x: classify_esg(x, models, api_key))
50
+ # st.write("News with ESG Classification:")
51
+ # st.dataframe(data)
52
+
53
+ # if st.button('Determine Sentiment'):
54
+ # data['Sentiment'] = data['news'].apply(lambda x: determine_sentiment(x, models, api_key))
55
+ # st.write("News with Sentiment Analysis:")
56
+ # st.dataframe(data)
57
+
58
+ # if st.button('Run Alphalens Analysis'):
59
+ # metrics, plots = run_alphalens_analysis(data, models, api_key)
60
+ # st.write("Alphalens Analysis Metrics:")
61
+ # st.json(metrics)
62
+
63
+ # st.write("Alphalens Analysis Plots:")
64
+ # for plot in plots:
65
+ # st.pyplot(plot)
66
+
67
+
68
+ import streamlit as st
69
+ import pandas as pd
70
+ import numpy as np
71
+ import os
72
+ import openai
73
+ import json
74
+ from getpass import getpass
75
+ from tqdm import tqdm
76
+ import matplotlib.pyplot as plt
77
+
78
+ def get_sentiment_gpt(company, SASB, news, max_retries=5, model = 'gpt-4-turbo-2024-04-09'):
79
+ system_prompt = """
80
+ As a specialist in ESG analytics,
81
+ You possess a deep understanding of evaluating environmental, social, and governance factors in the context of corporate news.
82
+ Your expertise lies in discerning the underlying sentiment of news segments that pertain to a company's ESG practices,
83
+ determining whether the coverage reflects a positive, negative, or neutral stance.
84
+ """
85
+
86
+ allowed_sentiments = ['Negative', 'Positive', 'Neutral']
87
+ attempt = 0
88
+
89
+ while attempt < max_retries:
90
+ main_prompt = f"""
91
+ Classify the sentiment (Only options: Positive, Negative, Neutral) of the following news: {news} |
92
+ The sentiment classification should be about the sections of the news talking about the company {company}. |
93
+ The ESG part of the news should be around topics within the following SASB topics {SASB}
94
+
95
+ The output should be a structured JSON object with the key: "sentiment".
96
+
97
+ Here is the format I expect for the JSON object:
98
+
99
+ {{
100
+ "sentiment": "Enter 'Positive', 'Neutral', or 'Negative'",
101
+ }}
102
+
103
+ Do not return any additional text or information outside of this JSON structure.
104
+ """
105
+
106
+ messages = [
107
+ {"role": "system", "content": system_prompt},
108
+ {"role": "user", "content": main_prompt}
109
+ ]
110
+
111
+ response = openai.chat.completions.create(
112
+ model=model,
113
+ messages=messages,
114
+ response_format={"type": "json_object"} # Enable JSON mode
115
+ )
116
+
117
+ response_json = json.loads(response.choices[0].message.content)
118
+ json_sentiment = response_json.get('sentiment')
119
+
120
+ if json_sentiment in allowed_sentiments:
121
+ return json_sentiment
122
+
123
+ attempt += 1
124
+
125
+ # After max retries, if no valid sentiment is found, handle as needed (e.g., return a default sentiment)
126
+ print("Failed to obtain a valid sentiment after maximum retries. Defaulting to 'Neutral'.")
127
+ return 'Neutral' # Default return value if no valid sentiment is obtained
128
+
129
+
130
+ def update_dataset_with_gpt_sentiment(df, model, column_name='GPT_based_sentiment'):
131
+ # Initialize the new column to store GPT-based sentiment
132
+ df['GPT_based_sentiment'] = None
133
+
134
+ # Use tqdm to show a progress bar for the operation
135
+ for index, row in tqdm(df.iterrows(), total=len(df), desc="Processing rows"):
136
+ # Extract necessary information for each row
137
+ company = row['Company'] # Make sure this matches your DataFrame's column name
138
+ SASB = row['SASB'] # Make sure this matches your DataFrame's column name
139
+ news = row['title & content'] # Make sure this matches your DataFrame's column name
140
+
141
+ # Call the function to get the sentiment
142
+ sentiment = get_sentiment_gpt(company, SASB, news, model=model)
143
+
144
+ # Update the DataFrame with the obtained sentiment
145
+ df.at[index, column_name] = sentiment # Now correctly assigns the sentiment
146
+
147
+ return df
148
+
149
+ def app_layout():
150
+ st.set_page_config(page_title="NLP ESG Project", page_icon="πŸ“ˆ")
151
+
152
+ # Custom styles
153
+ st.markdown(
154
+ """
155
+ <style>
156
+ .streamlit-container {
157
+ background-color: #F5F5F5;
158
+ }
159
+ .stButton>button {
160
+ width: 100%;
161
+ border-radius: 10px;
162
+ border: none;
163
+ margin: 10px 0;
164
+ padding: 15px 20px;
165
+ background-color: #79AEC8;
166
+ color: white;
167
+ font-size: 18px;
168
+ }
169
+ .stButton>button:hover {
170
+ background-color: #6699CC;
171
+ }
172
+ </style>
173
+ """,
174
+ unsafe_allow_html=True,
175
+ )
176
+
177
+ # Header section
178
+ st.write("# NLP Project: ESG News Analysis and Financial Impact")
179
+ st.sidebar.write("## Configuration")
180
+
181
+ # API Key input
182
+ openai_api_key = st.sidebar.text_input("Enter your OpenAI API key", type="password")
183
+
184
+ # File Upload
185
+ st.sidebar.write("## Upload Data")
186
+ uploaded_file = st.sidebar.file_uploader("", type="csv")
187
+
188
+ # Investment Strategy Slider
189
+ st.sidebar.markdown("### Investment Strategy")
190
+ investment_strategy = st.sidebar.slider(
191
+ "Investment Strategy",
192
+ min_value=0.0, max_value=1.0, value=0.5, step=0.01,
193
+ format="",
194
+ help="0 is Conservative, 1 is Aggressive",
195
+ label_visibility="collapsed"
196
+ )
197
+ st.sidebar.text(f"Current Strategy: {'Conservative' if investment_strategy <= 0.5 else 'Aggressive'}")
198
+
199
+ # Main container
200
+ if uploaded_file is not None:
201
+ # Displaying the file
202
+ data = pd.read_csv(uploaded_file)
203
+ st.write("### Uploaded News Data:")
204
+ st.dataframe(data, use_container_width=True)
205
+
206
+ if st.button("πŸ” Classify ESG"):
207
+ st.write("Classifying ESG-related news...")
208
+ # Placeholder - replace with actual ESG classification code
209
+ data['ESG'] = "Yes" # placeholder
210
+
211
+ if st.button("😊 Determine Sentiment"):
212
+ st.write("Determining sentiment using GPT...")
213
+ # Run sentiment analysis with GPT
214
+ try:
215
+ with st.spinner("Analyzing sentiment..."):
216
+ # Assume you have your API key set and a function defined to handle sentiment analysis
217
+ updated_data = update_dataset_with_gpt_sentiment(data, model='gpt-4-turbo-2024-04-09')
218
+ st.write("News with GPT-based Sentiment Analysis:")
219
+ st.dataframe(updated_data, use_container_width=True)
220
+ except Exception as e:
221
+ st.error(f"An error occurred: {e}")
222
+
223
+ if st.button("πŸ“Š Alphalens Analysis"):
224
+ st.write("Alphalens analysis will be here") # placeholder
225
+
226
+ # Expander for advanced settings
227
+ with st.expander("Advanced Settings"):
228
+ st.write("Any advanced settings and configurations will go here.")
229
+
230
+ def main():
231
+ app_layout()
232
+
233
+ if __name__ == "__main__":
234
+ main()
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ pandas
3
+ numpy
4
+ os
5
+ openai
6
+ json
7
+ getpass
8
+ tqdm
9
+ matplotlib.pyplot