热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

CDA营销项目

《产品营销模型之建置及预测》赛题说明最终成绩:0.8225背景:A公司有一款在线服务的P产品,公司的营销通路是100%的

《产品营销模型之建置及预测》赛题说明

最终成绩:0.8225

背景:
A公司有一款在线服务的P产品,公司的营销通路是100%的网络媒介。A公司希望提供30天免费的P产品后,期望顾客能正式签约购买P产品之服务。但A公司发现‚每隔1~2天便对数以万计的顾客发送电子营销文宣,不但购买率低下,甚至造成诸多客诉。同时,客户之预期获利是以人工经验评估之,没有量化或模型工具之协助,不晓得到底应该使用广告全投放还是机器学习模型来做投放?

目标:
A公司希望发掘用户购买产品的行为习惯,建立产品精准营销模型,对有意向的客户进行精准营销,增加收入,减少开支。

评分标准:
我们通过混淆矩阵(Confusion matrix)来评价分类模型的准确率。准确率越高,说明正确预测出响应营销效果越好。

提交结果:
选手以训练数据为基础,建立产品营销模型,并上传一个测试结果的档案results.csv,文档中只有两个字段,分别是客户ID以及预测客户是否会购买(Predicted_Results)的结果。

字段说明
在这里插入图片描述

代码

"""准备工具"""
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
#查看缺失值
import missingno as msno
#时间模块
import time
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report,roc_auc_score,accuracy_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
import xgboost
from sklearn.naive_bayes import GaussianNB
import gc
import warnings
warnings.filterwarnings('ignore')
#解决显示中文错误
import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = [u'SimHei']
mpl.rcParams['axes.unicode_minus'] = False
pd.set_option('display.max_columns',None)
pd.set_option('display.max_rows',None)

"""写入文件"""
train_data = pd.read_csv('df_training.csv',na_values='?',names=['客户ID','产品使用分数','用户地区','性别','年龄','使用累计时间','点数余额','产品服务使用量','是否为使用信用卡付月费','是否为活跃用户','估计薪资','购买与否'],header=0)

ID不是特征不使用,购买与否为要预测的标签,查看缺失值,判断是否为离散型数据

train_data.info()<class &#39;pandas.core.frame.DataFrame&#39;>
RangeIndex: 6000 entries, 0 to 5999
Data columns (total 12 columns):# Column Non-Null Count Dtype
--- ------ -------------- ----- 0 客户ID 6000 non-null int64 1 产品使用分数 4165 non-null float642 用户地区 4167 non-null object 3 性别 4156 non-null object 4 年龄 4179 non-null float645 使用累计时间 4207 non-null float646 点数余额 4232 non-null float647 产品服务使用量 4188 non-null float648 是否为使用信用卡付月费 4118 non-null float649 是否为活跃用户 4181 non-null float6410 估计薪资 4161 non-null float6411 购买与否 6000 non-null int64
dtypes: float64(8), int64(2), object(2)
memory usage: 562.6&#43; KB

这里认为nunique值大于15为连续性变量&#xff0c;反之则为离散变量

con &#61; [] #收集连续型数据
dis &#61; [] #收集离散型数据
for col in train_data.columns[1:-1]:print(col)print(train_data[col].value_counts())print(&#39;缺失值比例&#39;,train_data[col].isnull().sum()/train_data.shape[0])if train_data[col].nunique() > 15:print(&#39;连续型&#39;)con.append(col)else:print(&#39;离散型&#39;)dis.append(col)print()

先处理离散型数据&#xff0c;统一将空值填充为一个不影响的值&#xff0c;独热后将该列的独热列删除

data &#61; train_data.copy()
data &#61; data.fillna(&#39;999&#39;) #用xxx代表空值&#xff0c;便于独热后区分
hot_col &#61; [&#39;area&#39;,&#39;sex&#39;,&#39;time&#39;,&#39;service&#39;,&#39;monthly&#39;,&#39;active&#39;] #独热时的名字#将每一列进行独热编码&#xff0c;删除掉‘999’的独热列
area_hot &#61; pd.get_dummies(data[dis[0]],prefix&#61;hot_col[0])
area_hot &#61; area_hot.drop(&#39;area_999&#39;,axis&#61;1) #删
sex_hot &#61; pd.get_dummies(data[dis[1]],prefix&#61;hot_col[1])
sex_hot &#61; sex_hot.drop(&#39;sex_999&#39;,axis&#61;1) #删
time_hot &#61; pd.get_dummies(data[dis[2]],prefix&#61;hot_col[2])
time_hot &#61; time_hot.drop(&#39;time_999&#39;,axis&#61;1) #删
service_hot &#61; pd.get_dummies(data[dis[3]],prefix&#61;hot_col[3])
service_hot &#61; service_hot.drop(&#39;service_999&#39;,axis&#61;1) #删
monthly_hot &#61; pd.get_dummies(data[dis[4]],prefix&#61;hot_col[4])
monthly_hot &#61; monthly_hot.drop(&#39;monthly_999&#39;,axis&#61;1) #删
active_hot &#61; pd.get_dummies(data[dis[5]],prefix&#61;hot_col[5])
active_hot &#61; active_hot.drop(&#39;active_999&#39;,axis&#61;1) #删

数据格式转化&#xff0c;字符数据数值化

for col in dis[2:]:data[col] &#61; data[col].astype(&#39;float32&#39;)
for i in con:data[i] &#61; data[i].astype(&#39;float32&#39;)# 可以使用LabelEncoder
data[&#39;用户地区&#39;] &#61; data[&#39;用户地区&#39;].replace(&#39;Taipei&#39;,0)
data[&#39;用户地区&#39;] &#61; data[&#39;用户地区&#39;].replace(&#39;Taichung&#39;,1)
data[&#39;用户地区&#39;] &#61; data[&#39;用户地区&#39;].replace(&#39;Tainan&#39;,2)
data[&#39;用户地区&#39;] &#61; data[&#39;用户地区&#39;].astype(&#39;float32&#39;)
data[&#39;性别&#39;] &#61; data[&#39;性别&#39;].replace(&#39;Male&#39;,0)
data[&#39;性别&#39;] &#61; data[&#39;性别&#39;].replace(&#39;Female&#39;,1)
data[&#39;性别&#39;] &#61; data[&#39;性别&#39;].astype(&#39;float32&#39;)

对离散型数据进行缺失值填充&#xff0c;利用xgboost,用其他所有列对该列进行预测

for i in range(len(dis)):start &#61; time.time()print(&#39;当前特征列为&#xff1a;%s&#39;%(dis[i]))print(&#39;第一步:构造特征与标签--------------------&#39;)res &#61; data[dis[i]]y_train &#61; res[res!&#61;999]#将其余的独热编码后的列和连续型数据组合在一起来做训练com &#61; [area_hot,sex_hot,time_hot,service_hot,monthly_hot,active_hot,data[con],data[dis[i]]]df &#61; pd.concat(com,axis&#61;1)#分为训练测试集x_train &#61; df[df[dis[i]]!&#61;999].iloc[:,:-1]x_test &#61; df[df[dis[i]]&#61;&#61;999].iloc[:,:-1]print(&#39;第二步&#xff1a;建模与预测填充--------------------&#39;)xgb &#61; xgboost.XGBClassifier()xgb.fit(x_train,y_train)y_res &#61; xgb.predict(x_test)data[dis[i]][data[dis[i]]&#61;&#61;999] &#61; y_resend &#61; time.time()print(&#39;运行时间&#xff1a;%s&#39;%(end-start))print()

for i in range(len(con)):start &#61; time.time()print(&#39;当前特征列为&#xff1a;%s&#39;%(con[i]))print(&#39;第一步:构造特征与标签--------------------&#39;)res &#61; data[con[i]]y_train &#61; res[res!&#61;999]com &#61; [area_hot,sex_hot,time_hot,service_hot,monthly_hot,active_hot,data[con]]df &#61; pd.concat(com,axis&#61;1)x_train &#61; df[df[con[i]]!&#61;999].drop(con[i],axis&#61;1)x_test &#61; df[df[con[i]]&#61;&#61;999].drop(con[i],axis&#61;1)print(&#39;第二步&#xff1a;建模与预测填充--------------------&#39;)xgb &#61; xgboost.XGBClassifier()xgb.fit(x_train,y_train)res_y &#61; xgb.predict(x_test)data[con[i]][data[con[i]]&#61;&#61;999] &#61; res_yend &#61; time.time()print(&#39;运行时间&#xff1a;%s&#39;%(end-start))

上面一步将离散型数据填充完成&#xff0c;接下来用离散型数据填充连续性数据

for i in range(len(con)):start &#61; time.time()print(&#39;当前特征列为&#xff1a;%s&#39;%(con[i]))print(&#39;第一步:构造特征与标签--------------------&#39;)res &#61; data[con[i]]y_train &#61; res[res!&#61;999]com &#61; [area_hot,sex_hot,time_hot,service_hot,monthly_hot,active_hot,data[con]]df &#61; pd.concat(com,axis&#61;1)x_train &#61; df[df[con[i]]!&#61;999].drop(con[i],axis&#61;1)x_test &#61; df[df[con[i]]&#61;&#61;999].drop(con[i],axis&#61;1)print(&#39;第二步&#xff1a;建模与预测填充--------------------&#39;)xgb &#61; xgboost.XGBClassifier()xgb.fit(x_train,y_train)res_y &#61; xgb.predict(x_test)data[con[i]][data[con[i]]&#61;&#61;999] &#61; res_yend &#61; time.time()print(&#39;运行时间&#xff1a;%s&#39;%(end-start))

利用matplotlib,seaborn,pyechars可视化工具&#xff0c;查看各特征的分布&#xff0c;查看各特征与标签之前的关系&#xff0c;查看特征与特征之间的关系

"""查看各特征是否有异常值"""
for i in range(len(data.columns)):plt.figure(figsize&#61;(10,58))plt.subplot(len(data.columns),1,i&#43;1)sns.boxplot(data[data.columns[i]])年龄有异常值&#xff0c;对年龄大于60的数据进行单独查看,图中显示异常的部分只占总体的 3.9%&#xff0c;从数据上看&#xff0c;年龄符合人类正常寿命

"""离散型特征与标签"""
for i in range(len(dis)):sns.catplot(x&#61;dis[i],y&#61;&#39;购买与否&#39;,data&#61;data,kind&#61;&#39;bar&#39;,aspect&#61;2.5)用户地区&#xff0c;性别&#xff0c;使用累计时间&#xff0c;产品服务用量&#xff0c;是否为活跃用户对标签有比较明显的区分

"""连续型数据分箱查看与标签之间的关系"""
for i in range(len(con)):name &#61; &#39;%s_10&#39;%(con[i])data[name] &#61; pd.cut(data[con[i]],bins&#61;10)t &#61; data.groupby(name,as_index&#61;False)[[&#39;购买与否&#39;]].count().groupby(name,as_index&#61;False)[[&#39;购买与否&#39;]].sum()print(t) sns.catplot(x&#61;name,y&#61;&#39;购买与否&#39;,data&#61;t,kind&#61;&#39;point&#39;,aspect&#61;2.5)plt.xticks(rotation&#61;30)plt.show()产品使用分数&#xff0c;年龄对标签有比较明显的区分

"""查看相关系数"""
plt.figure(figsize&#61;(16,16))
sns.heatmap(data.iloc[:,:-4].corr(),annot&#61;True)

使用XGBOOST建模预测

"""选择比较好的特征"""
data_t &#61; data[[&#39;用户地区&#39;,&#39;性别&#39;,&#39;使用累计时间&#39;,&#39;产品服务使用量&#39;,&#39;是否为活跃用户&#39;,&#39;产品使用分数&#39;,&#39;年龄&#39;,&#39;购买与否&#39;]]"""划分数据集"""
x_train,x_test,y_train,y_test &#61; train_test_split(data_t.iloc[:,:-1],data_t.iloc[:,-1],test_size&#61;0.2,random_state&#61;42)"""利用网格搜索搜索超参数"""
xgb &#61; xgboost.XGBClassifier()
gs &#61; GridSearchCV(xgb,{&#39;max_depth&#39;:[2,4,6,7,9,10],&#39;n_estimators&#39;:[50,100,150,200],&#39;learning_rate&#39;:[1,0.1,0.01,0.001],&#39;n_jobs&#39;:[10]},cv&#61;10,refit&#61;True)
gs.fit(x_train,y_train)
pre &#61; gs.predict(x_test)

print(gc.best_params_)
print(accuracy_score(y_test,g)){&#39;learning_rate&#39;: 0.1, &#39;max_depth&#39;: 2, &#39;n_estimators&#39;: 150, &#39;n_jobs&#39;: 10}
0.8225


推荐阅读
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 怀疑是每次都在新建文件,具体代码如下 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • Python使用Pillow包生成验证码图片的方法
    本文介绍了使用Python中的Pillow包生成验证码图片的方法。通过随机生成数字和符号,并添加干扰象素,生成一幅验证码图片。需要配置好Python环境,并安装Pillow库。代码实现包括导入Pillow包和随机模块,定义随机生成字母、数字和字体颜色的函数。 ... [详细]
  • 本文整理了315道Python基础题目及答案,帮助读者检验学习成果。文章介绍了学习Python的途径、Python与其他编程语言的对比、解释型和编译型编程语言的简述、Python解释器的种类和特点、位和字节的关系、以及至少5个PEP8规范。对于想要检验自己学习成果的读者,这些题目将是一个不错的选择。请注意,答案在视频中,本文不提供答案。 ... [详细]
  • 大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记
    本文介绍了大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记,包括outputFormat接口实现类、自定义outputFormat步骤和案例。案例中将包含nty的日志输出到nty.log文件,其他日志输出到other.log文件。同时提供了一些相关网址供参考。 ... [详细]
author-avatar
mobiledu2502891957
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有