Epik / app.py
jh000107
adding GPT part
ff0c789
raw
history blame
13.2 kB
import os
import openai
from openai import OpenAI
from dotenv import load_dotenv, find_dotenv
%matplotlib inline
import re
import matplotlib.pyplot as plt
sample_input = \
"""
Visitor: Heyyy
Visitor: How are you this evening
Agent: better now ;) call me
Visitor: I am at work for now, be off around 10pm
Visitor: Need some company
Visitor: Are you independent honey
Agent: well since you arent available at the moment ill just come out and say-these sites are bad news. \
did you know that most of the girls on here are here against their will? \
Most of them got dragged into this lifestyle by an abuser, \
oftentimes before they were of legal consenting age. isnt that sad?
Agent: we are with some guys who are trying to spread awareness of the realities of this "industry".
Agent: https://exoduscry.com/choice/
Visitor: Thanks
Agent: i encourage you to watch this video. it is jarring to think about how bad someone else's options must be to choose to be on these sites
Visitor: Ooohhh
Agent: selling their body to make ends meet or appease a pimp
Visitor: That's really awful
Agent: it is. you seem like the kind of guy who wouldnt wont to proliferate that kind of harmful lifestyle. am i right in thinking that?
Visitor: Well iam just looking for attention
Visitor: My marriage is not going well lol
Agent: i know that it is hard to find ourselves lonely and without much alternative to meet that perceived need but \
its humbling to think that our needs can force someone else into such a dark place
Agent: hey, thanks for sharing that my man. i know it can be hard
Agent: marraige is the most humbling of relationships, isnt it?
Visitor: She leaves with her friends n no time for me
Agent: ive been there my guy. i know that it is alot easier to numb that loneliness for sure
Visitor: I want to be faithful
Agent: does your wife know how you feel when she chooses her friends instead of you?
Visitor: I been drinking lately
Visitor: Yes, she takes pills
Agent: if so, i hope you are praying for her to realize the hurt she is causing and to seek change
Visitor: She had surgery 4 yes ago n it's been hard for her n her addiction on pills
Visitor: Yes for now i am looking for a female friend to talk n see what can we do for each other
Agent: that is hard my man. physical pain is a huge obstacle in life for sure so i hear you
Visitor: Well chat later. thanks
Agent: have you considered pursuing other men who can encourage you instead of looking for the easy way out?
Agent: what is your name my friend? i will be praying for you by name if you wouldnt mind sharing it
Agent: well, i gotta run. watch that video i sent and i will definitely be praying for you. \
I hope you pray for yourself and for your wife - God can definitely intervene and cause complete change in the situation if He wills it. \
He is good and He hears you. You are loved by Him, brother. Good night
"""
sample_output = \
"""
Visitor: Heyyy
[Greeting]
Visitor: How are you this evening
[Greeting]
Agent: better now ;) call me
[Openness]
Visitor: I am at work for now, be off around 10pm
[Interest]
Visitor: Need some company
[Interest]
Visitor: Are you independent honey
[Interest]
Agent: well since you arent available at the moment ill just come out and say-these sites are bad news. \
did you know that most of the girls on here are here against their will? \
Most of them got dragged into this lifestyle by an abuser, \
oftentimes before they were of legal consenting age. isnt that sad?
[Informative]
Agent: we are with some guys who are trying to spread awareness of the realities of this "industry".
[Informative]
Agent: https://exoduscry.com/choice/
[Informative]
Visitor: Thanks
[Acceptance]
Agent: i encourage you to watch this video. it is jarring to think about how bad someone else's options must be to choose to be on these sites
[Informative]
Visitor: Ooohhh
[Interest]
Agent: selling their body to make ends meet or appease a pimp
[Informative]
Visitor: That's really awful
[Remorse]
Agent: it is. you seem like the kind of guy who wouldnt wont to proliferate that kind of harmful lifestyle. am i right in thinking that?
[Accusatory]
Visitor: Well iam just looking for attention
[Anxious]
Visitor: My marriage is not going well lol
[Anxious]
Agent: i know that it is hard to find ourselves lonely and without much alternative to meet that perceived need but \
its humbling to think that our needs can force someone else into such a dark place
[Informative]
Agent: hey, thanks for sharing that my man. i know it can be hard
[Acceptance]
Agent: marraige is the most humbling of relationships, isnt it?
[Openness]
Visitor: She leaves with her friends n no time for me
[Annoyed]
Agent: ive been there my guy. i know that it is alot easier to numb that loneliness for sure
[Acceptance]
Visitor: I want to be faithful
[Acceptance]
Agent: does your wife know how you feel when she chooses her friends instead of you?
[Curiosity]
Visitor: I been drinking lately
[Anxious]
Visitor: Yes, she takes pills
[Anxious]
Agent: if so, i hope you are praying for her to realize the hurt she is causing and to seek change
[Interest]
Visitor: She had surgery 4 yes ago n it's been hard for her n her addiction on pills
[Anxious]
Visitor: Yes for now i am looking for a female friend to talk n see what can we do for each other
[Informative]
Agent: that is hard my man. physical pain is a huge obstacle in life for sure so i hear you
[Acceptance]
Visitor: Well chat later. thanks
[Openness]
Agent: have you considered pursuing other men who can encourage you instead of looking for the easy way out?
[Informative]
Agent: what is your name my friend? i will be praying for you by name if you wouldnt mind sharing it
[Openness]
Agent: well, i gotta run. watch that video i sent and i will definitely be praying for you. \
I hope you pray for yourself and for your wife - God can definitely intervene and cause complete change in the situation if He wills it. \
He is good and He hears you. You are loved by Him, brother. Good night
[Openness]
Sentiment Flow Analysis on the Visitor's side:
The Visitor begins the conversation with a friendly and casual tone, expressing a desire for company and showing interest in the Agent. \
However, as the Agent provides information about the harsh realities of the commercial sex industry, the Visitor's sentiment shifts to acceptance of the information \
and a sense of confusion and remorse about the situation.
The Visitor then reveals personal issues, indicating anxiety and seeking attention due to marital problems. \
The sentiment continues to be anxious as the Visitor discusses personal struggles with alcohol and his wife's pill addiction, \
showing a need for companionship and support.
Despite the heavy topics, the Visitor expresses a desire to remain faithful and shows interest in finding a friend, albeit with a hint of desperation. \
The Visitor openly takes the Agent's information and the conversation flows smoothly as both the Visitor and the Agent \
show openness toward each other.
"""
def get_completion(conversation, model="gpt-4-1106-preview"):
prompt = f"""
The EPIK Project is about mobilizing male allies \
to disrupt the commercial sex market, \
equipping them to combat the roots of exploitation \
and encouraging them to collaborate effectively \
with the wider anti-trafficking movement. \
You are an adept expert conversation sentiment analyzer. \
Your job is to analyze the conversation and provide a report \
based on the sentiment flow of the conversation on the visitor's \
perspective. Visitor indicates the potential buyer, and Agent indicates the volunteer from EPIK. \
The conversation is going to be given in the format:
Visitor: <Visitor's message here>
Agent: <Agent's message here>
The actual conversation is delimited by triple backticks
```{conversation}```
Here is the list of sentiment labels you should use delimited by square brackets. \
["Openness", "Anxious", "Confused", "Disapproval", "Remorse", "Accusatory", \
"Denial", "Obscene", "Uninterested", "Annoyed", "Informative", "Greeting", \
"Interest", "Curiosity", "Acceptance"]
Your output should look like:
```
Speaker: <Speaker's message here>
[sentiment label]
...
Speaker: <Speaker's message here>
[sentiment label]
```
where Speaker can either be Visitor or Agent. Then, you should write your report on the sentiment flow \
on the Visitor's side below.
Here is a sample input delimited by triple backticks
```{sample_input}```
Here is a same output that you should try to aim for delimited by sqaure brackets
[{sample_output}]
"""
client = OpenAI()
messages = [{"role": "user", "content": prompt}]
response = client.chat.completions.create(
model=model,
messages=messages,
temperature=0, # this is the degree of randomness of the model's output
)
analysis = response.choices[0].message.content
def extract_conv_with_labels(analysis):
analysis = analysis.replace("\n", " ")
BETWEEN_BACKTICKS = "\\`\\`\\`(.*?)\\`\\`\\`"
match = re.search(BETWEEN_BACKTICKS, analysis)
if match:
conv_with_labels = match.group()[4:-4]
else:
return "OUTPUT IS IN WRONG FORMAT"
# just reformatting it for better format
conv_with_labels = conv_with_labels.split('] ')
temp = [utterance + ']' for utterance in conv_with_labels[:-1]]
conv_with_labels = temp + [conv_with_labels[-1]]
return conv_with_labels
grouped_sentiments = {
'Acceptance': 3,
'Openness': 3,
'Interest': 2,
'Curiosity': 2,
'Informative': 1,
'Greeting': 0,
'None': 0,
'Uninterested': -1,
'Anxious': -2,
'Confused': -2,
'Annoyed': -2,
'Remorse': -2,
'Disapproval': -3,
'Accusatory': -3,
'Denial': -3,
'Obscene': -3
}
def sentiment_flow_plot(conv):
conv_with_labels = extract_conv_with_labels(analysis)
num_utterances = len(conv_with_labels)
visitor_Y = [''] * num_utterances
agent_Y = [''] * num_utterances
for i in range(num_utterances):
utterance = conv_with_labels[i]
match = re.search(r'\[(.*?)\]$', utterance)
if match:
label = match.group(1)
else:
print("OUTPUT IS IN WRONG FORMAT")
break
if utterance.startswith('Visitor'):
visitor_Y[i] = label
if i == 0:
agent_Y[i] = 'None'
else:
agent_Y[i] = agent_Y[i-1]
elif utterance.startswith('Agent'):
agent_Y[i] = label
if i == 0:
visitor_Y[i] = 'None'
else:
visitor_Y[i] = visitor_Y[i-1]
X = range(1,num_utterances+1)
visitor_Y_converted = [grouped_sentiments[visitor_Y[i]] for i in range(num_utterances)]
agent_Y_converted = [grouped_sentiments[agent_Y[i]] for i in range(num_utterances)]
plt.style.use('seaborn')
fig, ax = plt.subplots()
ax.plot(X, visitor_Y_converted, label='Visitor', color='blue', marker='o')
ax.plot(X, agent_Y_converted, label='Agent', color='green', marker='o')
plt.yticks(ticks=[-3,-2,-1,0,1,2,3],
labels=['Disapproval/Accusatory/Denial/Obscene', 'Anxious/Confused/Annoyed/Remorse',
'Uninterested', 'Greeting/None', 'Informative', 'Interest/Curiosity', 'Acceptance/Openness'])
for label in ax.get_yticklabels():
label.set_rotation(45)
plt.xlabel('Number of utterances')
plt.ylabel('Sentiments')
plt.title('Sentiment Flow Plot')
plt.close(fig)
return fig
fig = sentiment_flow_plot(analysis)
return response.choices[0].message.content, fig
def set_key(key):
with open("_.env", "w") as file:
file.write(f"OPENAI_API_KEY={key}")
load_dotenv(find_dotenv("_.env"), override=True)
return
import gradio as gr
with gr.Blocks() as gpt_analysis:
gr.Markdown("## Conversation Analysis")
gr.Markdown(
"This is a custom GPT model designed to provide \
a report on overall sentiment flow of the conversation on the \
volunteer's perspective.<br /> Click on them and submit them to the model to see how it works.")
api_key = gr.Textbox(label="Key", lines=1)
btn_key = gr.Button(value="Submit Key")
btn_key.click(set_key, inputs=api_key)
conversation = gr.Textbox(label="Input", lines=2)
btn = gr.Button(value="Submit")
with gr.Row():
output_box = gr.Textbox(value="", label="Output",lines=4)
plot_box = gr.Plot(label="Analysis Plot")
btn.click(get_completion, inputs=conversation, outputs=[output_box, plot_box])
gr.TabbedInterface([gpt_analysis], ["GPT Anlysis"]).launch(inline=False)