广告点击率预测(kaggle)

本文介绍了在一个Kaggle广告点击率预测竞赛中的项目实践,包括数据采样、读取、理解,特征构造、转换与选择,以及使用逻辑回归、决策树和XGBoost进行模型训练与评估。通过对广告数据的深入分析,探讨了特征的重要性,特别是对类别型特征的处理和不平衡数据的应对策略。
摘要由CSDN通过智能技术生成

一、项目背景

数据来源:使用的是kaggle的一个竞赛数据,具体官网地址为https://www.kaggle.com/c/avazu-ctr-prediction
训练和测试数据分别为train.csv和test.csv。官网提供的数据比较大,压缩之后的已经达到1G以上。为了确保可以在本机上无障碍去调模型,在此项目中,我特意去采样了一部分数据。 采样的规则为:从train.csv文件中读取头400000个样本,并重命名为train_subset.csv。 之后在这个数据的基础上我们会进一步分为训练集和测试集。

这个项目的主要的目的是通过给定的广告信息和用户信息来预测一个广告被点击与否。 如果广告有很大概率被点击就展示广告,如果概率低,就不展示。 因为如果广告没有被点击,对双方(广告主、平台)来讲都没有好处。所以预测这个概率非常重要,也是此项目的目标。

在这个项目中,主要做了如下几个方面的工作:

  1. 数据的读取和理解: 把给定的.csv文件读入到内存,并通过pandas做数据方面的统计以及可视化来更深入地理解数据。
  2. 特征构造: 从原始特征中衍生出一些新的特征。
  3. 特征的转化: 特征一般分为连续型(continuous)和类别型(categorical), 需要分别做不同的处理。
  4. 特征选择: 从已有的特征中选择合适的特征。
  5. 模型训练与评估: 通过交叉验证方式来训练模型,使用到了网格搜索的技术。

二、数据的读取

# 导入基本的库,每个项目的必备
import numpy as np
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import KFold
from sklearn.model_selection import train_test_split
from sklearn.feature_selection import SelectFromModel
from sklearn.metrics import f1_score
from sklearn.metrics import classification_report
from sklearn.tree import DecisionTreeClassifier
from xgboost import XGBClassifier
import warnings
#将warning过滤掉
warnings.filterwarnings('ignore')
# 设置matplotlib的模式
%matplotlib inline
# 设置matplot的样式
matplotlib.style.use('ggplot')
#导入成功
print('导入成功!')
data_df = pd.read_csv("./train.csv",nrows=400000)
data_df.head()

在写入csv文件的时候,默认会自动加入新的一列,Unnamed,
解决方案:to_csv()时候,设置index=False。或者加上index=True, index_label=“id”

# 将读出来的数据保存为新表
data_df.to_csv("train_subset.csv",index=False)
# 通过pandas读取.csv文件,并展示头几个样本。
data_df = pd.read_csv('train_subset.csv')
#展示前五个样本
data_df.head()

在这里插入图片描述

data_df.shape
(400000, 24)
# 查看一下每一个特征的类型以及是否存在null
data_df.info(null_counts=True)
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000000 entries, 0 to 999999
Data columns (total 24 columns):
id                  1000000 non-null float64
click               1000000 non-null int64
hour                1000000 non-null int64
C1                  1000000 non-null int64
banner_pos          1000000 non-null int64
site_id             1000000 non-null object
site_domain         1000000 non-null object
site_category       1000000 non-null object
app_id              1000000 non-null object
app_domain          1000000 non-null object
app_category        1000000 non-null object
device_id           1000000 non-null object
device_ip           1000000 non-null object
device_model        1000000 non-null object
device_type         1000000 non-null int64
device_conn_type    1000000 non-null int64
C14                 1000000 non-null int64
C15                 1000000 non-null int64
C16                 1000000 non-null int64
C17                 1000000 non-null int64
C18                 1000000 non-null int64
C19                 1000000 non-null int64
C20                 1000000 non-null int64
C21                 1000000 non-null int64
dtypes: float64(1), int64(14), object(9)
memory usage: 183.1+ MB

hour数据类型转换

# TODO 把hour特征格式化成 '%y%m%d%H'形式。
#将hour数据由整型转换为字符串
data_df['hour'].astype(str)
#使用to_datetime方法,将hour特征由字符串转换为datetime数据格式,format设置为%y%m%d%H'
data_df['hour'] = pd.to_datetime(data_df['hour'],format='%y%m%d%H')
#显示转换后的hour
data_df['hour'].unique()
array(['2014-10-21T00:00:00.000000000', '2014-10-21T01:00:00.000000000',
       '2014-10-21T02:00:00.000000000'], dtype='datetime64[ns]')
# 重新打印一下是否有改变
data_df.head()

在这里插入图片描述
分两次展示所有特征

data_df.iloc[:, :12].head()

在这里插入图片描述

data_df.iloc[:, 12:].head()

在这里插入图片描述
从上述数据中,发现大量的特征为类别型特征,而且很多特征已经被编码成看不懂的字符串(这些都是为了不公开用户数据),但即便如此,也可以把它们直接看成是类别型特征。

三、数据的理解

id

len(data_df['id'].unique())
400000

说明该特征没有意义,予以删除

#删除id列
data_df.drop('id',axis=1,inplace=True)
#重新查看数据
data_df.head()

click
对标签分布的理解是必不可少的,因为这直接跟样本不平衡相关。

#提取标签中0和1的数量,并存入df_click中
df_click = data_df['click'].value_counts()
#打印结果
print(df_click)
#计算1、0的占比
pos_proportion = df_click[1]/(df_click[1] + df_click[0])
neg_proportion = df_click[0]/(df_click[1] + df_click[0])
#打印结果
print('正样本比例为:%.2f'%(pos_proportion))
print('负样本比例为:%.2f'%(neg_proportion))
0    333644
1     66356
Name
  • 12
    点赞
  • 102
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值