L00171275 commited on
Commit
4435743
·
1 Parent(s): ea1f00c

hf application

Browse files
Files changed (5) hide show
  1. .gradio/certificate.pem +31 -0
  2. Procfile.txt +1 -0
  3. Yelp3k.json +0 -0
  4. app.py +203 -0
  5. requirements.txt +218 -0
.gradio/certificate.pem ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ -----END CERTIFICATE-----
Procfile.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ web: python app.py
Yelp3k.json ADDED
The diff for this file is too large to render. See raw diff
 
app.py ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import json
3
+ import re
4
+ import html
5
+ import os
6
+ import pandas as pd
7
+ import re
8
+
9
+ #models
10
+ from transformers import AutoTokenizer, AutoModelForTokenClassification,AutoModelForSequenceClassification, pipeline
11
+ import torch
12
+
13
+ aspdevice = "cpu"
14
+ # Your aspect extraction logic
15
+ model_id_ate = "gauneg/roberta-base-absa-ate-sentiment"
16
+ tokenizer_ate = AutoTokenizer.from_pretrained(model_id_ate)
17
+ model_ate = AutoModelForTokenClassification.from_pretrained(model_id_ate)
18
+ senti_pipeline = pipeline(task='ner', model=model_ate, tokenizer=tokenizer_ate, device=aspdevice, aggregation_strategy='simple')
19
+
20
+ # Your emotion detection logic
21
+ emodevice = "mps" if torch.backends.mps.is_available() else 0 if torch.cuda.is_available() else -1
22
+ emotion_model = "j-hartmann/emotion-english-distilroberta-base"
23
+ emo_tokenizer = AutoTokenizer.from_pretrained(emotion_model)
24
+ emo_model = AutoModelForSequenceClassification.from_pretrained(emotion_model)
25
+ classifier = pipeline("text-classification", model=emo_model,tokenizer=emo_tokenizer, top_k=None, device=emodevice)
26
+
27
+ def extract_full_word(text, start, end):
28
+ word_start = start
29
+ while word_start > 0 and re.match(r'\w', text[word_start - 1]):
30
+ word_start -= 1
31
+ word_end = end
32
+ while word_end < len(text) and re.match(r'\w', text[word_end]):
33
+ word_end += 1
34
+ return text[word_start:word_end].strip()
35
+
36
+ def extract_full_analysis(review):
37
+ sentences = [rev.strip() for rev in review.split(".") if rev.strip()]
38
+ #aspect predictions
39
+ asppredictions = senti_pipeline(review)
40
+ #emotion predictions
41
+ emopredictions = classifier(sentences)
42
+ #Extract aspects
43
+ aspect_word = [
44
+ {"word": d["word"].strip(), "start": d["start"], "end": d["end"]}
45
+ for d in asppredictions
46
+ ]
47
+ # Extract sentiment term
48
+ sentiments = [d["entity_group"] for d in asppredictions]
49
+ scores = [f"{d['score']:.4f}" for d in asppredictions]
50
+ refined_aspects = []
51
+ for aspect in aspect_word:
52
+ full_word = extract_full_word(review, aspect["start"], aspect["end"])
53
+ if len(full_word) >= 3:
54
+ refined_aspects.append(full_word)
55
+ refined_aspects = list(dict.fromkeys(refined_aspects))
56
+
57
+ flat_preds = [d for sentence_preds in emopredictions for d in sentence_preds if d["score"] >= 0.1]
58
+ emotions = [d["label"] for d in flat_preds]
59
+ emotion_score = [d["score"] for d in flat_preds]
60
+ dynamic_result ={
61
+ "review": review,
62
+ "aspect_words": refined_aspects,
63
+ "sentiment": sentiments,
64
+ "score": scores,
65
+ "emotions": emotions,
66
+ "emo-score": emotion_score
67
+ }
68
+ return dynamic_result
69
+
70
+ with open('yelp3k.json', 'r', encoding='utf-8') as fp:
71
+ static_reviews = json.load(fp)
72
+ def highlight_aspects(text, aspects):
73
+ aspects_sorted = sorted(aspects, key=len, reverse=True)
74
+ aspects_regex = [re.escape(asp) for asp in aspects_sorted]
75
+ pattern = r'\b(?:' + '|'.join(aspects_regex) + r')\b'
76
+ def replace_match(match):
77
+ return f'<span style="font-weight: bold; background-color: yellow;">{match.group()}</span>'
78
+ return re.sub(pattern, replace_match, text, flags=re.IGNORECASE)
79
+
80
+ def format_review(review):
81
+ text = review[0]['review']
82
+ aspects = review[0]['aspect_words']
83
+
84
+ highlighted_text = highlight_aspects(text, aspects)
85
+ aspects = [asp.strip() for asp in review[0]['aspect_words']]
86
+ emotions = [emo.strip() for emo in review[0]['emotions']]
87
+ sentiments = [senti for senti in review[0]['sentiment']]
88
+ sentimentScores = [scor for scor in review[0]['score']]
89
+ emotionScores = [emscor for emscor in review[0]['emo-score']]
90
+
91
+ aspects_html = '<div class="cell-grid">' + "".join(f'<div class="cell-item">{html.escape(asp)}</div>' for asp in aspects) + '</div>'
92
+ emotions_html = '<div class="cell-grid">' + "".join(f'<div class="cell-item">{html.escape(emo)}</div>' for emo in emotions) + '</div>'
93
+ sentiments_html = '<div class="cell-grid">' + "".join(f'<div class="cell-item">{html.escape(senti)}</div>' for senti in sentiments) + '</div>'
94
+ sentiScor_html = '<div class="cell-grid">' + "".join(f'<div class="cell-item">{sentiscor}</div>' for sentiscor in sentimentScores) + '</div>'
95
+ emoScor_html = '<div class="cell-grid">' + "".join(f'<div class="cell-item">{emoscor}</div>' for emoscor in emotionScores) + '</div>'
96
+ return f"""
97
+ <div style="border: 1px solid #ccc; padding: 10px; margin-bottom: 10px;">
98
+ <h4>Review</h4>
99
+ <p>{highlighted_text}</p>
100
+ <h3>Aspect Words</h3>
101
+ {aspects_html}
102
+ <h3>Sentiments</h3>
103
+ {sentiments_html}
104
+ <h3>Sentiments Score</h3>
105
+ {sentiScor_html}
106
+
107
+ <h3>Emotions</h3>
108
+ {emotions_html}
109
+ <h3>Emotions Score</h3>
110
+ {emoScor_html}
111
+
112
+ </div>
113
+ """
114
+
115
+ # Format dynamic reviews
116
+ def format_dynamic_reviews(reviews):
117
+ return "<div>" + "".join(format_review(rev) for rev in reviews) + "</div>"
118
+
119
+ def get_static_review(index):
120
+ review = static_reviews[index]
121
+ highlighted_text = highlight_aspects(review['text'], review['aspect_word'].split(','))
122
+ stars_html = f"Stars: {review['stars']}"
123
+ aspects = [asp.strip() for asp in review['aspect_word'].split(',')]
124
+ emotions = [emo.strip() for emo in review['emotion'].split(',')]
125
+
126
+ aspects_html = '<h3>Aspect Words</h3><div class="cell-grid">' + "".join(f'<div class="cell-item">{html.escape(asp)}</div>' for asp in aspects) + '</div>'
127
+ emotions_html = '<h3>Emotions Extracted</h3><div class="cell-grid">' + "".join(f'<div class="cell-item">{html.escape(emo)}</div>' for emo in emotions) + '</div>'
128
+
129
+ info_text = f"Review {index+1} of {len(static_reviews)}"
130
+ return highlighted_text, stars_html, aspects_html, emotions_html, info_text
131
+
132
+ def navigate(direction, current_index):
133
+ if direction == 'prev':
134
+ return max(current_index - 1, 0)
135
+ return min(current_index + 1, len(static_reviews) - 1)
136
+
137
+ def submit_new_review(text):
138
+ if not text.strip():
139
+ return "Please enter a review.", []
140
+ new_dynamic_reviews =[]
141
+ _reviews = extract_full_analysis(text)
142
+ new_dynamic_reviews.append(_reviews)
143
+ return format_review(new_dynamic_reviews), new_dynamic_reviews
144
+
145
+ with gr.Blocks(css="""
146
+ .cell-grid {
147
+ display: grid;
148
+ grid-template-columns: repeat(6, 1fr);
149
+ gap: 10px;
150
+ }
151
+ .cell-item {
152
+ background-color: #f0f0f0;
153
+ padding: 10px;
154
+ border: 1px solid #ccc;
155
+ text-align: center;
156
+ }
157
+ """) as demo:
158
+ # Header
159
+ gr.Markdown("# Yelp Review Demonstration for Aspect and Emotion Extracted")
160
+
161
+ # Static Reviews
162
+ with gr.Row():
163
+ with gr.Column(scale=11):
164
+ static_text = gr.HTML(label="Review Text")
165
+ with gr.Column(scale=1):
166
+ static_stars = gr.HTML(label="Stars")
167
+ static_aspects = gr.HTML(label=None)
168
+ static_emotions = gr.HTML(label="Emotions")
169
+ static_info = gr.Textbox(label="Review Info", interactive=False)
170
+ with gr.Row():
171
+ prev_button = gr.Button("Previous")
172
+ next_button = gr.Button("Next")
173
+
174
+ # Submit Form
175
+ gr.Markdown("## Submit Your Review")
176
+ with gr.Row():
177
+ with gr.Column(scale=8):
178
+ submit_text = gr.Textbox(label="Write your review", lines=5)
179
+ submit_button = gr.Button("Submit")
180
+
181
+ # Dynamic Reviews
182
+ gr.Markdown("## User Submitted Reviews")
183
+ dynamic_display = gr.HTML()
184
+
185
+ # States
186
+ current_static_index = gr.State(0)
187
+ dynamic_reviews_state = gr.State()
188
+
189
+ # Load Initial Data
190
+ demo.load(get_static_review, inputs=current_static_index, outputs=[static_text, static_stars, static_aspects, static_emotions, static_info])
191
+
192
+ # Event Handlers
193
+ prev_button.click(lambda ci: navigate('prev', ci), inputs=current_static_index, outputs=current_static_index).then(
194
+ get_static_review, inputs=current_static_index, outputs=[static_text, static_stars, static_aspects, static_emotions, static_info])
195
+ next_button.click(lambda ci: navigate('next', ci), inputs=current_static_index, outputs=current_static_index).then(
196
+ get_static_review, inputs=current_static_index, outputs=[static_text, static_stars, static_aspects, static_emotions, static_info])
197
+ submit_button.click(submit_new_review, inputs=submit_text, outputs=[dynamic_display, dynamic_reviews_state])
198
+
199
+ # Launch
200
+ if __name__ == "__main__":
201
+ port = int(os.environ.get('PORT', 7814))
202
+ demo.launch(server_name="0.0.0.0", server_port=port,share=True)
203
+ # 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
requirements.txt ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiofiles==23.2.1
2
+ aiohappyeyeballs==2.4.4
3
+ aiohttp==3.11.10
4
+ aiosignal==1.3.2
5
+ annotated-types==0.7.0
6
+ anyio==4.7.0
7
+ appnope==0.1.4
8
+ argon2-cffi==23.1.0
9
+ argon2-cffi-bindings==21.2.0
10
+ arrow==1.3.0
11
+ asgiref==3.8.1
12
+ asttokens==3.0.0
13
+ async-lru==2.0.4
14
+ attrs==24.3.0
15
+ babel==2.16.0
16
+ backoff==2.2.1
17
+ bcrypt==4.2.1
18
+ beautifulsoup4==4.12.3
19
+ bleach==6.2.0
20
+ build==1.2.2.post1
21
+ cachetools==5.5.0
22
+ certifi==2024.12.14
23
+ cffi==1.17.1
24
+ charset-normalizer==3.4.0
25
+ chroma-hnswlib==0.7.6
26
+ #chromadb==0.5.23
27
+ chromadb>=0.6.0
28
+ click==8.1.7
29
+ coloredlogs==15.0.1
30
+ comm==0.2.2
31
+ contourpy==1.3.1
32
+ cycler==0.12.1
33
+ dataclasses-json==0.6.7
34
+ debugpy==1.8.11
35
+ decorator==5.1.1
36
+ defusedxml==0.7.1
37
+ Deprecated==1.2.15
38
+ distro==1.9.0
39
+ durationpy==0.9
40
+ executing==2.1.0
41
+ fastapi==0.115.6
42
+ fastjsonschema==2.21.1
43
+ ffmpy==0.4.0
44
+ filelock==3.16.1
45
+ flatbuffers==24.3.25
46
+ fonttools==4.55.3
47
+ fqdn==1.5.1
48
+ frozenlist==1.5.0
49
+ fsspec==2024.10.0
50
+ google-auth==2.37.0
51
+ googleapis-common-protos==1.66.0
52
+ gradio==5.9.1
53
+ gradio_client==1.5.2
54
+ grpcio==1.68.1
55
+ h11==0.14.0
56
+ httpcore==1.0.7
57
+ httptools==0.6.4
58
+ httpx==0.28.1
59
+ httpx-sse==0.4.0
60
+ huggingface-hub==0.27.0
61
+ humanfriendly==10.0
62
+ idna==3.10
63
+ importlib_metadata==8.5.0
64
+ importlib_resources==6.4.5
65
+ ipykernel==6.29.5
66
+ ipython==8.30.0
67
+ ipywidgets==8.1.5
68
+ isoduration==20.11.0
69
+ jedi==0.19.2
70
+ Jinja2==3.1.4
71
+ jiter==0.8.2
72
+ json5==0.10.0
73
+ jsonpatch==1.33
74
+ jsonpointer==3.0.0
75
+ jsonschema==4.23.0
76
+ jsonschema-specifications==2024.10.1
77
+ jupyter-events==0.11.0
78
+ jupyter-lsp==2.2.5
79
+ jupyter_client==8.6.3
80
+ jupyter_core==5.7.2
81
+ jupyter_server==2.14.2
82
+ jupyter_server_terminals==0.5.3
83
+ jupyterlab==4.3.3
84
+ jupyterlab_pygments==0.3.0
85
+ jupyterlab_server==2.27.3
86
+ jupyterlab_widgets==3.0.13
87
+ kagglehub==0.3.5
88
+ kiwisolver==1.4.7
89
+ kubernetes==31.0.0
90
+ langchain==0.3.12
91
+ #langchain-chroma==0.1.4
92
+ langchain-chroma>=0.1.5
93
+ langchain-community==0.3.12
94
+ langchain-core==0.3.25
95
+ langchain-openai==0.2.12
96
+ langchain-text-splitters==0.3.3
97
+ langsmith==0.2.3
98
+ markdown-it-py==3.0.0
99
+ MarkupSafe==2.1.5
100
+ marshmallow==3.23.1
101
+ matplotlib==3.10.0
102
+ matplotlib-inline==0.1.7
103
+ mdurl==0.1.2
104
+ mistune==3.0.2
105
+ mmh3==5.0.1
106
+ monotonic==1.6
107
+ mpmath==1.3.0
108
+ multidict==6.1.0
109
+ mypy-extensions==1.0.0
110
+ nbclient==0.10.1
111
+ nbconvert==7.16.4
112
+ nbformat==5.10.4
113
+ nest-asyncio==1.6.0
114
+ networkx==3.4.2
115
+ notebook==7.3.1
116
+ notebook_shim==0.2.4
117
+ numpy==1.26.4
118
+ oauthlib==3.2.2
119
+ onnxruntime==1.20.1
120
+ openai==1.57.4
121
+ opentelemetry-api==1.29.0
122
+ opentelemetry-exporter-otlp-proto-common==1.29.0
123
+ opentelemetry-exporter-otlp-proto-grpc==1.29.0
124
+ opentelemetry-instrumentation==0.50b0
125
+ opentelemetry-instrumentation-asgi==0.50b0
126
+ opentelemetry-instrumentation-fastapi==0.50b0
127
+ opentelemetry-proto==1.29.0
128
+ opentelemetry-sdk==1.29.0
129
+ opentelemetry-semantic-conventions==0.50b0
130
+ opentelemetry-util-http==0.50b0
131
+ orjson==3.10.12
132
+ overrides==7.7.0
133
+ packaging==24.2
134
+ pandas==2.2.3
135
+ pandocfilters==1.5.1
136
+ parso==0.8.4
137
+ pexpect==4.9.0
138
+ pillow==11.0.0
139
+ platformdirs==4.3.6
140
+ posthog==3.7.4
141
+ prometheus_client==0.21.1
142
+ prompt_toolkit==3.0.48
143
+ propcache==0.2.1
144
+ protobuf==5.29.1
145
+ psutil==6.1.0
146
+ ptyprocess==0.7.0
147
+ pure_eval==0.2.3
148
+ pyasn1==0.6.1
149
+ pyasn1_modules==0.4.1
150
+ pycparser==2.22
151
+ pydantic==2.10.3
152
+ pydantic-settings==2.7.0
153
+ pydantic_core==2.27.1
154
+ pydub==0.25.1
155
+ Pygments==2.18.0
156
+ pyparsing==3.2.0
157
+ PyPika==0.48.9
158
+ pyproject_hooks==1.2.0
159
+ python-dateutil==2.9.0.post0
160
+ python-dotenv==1.0.1
161
+ python-json-logger==3.2.1
162
+ python-multipart==0.0.20
163
+ pytz==2024.2
164
+ PyYAML==6.0.2
165
+ pyzmq==26.2.0
166
+ referencing==0.35.1
167
+ regex==2024.11.6
168
+ requests==2.32.3
169
+ requests-oauthlib==2.0.0
170
+ requests-toolbelt==1.0.0
171
+ rfc3339-validator==0.1.4
172
+ rfc3986-validator==0.1.1
173
+ rich==13.9.4
174
+ rpds-py==0.22.3
175
+ rsa==4.9
176
+ ruff==0.8.3
177
+ safehttpx==0.1.6
178
+ safetensors==0.4.5
179
+ seaborn==0.13.2
180
+ semantic-version==2.10.0
181
+ Send2Trash==1.8.3
182
+ shellingham==1.5.4
183
+ six==1.17.0
184
+ sniffio==1.3.1
185
+ soupsieve==2.6
186
+ SQLAlchemy==2.0.36
187
+ stack-data==0.6.3
188
+ starlette==0.41.3
189
+ sympy==1.13.1
190
+ tenacity==9.0.0
191
+ terminado==0.18.1
192
+ tiktoken==0.8.0
193
+ tinycss2==1.4.0
194
+ tokenizers==0.21.0
195
+ tomlkit==0.13.2
196
+ torch==2.5.1
197
+ tornado==6.4.2
198
+ tqdm==4.67.1
199
+ traitlets==5.14.3
200
+ transformers==4.47.1
201
+ typer==0.15.1
202
+ types-python-dateutil==2.9.0.20241206
203
+ typing-inspect==0.9.0
204
+ typing_extensions==4.12.2
205
+ tzdata==2024.2
206
+ uri-template==1.3.0
207
+ urllib3==2.2.3
208
+ uvicorn==0.34.0
209
+ watchfiles==1.0.3
210
+ wcwidth==0.2.13
211
+ webcolors==24.11.1
212
+ webencodings==0.5.1
213
+ websocket-client==1.8.0
214
+ websockets==14.1
215
+ widgetsnbextension==4.0.13
216
+ wrapt==1.17.0
217
+ yarl==1.18.3
218
+ zipp==3.21.0