比赛介绍 数据集 本数据集来源于DC竞赛平台 。数据主要包括影响员工离职的各种因素(工资、出差、工作环境满意度、工作投入度、是否加班、是否升职、工资提升比例等)以及员工是否已经离职的对应记录。
其中训练数据主要包括1100条记录,31个字段,测试数据主要包括350条记录,30个字段,测试数据不包括员工是否已经离职的记录,要求使用逻辑回归等对员工离职进行预测。(注:比赛所用到的数据取自于IBM Watson Analytics分析平台分享的样例数据。该平台只选取了其中的子集,并对数据做了一些预处理使数据更加符合逻辑回归分析比赛的要求。)
评测标准 使用混淆矩阵来评价模型的准确率acc。 acc = (TP+TN)/(TP+FP+FN+TN)
数据分析和预处理 首先观察数据类型train.info()
、test.info()
。可以看到既有int也有object,要对他们进行分别处理。当然,有时候int其实也代表着离散变量,可当作object处理。
查看数字型参数。其中,EmployeeNumber
列是没有意义的参数,可以删去。同时,可以发现Over18
和StandardHours
中的元素全部相同,也删去。
1 2 3 4 5 6 7 8 train['Over18' ].unique() test['Attrition' ]=-1 data = train.append(test).reset_index(drop=True ) data.drop(['Over18' , 'StandardHours' ,'EmployeeNumber' ], axis=1 , inplace=True ) feat_col = [i for i in data.select_dtypes(object).columns if i not in ['Attrition' ]]
可以看到现在的object列为['BusinessTravel', 'Department', 'EducationField', 'Gender', 'JobRole', 'MaritalStatus', 'OverTime']
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def encode_onehot (df,column_name) : feature_df=pd.get_dummies(df[column_name], prefix=column_name) all_col = pd.concat([df.drop([column_name], axis=1 ),feature_df], axis=1 ) return all_col for i in cat_col: data = encode_onehot(data,i) max_min_scaler = lambda x : (x-np.min(x))/(np.max(x)-np.min(x)) for i in feats: data[i]=data[[i]].apply(max_min_scaler) data.isnull().sum()
此时再打印data可以看到所有数据都被转化成了[0,1]之间的浮点数。
建模及预测 1 2 3 4 5 6 7 8 9 10 X_train = data[data['Attrition' ] !=-1 ][feats] y_train = data[data['Attrition' ] !=-1 ]['Attrition' ] X_test = data[data['Attrition' ] ==-1 ][feats] lr_model = LogisticRegression() lr_model.fit(X_train,y_train) pre = lr_pre.predict(X_test) result = pd.DataFrame({'result' :pre.astype(int)}) result.to_csv(path+'output/new_lr' ,index=False )
逻辑回归单个模型simple版得分0.89428。可以做更进一步的分析处理。
进一步提升 之前也简单写过数据清洗和特征工程对于一个模型的优劣有着重要的影响,下面就来看一下效果。
Solution1:特征提取 1 2 3 4 5 6 7 8 9 corr = data.corr() import matplotlib.pyplot as pltimport seaborn as sns%matplotlib inline plt.style.use({'figure.figsize' :(10 ,8 )}) sns.heatmap(corr, xticklabels=corr.columns.values, yticklabels=corr.columns.values,cmap="YlGnBu" ) plt.show()
可以看到MonthlyIncome
和JobLevel
高度相关,TotalWorkingYears
和多个特征都较相关,故尝试删除JobLevel
和TotalWorkingYears
。
Solution2:交叉验证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 from sklearn.model_selection import KFoldmodel=LogisticRegression() n_splits=5 kfold = KFold(n_splits=5 , shuffle=True , random_state=42 ) res['pred' ] = 0 model.random_state = 42 for train_idx, val_idx in kfold.split(X_train): model.random_state = model.random_state + 1 train_x1 = X_train.loc[train_idx] train_y1 = y_train.loc[train_idx] test_x1 = X_train.loc[val_idx] test_y1 = y_train.loc[val_idx] model.fit(train_x1, train_y1) result = model.predict(X_test)
结合Solution1和2得分为0.905714(96/2816)。
Solution3:模型融合