【机器学习案例三】网购人群购买意图分析(分类)

案例背景

数据集“online_shoppers_intention”给出了网购人群是否将浏览行为转化为购买行为的相关数据,包括 10 个数值型属性与 8 个类别型属性,其中“revenue”可以作为分类的类标签。请将该数据集随机划分为训练集(80%)和测试集(20%)并进行分类。

数据预处理

  • 导入库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import os
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
from sklearn.metrics import accuracy_score
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve,roc_auc_score
import time
  • 读取数据
os.chdir('E:\\input')
df=pd.read_csv('online_shoppers_intention.csv')
  • 数据了解
df.columns

[‘Administrative’, ‘Administrative_Duration’, ‘Informational’, ‘Informational_Duration’, ‘ProductRelated’, ‘ProductRelated_Duration’, ‘BounceRates’, ‘ExitRates’, ‘PageValues’, ‘SpecialDay’, ‘Month’, ‘OperatingSystems’, ‘Browser’, ‘Region’, ‘TrafficType’, ‘VisitorType’, ‘Weekend’, ‘Revenue’]

df.dtypes

在这里插入图片描述

  • 处理缺失值
  1. 查看缺失值情况
df.isna().sum()

在这里插入图片描述
每一列的数据都是完整的,没有缺失值。

  • 划分训练集测试集
x=df.drop('Revenue',axis=1)
y=df['Revenue']
x=pd.get_dummies(x)
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=1)

Logistics 回归

要求

请建立带有 L1 惩罚项的 Logistics 回归模型对数据集进行分类,并利用基于 5 折交叉验证的格子搜索技术确定最优惩罚因子;在最优惩罚因子下,分别评价模型在训练集和测试集的预测效果(包括混肴矩阵、准确率、F1-Score、AUC 等)。

模型参数
LogisticRegression().get_params() 

{‘C’: 1.0,
‘class_weight’: None,
‘dual’: False,
‘fit_intercept’: True,
‘intercept_scaling’: 1,
‘max_iter’: 100,
‘multi_class’: ‘warn’,
‘n_jobs’: None,
‘penalty’: ‘l2’,
‘random_state’: None,
‘solver’: ‘warn’,
‘tol’: 0.0001,
‘verbose’: 0,
‘warm_start’: False}

调参
logit=LogisticRegression(penalty='l1')
parameters={'C':np.arange(0.1,30,1)}
logit_cv=GridSearchCV(logit,param_grid=parameters,cv=5)
logit_cv.fit(x,y)
print(logit_cv.best_params_)   #22.1
print(logit_cv.best_score_)   

best_params_:{‘C’: 22.1}
best_score:0.884

用最优参数训练模型
logit=LogisticRegression(penalty='l1',C=22.1)
logit.fit(x_train,y_train)
y_pre=logit.predict(x_test)
logit.score(x_train,y_train)
logit.score(x_test,y_test)

训练集精度:0.883
测试集精度:0.892

模型评价
  1. 混淆矩阵
classification_report(y_test,y_pre)

在这里插入图片描述

  1. AUC
y_prob=logit.predict_proba(x_test)
fpr,tpr,_=roc_curve(y_test,y_prob[:,1])
plt.figure()
plt.plot(fpr,tpr,color='r',lw=2)
auc=roc_auc_score(y_test,y_prob[:,1])
print(auc) 

在这里插入图片描述
auc=0.9058

平衡正负样例

要求

原始数据存在比较明显的类别不平衡问题,请采用样本复制法修正训练集的类别不平衡问题(也就是将训练集中 revenue=True 的样例复制多次,使得 revenue=True 与 revenue=False 的样例数相等);在修正后的训练集中重新训练模型,并比较类别不平衡修正前后模型预测效果的差异。

平衡样例
  1. 查看正负样例情况
df['Revenue'].value_counts()

在这里插入图片描述
2. 复制较少的样例并合并到数据框中

df_true=df[df['Revenue']==True]
df_balanced=pd.concat([df,df_true],axis=0)
df_balanced=pd.concat([df_balanced,df_true],axis=0)
df_balanced=pd.concat([df_balanced,df_true],axis=0)
df_balanced=pd.concat([df_balanced,df_true],axis=0)
#还差882个
df_true882=df[df['Revenue']==True].sample(882)
df_balanced=pd.concat([df_balanced,df_true882],axis=0)
  1. 查看平衡结果
df_balanced['Revenue'].value_counts()

在这里插入图片描述

用新训练集训练模型
x1=df_balanced.drop('Revenue',axis=1)
y1=df_balanced['Revenue']
x1=pd.get_dummies(x1)
x_train1,x_test1,y_train1,y_test1=train_test_split(x1,y1,test_size=0.2,random_state=1)
logit=LogisticRegression(penalty='l1',C=22.1)
logit.fit(x_train1,y_train1)
y_pre1=logit.predict(x_test1)

平衡样例结果

classification_report(y_test1,y_pre1)

平衡样例以后,True类的查准率和召回率都显著的提高。
平衡样例结果

模型预测效果差异

原始结果
在这里插入图片描述
样本类别为True的查准率和召回率都提高

SVM模型

要求

请建立 SVM 模型对数据集进行分类,并利用基于 5 折交叉验证的格子搜索技术调参;在最优算法参数下,分别评价模型在训练集和测试集的预测效果(包括混肴矩阵、准确率、F1-Score、AUC 等)。

模型参数
from sklearn.svm import SVC
SVC().get_params()

{‘C’: 1.0,
‘cache_size’: 200,
‘class_weight’: None,
‘coef0’: 0.0,
‘decision_function_shape’: ‘ovr’,
‘degree’: 3,
‘gamma’: ‘auto_deprecated’,
‘kernel’: ‘rbf’,
‘max_iter’: -1,
‘probability’: False,
‘random_state’: None,
‘shrinking’: True,
‘tol’: 0.001,
‘verbose’: False}
核技巧:使用一个变化将原空间的数据映射到新空间;然后在新空间里用线性分类的学习的方法从训练数据中学习分类模型。
SVM模型有两个非常重要的参数C与gamma。其中 C是惩罚系数,即对误差的宽容度。c越高,说明越不能容忍出现误差,容易过拟合。C越小,容易欠拟合。C过大或过小,泛化能力变差。
gamma是选择RBF函数作为kernel后,该函数自带的一个参数。隐含地决定了数据映射到新的特征空间后的分布,gamma越大,支持向量越少,gamma值越小,支持向量越多。支持向量的个数影响训练与预测的速度。

调参
svc=SVC(kernel='rbf')
parameters={'gamma':[0.0001,0.0005,0.001],'C':[0.1,0.2,0.5,0.6,0.7,0.8,0.9,1,2,3,4]}
svc_grid=GridSearchCV(svc,param_grid=parameters,cv=5)
svc_grid.fit(x,y)
svc_grid.cv_results_
print(svc_grid.best_params_)  
print(svc_grid.best_score_) 

best_params_:{‘C’: 0.7, ‘gamma’: 0.0001}
best_score:0.8769

用最优参数训练模型
svc=SVC(kernel='rbf',C=0.7,gamma= 0.0001,probability=True)
  #svc画auc时probability=True才能运行
svc.fit(x_train,y_train)
ypred=svc.predict(x_test)
yhat=svc.predict(x_train)
np.mean(y_train==yhat)
np.mean(y_test==ypred)

训练集精度:0.9943
测试集精度:0.857

模型评价
  1. 混淆矩阵
classification_report(y_test,ypred)

在这里插入图片描述
比logit回归查准率提高,但是召回率下降。
2. AUC

y_prob=svc.predict_proba(x_test)
fpr,tpr,_=roc_curve(y_test,y_prob[:,1])
plt.figure()
plt.plot(fpr,tpr,color='r',lw=2)
auc=roc_auc_score(y_test,y_prob[:,1])
print(auc) 

在这里插入图片描述
AUC=0.808

决策树

要求

请建立决策树模型(max_depth=3)对数据集进行分类,并绘制相应的决策树;在此基础上利用基于 5 折交叉验证的格子搜索技术确定最优 max_depth,并分别评价模型在训练集和测试集的预测效果;利用产生的决策树确定属性重要性。

导入库
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
from sklearn.externals.six import StringIO
import pydotplus
from IPython.core.display import Image
模型参数
DecisionTreeClassifier().get_params()

{‘class_weight’: None,
‘criterion’: ‘gini’,
‘max_depth’: None,
‘max_features’: None,
‘max_leaf_nodes’: None,
‘min_impurity_decrease’: 0.0,
‘min_impurity_split’: None,
‘min_samples_leaf’: 1,
‘min_samples_split’: 2,
‘min_weight_fraction_leaf’: 0.0,
‘presort’: False,
‘random_state’: None,
‘splitter’: ‘best’}

画出决策树
tree=DecisionTreeClassifier(max_depth=3)
tree.fit(x_train,y_train)
tree.score(x_test,y_test)  #0.9
dot_data=StringIO()
export_graphviz(tree,
                out_file=dot_data,
                filled=True,
                feature_names=x.columns,
                class_names=y.unique().astype(str),
                rounded=True,
                special_characters=True,
                )
graph=pydotplus.graph_from_dot_data(dot_data.getvalue())
Image(graph.create_png())
graph.write_pdf("online_shop.pdf")

在这里插入图片描述

最优 max_depth
tree=DecisionTreeClassifier()
parameters={'max_depth':np.arange(1,20,1)}
tree_grid=GridSearchCV(tree,param_grid=parameters,cv=5)
tree_grid.fit(x,y)
print(tree_grid.best_params_) 
print(tree_grid.best_score_)

best_params_:{‘max_depth’:5}
best_score_:0.8953

在最优 max_depth的基础上评价模型效果
tree=DecisionTreeClassifier(max_depth=5)
tree.fit(x_train,y_train)
pre=tree.predict(x_test)
acc_train=tree.score(x_train,y_train)  
acc_test=tree.score(x_test,y_test)   

训练集精度:0.909
测试集精度:0.9018

属性重要性
stat=pd.DataFrame(columns=['importance','feature'])
stat['importance']=tree.feature_importances_
stat['feature']=x.columns
stat.sort_values(by='importance',ascending=False,inplace=True)

在这里插入图片描述

Bagging、AdaBoost 、随机森林

要求

以 Logistic 模型(L1 惩罚项、惩罚因子 C=1)与 max_depth=2 的决策树模型为基学习器,然后分别基于 Bagging、AdaBoost 以及随机森林构造集成学习(基学习器个数均为 100),请比较不同集成学习算法在训练集和测试集上的预测效果以及算法的执行时间。

模型训练
logit=LogisticRegression(penalty='l1',C=1)
tree=DecisionTreeClassifier(max_depth=2)
from sklearn.ensemble import BaggingClassifier

bag_train_=[]
bag_test_=[]
bag_time=[]
for i in [logit,tree]:
    a=time.time()
    model=BaggingClassifier(base_estimator=i,n_estimators=100)
    model.fit(x_train,y_train) 
    bag_train = accuracy_score(y_train,model.predict(x_train))
    bag_test = accuracy_score(y_test,model.predict(x_test))
    print("Bagging  train/test accuracies : %.3f/%.3f"%(bag_train,bag_test))
    bag_train_.append(str(bag_train)[:5])
    bag_test_.append(str(bag_test)[:5])
    bag_time.append(time.time()-a)
    
from sklearn.ensemble import AdaBoostClassifier

ada_train_=[]
ada_test_=[]
ada_time=[]
for i in [logit,tree]:
    a=time.time()
    model=AdaBoostClassifier(base_estimator=i,n_estimators=100)
    model.fit(x_train,y_train) 
    ada_train = accuracy_score(y_train,model.predict(x_train))
    ada_test = accuracy_score(y_test,model.predict(x_test))
    print("AdaBoost  train/test accuracies : %.3f/%.3f"%(ada_train,ada_test))
    ada_train_.append(str(ada_train)[:5])
    ada_test_.append(str(ada_test)[:5])
    ada_time.append(time.time()-a)

from sklearn.ensemble import RandomForestClassifier

stat={}
stat['bag_train']=bag_train_
stat['bag_test']=bag_test_
stat['bag_time']=bag_time
stat['ada_train']=ada_train
stat['ada_test']=ada_test_
stat['ada_time']=ada_time

stat=pd.DataFrame(stat,index=['logit','tree'])
stat.to_excel('online_shop_ensemble.xls')

对于bagging集成学习模型, 基学习器用Logistic或者决策树在训练集上和测试集上的表现效果都差不多 ,但时间上决策树作为基学习器的速度明显快于Logistic。
在这里插入图片描述
对于adaboost集成学习模型,基学习器用Logistic或者决策树在训练集上和测试集上的表现效果都差不多 ,时间上的差异比bagging更大,原因可能是因为bagging每个基学习期可以同时训练,而adaboost的基学习器只能一个一个的训练,所以时间上的差异会更明显。
在这里插入图片描述

from sklearn.ensemble import RandomForestClassifier
model=RandomForestClassifier(n_estimators=100)
model.get_params()

{‘bootstrap’: True,
‘class_weight’: None,
‘criterion’: ‘gini’,
‘max_depth’: None,
‘max_features’: ‘auto’,
‘max_leaf_nodes’: None,
‘min_impurity_decrease’: 0.0,
‘min_impurity_split’: None,
‘min_samples_leaf’: 1,
‘min_samples_split’: 2,
‘min_weight_fraction_leaf’: 0.0,
‘n_estimators’: 100,
‘n_jobs’: None,
‘oob_score’: False,
‘random_state’: None,
‘verbose’: 0,
‘warm_start’: False}

随机深林的基学习器只能是决策树,没有改变基学习器的这个参数,

a=time.time()
model=RandomForestClassifier(n_estimators=100)
model.fit(x_train,y_train) 
rf_train = accuracy_score(y_train,model.predict(x_train))
rf_test = accuracy_score(y_test,model.predict(x_test))
rf_time=time.time()-a

在这里插入图片描述
在训练集和测试你集上的精度都高于前两个模型,时间也是最短的。

  • 15
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值