Khóa học
Trước đây, phần lớn sự tập trung là vào các “tỷ lệ” như tỷ lệ nghỉ việc (attrition) và tỷ lệ giữ chân. Các quản lý nhân sự (HR) tính toán các tỷ lệ trước đây và cố gắng dự đoán các tỷ lệ trong tương lai bằng công cụ kho dữ liệu. Những tỷ lệ này cho thấy tác động tổng hợp của churn, nhưng đó mới chỉ là một nửa bức tranh. Một cách tiếp cận khác là tập trung vào từng hồ sơ cá nhân bên cạnh mức tổng hợp.
Có rất nhiều nghiên cứu tình huống về churn khách hàng. Với churn khách hàng, bạn có thể dự đoán ai và khi nào khách hàng sẽ ngừng mua. Churn nhân sự tương tự churn khách hàng, nhưng tập trung vào nhân viên thay vì khách hàng. Ở đây, bạn có thể dự đoán ai và khi nào một nhân viên sẽ chấm dứt làm việc. Churn nhân sự rất tốn kém, và những cải tiến nhỏ cũng có thể mang lại kết quả đáng kể. Nó giúp chúng ta thiết kế các kế hoạch giữ chân tốt hơn và cải thiện mức độ hài lòng của nhân viên.
Phân tích Churn Nhân sự

Churn nhân sự có thể được định nghĩa là sự thất thoát hay rời đi của tài sản trí tuệ khỏi một công ty hoặc tổ chức. Nói cách khác, khi nhân viên rời tổ chức thì được xem là churn. Một định nghĩa khác: khi một thành viên rời khỏi một quần thể, điều đó được gọi là churn.
Trong nghiên cứu, người ta thấy rằng churn nhân sự bị ảnh hưởng bởi tuổi, thâm niên, lương, mức độ hài lòng trong công việc, điều kiện làm việc, tiềm năng phát triển và cảm nhận của nhân viên về sự công bằng. Một số biến khác như tuổi, giới tính, sắc tộc, học vấn và tình trạng hôn nhân cũng là yếu tố quan trọng trong việc dự đoán churn. Ở một số trường hợp, nhân viên có kỹ năng chuyên biệt sẽ khó thay thế hơn, ảnh hưởng đến công việc đang diễn ra và năng suất của nhân viên hiện hữu. Tuyển dụng nhân viên mới để thay thế có chi phí như chi phí tuyển dụng và đào tạo. Ngoài ra, nhân viên mới cần thời gian để đạt trình độ kỹ thuật hay hiểu biết nghiệp vụ tương đương với nhân viên cũ. Các tổ chức giải quyết vấn đề này bằng cách áp dụng kỹ thuật học máy để dự đoán churn nhân sự, giúp họ đưa ra hành động cần thiết.
Các điểm sau giúp bạn hiểu churn nhân sự và churn khách hàng tốt hơn:
-
Doanh nghiệp chọn nhân viên để tuyển, còn trong marketing bạn không thể chọn khách hàng của mình.
-
Nhân viên là bộ mặt của công ty bạn, và tập thể nhân viên tạo ra mọi thứ công ty bạn làm.
-
Mất một khách hàng ảnh hưởng đến doanh thu và hình ảnh thương hiệu. Thu hút khách hàng mới khó và tốn kém hơn so với giữ chân khách hàng hiện có. Churn nhân sự cũng gây đau đầu cho doanh nghiệp và tổ chức. Nó đòi hỏi thời gian và công sức để tìm và đào tạo người thay thế.
Churn nhân sự có những động lực riêng so với churn khách hàng. Nó giúp chúng ta thiết kế các kế hoạch giữ chân nhân viên tốt hơn và cải thiện sự hài lòng. Các thuật toán khoa học dữ liệu có thể dự đoán churn trong tương lai.
Phân tích Khám phá (Exploratory Analysis)
Phân tích dữ liệu khám phá (EDA) là bước đầu trong quá trình phân tích, trong đó bạn tóm tắt các đặc trưng của dữ liệu như mẫu hình, xu hướng, giá trị ngoại lai và kiểm định giả thuyết thông qua thống kê mô tả và trực quan hóa.
Nhập Mô-đun
#import modules
import pandas # for dataframes
import matplotlib.pyplot as plt # for plotting graphs
import seaborn as sns # for plotting graphs
% matplotlib inline
Nạp Tập Dữ liệu
Trước tiên, hãy nạp tập dữ liệu HR cần thiết bằng hàm đọc CSV của pandas. Bạn có thể tải dữ liệu từ liên kết này.
data=pandas.read_csv('HR_comma_sep.csv')
data.head()

- Ở đây, dữ liệu gốc được phân tách bằng dấu phẩy (", ") trong tập dữ liệu đã cho.
- Bạn có thể xem nhanh dữ liệu nhờ hàm “head()” của thư viện pandas, hàm này trả về 5 quan sát đầu tiên.
- Tương tự, “tail()” trả về 5 quan sát cuối cùng.
data.tail()

Sau khi nạp tập dữ liệu, bạn có thể muốn biết thêm đôi chút về nó. Bạn có thể kiểm tra tên thuộc tính và kiểu dữ liệu bằng info().
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 14,999 entries, 0 to 14,998
Data columns (total 10 columns):
satisfaction_level 14999 non-null float64
last_evaluation 14999 non-null float64
number_project 14999 non-null int64
average_montly_hours 14999 non-null int64
time_spend_company 14999 non-null int64
Work_accident 14999 non-null int64
left 14999 non-null int64
promotion_last_5years 14999 non-null int64
Departments 14999 non-null object
salary 14999 non-null object
dtypes: float64(2), int64(6), object(2)
memory usage: 1.1+ MB
- Tập dữ liệu này có 14.999 mẫu và 10 thuộc tính (6 số nguyên, 2 số thực và 2 kiểu đối tượng).
- Không có cột biến nào có giá trị null/thiếu.
Bạn có thể mô tả chi tiết 10 thuộc tính như sau:
- satisfaction_level: Điểm hài lòng của nhân viên, nằm trong khoảng 0-1.
- last_evaluation: Điểm đánh giá hiệu suất bởi nhà tuyển dụng, cũng trong khoảng 0-1.
- number_projects: Số lượng dự án được giao cho một nhân viên.
- average_monthly_hours: Số giờ làm việc trung bình mỗi tháng của nhân viên.
- time_spent_company: Thời gian làm việc tại công ty, tức số năm nhân viên gắn bó với công ty.
- work_accident: Nhân viên có gặp tai nạn lao động hay không.
- promotion_last_5years: Nhân viên có được thăng chức trong 5 năm gần đây hay không.
- Departments: Phòng ban/bộ phận làm việc của nhân viên.
- Salary: Mức lương của nhân viên như thấp, trung bình và cao.
- left: Nhân viên đã rời công ty hay chưa.
Bắt tay vào Khai phá Thông tin Dữ liệu
Trong tập dữ liệu này, có hai nhóm nhân viên: người ở lại và người rời công ty. Vì vậy, bạn có thể chia dữ liệu thành hai nhóm và so sánh đặc trưng của họ. Ở đây, bạn có thể tìm giá trị trung bình của cả hai nhóm bằng groupby() và mean().
left = data.groupby('left')
left.mean()

Từ đây có thể diễn giải rằng, nhân viên rời công ty có mức hài lòng thấp, tỷ lệ thăng chức thấp, lương thấp và làm việc nhiều hơn so với những người ở lại.
Hàm describe() trong pandas rất tiện lợi để lấy các thống kê tóm tắt. Hàm này trả về số lượng, trung bình, độ lệch chuẩn, giá trị nhỏ nhất và lớn nhất, cùng các phân vị của dữ liệu.
data.describe()

Trực quan hóa Dữ liệu
Nhân viên Rời đi
Hãy kiểm tra có bao nhiêu nhân viên đã rời công ty?
Ở đây, bạn có thể vẽ biểu đồ cột bằng Matplotlib. Biểu đồ cột phù hợp để hiển thị số đếm của biến rời rạc.
left_count=data.groupby('left').count()
plt.bar(left_count.index.values, left_count['satisfaction_level'])
plt.xlabel('Employees Left Company')
plt.ylabel('Number of Employees')
plt.show()

data.left.value_counts()
0 11428
1 3571
Name: left, dtype: int64
Ở đây, bạn thấy trong khoảng 15.000 người thì có 3.571 người rời đi và 11.428 người ở lại. Số nhân viên rời đi chiếm 23% tổng số lao động.
Số lượng Dự án
Tương tự, bạn có thể vẽ biểu đồ cột để đếm số nhân viên được phân bổ theo số lượng dự án.
num_projects=data.groupby('number_project').count()
plt.bar(num_projects.index.values, num_projects['satisfaction_level'])
plt.xlabel('Number of Projects')
plt.ylabel('Number of Employees')
plt.show()

- Phần lớn nhân viên tham gia 3–5 dự án.
Thời gian Gắn bó với Công ty
Tương tự, bạn có thể vẽ biểu đồ cột để đếm số nhân viên theo mức thâm niên kinh nghiệm.
time_spent=data.groupby('time_spend_company').count()
plt.bar(time_spent.index.values, time_spent['satisfaction_level'])
plt.xlabel('Number of Years Spend in Company')
plt.ylabel('Number of Employees')
plt.show()

Phần lớn nhân viên có kinh nghiệm từ 2–4 năm. Ngoài ra, có một khoảng cách lớn giữa nhóm 3 năm và 4 năm kinh nghiệm.
Biểu đồ con với Seaborn
Bạn có thể phân tích từng đặc trưng một, nhưng sẽ tốn thời gian. Lựa chọn tốt hơn là dùng thư viện Seaborn và vẽ tất cả biểu đồ trong một lần chạy bằng các subplot.
features=['number_project','time_spend_company','Work_accident','left', 'promotion_last_5years','Departments ','salary']
fig=plt.subplots(figsize=(10,15))
for i, j in enumerate(features):
plt.subplot(4, 2, i+1)
plt.subplots_adjust(hspace = 1.0)
sns.countplot(x=j,data = data)
plt.xticks(rotation=90)
plt.title("No. of employee")

Bạn có thể quan sát những điểm sau trong hình trực quan trên:
- Phần lớn nhân viên tham gia 3–5 dự án.
- Có sự sụt giảm lớn giữa nhóm 3 năm và 4 năm kinh nghiệm.
- Số nhân viên rời đi chiếm 23% tổng số lao động.
- Số nhân viên được thăng chức trong 5 năm gần đây rất ít.
- Phòng Sales có số nhân viên nhiều nhất, tiếp theo là Technical và Support.
- Đa số nhân viên nhận lương mức trung bình hoặc thấp.
fig=plt.subplots(figsize=(10,15))
for i, j in enumerate(features):
plt.subplot(4, 2, i+1)
plt.subplots_adjust(hspace = 1.0)
sns.countplot(x=j,data = data, hue='left')
plt.xticks(rotation=90)
plt.title("No. of employee")

Bạn có thể quan sát những điểm sau trong hình trực quan trên:
- Những nhân viên có số dự án lớn hơn 5 thường rời công ty.
- Nhân viên làm 6 và 7 dự án đã rời công ty, có vẻ họ bị quá tải công việc.
- Nhân viên có 5 năm kinh nghiệm rời đi nhiều hơn do không được thăng chức trong 5 năm gần đây; còn những người trên 6 năm thì ít rời đi do gắn bó với công ty.
- Những người được thăng chức trong 5 năm gần đây thì không rời đi; tức là tất cả những người rời đi đều không được thăng chức trong 5 năm qua.
Tóm tắt Phân tích và Trực quan hóa Dữ liệu:
Các đặc trưng sau ảnh hưởng nhiều nhất đến việc một người rời công ty:
- Thăng chức: Nhân viên có khả năng nghỉ việc cao hơn nhiều nếu họ không được thăng chức trong 5 năm qua.
- Thời gian gắn bó: Mốc 3 năm có vẻ là thời điểm then chốt trong sự nghiệp của một nhân viên. Nhiều người nghỉ việc quanh mốc này. Một điểm quan trọng khác là mốc 6 năm, nơi nhân viên rất ít rời đi.
- Số lượng dự án: Mức độ gắn kết cũng là yếu tố then chốt ảnh hưởng đến việc rời đi. Nhân viên tham gia 3–5 dự án ít có khả năng rời công ty. Người có số dự án quá ít hoặc quá nhiều thì dễ rời đi hơn.
- Lương: Phần lớn nhân viên nghỉ việc nằm trong nhóm lương trung bình hoặc thấp.
Phân cụm (Cluster Analysis):
Hãy tìm các nhóm nhân viên đã rời đi. Bạn có thể nhận thấy yếu tố quan trọng nhất để một nhân viên ở lại hay rời đi là mức hài lòng và hiệu suất trong công ty. Vậy hãy gom họ vào các nhóm bằng phân tích cụm.
#import module
from sklearn.cluster import KMeans
# Filter data
left_emp = data[['satisfaction_level', 'last_evaluation']][data.left == 1]
# Create groups using K-means clustering.
kmeans = KMeans(n_clusters = 3, random_state = 0).fit(left_emp)
# Add new column "label" annd assign cluster labels.
left_emp['label'] = kmeans.labels_
# Draw scatter plot
plt.scatter(left_emp['satisfaction_level'], left_emp['last_evaluation'], c=left_emp['label'],cmap='Accent')
plt.xlabel('Satisfaction Level')
plt.ylabel('Last Evaluation')
plt.title('3 Clusters of employees who left')
plt.show()

Ở đây, nhân viên rời công ty có thể được nhóm thành 3 loại:
- Hài lòng cao và Đánh giá cao (tô màu xanh lá trên đồ thị), còn gọi là Người chiến thắng.
- Hài lòng thấp và Đánh giá cao (tô màu xanh dương; tô màu xanh lá trên đồ thị), còn gọi là Người bất mãn.
- Hài lòng trung bình và Đánh giá trung bình (tô màu xám trên đồ thị), còn gọi là “Không phù hợp”.
Xây dựng Mô hình Dự đoán
Tiền xử lý Dữ liệu
Nhiều thuật toán học máy yêu cầu dữ liệu đầu vào dạng số, nên bạn cần biểu diễn các cột phân loại thành dạng số.
Để mã hóa dữ liệu này, bạn có thể ánh xạ mỗi giá trị sang một con số. Ví dụ, cột Salary có thể biểu diễn low:0, medium:1 và high:2.
Quy trình này gọi là mã hóa nhãn (label encoding), và sklearn hỗ trợ tiện lợi qua LabelEncoder.
# Import LabelEncoder
from sklearn import preprocessing
#creating labelEncoder
le = preprocessing.LabelEncoder()
# Converting string labels into numbers.
data['salary']=le.fit_transform(data['salary'])
data['Departments ']=le.fit_transform(data['Departments '])
Ở đây, bạn đã nhập mô-đun preprocessing và tạo đối tượng Label Encoder. Dùng đối tượng này để fit và transform các cột "salary" và "Departments " thành cột số.
Chia Tập Huấn luyện và Kiểm tra
Để hiểu hiệu năng mô hình, chia tập dữ liệu thành tập huấn luyện và tập kiểm tra là một chiến lược tốt.
Hãy chia tập dữ liệu bằng hàm train_test_split(). Bạn cần truyền 3 tham số: đặc trưng, mục tiêu và kích thước tập kiểm tra. Ngoài ra, bạn có thể dùng random_state để chọn mẫu ngẫu nhiên.
#Spliting data into Feature and
X=data[['satisfaction_level', 'last_evaluation', 'number_project',
'average_montly_hours', 'time_spend_company', 'Work_accident',
'promotion_last_5years', 'Departments ', 'salary']]
y=data['left']
# Import train_test_split function
from sklearn.model_selection import train_test_split
# Split dataset into training set and test set
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) # 70% training and 30% test
Ở đây, tập dữ liệu được chia làm hai phần theo tỷ lệ 70:30. Tức là 70% dữ liệu dùng để huấn luyện mô hình và 30% để kiểm tra mô hình.
Xây dựng Mô hình
Hãy xây dựng một mô hình dự đoán churn nhân sự.
Ở đây, bạn sẽ dự đoán churn bằng Gradient Boosting Classifier.
Đầu tiên, nhập mô-đun GradientBoostingClassifier và tạo đối tượng bộ phân loại Gradient Boosting bằng hàm GradientBoostingClassifier().
Sau đó, fit mô hình trên tập huấn luyện bằng fit() và dự đoán trên tập kiểm tra bằng predict().
#Import Gradient Boosting Classifier model
from sklearn.ensemble import GradientBoostingClassifier
#Create Gradient Boosting Classifier
gb = GradientBoostingClassifier()
#Train the model using the training sets
gb.fit(X_train, y_train)
#Predict the response for test dataset
y_pred = gb.predict(X_test)
Đánh giá Hiệu năng Mô hình
#Import scikit-learn metrics module for accuracy calculation
from sklearn import metrics
# Model Accuracy, how often is the classifier correct?
print("Accuracy:",metrics.accuracy_score(y_test, y_pred))
# Model Precision
print("Precision:",metrics.precision_score(y_test, y_pred))
# Model Recall
print("Recall:",metrics.recall_score(y_test, y_pred))
Accuracy: 0.971555555556
Precision: 0.958252427184
Recall: 0.920708955224
Bạn đạt tỷ lệ phân loại 97%, được xem là độ chính xác tốt.
Precision: Precision nói về mức độ chính xác, tức mô hình của bạn chính xác đến đâu. Nói cách khác, khi mô hình đưa ra dự đoán, thì đúng bao nhiêu lần. Trong trường hợp này, khi mô hình Gradient Boosting dự đoán một nhân viên sẽ rời đi, thì 95% thời gian nhân viên đó thực sự rời đi.
Recall: Nếu trong tập kiểm tra có một nhân viên đã rời đi, mô hình Gradient Boosting có thể nhận diện đúng 92% trường hợp đó.
Kết luận
Chúc mừng bạn đã hoàn thành bài hướng dẫn này!
Trong hướng dẫn này, bạn đã học Churn nhân sự là gì, nó khác churn khách hàng ra sao, EDA và trực quan hóa tập dữ liệu churn nhân sự bằng matplotlib và seaborn, xây dựng và đánh giá mô hình bằng gói python scikit-learn.
Rất mong nhận được phản hồi hoặc câu hỏi từ bạn. Bạn có thể đặt câu hỏi bằng cách để lại bình luận, tôi sẽ cố gắng phản hồi tốt nhất.
Nếu bạn quan tâm học thêm về Python, hãy xem khóa Intermediate Python for Data Science của DataCamp.