Spaces:
Sleeping
Sleeping
Update src/streamlit_app.py
Browse files- src/streamlit_app.py +110 -38
src/streamlit_app.py
CHANGED
@@ -1,40 +1,112 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
import pandas as pd
|
4 |
import streamlit as st
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
|
10 |
-
If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
|
11 |
-
forums](https://discuss.streamlit.io).
|
12 |
-
|
13 |
-
In the meantime, below is an example of what you can do with just a few lines of code:
|
14 |
-
"""
|
15 |
-
|
16 |
-
num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
|
17 |
-
num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
|
18 |
-
|
19 |
-
indices = np.linspace(0, 1, num_points)
|
20 |
-
theta = 2 * np.pi * num_turns * indices
|
21 |
-
radius = indices
|
22 |
-
|
23 |
-
x = radius * np.cos(theta)
|
24 |
-
y = radius * np.sin(theta)
|
25 |
-
|
26 |
-
df = pd.DataFrame({
|
27 |
-
"x": x,
|
28 |
-
"y": y,
|
29 |
-
"idx": indices,
|
30 |
-
"rand": np.random.randn(num_points),
|
31 |
-
})
|
32 |
-
|
33 |
-
st.altair_chart(alt.Chart(df, height=700, width=700)
|
34 |
-
.mark_point(filled=True)
|
35 |
-
.encode(
|
36 |
-
x=alt.X("x", axis=None),
|
37 |
-
y=alt.Y("y", axis=None),
|
38 |
-
color=alt.Color("idx", legend=None, scale=alt.Scale()),
|
39 |
-
size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
|
40 |
-
))
|
|
|
1 |
+
# python -m streamlit run app.py
|
2 |
+
|
|
|
3 |
import streamlit as st
|
4 |
+
import pandas as pd
|
5 |
+
import plotly.express as px
|
6 |
+
from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
|
7 |
+
import os
|
8 |
+
import zipfile
|
9 |
+
|
10 |
+
# แตกไฟล์ zip ถ้ายังไม่มีโฟลเดอร์
|
11 |
+
if not os.path.exists("Senti_real"):
|
12 |
+
with zipfile.ZipFile("Senti_real.zip", "r") as zip_ref:
|
13 |
+
zip_ref.extractall()
|
14 |
+
|
15 |
+
# ---------- CONFIG ----------
|
16 |
+
st.set_page_config(page_title="CheckPD Sentiment Dashboard", layout="wide")
|
17 |
+
st.title("ภาพรวมความรู้สึกของผู้ใช้ CheckPD (Real-time)")
|
18 |
+
|
19 |
+
# ---------- LOAD DATA ----------
|
20 |
+
def load_data():
|
21 |
+
base_path = os.path.dirname(__file__)
|
22 |
+
file_path = os.path.join(base_path, "Senti_real", "Sentiment", "checkpd_sentiment.csv")
|
23 |
+
df = pd.read_csv(file_path)
|
24 |
+
return df
|
25 |
+
|
26 |
+
if st.button("รีเฟรชข้อมูล"):
|
27 |
+
st.cache_data.clear()
|
28 |
+
st.rerun()
|
29 |
+
|
30 |
+
# โหลดข้อมูลและตัวกรองจังหวัด
|
31 |
+
df = load_data()
|
32 |
+
locations = df['service_location'].dropna().unique().tolist()
|
33 |
+
locations.insert(0, "ดูทั้งหมด")
|
34 |
+
selected_location = st.selectbox("เลือกจังหวัด/สถานที่บริการ", options=locations)
|
35 |
+
|
36 |
+
if selected_location == "ดูทั้งหมด":
|
37 |
+
df_filtered = df.copy()
|
38 |
+
else:
|
39 |
+
df_filtered = df[df['service_location'] == selected_location]
|
40 |
+
|
41 |
+
# ---------- SIDEBAR MENU ----------
|
42 |
+
menu = st.sidebar.radio("เลือกหน้าที่จะแสดง", ["Dashboard สรุป", "Bar Chart เปรียบเทียบความรู้สึก"])
|
43 |
+
|
44 |
+
# ---------- กำหนดสี ----------
|
45 |
+
sentiment_colors = {'pos': 'skyblue', 'neg': 'red'}
|
46 |
+
|
47 |
+
if menu == "Dashboard สรุป":
|
48 |
+
st.subheader("1. สัดส่วนความรู้สึก (แยกตามประเภท)")
|
49 |
+
text_columns = {
|
50 |
+
'user_feeling_first_use': 'คุณรู้สึกอย่างไรเมื่อใช้งานแอปพลิเคชัน CheckPD ครั้งแรก?',
|
51 |
+
'staff_emotion_feedback': 'บริการของเจ้าหน้าที่ทำให้คุณรู้สึกอย่างไร?',
|
52 |
+
'improvement_suggestions': 'สิ่งใดในแอปพลิเคชันหรืองานบริการที่คุณคิดว่าควรปรับปรุง?'
|
53 |
+
}
|
54 |
+
|
55 |
+
for col, label in text_columns.items():
|
56 |
+
chart_col = col + '_sentiment'
|
57 |
+
df_chart = df_filtered[df_filtered[chart_col].isin(['pos', 'neg'])]
|
58 |
+
st.markdown(f"#### ➤ {label}")
|
59 |
+
fig = px.pie(df_chart, names=chart_col, title=f"สัดส่วนความรู้สึก - {label}", hole=0.4,
|
60 |
+
color=chart_col, color_discrete_map=sentiment_colors)
|
61 |
+
fig.update_traces(textfont_size=20)
|
62 |
+
st.plotly_chart(fig, use_container_width=True)
|
63 |
+
|
64 |
+
st.subheader("2. สัดส่วนภาพรวมทุกประเภท")
|
65 |
+
combined_counts = pd.concat([
|
66 |
+
df_filtered['user_feeling_first_use_sentiment'],
|
67 |
+
df_filtered['staff_emotion_feedback_sentiment'],
|
68 |
+
df_filtered['improvement_suggestions_sentiment']
|
69 |
+
])
|
70 |
+
combined_counts = combined_counts[combined_counts.isin(['pos', 'neg'])]
|
71 |
+
combined_counts = combined_counts.value_counts().reset_index()
|
72 |
+
combined_counts.columns = ['sentiment', 'count']
|
73 |
+
fig_total = px.pie(combined_counts, names='sentiment', values='count',
|
74 |
+
title="สัดส่วนความรู้สึกโดยรวมจากทุกหมวด", hole=0.4,
|
75 |
+
color='sentiment', color_discrete_map=sentiment_colors)
|
76 |
+
fig_total.update_traces(textfont_size=20)
|
77 |
+
st.plotly_chart(fig_total, use_container_width=True)
|
78 |
+
|
79 |
+
st.subheader("3. ข้อความที่ให้ความคิดเห็น (ตามตัวกรอง)")
|
80 |
+
|
81 |
+
cols_to_show = [
|
82 |
+
'service_location',
|
83 |
+
'user_feeling_first_use',
|
84 |
+
'staff_emotion_feedback',
|
85 |
+
'improvement_suggestions'
|
86 |
+
]
|
87 |
+
st.dataframe(df_filtered[cols_to_show], use_container_width=True)
|
88 |
+
|
89 |
+
|
90 |
+
elif menu == "Bar Chart เปรียบเทียบความรู้สึก":
|
91 |
+
st.subheader("ปรียบเทียบความรู้สึกในแต่ละหมวดด้วย Bar Chart")
|
92 |
+
text_columns = {
|
93 |
+
'user_feeling_first_use_sentiment': 'รู้สึกเมื่อใช้งานครั้งแรก',
|
94 |
+
'staff_emotion_feedback_sentiment': 'รู้สึกต่อเจ้าหน้าที่',
|
95 |
+
'improvement_suggestions_sentiment': 'ข้อเสนอแนะต่อแอป/บริการ'
|
96 |
+
}
|
97 |
+
|
98 |
+
for col, label in text_columns.items():
|
99 |
+
st.markdown(f"#### ➤ {label}")
|
100 |
+
df_chart = df_filtered[df_filtered[col].isin(['pos', 'neg'])]
|
101 |
+
counts = df_chart[col].value_counts().reset_index()
|
102 |
+
counts.columns = ['sentiment', 'count']
|
103 |
+
fig = px.bar(counts, x='sentiment', y='count',
|
104 |
+
labels={'sentiment': 'ความรู้สึก', 'count': 'จำนวน'},
|
105 |
+
title=f"Bar Chart - {label}",
|
106 |
+
color='sentiment', color_discrete_map=sentiment_colors)
|
107 |
+
fig.update_layout(font=dict(size=18))
|
108 |
+
st.plotly_chart(fig, use_container_width=True)
|
109 |
|
110 |
+
# ---------- SIDEBAR INFO ----------
|
111 |
+
st.sidebar.title("Model & Pipeline")
|
112 |
+
st.sidebar.info("กำลังใช้โมเดล: phoner45/wangchan-sentiment-thai-text-model")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|