AI离职分析配置:从零搭建员工离职风险分析流程
员工离职风险分析的核心是把历史人事数据整理成特征,训练一个分类模型来预测离职概率。
本文以Python和scikit-learn为例,从零配置一套可运行的离职分析流程,适合有基础Linux操作经验、想快速验证效果的运维或HR技术人员。
环境准备与依赖安装
建议使用Ubuntu 22.04或CentOS 7以上系统,Python版本3.8到3.11均可。
先创建独立虚拟环境,避免污染系统包。
python3 -m venv /opt/attrition-env
source /opt/attrition-env/bin/activate
pip install pandas scikit-learn flask joblib
准备一份CSV格式的人事数据,至少包含以下字段:员工编号、部门、职位级别、司龄、最近绩效评分、是否离职(0或1)。
字段名建议用英文,例如emp_id, department, level, tenure, performance, attrition。
数据清洗与特征处理
读取CSV后,先检查缺失值和类别分布。
离职样本通常较少,需要关注类别不平衡问题。
import pandas as pd
df = pd.read_csv('/data/hr.csv')
print(df.isnull().sum())
print(df['attrition'].value_counts())
对类别字段做独热编码,数值字段做标准化。
使用ColumnTransformer组合处理,方便后续复用。
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
cat_cols = ['department', 'level']
num_cols = ['tenure', 'performance']
preprocessor = ColumnTransformer(
transformers=[
('cat', OneHotEncoder(handle_unknown='ignore'), cat_cols),
('num', StandardScaler(), num_cols)
])
模型训练与评估
用逻辑回归作为基线模型,训练集和测试集按7:3划分。
如果离职样本占比低于20%,设置class_weight='balanced'。
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.metrics import classification_report
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.3, random_state=42)
model = Pipeline([
('prep', preprocessor),
('clf', LogisticRegression(class_weight='balanced', max_iter=1000))
])
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print(classification_report(y_test, y_pred))
关注recall(召回率)而不是准确率,因为漏掉真正要离职的员工代价更高。
如果召回率低于0.6,可以尝试调整阈值或增加特征。
部署为API服务
用Flask暴露一个预测接口,接收JSON格式的员工特征,返回离职概率。
保存模型到磁盘,服务启动时加载。
import joblib
from flask import Flask, request, jsonify
joblib.dump(model, '/opt/attrition_model.pkl')
app = Flask(__name__)
model = joblib.load('/opt/attrition_model.pkl')
@app.route('/predict', methods=['POST'])
def predict():
data = request.get_json()
df_input = pd.DataFrame([data])
prob = model.predict_proba(df_input)[0][1]
return jsonify({'attrition_probability': round(float(prob), 4)})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
启动服务:python app.py。
用curl测试:
curl -X POST http://127.0.0.1:5000/predict \
-H 'Content-Type: application/json' \
-d '{"department":"IT","level":"P5","tenure":3,"performance":4}'
预期返回类似{"attrition_probability": 0.32}。
如果返回500错误,检查请求字段名是否与训练时一致。
避坑与效果验证
常见坑一:训练和推理字段不一致。 API接收的JSON字段名必须和训练CSV列名完全一致,包括大小写。
建议在代码中固定字段列表,启动时校验。
常见坑二:类别值未覆盖。 如果新数据出现训练时未出现的部门,OneHotEncoder会忽略该值,导致特征维度变化。
设置handle_unknown='ignore'可以避免报错,但需要监控未知类别比例。
验证方法: 用测试集生成混淆矩阵,确认召回率和精确率在可接受范围。
上线后每周抽样人工核对预测结果,记录误判案例,用于迭代特征。
如果模型效果长期不理想,优先检查数据质量:司龄、绩效评分是否存在大量缺失或异常值。
数据清洗往往比换模型更有效。