数据的分析
数据的截图
# EmpID 唯一的员工ID # Age 年龄 # AgeGroup 年龄组 # Attrition 是否离职 # BusinessTravel 出差:很少、频繁、不出差 # DailyRate 日薪 # Department 任职部门:研发部门、销售部门、人力资源部门 # DistanceFromHome 通勤距离 # Education 教育等级 # EducationField 专业领域:生命科学、医学、市场营销、技术、其他 # EnvironmentSatisfaction 工作环境满意度 # Gender 性别 # HourlyRate 时薪 # JobInvolvement 工作参与度 # JobLevel 工作级别 # JobRole 工作角色 # JobSatisfaction 工作满意度 # MaritalStatus 婚姻状况 # MonthlyIncome 月收入 # SalarySlab 工资单 # MonthlyRate 月薪 # NumCompaniesWorked 工作过的公司数量 # PercentSalaryHike 加薪百分比 # PerformanceRating 绩效评级 # RelationshipSatisfaction 关系满意度 # StandardHours 标准工时 # StockOptionLevel 股票期权级别 # TotalWorkingYears 总工作年数 # TrainingTimesLastYear 去年培训时间 # WorkLifeBalance 工作生活平衡评价 # YearsAtCompany 在公司工作年数 # YearsInCurrentRole 担任现职年数 # YearsSinceLastPromotion 上次晋升后的年数 # YearsWithCurrManager 与现任经理共事年数
这是对数据的分析
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score,precision_score,recall_score,f1_score
df = pd.read_csv("HR_Analytics.csv")
pd.set_option("display.max_columns",100)
# print(df.info())
# 从这里我们可以发现YearsWithCurrManager这一列有缺失值
# 这里我们选择以众数来填充
df['YearsWithCurrManager'] = df['YearsWithCurrManager'].fillna(df['YearsWithCurrManager'].mode()[0])
# 处理完缺失值,我们来看数据本身,EmpID员工的id这本身就是一种没有用的信息
# print(df.nunique())
# 从这里可以看出EmployeeCount,Over18,StandardHours这三个数据只有一种数据,可以明确其对我们的分析没有任何帮助,
# 所以,我们将这几列数据全部删除
df = df.drop(['EmpID','EmployeeCount','Over18','StandardHours'],axis=1)
# 到这里我们对数据集的基础处理就结束了
问题描述
识别导致员工离职的因素(Attrition与其他字段的关系)。
分析不同年龄组、婚姻状况、工作年数与离职之间的关系。。
用历史数据建模,预测员工潜在的流失风险。
问题一
# 1.识别导致员工离职的因素(Attrition与满意度的关系)。
plt.rcParams['font.family'] = ['sans-serif']
plt.rcParams['font.sans-serif'] = ['SimHei']
df['Attrition'] = df['Attrition'].map({'Yes':1,'No':0})
Esatisfaction_attrition = df.groupby('EnvironmentSatisfaction')['Attrition'].sum().reset_index()
Esatisfaction_attrition = Esatisfaction_attrition.sort_values(by='Attrition',ascending=False)
plt.figure(figsize=(10,6))
plt.subplot(1,3,1)
plt.bar(Esatisfaction_attrition['EnvironmentSatisfaction'],Esatisfaction_attrition['Attrition'],color= 'lightblue')
plt.title("工作环境满意度与员工离职的关系")
Jsatisfaction_attrition = df.groupby('JobSatisfaction')['Attrition'].sum().reset_index()
Jsatisfaction_attrition = Jsatisfaction_attrition.sort_values(by='Attrition',ascending=False)
plt.subplot(1,3,2)
plt.bar(Jsatisfaction_attrition['JobSatisfaction'],Jsatisfaction_attrition['Attrition'],color='red')
plt.title("工作满意度与员工离职的关系")
Rsatisfaction_attrition = df.groupby('RelationshipSatisfaction')['Attrition'].sum().reset_index()
Rsatisfaction_attrition = Rsatisfaction_attrition.sort_values(by='Attrition',ascending=False)
plt.subplot(1,3,3)
plt.bar(Rsatisfaction_attrition['RelationshipSatisfaction'],Rsatisfaction_attrition['Attrition'],color='green')
plt.title("关系满意度与员工离职的关系")
由于第一问的分析涉及工作方面,教育方面等多个方面,故这里不做过多展示(仅展示与工作方面的关系):
# 1.识别导致员工离职的因素(Attrition与工作的关系)。
department_attrition = pd.crosstab(df['Department'], df['Attrition']) # 部门
business_travel_attrition = pd.crosstab(df['BusinessTravel'], df['Attrition']) # 出差
Distance_attrition = pd.crosstab(df['DistanceFromHome'],df['Attrition']) # 通勤距离
Job_role_attrition = pd.crosstab(df['JobRole'], df['Attrition'])
department_attrition.plot(kind='bar',colormap='inferno')
business_travel_attrition.plot(kind='bar',colormap='viridis')
Distance_attrition.plot(kind='bar',colormap='autumn')
Job_role_attrition.plot(kind='bar',colormap='summer')
问题二
# 2.分析不同年龄组、婚姻状况、工作年数与离职率之间的关系。
# 为了方便观察这些特征之间的关系,我们做对比图
age_attrition = df.groupby(['AgeGroup','Attrition']).size().unstack()
age_attrition.plot(kind='bar')
plt.title("年龄与离职之间的关系")
marry_attrition = df.groupby(['MaritalStatus','Attrition']).size().unstack()
marry_attrition.plot(kind='bar')
plt.title("婚姻状况与离职之间的关系")
year_attrition = df.groupby(['TotalWorkingYears','Attrition']).size().unstack()
year_attrition.plot(kind='bar')
plt.title("工作年数与离职之间的关系")
# plt.show()
问题三:
X = df.drop('Attrition',axis=1)
y = df['Attrition']
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=42)
Dtree = DecisionTreeClassifier(random_state=42)
Rtree = RandomForestClassifier(random_state=42)
knn = KNeighborsClassifier(n_neighbors=5)
Dtree.fit(X_train,y_train)
Rtree.fit(X_train,y_train)
knn.fit(X_train,y_train)
y_pred_Dtree = Dtree.predict(X_test)
y_pred_Rtree = Rtree.predict(X_test)
y_pred_knn = knn.predict(X_test)
accuracy_Dtree = accuracy_score(y_test,y_pred_Dtree)
accuracy_Rtree = accuracy_score(y_test,y_pred_Rtree)
accuracy_knn = accuracy_score(y_test,y_pred_knn)
# print("决策树的准确值:",accuracy_Dtree)
# print("随机森林的准确值:",accuracy_Rtree)
# print("KNN的准确值:",accuracy_knn)
precision_Dtree = precision_score(y_test, y_pred_Dtree)
precision_Rtree = precision_score(y_test, y_pred_Rtree)
precision_knn = precision_score(y_test, y_pred_knn)
# print("决策树的精确度:", precision_Dtree)
# print("随机森林的精确度:", precision_Rtree)
# print("KNN的精确度:", precision_knn)
recall_Dtree = recall_score(y_test, y_pred_Dtree)
recall_Rtree = recall_score(y_test, y_pred_Rtree)
recall_knn = recall_score(y_test, y_pred_knn)
# print("决策树的召回率:", recall_Dtree)
# print("随机森林的召回率:", recall_Rtree)
# print("KNN的召回率:", recall_knn)
f1_Dtree = f1_score(y_test, y_pred_Dtree)
f1_Rtree = f1_score(y_test, y_pred_Rtree)
f1_knn = f1_score(y_test, y_pred_knn)
# print("决策树的F1分数:", f1_Dtree)
# print("随机森林的F1分数:", f1_Rtree)
# print("KNN的F1分数:", f1_knn)
result = pd.DataFrame({
'Model':['决策树','随机森林','KNN'],
'准确值':[accuracy_Dtree,accuracy_Rtree,accuracy_knn],
'精确度':[precision_Dtree,precision_Rtree,precision_knn],
'召回率':[recall_Dtree,recall_Rtree,recall_knn],
'F1-分数':[f1_Dtree,f1_Rtree,f1_knn]
})
# 创建表格
# fig, ax = plt.subplots()
# ax.axis('off') # 不显示坐标轴
# table = ax.table(cellText=result.values, colLabels=result.columns, cellLoc='center', loc='center')
# plt.show()
print(result)
我们选择三种模型来进行预测:
在选择模型时,我们需要根据具体应用场景来决定哪些指标更为重要。例如:
- 如果我们希望模型的预测尽可能准确,那么我们应该选择准确值最高的模型,即随机森林。
- 如果我们希望模型对于正类的预测更加精准,那么我们应该选择精确度最高的模型,这里也是随机森林。
- 如果我们希望模型能够捕捉到更多的正类实例,那么我们应该选择召回率最高的模型,这里是决策树。
- 如果我们需要一个平衡精确度和召回率的模型,那么我们应该选择F1-分数最高的模型,这里也是决策树。