此篇文章是用来梳理"paper:Causal Analysis Churn"的代码
流程:
- 1.导入数据集
- 2.将前两个数据集拼接在一起
- 3.特征工程:
- 3.1创建副本 删掉重复行
- 3.2找到分类列和数量列
- 3.3删掉高相关性特征
- 3.4预处理:对类别特征进行one-hot编码
- 4.模型评估
- 4.1对训练数据进行欠采样处理
- 4.2评估指标
- 5.集成学习
- 5.1建立集成学习分类器-hard
- 5.2建立集成学习分类器-soft
- 6.特征选择-随机森林变量的重要性
- 6.1训练随机森林分类器
- 6.2显示重要性最大的前180个
- 6.3将重要性前100个存入列表,然后将训练数据只保存前100个
- 6.4将修改后的数据集用于训练,并添加模型评价指标
- 7.特征挑选方法-递归特征消除
- 7.1过采样处理,平衡样本量
- 7.2定义特征选择器,进行特征选择
- 7.3保留选择后的特征
- 7.4创建评价指标列表,并将分类器加入到model列表中
- 7.5训练模型
- 8.在简单模型上的集成
- 8.1simple voting
- 8.2weight voting
- 8.3weight voting2
- 9.基于深度学习的集成
- 9.1对训练数据和测试数据进行特征缩放
- 9.2定义深度学习模型:ANN1,ANN2
- 9.3进行模型训练
- 10.ROC AUC曲线
- 10.1定义模型
- 10.2训练模型
- 10.3定义roc auc函数
- 10.4展示图像
- 11.precision-recall曲线
- 11.1定义函数
- 11.2绘图
- 12.dowhy归因分析
- 13.模型可解释性
- 13.1eli5展示特征重要性
- 13.2pdp图(部分依赖图)
- 13.3shap
1.导入数据集
1 | observation_window1 = pd.read_csv('new_data/features_201506.csv') |
2.将前两个数据集拼接在一起,将observation的churn列去掉换上outcome的churn列
1 | #将两个数据集拼接在一起 |
去掉churn列
1 | # 去除数据中存款低于1500和任期低于6个月的客户数据,这样能增加预测的正确性 |
添加上outcome的churn列
1 | #outcome_window中只要id列和churn列 |
3.特征工程
3.1创建副本 删掉重复行
1 | # 创建一个之前数据集的副本,检查数据集中是否还有重复行 |
3.2 找到分类列和数量列
Display uniqueness in each column
显示df每一列的唯一值和缺失值
1 | def summarize_categoricals(df, show_levels=False): |
cutoff是分类的阈值
如果说一个列的唯一值数量小于10,那么他就会被判别为一列分类数据,其列名将会加入到返回的分类列表中
一个好的分类列应该有较少的unique值
1 | def find_categorical(df, cutoff=10): |
将指定列转换为categorical类型
categorical类型在pandas中meaning表示分类的数据,比普通object类型会更加高效,尤其是在内存使用上
1 | def to_categorical(columns, df): |
💡总结:先用summarize_categoricals统计每个特征的唯一值和空值,然后根据统计好的唯一值和空值来自动判断是不是类别特征,然后将判断为类别特征的对象转化为类别特征类型
执行:
找到分类列
1 | categoricals = find_categorical(finalDF, cutoff=12) |
找到数量列
1 | numericals = list(set(finalDF.columns.tolist()) - set(categoricals)) + list(set(categoricals) - set(finalDF.columns.tolist())) |
3.3 删掉高相关性特征
Objective:移除特征间相关性太高的特征列
Inputs:
- x: df
- threshold: 相关性大于此值将被移除
Output: df
1 | def remove_collinear_features(x, threshold = 0.99): |
执行
1 | #移除特征相关性超过0.9的特征并print |
3.4 预处理:对类别特征进行one-hot编码
one-hot编码
1 | def one_hot_encoding(df, cols): |
规范化处理
1 | def normalize(df, cols): |
执行:
对类别特征进行one-hot编码
1 | finalDF = one_hot_encoding(finalDF, categoricals) |
创建分类特征和数值特征的列表
1 | categorical_columns = list(x.select_dtypes(include='category').columns) |
切分数据集
1 | data_splits = train_test_split(x, y, test_size=0.2, random_state=0, |
4.模型评估
4.1 对训练数据进行欠采样处理
进行欠采样处理,删除掉训练数据中的一部分,使得样本数量变得平衡
1 | X_train, y_train = RandomUnderSampler().fit_resample(X_train, y_train) |
4.2 评估指标
定义多个列表来存储不同评估指标
1 | train_accuracy = [] #训练集精度 |
添加分类器
1 | classifiers.append(BernoulliNB()) |
训练不同的分类模型,并计算各种重要的评价指标
1 | for classifier,model in zip(classifiers, models): |
5.集成学习
5.1 建立集成学习器(硬投票) ,并将指标存入
1 | nsemble = VotingClassifier(estimators=[('Logistic Regression', LogisticRegression(random_state = random_state)), |
训练集成学习模型,并将指标存入
1 | y_train_ensemble = ensemble.predict(X_train) |
5.2 建立集成学习器(软投票) ,并将指标存入
1 | #与ensemble1不同的是:这里是soft voting |
6.特征选择-随机森林变量重要性
6.1 训练随机森林分类器
1 | # 初始化随机森林分类器,并将🌲的个数设置为500 |
6.2 显示重要性最大的前180个
1 | # 创建series对象,内容包含随机森林分类器的重要性得分 |
6.3将重要性最高的前100个存入列表,然后将训练数据中的特征只保存前100个
1 | # 将重要性最高的前一百个特征存入到列表中 |
6.4将修改后的数据集用于训练,并添加评价指标
创建评价指标,将分类器加入到模型中
1 | train_accuracy = [] |
训练模型并将指标存入列表中
1 | for classifier,model in zip(classifiers, models): |
1 | scoreDF = pd.DataFrame({'Model' : models}) |
7. 特征挑选方法-递归特征消除(这个方法和6是并列的关系)
7.1 过采样处理,平衡样本量
1 | from imblearn.over_sampling import SMOTE |
7.2 定义特征选择器,进行特征选择
1 | # 定义特征选择器 |
7.3 保留选择后的特征
1 | X_train = X_train[rfe_feature] |
7.4 创建评价指标列表,并将分类器加入到models列表中
1 | train_accuracy = [] |
7.5 训练模型
1 | for classifier,model in zip(classifiers, models): |
8.在简单模型上的集成
8.1 simple voting
训练分类器
1 | LR = LogisticRegression(random_state = random_state, n_jobs=-1) |
进行预测
1 | LR_pred = LR.predict(X_test) |
宏平均求得结果
1 | averaged_preds = (LR_pred + NB_pred + RF_pred + KNN_pred + DT_pred + BG_pred + ADA_pred +XGB_pred + ET_pred + GBM_pred)//10 |
8.2 weight averaging
定义集成学习器
1 | ensemble = VotingClassifier(estimators=[('Logistic Regression', LogisticRegression(random_state = random_state)), |
计算评价指标
1 |
|
8.3 weight averaging2
定义集成学习分类器并进行训练
1 | ensemble = VotingClassifier(estimators=[('Logistic Regression', LogisticRegression(random_state = random_state)), |
计算评价指标
1 | trainaccuracy = accuracy_score(y_train, y_train_ensemble) |
9.基于深度学习的集成
9.1对训练数据和测试数据进行特征缩放
1 | scaler = MinMaxScaler(feature_range=(0, 1)) |
9.2 定义深度学习模型: ANN1,ANN2
1 | def model_ANN1(input_shape=X_train.shape[1], num_classes=2): |
1 |
|
9.3 进行模型训练
1 | models = [] |
10.ROC AUC曲线
10.1 定义模型
同上
10.2 训练模型
同上
10.3 定义roc auc函数
1 | def roc_auc_plot(y_true, y_proba, label=' ', l='-', lw=1.0): |
10.4 展示图像
1 | roc_auc_plot(y_test,LR.predict_proba(X_test),label='Logsitic Regression Classifier ',l='-') |
11.precision-recall曲线
11.1定义函数
1 | def precision_recall_plot(y_true, y_proba, label=' ', l='-', lw=1.0): |
11.2 绘图
1 | precision_recall_plot(y_test,LR.predict_proba(X_test),label='Logsitic Regression Classifier ',l='-') |
12 dowhy 归因分析
13. 模型可解释性
13.1 eli5展示特征重要性
1 | import eli5 |
13.2 pdp图(部分依赖图)
1 | # 特征名称 |
13.3 shap
单个数据的shap图
1 | # Create object that can calculate shap values |
总体数据的shap图
1 | # Create object that can calculate shap values |