内容简介:本系列适合以下人员:本文为该系列第二篇,承接自第一篇
作者·黄崇远
『数据虫巢』
全文共 3349 字
题图ssyer.com
“ 掌握了基本数据挖掘Python流程,意味着你已经踏出了最基本的一步。 ”
本系列适合以下人员:
-
数据开发/分析师、或者后台开发等但对对数据挖掘感兴趣。
-
计算机专业相关初学者,有志于从事数据相关工作。
本文为该系列第二篇,承接自第一篇 《【初学者系列】01-机器学习入门教程,启发式实例》 ,核心内容将第一篇中简单基于jupyter的机器学习实例,转化为相对流程化的Python代码以及基本的阶段化流程。
所以,看本文之前,建议先看第一篇。
01
目的以及实验环境
项目目的
由于jupyter只适合作为实验过程,真正的在线过程,或者在线生产环境是使用python来执行。所以,我们基于01,如何把jupyter转换为流程化的python。
环境准备
我们先在01的数据基础上,模拟出来训练数据,以及假设我们要预测的待预测数据。我们在01教程输入数据的基础上,切割出两份没有交叉的数据。
+先把需要的目录创建好
(1) data中放之前我们的那份数据,先把01教程的数据丢进去
(2) model将存储模型文件
(3) predict将存放预测结果
02
数据切分
创建一个python文件,命名为01_split_data.py,实在不行,你用文本编辑器创建,写代码,再上传也行。
或者直接在 linux 上创建一个:
touch 01_split_data.py
然后使用vim在上面写代码:
#!/user/bin/env python3
# -*- coding: utf-8 -*-
import warnings
warnings.filterwarnings("ignore")
import pandas as pd
file = './data/train_subset_1000000.csv'
df = pd.read_csv(file)
##截取部分当成训练集
df_click_1 = df[df["click"] == 1].iloc[:10000,:]
df_click_0 = df[df["click"] == 0].iloc[:52400,:]
#然后合并回去(行合并),作为新的df_train
df_train=pd.concat([df_click_1, df_click_0])
##截取部分当成预测集
df_click_1 = df[df["click"] == 1].iloc[10001:20000,:]
df_click_0 = df[df["click"] == 0].iloc[52401:100000,:]
#然后合并回去(行合并),作为新的df_train
df_predict=pd.concat([df_click_1, df_click_0])
#保存数据
df_train.to_csv('./data/df_train.csv')
df_predict.to_csv('./data/df_predict.csv')
给予执行权限:
chmod +x 01_split_data.py
执行数据分割程序:
python 01_split_data.py
可以看到data下已经多出来了两份文件,分别用于train和predict.
在实际的工作场景中,同样,我们需要准备好训练数据和预测数据,真实差异在哪呢?
训练集和待预测数据的差异在于,训练数据是带标的,即是有click这个字段的,而预测集中同样带属性,但没有click标志。
而训练的目的就是给predict数据集打上这个click标志,所以一般train数据集是历史数据,而predict数据是待预测的数据。
03
模型训练
建一个训练文件02_train_data.py:
#!/user/bin/env python3
# -*- coding: utf-8 -*-
import warnings
warnings.filterwarnings("ignore")
import pandas as pd
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
##导入XGB相关的库
from xgboost import XGBClassifier
from sklearn import metrics
from sklearn.externals import joblib
import time
##接下来对特征进行处理,先将类别特征进行编码
#针对类型类的特征,先进行编码,编码之前构建字典
def label_encode(field,df):
dic = []
df_field = df[field]
list_field = df_field.tolist()
#构建field字典
for i in list_field:
if i not in dic:
dic.append(i)
label_field = preprocessing.LabelEncoder()
label_field.fit(dic)
df_field_enconde_tmp = label_field.transform(df_field)
df_field_enconde = pd.DataFrame(df_field_enconde_tmp, index=df.index, columns=[(field+'_enconde')])
return df_field_enconde
#数据准备
def encode_data():
# 读入我们切割好的训练文件
file = './data/df_train.csv'
df = pd.read_csv(file)
print(f'--All data:{df.id.count()}')
y_1_nums = df[df["click"] == 1].id.count()
y_0_nums = df[df["click"] == 0].id.count()
print(f'--1 data:{y_1_nums}')
print(f'--0 data:{y_0_nums}')
print(f'--0 VS 1 => {round(y_0_nums / y_1_nums, 2)}:1')
# 特征编码
df_site_id_enconde = label_encode('site_id', df)
df_site_domain_enconde = label_encode('site_domain', df)
df_site_category_enconde = label_encode('site_category', df)
df_app_id_enconde = label_encode('app_id', df)
df_app_domain_enconde = label_encode('app_domain', df)
df_app_category_enconde = label_encode('app_category', df)
df_device_id_enconde = label_encode('device_id', df)
df_device_ip_enconde = label_encode('device_ip', df)
df_device_model_enconde = label_encode('device_model', df)
#特征拼接
df_input = pd.concat([df[['click','banner_pos','device_type','device_conn_type'
,'C1','C14','C15','C16','C17','C18','C19','C20','C21']]
,df_site_id_enconde
,df_site_domain_enconde
,df_site_category_enconde
,df_app_id_enconde
,df_app_domain_enconde
,df_app_category_enconde
,df_device_id_enconde
,df_device_ip_enconde
,df_device_model_enconde], axis=1)
return df_input
#效果输出函数
def func_print_score(x_data, y_data, data_type, model_x):
y_pred = model_x.predict(x_data)
print(f'==============({data_type})===================')
confusion = metrics.confusion_matrix(y_data, y_pred)
print(confusion)
print('------------------------')
auc = metrics.roc_auc_score(y_data, y_pred)
print(f'AUC: {auc}')
print('------------------------')
accuracy = metrics.accuracy_score(y_data, y_pred)
print(f'Accuracy: {accuracy}')
print('------------------------')
report = metrics.classification_report(y_data, y_pred)
print(report)
print('=============================================')
#训练模型
def train_data(df_input):
#对数据进行分割,分割为训练集和测试集
x_train,x_test,y_train,y_test = train_test_split(df_input.iloc[:,1:],df_input["click"],test_size=0.3, random_state=123)
begin_time = time.time()
print(f'Begin Time : {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(begin_time))}')
##受限于机器的资源,这里就不做gridsearch调参了,直接凑合着来(按最小资源消耗来设置参数)
model = XGBClassifier(learning_rate=0.1
,n_estimators=10
,max_depth=3
,objective='binary:logistic'
)
model.fit(x_train, y_train, eval_metric="auc")
end_time = time.time()
print(f'End Time : {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(end_time))}')
if __name__=='__main__':
df_input=encode_data()
model=train_data(df_input)
#保存模型
joblib.dump(model, './model/xgb_model.pkl')
这里简单的封装几个函数,上面split数据的由于太简单了,就直接执行了。
可以看到打印的一些信息和模型已经生成。
有了模型以ready好的预测数据(所谓ready就是预测数据带上了特征),我们可以用这个模型来预测数据了。
04
预测数据
创建一个03_predict_data.py
#!/user/bin/env python3
# -*- coding: utf-8 -*-
import warnings
warnings.filterwarnings("ignore")
import pandas as pd
from sklearn import preprocessing
from sklearn.externals import joblib
from sklearn import metrics
from xgboost import XGBClassifier
##接下来对特征进行处理,先将类别特征进行编码
#针对类型类的特征,先进行编码,编码之前构建字典
def label_encode(field,df):
dic = []
df_field = df[field]
list_field = df_field.tolist()
#构建field字典
for i in list_field:
if i not in dic:
dic.append(i)
label_field = preprocessing.LabelEncoder()
label_field.fit(dic)
df_field_enconde_tmp = label_field.transform(df_field)
df_field_enconde = pd.DataFrame(df_field_enconde_tmp, index=df.index, columns=[(field+'_enconde')])
return df_field_enconde
#数据准备
def encode_data():
# 读入我们切割好的预测文件
file = './data/df_predict.csv'
df = pd.read_csv(file)
# 特征编码
df_site_id_enconde = label_encode('site_id', df)
df_site_domain_enconde = label_encode('site_domain', df)
df_site_category_enconde = label_encode('site_category', df)
df_app_id_enconde = label_encode('app_id', df)
df_app_domain_enconde = label_encode('app_domain', df)
df_app_category_enconde = label_encode('app_category', df)
df_device_id_enconde = label_encode('device_id', df)
df_device_ip_enconde = label_encode('device_ip', df)
df_device_model_enconde = label_encode('device_model', df)
#特征拼接,注意,这里在实际中是没有click数据的
df_input = pd.concat([df[['id','click','banner_pos','device_type','device_conn_type'
,'C1','C14','C15','C16','C17','C18','C19','C20','C21']]
,df_site_id_enconde
,df_site_domain_enconde
,df_site_category_enconde
,df_app_id_enconde
,df_app_domain_enconde
,df_app_category_enconde
,df_device_id_enconde
,df_device_ip_enconde
,df_device_model_enconde], axis=1)
return df_input
if __name__=='__main__':
df_input=encode_data()
#加载模型
model = joblib.load('./model/xgb_model.pkl')
#预测数据
#这里我们先把id和原来的click摘出来,然后一会儿predict出来之后,用来对比一下预测结果
df_id_click=df_input.iloc[:,:2]
df_predict = df_input.iloc[:, 2:]
y_predict = model.predict(df_predict)
#将序列转换成df,原始是这样的array([0, 0, 0, ..., 0, 0, 0]),并字段命名为p_click
df_y_predict = pd.DataFrame(y_predict, columns=["p_click"], index=df_id_click.index)
#我们先把预测数据保存下来,在实际生产过程中,这个结果就可以拿去用了
df_output=pd.concat([df_id_click.iloc[:,:1], df_y_predict], axis=1)
df_output.to_csv('./predict/predict.csv')
#为了验证我们的预测结果,我们看下多少个完全预测对了
#合并新旧数据,click为真实的click,p_predict为预测的click
df_new_id = pd.concat([df_id_click, df_y_predict], axis=1)
df_new_id.to_csv('./predict/predict_pk.csv')
#我们适当打印一下差异
print(f'ALL ID: {df_id_click.id.count()}')
print(f'Disaccord ID: {df_new_id[df_new_id["click"] != df_new_id["p_click"]].id.count()}')
执行之后结果如下:
忽略掉告警,可以看到结果文件和PK对比文件已经保存。
预测的准确率=(57598-9849)/57598=82.9%,看着准确率(Accuracy)很高,但实际上是由于数据分布过于一致导致的,在实际生产环境中是不可能这么高的。
05
总结
首先微信看代码不好看,可以看github上的:
https://github.com/blogchong/data_and_advertisement/tree/master/code/ml_course/ml_02_ctr_python
记得给star,不要白嫖~~ 然后就是,如果想更有一个学习氛围,或者更多的参与互动,可以加入俺的知识星球,为初学者或者广告知识爱好者准备的坑,这里只做知识记录。
数据虫巢知识星球
【01】 适合数据行业出入者。
【02】 适合对于数据挖掘、算法感兴趣的朋友。
【03】 适合对于数据方向职业困惑的朋友。
【04】 适合对于广告与数据算法相关感兴趣的人。
文章都看完了,还不点个赞来个赏~
OTHER 相关系列文章(初学者系列)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
计算机程序的构造和解释
Harold Abelson、Gerald Jay Sussman、Julie Sussman / 裘宗燕 / 机械工业出版社 / 2004-2 / 45.00元
《计算机程序的构造和解释(原书第2版)》1984年出版,成型于美国麻省理工学院(MIT)多年使用的一本教材,1996年修订为第2版。在过去的二十多年里,《计算机程序的构造和解释(原书第2版)》对于计算机科学的教育计划产生了深刻的影响。第2版中大部分重要程序设计系统都重新修改并做过测试,包括各种解释器和编译器。作者根据其后十余年的教学实践,还对其他许多细节做了相应的修改。 海报:一起来看看 《计算机程序的构造和解释》 这本书的介绍吧!