forked from lachlanpage/Markov-Chain-Sentence-Generator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsentiment_utilities.py
206 lines (143 loc) · 7.37 KB
/
sentiment_utilities.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
from textblob import TextBlob
from text_utilities import TextGenerator
from colorama import Fore, Style
from config import Config
from graph_utilities import display_polarity_graph, display_subjectivity_graph
def analyze_sentiment_of_file(training_corpus_filename):
"""
Analyzes the sentiment of the given text using TextBlob and returns a sentiment polarity score.
Args:
training_corpus_filename (str): The input text to analyze for sentiment.
Returns:
float: The sentiment polarity score, which ranges from -1.0 (most negative) to 1.0 (most positive).
Raises:
Exception: Any exceptions raised during TextBlob analysis will propagate.
"""
if Config.VERBOSE:
print(f"{Fore.GREEN}[+] Analyzing sentiment of {training_corpus_filename}{Style.RESET_ALL}")
# Convert the corpus text to a string and pass it to TextBlob
corpus_string = TextGenerator.return_corpus_text(training_corpus_filename)
average_polarity = print_sentiment_analysis_results(corpus_string, training_corpus_filename)
return average_polarity
def print_sentiment_analysis_results(corpus_string, training_corpus_filename=None):
# This will print the sentiment of the input string and display the sentiment score graphically.
# The training corpus filename is optional and will be used to print the sentiment of the input string.
average_polarity, average_subjectivity = analyze_sentiment_by_sentence(corpus_string)
# Gather mnemonic sentiment phrases for polarity and subjectivity
polarity_phrase = interpret_sentiment_polarity(average_polarity)
subjectivity_phrase = interpret_sentiment_subjectivity(average_subjectivity)
print("[" + Fore.YELLOW + "SENTIMENT ANALYSIS" + Style.RESET_ALL + "]")
if training_corpus_filename is not None:
print(f" The training corpus {Fore.LIGHTGREEN_EX}{training_corpus_filename}{Style.RESET_ALL}"
f" is {polarity_phrase} and {subjectivity_phrase}.\n"
f" Sentiment Polarity: {Fore.LIGHTBLUE_EX}{average_polarity:>10.4f}{Style.RESET_ALL}", end=" ")
elif training_corpus_filename is None:
print(f" The output text is {polarity_phrase} and {subjectivity_phrase}.\n"
f" Sentiment Polarity: {Fore.LIGHTBLUE_EX}{average_polarity:>10.4f}{Style.RESET_ALL}", end=" ")
display_polarity_graph(average_polarity)
print(f" Sentiment Subjectivity: {Fore.LIGHTBLUE_EX}{average_subjectivity:.4f}{Style.RESET_ALL}", end=" ")
display_subjectivity_graph(average_subjectivity)
return average_polarity
def analyze_sentiment_of_string(text_string):
"""
**This function is optimized for analyzing shorter strings.**
Analyze the overall sentiment of a text string and display the sentiment score.
The function uses the TextBlob library to analyze the sentiment polarity
of a text string. It then interprets the sentiment, prints the sentiment and its
polarity score, and displays the sentiment score graphically.
Parameters:
text_string (str): The text string to analyze.
Returns:
float: The sentiment polarity of the text string.
"""
# Instantiate TextBlob and analyze sentiment
analysis = TextBlob(text_string)
# Return the polarity score of the analyzed the corpus text string
sentiment_polarity: float = analysis.sentiment.polarity
# Interpret the sentiment based on the polarity score
sentiment = interpret_sentiment_polarity(sentiment_polarity)
# Print the sentiment and its polarity score
print(f"Sentiment: {sentiment} (Polarity Score: {sentiment_polarity})")
# TODO: Distinguish between sentiment of corpus and output text
# Display the sentiment score graphically
display_polarity_graph(sentiment_polarity)
return sentiment_polarity
def analyze_sentiment_by_sentence(corpus_as_string):
"""
**This function is optimized for analyzing longer strings.**
Analyze the sentiment of each sentence in a text and return the average sentiment.
The function uses the TextBlob library to split the text into sentences, analyze the sentiment polarity
of each sentence, and then average the sentiment polarity scores for the whole text.
Parameters:
corpus_as_string (str): The text to analyze.
Returns:
float: The average sentiment polarity of the sentences in the text.
"""
# Create a TextBlob object for the given text
analysis = TextBlob(corpus_as_string)
# Split the text into sentences
sentences = analysis.sentences
# Initialize variables to keep track of total sentiment polarity and subjectivity
total_sentiment_polarity = 0
total_subjectivity = 0
# Loop through each sentence in the text
for i, sentence in enumerate(sentences):
# Get the sentiment polarity of the sentence
sentiment_polarity = sentence.sentiment.polarity
# Add the sentiment polarity of the sentence to the total sentiment polarity
total_sentiment_polarity += sentiment_polarity
# Get the subjectivity of the sentence
subjectivity = sentence.sentiment.subjectivity
# Add the subjectivity of the sentence to the total subjectivity
total_subjectivity += subjectivity
# Calculate the average sentiment polarity
average_sentiment_polarity = total_sentiment_polarity / len(sentences)
# Calculate the average subjectivity
average_subjectivity = total_subjectivity / len(sentences)
return average_sentiment_polarity, average_subjectivity
def interpret_sentiment_polarity(sentiment_polarity):
"""
Interpret the sentiment based on the polarity score.
Polarity typically ranges from -1 (very negative) to +1 (very positive),
with 0 being neutral. This function adds granularity by distinguishing
somewhat positive and somewhat negative values.
Parameters:
sentiment_polarity (float): A sentiment polarity score from -1 to 1.
Returns:
str: The interpreted sentiment which can be 'Positive', 'Somewhat Positive',
'Neutral', 'Somewhat Negative', or 'Negative'.
"""
if sentiment_polarity > 0.5:
sentiment = "positive"
elif 0 < sentiment_polarity <= 0.5:
sentiment = "somewhat positive"
elif 0 > sentiment_polarity >= -0.5:
sentiment = "somewhat negative"
elif sentiment_polarity < -0.5:
sentiment = "negative"
else:
sentiment = "emotionally neutral"
return sentiment
def interpret_sentiment_subjectivity(sentiment_subjectivity):
"""
Interpret the sentiment based on the subjectivity score.
Subjectivity typically ranges from 0 (very objective) to 1 (very subjective).
This function adds granularity by distinguishing somewhat subjective and somewhat
objective values.
Parameters:
sentiment_subjectivity (float): A sentiment subjectivity score from 0 to 1.
Returns:
str: The interpreted sentiment which can be 'Subjective', 'Somewhat Subjective',
'Neutral', 'Somewhat Objective', or 'Objective'.
"""
if sentiment_subjectivity > 0.7:
sentiment = "subjective"
elif 0.5 < sentiment_subjectivity <= 0.7:
sentiment = "somewhat subjective"
elif 0.3 < sentiment_subjectivity <= 0.5:
sentiment = "has balanced subjectivity"
elif 0 < sentiment_subjectivity <= 0.3:
sentiment = "somewhat objective"
else:
sentiment = "objective"
return sentiment