SF001-123456 commited on
Commit
d630ade
·
verified ·
1 Parent(s): 541ee72

Upload 2 files

Browse files
Files changed (2) hide show
  1. HR-Employee-Attrition.csv +0 -0
  2. dashboard.py +253 -0
HR-Employee-Attrition.csv ADDED
The diff for this file is too large to render. See raw diff
 
dashboard.py ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import plotly.express as px
4
+ import plotly.graph_objects as go
5
+ from sklearn.preprocessing import MinMaxScaler
6
+ from sklearn.ensemble import RandomForestClassifier
7
+ from sklearn.model_selection import train_test_split
8
+ from sklearn.metrics import accuracy_score
9
+
10
+ # Load data and pre-process
11
+ df = pd.read_csv("HR-Employee-Attrition.csv")
12
+ df['Attrition'] = df['Attrition'].map({'Yes': 1, 'No': 0})
13
+ df['Performance_Risk'] = (df['PerformanceRating'] < 3).astype(int)
14
+ df['Retention_Risk'] = ((df['JobInvolvement'] < 2) & (df['JobSatisfaction'] < 2)).astype(int)
15
+
16
+ # Create Retention Score using selected factors
17
+ scaler = MinMaxScaler()
18
+ retention_factors = df[['JobSatisfaction', 'EnvironmentSatisfaction', 'WorkLifeBalance', 'YearsAtCompany']]
19
+ df['Retention_Score'] = scaler.fit_transform(retention_factors).mean(axis=1)
20
+
21
+ # Configure the Streamlit page
22
+ st.set_page_config(layout="wide")
23
+ st.title("Employee Performance & Retention Analytics Dashboard")
24
+
25
+ # Sidebar Filters
26
+ st.sidebar.header("Filters")
27
+ selected_dept = st.sidebar.selectbox("Department", df['Department'].unique())
28
+ # Filter job roles by the selected department
29
+ filtered_jobs = df[df['Department'] == selected_dept]['JobRole'].unique()
30
+ selected_job = st.sidebar.selectbox("Job Role", filtered_jobs)
31
+ attrition_filter = st.sidebar.radio("Attrition Status", ['All', 'Left', 'Current'])
32
+
33
+ # Filter DataFrame based on sidebar filters
34
+ filtered_df = df[(df['Department'] == selected_dept) & (df['JobRole'] == selected_job)]
35
+ if attrition_filter == 'Left':
36
+ filtered_df = filtered_df[filtered_df['Attrition'] == 1]
37
+ elif attrition_filter == 'Current':
38
+ filtered_df = filtered_df[filtered_df['Attrition'] == 0]
39
+
40
+ # Display Key Metrics
41
+ col1, col2, col3, col4 = st.columns(4)
42
+ with col1:
43
+ st.metric("Attrition Rate", f"{filtered_df['Attrition'].mean()*100:.1f}%")
44
+ with col2:
45
+ st.metric("Avg Performance Rating", f"{filtered_df['PerformanceRating'].mean():.1f}")
46
+ with col3:
47
+ st.metric("High Retention Risk", f"{filtered_df['Retention_Risk'].mean()*100:.1f}%")
48
+ with col4:
49
+ st.metric("Avg Tenure (Years)", f"{filtered_df['YearsAtCompany'].mean():.1f}")
50
+
51
+ # Machine Learning Model for Attrition Prediction
52
+ features = ['Age', 'MonthlyIncome', 'JobSatisfaction', 'EnvironmentSatisfaction', 'WorkLifeBalance', 'YearsAtCompany']
53
+ X = df[features]
54
+ y = df['Attrition']
55
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
56
+ model = RandomForestClassifier(n_estimators=100, random_state=42)
57
+ model.fit(X_train, y_train)
58
+ predictions = model.predict(X_test)
59
+ accuracy = accuracy_score(y_test, predictions)
60
+ st.sidebar.write(f"Model Accuracy: {accuracy*100:.2f}%")
61
+
62
+ # Predict attrition for the filtered data
63
+ if not filtered_df.empty:
64
+ filtered_df['Predicted Attrition'] = model.predict(filtered_df[features])
65
+ attrition_probability = filtered_df['Predicted Attrition'].mean() * 100
66
+ else:
67
+ attrition_probability = 0
68
+
69
+ # Create Tabs for Visualizations and Explanations
70
+ tab1, tab2, tab3 = st.tabs(["Performance Analysis", "Retention Analysis", "Employee Evaluation"])
71
+
72
+ # -------------------------------
73
+ # Tab 1: Performance Analysis
74
+ # -------------------------------
75
+ with tab1:
76
+ st.header("Performance Analysis")
77
+ col_left, col_right = st.columns(2)
78
+
79
+ with col_left:
80
+ st.subheader("Performance Rating vs Monthly Income")
81
+ fig1 = px.box(
82
+ filtered_df,
83
+ x='PerformanceRating',
84
+ y='MonthlyIncome',
85
+ color='Attrition',
86
+ title="Performance vs Income"
87
+ )
88
+ st.plotly_chart(fig1, use_container_width=True)
89
+ st.markdown(
90
+ """
91
+ **Explanation:**
92
+ - **X-axis:** Performance Rating
93
+ - **Y-axis:** Monthly Income
94
+ - **Color:** Attrition status (Left/Stayed)
95
+ This box plot shows the distribution of salaries across different performance ratings. It can highlight if high-performing employees are under-compensated, potentially driving attrition.
96
+ """
97
+ )
98
+
99
+ with col_right:
100
+ st.subheader("Tenure vs Age Attrition Risk")
101
+ fig2 = px.density_heatmap(
102
+ filtered_df,
103
+ x='YearsAtCompany',
104
+ y='Age',
105
+ z='Attrition',
106
+ histfunc="avg",
107
+ title="Tenure vs Age Attrition Risk"
108
+ )
109
+ st.plotly_chart(fig2, use_container_width=True)
110
+ st.markdown(
111
+ """
112
+ **Explanation:**
113
+ - **X-axis:** Years at Company
114
+ - **Y-axis:** Age
115
+ - **Color Intensity:** Attrition likelihood
116
+ This heatmap correlates employees' age and tenure with their attrition risk. Darker areas suggest higher likelihoods of attrition, identifying groups that may need targeted retention efforts.
117
+ """
118
+ )
119
+
120
+ # -------------------------------
121
+ # Tab 2: Retention Analysis
122
+ # -------------------------------
123
+ with tab2:
124
+ st.header("Retention Analysis")
125
+ col_left, col_right = st.columns(2)
126
+
127
+ with col_left:
128
+ st.subheader("Job Satisfaction vs Work-Life Balance")
129
+ fig3 = px.scatter(
130
+ filtered_df,
131
+ x='JobSatisfaction',
132
+ y='WorkLifeBalance',
133
+ color='Attrition',
134
+ size='YearsAtCompany',
135
+ title="Satisfaction vs Retention"
136
+ )
137
+ st.plotly_chart(fig3, use_container_width=True)
138
+ st.markdown(
139
+ """
140
+ **Explanation:**
141
+ - **X-axis:** Job Satisfaction
142
+ - **Y-axis:** Work-Life Balance
143
+ - **Bubble Size:** Years at Company
144
+ - **Color:** Attrition status
145
+ This scatter plot helps visualize how job satisfaction and work-life balance correlate with attrition. Clusters in lower satisfaction and balance areas can indicate higher attrition risks.
146
+ """
147
+ )
148
+
149
+ with col_right:
150
+ st.subheader("Promotion History Impact")
151
+ fig4 = go.Figure()
152
+ fig4.add_trace(
153
+ go.Histogram(
154
+ x=filtered_df[filtered_df['Attrition'] == 1]['YearsSinceLastPromotion'],
155
+ name='Left'
156
+ )
157
+ )
158
+ fig4.add_trace(
159
+ go.Histogram(
160
+ x=filtered_df[filtered_df['Attrition'] == 0]['YearsSinceLastPromotion'],
161
+ name='Stayed'
162
+ )
163
+ )
164
+ fig4.update_layout(title="Promotion History Impact", barmode='overlay')
165
+ st.plotly_chart(fig4, use_container_width=True)
166
+ st.markdown(
167
+ """
168
+ **Explanation:**
169
+ - **X-axis:** Years Since Last Promotion
170
+ - **Bars:** Comparison between employees who left and those who stayed
171
+ This histogram examines whether long gaps since the last promotion correlate with higher attrition, suggesting that career stagnation might drive employees to leave.
172
+ """
173
+ )
174
+
175
+ # -------------------------------
176
+ # Tab 3: Employee Evaluation
177
+ # -------------------------------
178
+ with tab3:
179
+ st.header("Employee Evaluation")
180
+ if not filtered_df.empty:
181
+ selected_employee = st.selectbox("Select Employee", filtered_df['EmployeeNumber'])
182
+ emp_data = filtered_df[filtered_df['EmployeeNumber'] == selected_employee].iloc[0]
183
+
184
+ col_left, col_right = st.columns(2)
185
+
186
+ with col_left:
187
+ st.subheader("Employee Metrics")
188
+ metrics = {
189
+ 'Performance Rating': emp_data['PerformanceRating'],
190
+ 'Job Satisfaction': emp_data['JobSatisfaction'],
191
+ 'Work-Life Balance': emp_data['WorkLifeBalance'],
192
+ 'Retention Score': emp_data['Retention_Score']
193
+ }
194
+ fig5 = go.Figure(go.Bar(
195
+ x=list(metrics.values()),
196
+ y=list(metrics.keys()),
197
+ orientation='h'
198
+ ))
199
+ fig5.update_layout(title="Employee Profile")
200
+ st.plotly_chart(fig5, use_container_width=True)
201
+ st.markdown(
202
+ """
203
+ **Explanation:**
204
+ This bar chart visualizes the key metrics for the selected employee, highlighting performance, satisfaction, work-life balance, and overall retention score.
205
+ """
206
+ )
207
+
208
+ with col_right:
209
+ st.subheader("Retention Recommendation")
210
+ risk_factors = []
211
+ if emp_data['PerformanceRating'] < 3:
212
+ risk_factors.append("Low Performance")
213
+ if emp_data['YearsSinceLastPromotion'] > 3:
214
+ risk_factors.append("Stagnant Position")
215
+ if emp_data['WorkLifeBalance'] < 2:
216
+ risk_factors.append("Poor Work-Life Balance")
217
+
218
+ retention_prob = emp_data['Retention_Score'] * 100
219
+ st.metric("Retention Probability", f"{retention_prob:.1f}%")
220
+
221
+ if retention_prob > 70:
222
+ st.success("High Retention Potential - Recommend Retention Programs")
223
+ elif retention_prob > 40:
224
+ st.warning("Moderate Retention Risk - Monitor Closely")
225
+ else:
226
+ st.error("High Attrition Risk - Recommend Intervention")
227
+
228
+ if risk_factors:
229
+ st.write("**Key Risk Factors:**")
230
+ for factor in risk_factors:
231
+ st.write(f"- {factor}")
232
+
233
+ st.markdown(
234
+ """
235
+ **Explanation:**
236
+ This section provides tailored retention recommendations based on the employee's metrics and key risk factors. The displayed retention probability guides whether further intervention is needed.
237
+ """
238
+ )
239
+ else:
240
+ st.write("No employee data available for the selected filters.")
241
+
242
+ # -------------------------------
243
+ # AI-Powered Insights Section
244
+ # -------------------------------
245
+ st.header("AI-Powered Insights")
246
+ if st.button("Generate Department Insights"):
247
+ insights = f"""
248
+ **Department Insights for {selected_dept} - {selected_job}:**
249
+ - Overall Attrition Rate: {filtered_df['Attrition'].mean()*100:.1f}% compared to the company average: {df['Attrition'].mean()*100:.1f}%.
250
+ - Employees with lower job satisfaction and poor work-life balance tend to have higher attrition risk.
251
+ - Predicted attrition probability based on the ML model: {attrition_probability:.1f}%.
252
+ """
253
+ st.write(insights)