SonFox2920 commited on
Commit
9cde47b
·
verified ·
1 Parent(s): 7827c20

Update analyze.py

Browse files
Files changed (1) hide show
  1. analyze.py +182 -42
analyze.py CHANGED
@@ -3,6 +3,7 @@ import pandas as pd
3
  import plotly.express as px
4
  import plotly.graph_objects as go
5
  from plotly.subplots import make_subplots
 
6
 
7
  # Hàm để tải và xử lý dữ liệu
8
  @st.cache_data
@@ -65,11 +66,42 @@ def plot_criteria_comparison(df):
65
  # Hàm tạo biểu đồ phân bố ứng viên theo khoảng điểm
66
  def plot_score_range_distribution(df):
67
  df['Khoảng điểm'] = pd.cut(df['Điểm tổng quát'], bins=[0, 2, 4, 6, 8, 10], labels=['0-2', '2-4', '4-6', '6-8', '8-10'])
68
- fig = px.bar(df['Khoảng điểm'].value_counts().sort_index(), title="Phân bố ứng viên theo khoảng điểm")
 
69
  fig.update_xaxes(title="Khoảng điểm")
70
  fig.update_yaxes(title="Số lượng ứng viên")
71
  return fig
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  def dashboard():
74
  # Tiêu đề ứng dụng
75
  st.header("📈 Dashboard Phân tích Ứng viên")
@@ -81,63 +113,171 @@ def dashboard():
81
  # Tải dữ liệu
82
  df = load_data(uploaded_file)
83
 
 
 
 
 
 
 
 
 
84
  # Thông tin tổng quan
85
  st.header("📊 Thông tin tổng quan")
86
  col1, col2, col3, col4 = st.columns(4)
87
  col1.metric("Tổng số ứng viên", len(df))
88
- col2.metric("Điểm trung bình", f"{df['Điểm tổng quát'].mean():.2f}")
89
- col3.metric("Điểm cao nhất", df['Điểm tổng quát'].max())
90
- col4.metric("Điểm thấp nhất", df['Điểm tổng quát'].min())
91
 
92
- # Phân phối điểm Ma trận tương quan
93
- st.header("📈 Phân tích điểm số")
94
- col1, col2 = st.columns(2)
95
- with col1:
96
- st.plotly_chart(plot_score_distribution(df, 'Điểm tổng quát'), use_container_width=True)
97
- with col2:
98
- st.plotly_chart(plot_correlation_heatmap(df), use_container_width=True)
 
99
 
100
- # Phân tích đánh giá theo tiêu chí
101
- st.header("🔬 Phân tích đánh giá theo tiêu chí")
102
- st.plotly_chart(plot_criteria_comparison(df), use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
- # Phân bố ứng viên theo khoảng điểm
105
- st.plotly_chart(plot_score_range_distribution(df), use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
107
  # Biểu đồ radar cho từng ứng viên
108
- st.header("🎯 Biểu đồ kỹ năng ứng viên")
109
- col1, col2 = st.columns([1, 3])
110
- with col1:
111
- selected_candidate = st.selectbox("Chọn ứng viên", df['Tên ứng viên'].tolist())
112
- candidate_summary = df[df['Tên ứng viên'] == selected_candidate]['Tóm tắt'].values[0]
113
- st.subheader("Tóm tắt ứng viên")
114
- st.write(candidate_summary)
115
- with col2:
116
- st.plotly_chart(plot_candidate_radar(df, selected_candidate), use_container_width=True)
 
 
 
 
 
117
 
118
  # Lọc và sắp xếp ứng viên
119
  st.header("🔍 Lọc và sắp xếp ứng viên")
120
- col1, col2 = st.columns(2)
121
- with col1:
122
- min_score = st.slider("Điểm tổng quát tối thiểu", 0.0, 10.0, 0.0)
123
- with col2:
124
- sort_by = st.selectbox("Sắp xếp theo", ['Điểm tổng quát', 'Mức độ phù hợp', 'Kỹ năng kỹ thuật', 'Kinh nghiệm', 'Trình độ học vấn', 'Kỹ năng mềm'])
125
-
126
- filtered_df = df[df['Điểm tổng quát'] >= min_score].sort_values(sort_by, ascending=False)
127
- st.dataframe(filtered_df[['Tên ứng viên', 'Điểm tổng quát', 'Mức độ phù hợp', 'Kỹ năng kỹ thuật', 'Kinh nghiệm', 'Trình độ học vấn', 'Kỹ năng mềm', 'Link ứng viên']], column_config={
128
- "Link ứng viên": st.column_config.LinkColumn()
129
- }
130
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
 
132
  # Top ứng viên
133
- st.header("🏆 Top ứng viên theo điểm tổng quát")
134
- top_n = st.slider("Số lượng ứng viên hàng đầu", 1, 20, 5)
135
- top_candidates = df.sort_values('Điểm tổng quát', ascending=False).head(top_n)
136
- st.table(top_candidates[['Tên ứng viên', 'Điểm tổng quát', 'Mức độ phù hợp', 'Kỹ năng kỹ thuật', 'Kinh nghiệm', 'Trình độ học vấn', 'Kỹ năng mềm', 'Link ứng viên']])
 
137
 
138
  # Dữ liệu chi tiết
139
- st.header("📋 Dữ liệu chi tiết")
140
- st.dataframe(df)
141
 
142
  else:
143
  st.info("Vui lòng upload file CSV để bắt đầu phân tích.")
 
3
  import plotly.express as px
4
  import plotly.graph_objects as go
5
  from plotly.subplots import make_subplots
6
+ import numpy as np
7
 
8
  # Hàm để tải và xử lý dữ liệu
9
  @st.cache_data
 
66
  # Hàm tạo biểu đồ phân bố ứng viên theo khoảng điểm
67
  def plot_score_range_distribution(df):
68
  df['Khoảng điểm'] = pd.cut(df['Điểm tổng quát'], bins=[0, 2, 4, 6, 8, 10], labels=['0-2', '2-4', '4-6', '6-8', '8-10'])
69
+ counts = df['Khoảng điểm'].value_counts().sort_index()
70
+ fig = px.bar(counts, title="Phân bố ứng viên theo khoảng điểm")
71
  fig.update_xaxes(title="Khoảng điểm")
72
  fig.update_yaxes(title="Số lượng ứng viên")
73
  return fig
74
 
75
+ # Hàm tạo biểu đồ phân bố ứng viên theo giai đoạn
76
+ def plot_stage_distribution(df):
77
+ if 'Giai đoạn' in df.columns:
78
+ fig = px.bar(df['Giai đoạn'].value_counts().sort_index(),
79
+ title="Phân bố ứng viên theo giai đoạn tuyển dụng")
80
+ fig.update_xaxes(title="Giai đoạn")
81
+ fig.update_yaxes(title="Số lượng ứng viên")
82
+ return fig
83
+ return None
84
+
85
+ # Hàm tạo biểu đồ điểm trung bình theo giai đoạn
86
+ def plot_avg_score_by_stage(df):
87
+ if 'Giai đoạn' in df.columns:
88
+ avg_scores = df.groupby('Giai đoạn')['Điểm tổng quát'].mean().sort_values(ascending=False)
89
+ fig = px.bar(avg_scores, title="Điểm trung bình theo giai đoạn tuyển dụng")
90
+ fig.update_xaxes(title="Giai đoạn")
91
+ fig.update_yaxes(title="Điểm trung bình")
92
+ return fig
93
+ return None
94
+
95
+ # Hàm tạo biểu đồ heatmap so sánh điểm trung bình các tiêu chí theo giai đoạn
96
+ def plot_criteria_by_stage_heatmap(df):
97
+ if 'Giai đoạn' in df.columns:
98
+ criteria = ['Mức độ phù hợp', 'Kỹ năng kỹ thuật', 'Kinh nghiệm', 'Trình độ học vấn', 'Kỹ năng mềm']
99
+ pivot_df = df.pivot_table(index='Giai đoạn', values=criteria)
100
+ fig = px.imshow(pivot_df, text_auto=True, aspect="auto", color_continuous_scale="Blues",
101
+ title="Điểm trung bình các tiêu chí theo giai đoạn")
102
+ return fig
103
+ return None
104
+
105
  def dashboard():
106
  # Tiêu đề ứng dụng
107
  st.header("📈 Dashboard Phân tích Ứng viên")
 
113
  # Tải dữ liệu
114
  df = load_data(uploaded_file)
115
 
116
+ # Kiểm tra và chuyển đổi các cột số nếu cần
117
+ numeric_columns = ['Mức độ phù hợp', 'Kỹ năng kỹ thuật', 'Kinh nghiệm',
118
+ 'Trình độ học vấn', 'Kỹ năng mềm', 'Điểm tổng quát']
119
+
120
+ for col in numeric_columns:
121
+ if col in df.columns:
122
+ df[col] = pd.to_numeric(df[col], errors='coerce')
123
+
124
  # Thông tin tổng quan
125
  st.header("📊 Thông tin tổng quan")
126
  col1, col2, col3, col4 = st.columns(4)
127
  col1.metric("Tổng số ứng viên", len(df))
 
 
 
128
 
129
+ if 'Điểm tổng quát' in df.columns:
130
+ avg_score = df['Điểm tổng quát'].mean()
131
+ max_score = df['Điểm tổng quát'].max()
132
+ min_score = df['Điểm tổng quát'].min()
133
+
134
+ col2.metric("Điểm trung bình", f"{avg_score:.2f}")
135
+ col3.metric("Điểm cao nhất", f"{max_score:.2f}")
136
+ col4.metric("Điểm thấp nhất", f"{min_score:.2f}")
137
 
138
+ # Phân tích theo giai đoạn (mới)
139
+ if 'Giai đoạn' in df.columns:
140
+ st.header("🔄 Phân tích theo giai đoạn tuyển dụng")
141
+ col1, col2 = st.columns(2)
142
+
143
+ with col1:
144
+ stage_chart = plot_stage_distribution(df)
145
+ if stage_chart:
146
+ st.plotly_chart(stage_chart, use_container_width=True)
147
+
148
+ with col2:
149
+ avg_score_chart = plot_avg_score_by_stage(df)
150
+ if avg_score_chart:
151
+ st.plotly_chart(avg_score_chart, use_container_width=True)
152
+
153
+ # Biểu đồ heatmap các tiêu chí theo giai đoạn
154
+ criteria_stage_chart = plot_criteria_by_stage_heatmap(df)
155
+ if criteria_stage_chart:
156
+ st.plotly_chart(criteria_stage_chart, use_container_width=True)
157
 
158
+ # Phân phối điểm Ma trận tương quan
159
+ if 'Điểm tổng quát' in df.columns:
160
+ st.header("📈 Phân tích điểm số")
161
+ col1, col2 = st.columns(2)
162
+ with col1:
163
+ st.plotly_chart(plot_score_distribution(df, 'Điểm tổng quát'), use_container_width=True)
164
+ with col2:
165
+ try:
166
+ st.plotly_chart(plot_correlation_heatmap(df), use_container_width=True)
167
+ except Exception as e:
168
+ st.warning(f"Không thể tạo ma trận tương quan: {e}")
169
+
170
+ # Phân tích đánh giá theo tiêu chí
171
+ st.header("🔬 Phân tích đánh giá theo tiêu chí")
172
+ try:
173
+ st.plotly_chart(plot_criteria_comparison(df), use_container_width=True)
174
+ except Exception as e:
175
+ st.warning(f"Không thể tạo biểu đồ so sánh tiêu chí: {e}")
176
+
177
+ # Phân bố ứng viên theo khoảng điểm
178
+ try:
179
+ st.plotly_chart(plot_score_range_distribution(df), use_container_width=True)
180
+ except Exception as e:
181
+ st.warning(f"Không thể tạo biểu đồ phân bố khoảng điểm: {e}")
182
 
183
  # Biểu đồ radar cho từng ứng viên
184
+ if 'Tên ứng viên' in df.columns:
185
+ st.header("🎯 Biểu đồ kỹ năng ứng viên")
186
+ col1, col2 = st.columns([1, 3])
187
+ with col1:
188
+ selected_candidate = st.selectbox("Chọn ứng viên", df['Tên ứng viên'].tolist())
189
+ if 'Tóm tắt' in df.columns:
190
+ candidate_summary = df[df['Tên ứng viên'] == selected_candidate]['Tóm tắt'].values[0]
191
+ st.subheader("Tóm tắt ứng viên")
192
+ st.write(candidate_summary)
193
+ with col2:
194
+ try:
195
+ st.plotly_chart(plot_candidate_radar(df, selected_candidate), use_container_width=True)
196
+ except Exception as e:
197
+ st.warning(f"Không thể tạo biểu đồ radar: {e}")
198
 
199
  # Lọc và sắp xếp ứng viên
200
  st.header("🔍 Lọc và sắp xếp ứng viên")
201
+
202
+ # Cấu hình các bộ lọc
203
+ filter_columns = st.columns(3)
204
+
205
+ with filter_columns[0]:
206
+ # Tùy chọn lọc theo điểm
207
+ if 'Điểm tổng quát' in df.columns:
208
+ min_score = st.slider("Điểm tổng quát tối thiểu",
209
+ float(df['Điểm tổng quát'].min()),
210
+ float(df['Điểm tổng quát'].max()),
211
+ float(df['Điểm tổng quát'].min()))
212
+ else:
213
+ min_score = 0
214
+
215
+ with filter_columns[1]:
216
+ # Sắp xếp theo
217
+ sort_options = [col for col in df.columns if col in
218
+ ['Điểm tổng quát', 'Mức độ phù hợp', 'Kỹ năng kỹ thuật',
219
+ 'Kinh nghiệm', 'Trình độ học vấn', 'Kỹ năng mềm']]
220
+
221
+ if sort_options:
222
+ sort_by = st.selectbox("Sắp xếp theo", sort_options)
223
+ else:
224
+ sort_by = None
225
+
226
+ with filter_columns[2]:
227
+ # Lọc theo giai đoạn
228
+ if 'Giai đoạn' in df.columns and not df['Giai đoạn'].isna().all():
229
+ stages = ['Tất cả'] + list(df['Giai đoạn'].dropna().unique())
230
+ selected_stage = st.selectbox("Giai đoạn", stages)
231
+ else:
232
+ selected_stage = 'Tất cả'
233
+
234
+ # Áp dụng các bộ lọc
235
+ filtered_df = df.copy()
236
+
237
+ if 'Điểm tổng quát' in filtered_df.columns:
238
+ filtered_df = filtered_df[filtered_df['Điểm tổng quát'] >= min_score]
239
+
240
+ if selected_stage != 'Tất cả' and 'Giai đoạn' in filtered_df.columns:
241
+ filtered_df = filtered_df[filtered_df['Giai đoạn'] == selected_stage]
242
+
243
+ if sort_by and sort_by in filtered_df.columns:
244
+ filtered_df = filtered_df.sort_values(sort_by, ascending=False)
245
+
246
+ # Hiển thị dữ liệu đã lọc
247
+ display_columns = ['Tên ứng viên']
248
+ if 'Điểm tổng quát' in df.columns:
249
+ display_columns.append('Điểm tổng quát')
250
+
251
+ score_columns = [col for col in df.columns if col in
252
+ ['Mức độ phù hợp', 'Kỹ năng kỹ thuật', 'Kinh nghiệm',
253
+ 'Trình độ học vấn', 'Kỹ năng mềm']]
254
+ display_columns.extend(score_columns)
255
+
256
+ if 'Giai đoạn' in df.columns:
257
+ display_columns.append('Giai đoạn')
258
+
259
+ if 'Link ứng viên' in df.columns:
260
+ display_columns.append('Link ứng viên')
261
+
262
+ # Chỉ hiển thị các cột có trong DataFrame
263
+ display_columns = [col for col in display_columns if col in filtered_df.columns]
264
+
265
+ column_config = {}
266
+ if 'Link ứng viên' in display_columns:
267
+ column_config["Link ứng viên"] = st.column_config.LinkColumn()
268
+
269
+ st.dataframe(filtered_df[display_columns], column_config=column_config)
270
 
271
  # Top ứng viên
272
+ if 'Điểm tổng quát' in df.columns:
273
+ st.header("🏆 Top ứng viên theo điểm tổng quát")
274
+ top_n = st.slider("Số lượng ứng viên hàng đầu", 1, min(20, len(df)), 5)
275
+ top_candidates = df.sort_values('Điểm tổng quát', ascending=False).head(top_n)
276
+ st.table(top_candidates[display_columns])
277
 
278
  # Dữ liệu chi tiết
279
+ with st.expander("📋 Xem tất cả dữ liệu chi tiết"):
280
+ st.dataframe(df)
281
 
282
  else:
283
  st.info("Vui lòng upload file CSV để bắt đầu phân tích.")