初学者系列(二):算法实例 Jupyter 转换为 Python 流程

栏目: IT技术 · 发布时间: 4年前

内容简介:本系列适合以下人员:本文为该系列第二篇,承接自第一篇

作者·黄崇远

『数据虫巢』

全文共 3349

题图ssyer.com

初学者系列(二):算法实例 Jupyter 转换为  <a href='https://www.codercto.com/topics/20097.html'>Python</a>  流程

 掌握了基本数据挖掘Python流程,意味着你已经踏出了最基本的一步。

本系列适合以下人员:

  • 数据开发/分析师、或者后台开发等但对对数据挖掘感兴趣。

  • 计算机专业相关初学者,有志于从事数据相关工作。

本文为该系列第二篇,承接自第一篇 《【初学者系列】01-机器学习入门教程,启发式实例》 ,核心内容将第一篇中简单基于jupyter的机器学习实例,转化为相对流程化的Python代码以及基本的阶段化流程。

所以,看本文之前,建议先看第一篇。

01

目的以及实验环境

项目目的

由于jupyter只适合作为实验过程,真正的在线过程,或者在线生产环境是使用python来执行。所以,我们基于01,如何把jupyter转换为流程化的python。

环境准备

我们先在01的数据基础上,模拟出来训练数据,以及假设我们要预测的待预测数据。我们在01教程输入数据的基础上,切割出两份没有交叉的数据。

+先把需要的目录创建好

初学者系列(二):算法实例 Jupyter 转换为 Python 流程

(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

初学者系列(二):算法实例 Jupyter 转换为 Python 流程

可以看到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数据的由于太简单了,就直接执行了。

初学者系列(二):算法实例 Jupyter 转换为 Python 流程

可以看到打印的一些信息和模型已经生成。

有了模型以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()}')

执行之后结果如下:

初学者系列(二):算法实例 Jupyter 转换为 Python 流程

忽略掉告警,可以看到结果文件和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,不要白嫖~~ 然后就是,如果想更有一个学习氛围,或者更多的参与互动,可以加入俺的知识星球,为初学者或者广告知识爱好者准备的坑,这里只做知识记录。

数据虫巢知识星球

初学者系列(二):算法实例 Jupyter 转换为 Python 流程

【01】 适合数据行业出入者。

【02】 适合对于数据挖掘、算法感兴趣的朋友。

【03】 适合对于数据方向职业困惑的朋友。

【04】 适合对于广告与数据算法相关感兴趣的人。

初学者系列(二):算法实例 Jupyter 转换为 Python 流程

文章都看完了,还不点个赞来个赏~

OTHER 相关系列文章(初学者系列)

初学者系列(二):算法实例 Jupyter 转换为 Python 流程


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

计算机程序的构造和解释

计算机程序的构造和解释

Harold Abelson、Gerald Jay Sussman、Julie Sussman / 裘宗燕 / 机械工业出版社 / 2004-2 / 45.00元

《计算机程序的构造和解释(原书第2版)》1984年出版,成型于美国麻省理工学院(MIT)多年使用的一本教材,1996年修订为第2版。在过去的二十多年里,《计算机程序的构造和解释(原书第2版)》对于计算机科学的教育计划产生了深刻的影响。第2版中大部分重要程序设计系统都重新修改并做过测试,包括各种解释器和编译器。作者根据其后十余年的教学实践,还对其他许多细节做了相应的修改。 海报:一起来看看 《计算机程序的构造和解释》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具