腾讯广告算法大赛2020-广告产品种类单特征-入门级

前情提要:
此博客技术含量很low
仅记录过程,学习经验

1.比赛背景

1.1 题目:

广告受众基础属性预估

1.2 大赛简介

  1. 作为国内领先的营销平台,腾讯广告汇聚腾讯公司全量的应用场景,拥有核心商业数据、营 销技术与专业服务能力。同时,腾讯广告依托丰富的社交场景和数以亿计的优质用户,凭借 自身在大数据、算法和人工智能领域的技术优势,构建品牌与用户的智慧连接,助力广告主 高效实现商业增长。应用场景的复杂性、广告形态的多样性和人群的庞大规模,是实现这一 美好目标所必须面对的挑战。
  2. 为此,腾讯广告也在不断寻找更为优秀的数据挖掘和机器学习 算法。 腾讯广告算法大赛步入第四年,已经为来自海内外的企业和研究人员提供了富有研究价值和 应用价值的议题,有效地推动了产学研的交流与融合。本届算法大赛的题目“广告受众基础 属性预估”兼具实用性和趣味性,从广告行业的经典假设出发,逆向验证这一命题的科学性。 参赛者需要探索来自真实业务的海量脱敏数据,综合运用机器学习领域的各种技术,实现更 准确的预估。

1.3 赛题描述

  1. 本届算法大赛的题目来源于一个重要且有趣的问题。众所周知,像用户年龄和性别这样的人 口统计学特征是各类推荐系统的重要输入特征,其中自然也包括了广告平台。这背后的假设 是,用户对广告的偏好会随着其年龄和性别的不同而有所区别。许多行业的实践者已经多次 验证了这一假设。然而,大多数验证所采用的方式都是以人口统计学属性作为输入来产生推 荐结果,然后离线或者在线地对比用与不用这些输入的情况下的推荐性能。本届大赛的题目 尝试从另一个方向来验证这个假设,即以用户在广告系统中的交互行为作为输入来预测用户 的人口统计学属性。
  2. 我们认为这一赛题的“逆向思考”本身具有其研究价值和趣味性,此外也有实用价值和挑战 性。例如,对于缺乏用户信息的实践者来说,基于其自有系统的数据来推断用户属性,可以 帮助其在更广的人群上实现智能定向或者受众保护。与此同时,参赛者需要综合运用机器学 习领域的各种技术来实现更准确的预估。
  3. 具体而言,在比赛期间,我们将为参赛者提供一组用户在长度为 91 天(3 个月)的时间窗 口内的广告点击历史记录作为训练数据集。每条记录中包含了日期(从 1 到 91)、用户信息 (年龄,性别),被点击的广告的信息(素材 id、广告 id、产品 id、产品类目 id、广告主 id、广告主行业 id 等),以及该用户当天点击该广告的次数。测试数据集将会是另一组用户 的广告点击历史记录。提供给参赛者的测试数据集中不会包含这些用户的年龄和性别信息。 本赛题要求参赛者预测测试数据集中出现的用户的年龄和性别,并以约定的格式提交预测结 果。大赛官网后台将会自动计算得分并排名。详情参见【评估方式】和【提交方式】。
  4. 初赛和复赛除了所提供的训练数据集的量级有所不同之外,其他设置均相同。

1.4 数据说明

1.4.1 数据集

 测试集:https://tesla-ap-shanghai-1256322946.cos.ap-shanghai.myqcloud.com/ce phfs/tesla_common/deeplearning/dataset/algo_contest/test.zip 
 训练集:https://tesla-ap-shanghai-1256322946.cos.ap-shanghai.myqcloud.com/ce phfs/tesla_common/deeplearning/dataset/algo_contest/train_preliminary.zip  
 bucket: tesla-ap-shanghai region: ap-shanghai path: /cephfs/tesla_common/deeplearning/dataset/algo_contest/train_preliminary. zip sdk: cos://tesla-ap-shanghai/cephfs/tesla_common/deeplearning/dataset/algo_co ntest/train_preliminary.zip 
 notebook: https://tesla-ap-shanghai-1256322946.cos.ap-shanghai.myqcloud.com/ cephfs/tesla_common/deeplearning/dataset/algo_contest/train_preliminary.zip  

1.4.2 数据特征说明

训练数据中包含了一组用户 91 天的广告点击日志,被组织为三张表,以带标题行的 CSV 文 件的格式提供(编码采用无 BOM 的 UTF-8),分别是:click_log.csv,user.csv,ad.csv。 测试数据包含了另一组用户 91 天的广告点击日志,组织方式与训练数据相同,但不包含 user.csv。各表的详细格式描述如下(字段顺序以下面的描述为准,各字段用逗号’,’分隔, 中间无空格):

click_log.csv:

  1. time: 天粒度的时间,整数值,取值范围[1, 91]。
  2. user_id: 从 1 到 N 随机编号生成的不重复的加密的用户 id,其中 N 为用户总数目(训 练集和测试集)。
  3. creative_id: 用户点击的广告素材的 id,采用类似于 user_id 的方式生成。
  4. click_times: 当天该用户点击该广告素材的次数。

user.csv:

  1. user_id
  2. age: 分段表示的用户年龄,取值范围[1-10]。
  3. gender:用户性别,取值范围[1,2]。

ad.csv:

  1. creative_id
  2. ad_id: 该素材所归属的广告的 id,采用类似于 user_id 的方式生成。每个广告可能包 含多个可展示的素材。
  3. product_id: 该广告中所宣传的产品的 id,采用类似于 user_id 的方式生成。
  4. product_category: 该广告中所宣传的产品的类别 id,采用类似于 user_id 的方式生 成。
  5. advertiser_id: 广告主的 id,采用类似于 user_id 的方式生成。
  6. industry: 广告主所属行业的 id,采用类似于 user_id 的方式生成。

1.5 提交方式

参赛者提交的结果为一个带标题行的 submission.csv 文件,编码采用无 BOM 的 UTF-8, 具体格式如下(字段顺序以下面的描述为准,各字段用逗号分隔,中间无空格):

user_id

predicted_age: 预测的用户年龄分段,取值范围[1,10]。

predicted_gender: 预测的用户性别,取值范围[1,2]。

测试数据集中每个用户均应在 submission.csv 文件中对应有且仅有一行预测结果。各用户 的预测结果在该文件中的出现顺序与评估结果无关。

1.6 评估方式

  1. 大赛会根据参赛者提交的结果计算预测的准确率(accuracy)。年龄预测和性别预测将分别 评估准确率,两者之和将被用作参赛者的打分。
  2. 测试数据集会和训练数据集一起提供给参赛者。大赛会将测试数据集中出现的用户划分为两 组,具体的划分方式对参赛者不可见。其中一组用户将被用于初赛和复赛阶段除最后一天之 外的排行榜打分计算,另一组则用于初赛和复赛阶段最后一天的排行榜打分计算,以及最后 的胜出队伍选择

2.数据集处理

2.1导入包

import pandas as pd

2.2加载数据

path_log = "./data/train_preliminary/click_log.csv"
path_user = "./data/train_preliminary/user.csv"
path_ad = "./data/train_preliminary/ad.csv"
df_log = pd.read_csv(path_log,low_memory = False)
df_user = pd.read_csv(path_user,low_memory = False)
df_ad = pd.read_csv(path_ad,low_memory = False)

2.3查看数据

# df_log.info()#30082770
df_log.shape
(30082771, 4)

Out[12]:

click_log.csv:
time: 天粒度的时间,整数值,取值范围[1,91]。
user_id:1到N随机编号生成的不重复的加密的用户id,其中N为用户总数目(训练集和测试集)。
creative_id:用户点击的广告素材的id,采用类似于user_id的方式生成。
click_times: 当天该用户点击该广告素材的次数。
df_log.head(10)
df_log.sort_values("user_id")
df_log.sort_values("creative_id")
df_log["creative_id"].value_counts().head(10)
df_log.sort_values("click_times")
df_log["click_times"].value_counts()
df_log["click_times"].count()

ad.csv:

ad.csv:
creative_id
ad_id:该素材所归属的广告的id,采用类似于user_id的方式生成。每个广告可能包含多个可展示的素材。
product_id:该广告中所宣传的产品的id,采用类似于user_id的方式生成。
product_category: 该广告中所宣传的产品的类别id,采用类似于user_id的方式生成。
advertiser_id: 广告主的id,采用类似于user_id的方式生成。
industry:广告主所属行业的id,采用类似于user_id的方式生成。
df_ad.info()#2481134
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2481135 entries, 0 to 2481134
Data columns (total 6 columns):
creative_id         int64
ad_id               int64
product_id          object
product_category    int64
advertiser_id       int64
industry            object
dtypes: int64(4), object(2)
memory usage: 113.6+ MB
df_ad.shape
(2481135, 6)
df_ad.head()
creative_idad_idproduct_idproduct_categoryadvertiser_idindustry
011\N538178
144\N5108202
277\N5148297
388\N5713213
499\N5695213
# df_ad["creative_id"].value_counts()#Length: 2481135, dtype: int64
# df_ad["ad_id"].value_counts()#2264190, dtype: int64
# df_ad["product_id"].value_counts()#Length: 33273, dtype: int64
# df_ad["product_category"].value_counts()#19种
# df_ad["advertiser_id"].value_counts()#Length: 52090, dtype: int64
# df_ad["industry"].value_counts()#Length: 326, dtype: int64

user.csv:

user_id age: 分段表示的用户年龄,取值范围[1-10]。
gender:用户性别,取值范围[1,2]。

df_user.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 900000 entries, 0 to 899999
Data columns (total 3 columns):
user_id    900000 non-null int64
age        900000 non-null int64
gender     900000 non-null int64
dtypes: int64(3)
memory usage: 20.6 MB
df_user.shape
(900000, 3)
df_user.head()
user_idagegender
0141
12101
2372
3451
4541

2.4 合并表格

df1=pd.merge(df_log,df_user)
df1.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 30082771 entries, 0 to 30082770
Data columns (total 6 columns):
time           int64
user_id        int64
creative_id    int64
click_times    int64
age            int64
gender         int64
dtypes: int64(6)
memory usage: 1.6 GB
df1.shape
(30082771, 6)
df1.sort_values('user_id')
timeuser_idcreative_idclick_timesagegender
261965626412456345141
26196563401122032141
26196552201821396141
26196553201209778141
26196554201877468141
261965556413068256141
2619655143171691141
261965574611940159141

30082771 rows × 6 columns

df2=pd.merge(df1,df_ad)
df2.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 30082771 entries, 0 to 30082770
Data columns (total 11 columns):
time                int64
user_id             int64
creative_id         int64
click_times         int64
age                 int64
gender              int64
ad_id               int64
product_id          object
product_category    int64
advertiser_id       int64
industry            object
dtypes: int64(9), object(2)
memory usage: 2.7+ GB
df2.shape
(30082771, 11)
df2
timeuser_idcreative_idclick_timesagegenderad_idproduct_idproduct_categoryadvertiser_idindustry
093092056733012150442330673332638319
11532081556733013150442330673332638319
3008277050309198238697312120578111946217757259

30082771 rows × 11 columns

In [63]:

df2.sort_values("user_id")
timeuser_idcreative_idclick_timesagegenderad_idproduct_idproduct_categoryadvertiser_idindustry
887771164124563451412116146642188245
26781033201821396141724607\N57293326
95046894011220321411099591334211411\N

30082771 rows × 11 columns

df2.sort_values("creative_id")
timeuser_idcreative_idclick_timesagegenderad_idproduct_idproduct_categoryadvertiser_idindustry
245232208155610911511\N538178
245232188139869511411\N538178
245232198240402011311\N538178

| 28107405 | 91 | 101004 | 4445718 | 1 | 2 | 1 | 3812200 | 39287 | 17 | 427 | \N |

30082771 rows × 11 columns

df2["industry"].value_counts()
df_train = df2.to_csv('./data/train_preliminary/df_train.csv',index=None)
 df3 = pd.merge(df_user,df_log)
 df3

3. 训练集处理

import pandas as pd
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import time
import gc
import pandas as pd
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import time
import gc
#显示所有列
pd.set_option('display.max_columns', None)
path_log = "./data/train_preliminary/click_log.csv"#D:\hjz-py\Project\08-腾讯广告\data\train_preliminary
path_user = "./data/train_preliminary/user.csv"
path_ad = "./data/train_preliminary/ad.csv"
df_log = pd.read_csv(path_log,low_memory = False)
df_user = pd.read_csv(path_user,low_memory = False)
df_ad = pd.read_csv(path_ad,low_memory = False)
df_log.shape
(30082771, 4)
df_ad.shape
(2481135, 6)
df_log.info(verbose=True,null_counts=True)
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 30082771 entries, 0 to 30082770
Data columns (total 4 columns):
time           30082771 non-null int64
user_id        30082771 non-null int64
creative_id    30082771 non-null int64
click_times    30082771 non-null int64
dtypes: int64(4)
memory usage: 918.1 MB
# df_log["user_id"].value_counts()
# df_log["click_times"].value_counts()#1-185
# df_log["time"].value_counts()#1-91
# df_log["creative_id"].value_counts()#很多
df_ad.info(verbose=True,null_counts=True)
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2481135 entries, 0 to 2481134
Data columns (total 6 columns):
creative_id         2481135 non-null int64
ad_id               2481135 non-null int64
product_id          2481135 non-null object
product_category    2481135 non-null int64
advertiser_id       2481135 non-null int64
industry            2481135 non-null object
dtypes: int64(4), object(2)
memory usage: 113.6+ MB
# df_ad["product_category"].value_counts()#18类
# df_ad["creative_id"].value_counts()#2618159
# df_ad["ad_id"].value_counts()#2379475
# df_ad["product_id"].value_counts()#34111
df_ad["industry"].value_counts(ascending=True)#326
# df_ad["industry"].values#326
# df_ad["advertiser_id"].value_counts()#52861
# df_ad["product_category"].value_counts()#18类
# df_ad["creative_id"].value_counts()#2618159
# df_ad["ad_id"].value_counts()#2379475
# df_ad["product_id"].value_counts()#34111
df_ad["industry"].value_counts(ascending=True)#326
# df_ad["industry"].values#326
# df_ad["advertiser_id"].value_counts()#52861
283         1
94          1
266         1
78          1
142         1
68          1
282         1
96          1
42          1
325         1
287         1
314         1
152         1
59          1
268         1
143         1
212         2
93          2
101         2
71          2
273         2
244         2
180         2
83          2
102         3
269         3
114         3
103         3
37          3
97          3
        ...  
289     20764
26      21259
252     21615
24      21763
13      22078
246     22739
253     22885
40      23853
297     25284
60      25320
133     25506
259     26424
21      33202
27      36904
47      44245
36      44458
25      46671
329     49460
317     54328
248     55553
73      64130
54      64318
326     65196
238     76788
242     77113
\N     101048
322    159928
6      161962
319    178677
247    262634
Name: industry, Length: 326, dtype: int64

# df_ad=df_ad.drop(['ad_id','product_id',"advertiser_id","industry"], 1, inplace = False)
df_ad=df_ad.drop(['ad_id','product_id',"advertiser_id"], 1, inplace = False)
df_log = df_log.drop(["time"],1, inplace = False)
# product_category = df_ad['product_category']
# #画图展示一下'birth'这个数据的值得统计
# plt.bar(product_category.value_counts().index,product_category.value_counts().values,label='product_category')
# #刻度
# plt.xticks(np.arange(1,19,1))# plt.legend()
# plt.show()
df_train=pd.merge(df_log,df_ad)
df_train.sort_values('user_id')
user_id	creative_id	click_times	product_category	industry
15704991	1	2087846	1	18	64
13223979	1	1940159	1	5	73
15516145	1	3068256	1	2	238
16203201	1	877468	1	5	106
9498187	1	122032	1	2	\N
18768377	1	3592928	2	2	6
26781023	1	821396	1	5	326
8869317	1	2456345	1	2	245
22502265	1	1683713	1	5	326
23067445	1	209778	1	2	6
10203710	1	90171	1	5	217
5298558	1	71691	1	18	326
8869318	1	2456345	1	2	245
17616577	2	3574990	1	2	317
5961503	2	2143574	1	2	6
3893359	2	1696925	1	18	47
1388066	2	2085566	1	2	6
2728619	2	1145367	1	18	47
9037395	2	3443654	1	18	207
3595196	2	396652	1	2	238
27288390	2	2552139	1	2	242
1388065	2	2085566	1	2	6
4271773	2	96192	1	18	47
15214721	2	1074235	1	2	242
10847046	2	1662244	1	18	6
3893360	2	1696925	1	18	47
1580204	2	609050	1	2	6
10734795	2	513298	1	2	242
12311272	2	1657530	1	2	6
3216027	2	39714	1	2	6
...	...	...	...	...	...
10332634	899999	774777	1	13	252
25582912	899999	1287932	1	5	232
13611842	899999	279342	1	18	54
21745221	899999	122834	1	17	\N
3051750	899999	12838	1	2	317
3051749	899999	12838	1	2	317
5882005	899999	599699	1	18	6
8170173	899999	1055898	1	18	289
18811320	899999	2479870	1	2	183
10638246	899999	456738	1	18	54
25757630	899999	646020	1	5	333
23275031	899999	1513243	1	5	108
3051747	899999	12838	1	2	317
3051748	899999	12838	1	2	317
28131526	899999	4013563	1	16	\N
5882004	899999	599699	1	18	6
8767210	899999	1232816	1	18	6
18421872	899999	2288411	1	5	291
27221514	900000	234063	1	5	147
15723023	900000	3391205	1	5	73
10316932	900000	1405713	1	18	88
15276431	900000	4387250	1	18	25
9079708	900000	1807163	1	18	289
28703034	900000	2692144	1	5	148
20719151	900000	1224107	1	5	232
26241854	900000	285502	1	5	147
29912679	900000	2290180	1	5	291
7210458	900000	3471208	1	5	289
9632591	900000	3527098	1	18	203
23538200	900000	423617	1	18	183
30082771 rows × 5 columns
# path_user = "./data/train_preliminary/user.csv"
# df_user = pd.read_csv(path_user,low_memory = False)
df_train=df_train.drop(["creative_id"],1, inplace = False)
# df_test=df_test.sort_values('user_id')
df_train.head()
user_id	click_times	product_category	industry
0	30920	1	3	319
1	320815	1	3	319
2	355089	1	3	319
3	363442	1	3	319
4	370513	1	3	319

train3008w = df_train.to_csv("./data/train_preliminary/train3008w.csv",index=None)
df1 = pd.get_dummies(df_train['product_category'])
df_train = pd.concat([df_train,df1],axis=1)
for cg in range(1,19):
    df_train[cg] = df_train[cg]*df_train['click_times']
df_train = df_train.groupby(['user_id'],as_index = False).sum()
df_train=df_train.drop(['product_category','click_times'], 1, inplace = False)
df_train.head(15)

# df_test = df_test.groupby(['user_id']).sum()
df_train2=pd.merge(df_train,df_user)
df_train2
train90w = df_train2.to_csv("./data/train_preliminary/train90w.csv",index=None)
df_train2
df_train2

4.训练集-年龄-训练测试

4.1 代码

# -*- coding: utf-8 -*-
#导入包
import time
import numpy as np

import pandas as pd
import matplotlib.pyplot as plt

#显示所有列
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.linear_model import LinearRegression
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import xgboost as xgb
from xgboost import XGBRegressor, XGBClassifier
from xgboost import plot_importance
from sklearn.externals import joblib

# 设置忽略警告
import warnings
warnings.filterwarnings('ignore')

pd.set_option('display.max_columns', None)
#读取训练集数据
df_train = pd.read_csv("./data/train_preliminary/train90w.csv")
# print(df_train.head())
# df_train.info()
# print(df_train.gender.value_counts())#要把1,2改为0,1
df_train.gender.replace(1,0,inplace = True)
df_train.gender.replace(2,1,inplace = True)
df_train=df_train.drop(["user_id"],axis=1,inplace=False)
#划分X和Y,我们要单独训练X和Y1,X和Y2
Y1 = df_train["age"]
Y2 = df_train["gender"]
X = df_train.drop(["age","gender"],axis =1 ,inplace = False)

#训练测试集划分
#年龄建模
x_train,x_test,y_train,y_test = train_test_split(X,Y1,test_size=0.3,random_state=0)

print('1.线性回归模型开始训练:')
lr = LinearRegression()
start= time.time()
lr.fit(x_train, y_train)
y_train_hat = lr.predict(x_train)
y1_train_hat=np.around(y_train_hat,0)#四舍五入取整
lr_accuracy_train = accuracy_score(y1_train_hat,y_train)
print('在训练集准确率:',np.around(lr_accuracy_train,4))
y1_test_hat = lr.predict(x_test)#预测年龄y1_predict
y1_test_hat = np.around(y1_test_hat,0)#四舍五入取整,记得把y1_predict写道递交的age栏里
lr_accuracy_test = accuracy_score(y1_test_hat,y_test)
print('在测试集准确率:',np.around(lr_accuracy_test,4))
end = time.time()
print("耗时%.2f秒"%(end-start))
print('线性回归模型结束训练:')
print('*'*40)

print('2.KNN模型开始训练:')
knn = KNeighborsClassifier(n_neighbors=3)
start= time.time()
knn.fit(x_train, y_train)
train_predict = knn.predict(x_train)
KNN_train_accuracy = accuracy_score(y_train,train_predict)
print('在训练集准确率:',np.around(KNN_train_accuracy,4))
print('开始测试:')
test_predict = knn.predict(x_test)
KNN_test_accuracy = accuracy_score(y_test,test_predict)
print('在测试集准确率:',np.around(KNN_test_accuracy,4))
end = time.time()
print("耗时%.2f秒"%(end-start))
print('*'*40)
#
print('3.RF模型开始训练:')
RF = RandomForestClassifier(n_estimators=50,max_depth=5)
start= time.time()
RF.fit(x_train, y_train)
train_predict = RF.predict(x_train)
RF_train_accuracy = accuracy_score(y_train,train_predict)
print('在训练集准确率:',np.around(RF_train_accuracy,4))
print('开始测试:')
test_predict = RF.predict(x_test)
RF_test_accuracy = accuracy_score(y_test,test_predict)
print('在测试集准确率:',np.around(RF_test_accuracy,4))
end = time.time()
print("耗时%.2f秒"%(end-start))
print('*'*40)
#
print('4.开始GBDT模型训练:')
gb = GradientBoostingClassifier()
start= time.time()
gb.fit(x_train, y_train)
train_predict = gb.predict(x_train)
accuracy = accuracy_score(y_train,train_predict)
print("gbdt模型训练集上的效果如下:")
print('在训练集集准确率:',accuracy)
gb_predict = gb.predict(x_test)
gb_test_accuracy = accuracy_score(y_test,gb_predict)
print('在测试集准确率:',np.around(gb_test_accuracy,4))
end = time.time()
print("RF耗时%.2f秒"%(end-start))
print('*'*40)
#
print('5.Xgboost模型开始训练:')
start= time.time()
clf = XGBClassifier(
    n_estimators=100,  # 迭代次数
    learning_rate=0.1,  # 步长
    max_depth=7,  # 树的最大深度
    min_child_weight=1,  # 决定最小叶子节点样本权重和
    silent=1,  # 输出运行信息
    subsample=0.8,  # 每个决策树所用的子样本占总样本的比例(作用于样本)
    colsample_bytree=0.8,  # 建立树时对特征随机采样的比例(作用于特征)典型值:0.5-1
    objective='multi:softmax',  # 多分类!!!!!!
    num_class=10,#年龄类别数,1-10
    nthread=4,
    seed=27)
print("开始训练")
clf.fit(x_train, y_train, verbose=True)
train_pred = clf.predict(x_train)
print('在训练集准确率:',np.around(accuracy_score(train_pred,y_train),4))
print("开始测试")
test_pred = clf.predict(x_test)
print('在测试集准确率:',np.around(accuracy_score(test_pred,y_test),4))
end = time.time()
print("RF耗时%.2f秒"%(end-start))
#
#
# #模型持久化
joblib.dump(RF,'./model/RF_age.pkl')
joblib.dump(clf,'./model/xgb_age.pkl')
print("模型固化已完成")

### 保存为csv的数据
dir_path = './data/train_preliminary'
import os
if os.path.exists(dir_path):
    pass
else:
    os.makedirs(dir_path)
X.to_csv(dir_path+'/train_X.csv',index=False)
Y1.to_csv(dir_path+'/train_Y1.csv',index=False)
Y2.to_csv(dir_path+'/train_Y2.csv',index=False)
print("训练集划分已完成并保存")

4.2 训练集-年龄-模型对比

模型训练集测试集耗时(s)
线性回归0.16850.16780.44
KNN0.36920.1824611.65
RF0.22880.229418.82
GBDT0.23950.2377578.05
XGBOOST0.24340.2379203.18

5. 训练集-性别-训练测试

5.1 代码

# -*- coding: utf-8 -*-
#导入包
import time
import numpy as np

import pandas as pd
import matplotlib.pyplot as plt

# 设置忽略警告
import warnings

from sklearn.externals import joblib
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from xgboost import XGBClassifier

warnings.filterwarnings('ignore')

pd.set_option('display.max_columns', None)

#读取训练集数据
df_train = pd.read_csv("./data/train_preliminary/train90w.csv")
# print(df_train.head())
# df_train.info()
# print(df_train.gender.value_counts())#要把1,2改为0,1
df_train.gender.replace(1,0,inplace = True)
df_train.gender.replace(2,1,inplace = True)
df_train=df_train.drop(["user_id"],axis=1,inplace=False)
#划分X和Y,我们要单独训练X和Y1,X和Y2
Y1 = df_train["age"]
Y2 = df_train["gender"]
X = df_train.drop(["age","gender"],axis =1 ,inplace = False)

#训练测试集划分
#年龄建模
x_train,x_test,y_train,y_test = train_test_split(X,Y2,test_size=0.3,random_state=0)
#性别

print('1.逻辑回归模型开始训练:')
lr = LogisticRegression()
start= time.time()
lr.fit(x_train, y_train)
train_predict = lr.predict(x_train)
train_accuracy = accuracy_score(y_train,train_predict)
print('在训练集准确率:',np.around(train_accuracy,4))
print('开始测试:')
test_predict = lr.predict(x_test)#性别的预测值y2_predict,为0,1,递交表里要改为1,2
test_accuracy = accuracy_score(y_test,test_predict)
print('在测试集准确率:',np.around(test_accuracy,4))
end = time.time()
print("逻辑回归耗时%.2f秒"%(end-start))
print(test_predict)

joblib.dump(lr,'./model/lr_gender.pkl')
print("LR性别二分类模型固化已完成")

#网格搜索+cv+kf+xgb
# #xgboost
# import xgboost as xgb
# from sklearn.model_selection import GridSearchCV
# from sklearn.model_selection import KFold
# kf = KFold(n_splits=5, random_state=42,shuffle=True)
# parameters ={'max_depth':[3,5,7],'min_child_weight':list(range(1,6,2))}
# print('2.Xgboost模型开始网格搜索交叉训练:')
# start= time.time()
# xgb1=xgb.XGBClassifier(learning_rate=0.1, n_estimators=100,
#                  silent=0, objective='binary:logistic',
#                  gamma=0,subsample=0.8,colsample_bytree=0.8,
#                 nthread=4,scale_pos_weight=1,seed=27)
# grid_xgb=GridSearchCV(estimator=xgb1,param_grid=parameters,cv=kf)
# print("开始训练")
# grid_xgb.fit(x_train,y_train)
# print("最优参数是:",grid_xgb.best_params_)
# # grid_xgb.best_params_
# # {'max_depth': 4, 'min_child_weight': 1}
# #利用最佳模型来进行预测
# train_pred = grid_xgb.predict(x_train)
# print('在训练集准确率:',np.around(accuracy_score(train_pred,y_train),4))
# print("开始测试")
# best_xgb=grid_xgb.best_estimator_
# predict_xgb=best_xgb.predict(x_test)
# # 在回归问题objective一般使用reg:squarederror ,即MSE均方误差。二分类问题一般使用binary:logistic, 多分类问题一般使用multi:softmax。
# print('在测试集准确率:',np.around(accuracy_score(predict_xgb,y_test),4))

# 最优参数是: {'max_depth': 7, 'min_child_weight': 1}
# 在训练集准确率: 0.6841
# 开始测试
# 在测试集准确率: 0.6811

print('2.Xgboost模型开始训练:')
start= time.time()
clf = XGBClassifier(
    n_estimators=100,  # 迭代次数
    learning_rate=0.1,  # 步长
    max_depth=5,  # 树的最大深度
    min_child_weight=1,  # 决定最小叶子节点样本权重和
    silent=1,  # 输出运行信息
    subsample=0.8,  # 每个决策树所用的子样本占总样本的比例(作用于样本)
    colsample_bytree=0.8,  # 建立树时对特征随机采样的比例(作用于特征)典型值:0.5-1
    objective='binary:logistic',  # 2分类!!!!!!
    # num_class=2,#性别类别数,提前改为了0,1,记得提交改为1,2
    nthread=4,
    seed=27)
print("开始训练")
clf.fit(x_train, y_train, verbose=True)
train_pred = clf.predict(x_train)
print('在训练集准确率:',np.around(accuracy_score(train_pred,y_train),4))
print("开始测试")
test_pred = clf.predict(x_test)
print('在测试集准确率:',np.around(accuracy_score(test_pred,y_test),4))
end = time.time()
print("RF耗时%.2f秒"%(end-start))
# print(test_pred)

joblib.dump(clf,'./model/xgb_gender.pkl')
print("xgb性别二分类模型固化已完成")

5.2 训练集-性别

模型训练集测试集耗时(s)
LR0.67420.67358.31
XGBOOST0.68410.68113.28

6.模型预测和递交

6.1 代码

# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
import time
from sklearn.metrics import accuracy_score
from sklearn.externals import joblib

#1.加载数据
print('1.开始加载数据:')
start= time.time()

#读取训练集数据
df_train = pd.read_csv("./data/train_preliminary/train90w.csv")
# print(df_train.head())
# df_train.info()
# print(df_train.gender.value_counts())#要把1,2改为0,1
df_train.gender.replace(1,0,inplace = True)
df_train.gender.replace(2,1,inplace = True)
df_train=df_train.drop(["user_id"],axis=1,inplace=False)
#划分X和Y,我们要单独训练X和Y1,X和Y2
y1_train = df_train["age"]
y2_train = df_train["gender"]
x_train = df_train.drop(["age","gender"],axis =1 ,inplace = False)
print("训练集大小:",x_train.shape)
print("训练集年龄样本大小:",y1_train.shape)
print("训练集性别样本大小:",y2_train.shape)

df_test = pd.read_csv("./data/test/test100W.csv")#test100W.csv,提交时要用到df_test里面的user_id
x_test=df_test.drop(["user_id"],axis=1,inplace=False)
print("测试集大小:",x_test.shape)

print('数据加载完成:')
end = time.time()
print("数据加载耗时%.2f秒"%(end-start))


#2.加载模型
print('2.开始加载模型:')
start= time.time()

#年龄RF模型
rf_age = joblib.load('./model/RF_age.pkl')#D:\hjz-py\Project\08-腾讯广告\model\RF_age.pkl
#年龄xgboost模型
xgb_age = joblib.load('./model/xgb_age.pkl')# D:\hjz-py\Project\08-腾讯广告\model\xgb_age.pkl

#性别二分类模型
lr_gender = joblib.load('./model/lr_gender.pkl')#性别逻辑回归LR模型
xgb_gender = joblib.load('./model/xgb_gender.pkl')#性别xgboost模型
print('模型加载完成:')
end = time.time()
print("模型加载耗时%.2f秒"%(end-start))

#3.模型训练预测
#3.1.1 年龄-RF
print('3.1 RF模型开始训练年龄:')#rf_age
start= time.time()
rf_age.fit(x_train, y1_train)
train_predict = rf_age.predict(x_train)
train_accuracy = accuracy_score(y1_train,train_predict)
print('在训练集准确率:',np.around(train_accuracy,4))
print('开始预测:')
rf_age_predict = rf_age.predict(x_test)
end = time.time()
print("RF模型训练预测耗时%.2f秒"%(end-start))

#3.1.2 年龄-xgb,   xgb_age
print('3.2 xgb模型开始训练年龄:')
start= time.time()
xgb_age.fit(x_train, y1_train)
train_predict = xgb_age.predict(x_train)
train_accuracy = accuracy_score(y1_train,train_predict)
print('在训练集准确率:',np.around(train_accuracy,4))
print('开始预测:')
xgb_age_predict = xgb_age.predict(x_test)
end = time.time()
print("xgb_age模型训练预测耗时%.2f秒"%(end-start))

#3.2.1 性别-LR    lr_gender
print('3.2.1 lr模型开始训练性别:')
start= time.time()
lr_gender.fit(x_train, y2_train)
train_predict = lr_gender.predict(x_train)
train_accuracy = accuracy_score(y2_train,train_predict)
print('在训练集准确率:',np.around(train_accuracy,4))
print('开始预测:')
lr_gender_predict = lr_gender.predict(x_test)
end = time.time()
print("lr_gender模型训练预测耗时%.2f秒"%(end-start))

#3.2.2 性别-xgb    xgb_gender
print('3.2.1 xgb_gender模型开始训练性别:')
start= time.time()
xgb_gender.fit(x_train, y2_train)
train_predict = xgb_gender.predict(x_train)
train_accuracy = accuracy_score(y2_train,train_predict)
print('在训练集准确率:',np.around(train_accuracy,4))
print('开始预测:')
xgb_gender_predict = xgb_gender.predict(x_test)
end = time.time()
print("xgb_gender模型训练预测耗时%.2f秒"%(end-start))

#模型提交
print('4.1 开始模型提交:')
start= time.time()
submit = pd.concat([pd.DataFrame(df_test.user_id,columns=['user_id']),
                    pd.DataFrame(xgb_age_predict,columns=['predicted_age']),
                    pd.DataFrame(xgb_gender_predict,columns=['predicted_gender'])],axis=1)
submit.predicted_gender.replace(1,2,inplace = True)
submit.predicted_gender.replace(0,1,inplace = True)
submit.to_csv('./data/submit/submission20200605.csv',index=False)

submit2 = pd.concat([pd.DataFrame(df_test.user_id,columns=['user_id']),
                    pd.DataFrame(rf_age_predict,columns=['predicted_age']),
                    pd.DataFrame(xgb_gender_predict,columns=['predicted_gender'])],axis=1)#rf_age + xgb_gender
submit2.predicted_gender.replace(1,2,inplace = True)
submit2.predicted_gender.replace(0,1,inplace = True)
submit2.to_csv('./data/submit/submission20200605_2.csv',index=False)

submit3 = pd.concat([pd.DataFrame(df_test.user_id,columns=['user_id']),
                    pd.DataFrame(rf_age_predict,columns=['predicted_age']),
                    pd.DataFrame(lr_gender_predict,columns=['predicted_gender'])],axis=1)#rf_age + lr_gender
submit3.predicted_gender.replace(1,2,inplace = True)
submit3.predicted_gender.replace(0,1,inplace = True)
submit3.to_csv('./data/submit/submission20200605_3.csv',index=False)

print('4.2 提交结果完成,已保存为csv文件')
# print(submit.head(20))
print('提交文件完成:')
end = time.time()
print("提交文件用时%.2f秒"%(end-start))

6.2 代码运行结果

C:\Anaconda3\python.exe D:/hjz-py/Project/08-腾讯广告/moder_predict.py

1.开始加载数据:
训练集大小: (900000, 18)
训练集年龄样本大小: (900000,)
训练集性别样本大小: (900000,)
测试集大小: (1000000, 18)
数据加载完成:
数据加载耗时2.272.开始加载模型:
模型加载完成:
模型加载耗时1.443.1 RF模型开始训练年龄:
在训练集准确率: 0.2291
开始预测:
RF模型训练预测耗时40.773.2 xgb模型开始训练年龄:
在训练集准确率: 0.2518
开始预测:
xgb_age模型训练预测耗时439.403.2.1 lr模型开始训练性别:
在训练集准确率: 0.674
开始预测:
lr_gender模型训练预测耗时9.503.2.2 xgb_gender模型开始训练性别:
在训练集准确率: 0.6834
开始预测:
xgb_gender模型训练预测耗时45.124.1 开始模型提交:

4.2 提交结果完成,已保存为csv文件
提交文件完成:
提交文件用时9.40秒

Process finished with exit code 0

7.递交演示

7.1流程

报名注册--》实名认证---》腾讯云平台注册开通(有送免费券)--》T1-one平台
--

在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

8.总结说明

8.1 比赛说明

1.第一次打TX的广告比赛,时间紧,数据集训练集三个文件,三千万条点击日志,90万用户
2.测试集约三千八百万日志,不含百万用户的性别和年龄,因为是让我们来预测的两个属性
3.只处理单特征:是因为我对其他特征还没什么想法,只想走走比赛的流程,静下心来找个事做
个人难点:
海量数据集的处理缺乏经验;
推荐算法类做的少,比较适合数据分析和数据挖掘
在自己笔记本上完成的,几个晚上,加上其他事情的压力(摆摊找工作啦)
玩比赛交友权当放松了。。。
个人展望:
python科学计算库是好东西,当然大数据工具现在很多岗位都要学
不能只会潘大师pandas
此项目比较适合数据挖掘,有时间可以专研
广告算法也是目前比较火的能来钱快的方向
以后可以多组队学习参加这些比赛
比打游戏好玩多了
求带!求交流!求指导!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值