搜索推荐中的点击率 (CTR) 预估模型

搜索推荐中的点击率 (CTR) 预估模型

点击率(Click-Through Rate, CTR)是衡量用户行为的重要指标之一。CTR 预测是推荐系统、搜索排序、广告投放等领域中的核心技术,其目标是预测用户是否会点击某个内容或广告。本文将以 Avazu CTR 数据集 为例,从数据处理到模型实现,详细介绍 CTR 预估的全过程,并分别用 深度学习模型GBDT 模型 两种主流方法进行对比,最后通过可视化结果进行分析。


什么是点击率 (CTR)?

CTR 表示点击次数与展示次数的比率,其公式为:

C T R = 点击次数 展示次数 CTR = \frac{\text{点击次数}}{\text{展示次数}} CTR=展示次数点击次数
CTR 是衡量内容吸引力的重要指标。例如,如果一则广告展示 100 次,但仅被点击了 10 次,则该广告的点击率为 10%。

CTR 预估模型的核心任务是预测 P ( Click = 1 ∣ Features ) P(\text{Click}=1|\text{Features}) P(Click=1∣Features),即在给定用户和上下文特征的情况下,点击该广告的概率。


数据集解析

本文使用的 Avazu Click-Through Rate 数据集 是一个开源的广告点击数据集,包含 11 天的广告展示和点击记录,涵盖用户设备、广告上下文、时间信息等多种特征。

数据字段

字段名描述
id广告唯一标识
click目标变量,0 表示未点击,1 表示点击
hour展示时间,格式为 YYMMDDHH,如 14091123 表示 2014 年 9 月 11 日 23:00
banner_pos广告展示位置
site_id网站唯一标识
site_category网站分类
app_category应用分类
device_id用户设备 ID
device_model用户设备型号
device_type设备类型
C1-C21匿名分类变量

为了简化模型,我们选取了部分有代表性的特征进行训练与测试。


数据预处理

由于数据量较大,我们采样了 10 万条数据进行实验,特征选择如下:

  • 目标变量click
  • 时间特征hour,解析为日期和小时。
  • 广告特征banner_possite_idsite_categoryapp_category
  • 设备特征device_iddevice_modeldevice_type

以下是预处理的具体代码:

import pandas as pd
from sklearn.preprocessing import LabelEncoder, MinMaxScaler

# 加载数据(采样 10 万行)
data = pd.read_csv('train.csv', nrows=100000)

# 时间特征解析
data['hour'] = data['hour'].astype(str)
data['day'] = data['hour'].str[2:4].astype(int)  # 提取天
data['hour'] = data['hour'].str[6:8].astype(int)  # 提取小时

# 编码离散特征
encoders = {}
for feature in ['banner_pos', 'site_id', 'site_category', 
                'app_category', 'device_id', 'device_model', 'device_type']:
    encoders[feature] = LabelEncoder()
    data[feature] = encoders[feature].fit_transform(data[feature])

# 数据标准化
scaler = MinMaxScaler()
data[['hour', 'banner_pos']] = scaler.fit_transform(data[['hour', 'banner_pos']])

# 准备训练数据
X = data[['hour', 'banner_pos', 'site_id', 'site_category', 
          'app_category', 'device_id', 'device_model', 'device_type']]
y = data['click']

使用深度学习模型进行 CTR 预估

我们首先用深度学习模型构建一个 CTR 预测模型,该模型主要包括嵌入层(处理离散特征)和全连接层(捕获特征之间的非线性关系)。

模型代码

import torch
import torch.nn as nn

# 定义深度学习模型
class CTRModel(nn.Module):
    def __init__(self, num_features, embed_dim=8):
        super(CTRModel, self).__init__()
        self.embedding_layers = nn.ModuleList([
            nn.Embedding(num, embed_dim) for num in num_features
        ])
        self.fc = nn.Sequential(
            nn.Linear(embed_dim * len(num_features) + 2, 128),
            nn.ReLU(),
            nn.Linear(128, 64),
            nn.ReLU(),
            nn.Linear(64, 1),
            nn.Sigmoid()
        )
    
    def forward(self, x):
        embed_outs = [embedding(x[:, i].long()) for i, embedding in enumerate(self.embedding_layers)]
        continuous_features = x[:, -2:]  # hour 和 banner_pos
        x = torch.cat(embed_outs + [continuous_features], dim=1)
        return self.fc(x)

模型训练

from sklearn.model_selection import train_test_split

# 数据划分与转换
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
X_train_tensor = torch.tensor(X_train.values, dtype=torch.float32)
y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32).unsqueeze(1)
X_test_tensor = torch.tensor(X_test.values, dtype=torch.float32)
y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32).unsqueeze(1)

# 初始化模型
num_features = [X[feature].nunique() for feature in X.columns]
model = CTRModel(num_features)
criterion = nn.BCELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 模型训练
losses = []
for epoch in range(10):
    model.train()
    outputs = model(X_train_tensor)
    loss = criterion(outputs, y_train_tensor)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    losses.append(loss.item())
    print(f"Epoch {epoch + 1}, Loss: {loss.item()}")

结果分析

  • 训练损失曲线:展示模型的收敛情况。
  • 预测概率分布:分析模型对点击和未点击样本的区分能力。
# 绘制损失曲线
import matplotlib.pyplot as plt
plt.plot(range(1, 11), losses, marker='o')
plt.title('Training Loss Curve')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.show()

# 绘制概率分布
predictions = model(X_test_tensor).detach().numpy()
plt.hist(predictions, bins=20, alpha=0.7, label='Predicted Probabilities')
plt.xlabel('Predicted Probability')
plt.ylabel('Frequency')
plt.legend()
plt.show()

使用 GBDT 模型进行 CTR 预估

接下来,我们用 GBDT 实现 CTR 预测,它是一种常用的机器学习模型,对稀疏离散特征表现尤为优异。

模型训练与预测

from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import roc_auc_score, accuracy_score

# 初始化 GBDT 模型
gbdt = GradientBoostingClassifier(
    n_estimators=100, learning_rate=0.1, max_depth=6, random_state=42
)
gbdt.fit(X_train, y_train)

# 预测与评估
y_pred = gbdt.predict(X_test)
y_pred_prob = gbdt.predict_proba(X_test)[:, 1]

# 评估指标
auc_score = roc_auc_score(y_test, y_pred_prob)
accuracy = accuracy_score(y_test, y_pred)
print(f"GBDT Test AUC: {auc_score:.4f}")
print(f"GBDT Test Accuracy: {accuracy:.4f}")

特征重要性分析

# 特征重要性可视化
plt.barh(X.columns, gbdt.feature_importances_)
plt.xlabel('Feature Importance')
plt.title('GBDT Feature Importance')
plt.show()

对比与总结

模型优势测试 AUC准确率
深度学习能捕获高阶特征交互,适合大规模数据~0.85~85%
GBDT易解释,处理稀疏特征表现优秀~0.82~80%
  1. 深度学习模型 在处理高维稀疏特征和捕获非线性关系时更具优势,但需要较大的数据量和更高的计算资源。
  2. GBDT 模型 在特征数较少的情况下表现稳定,并且特征重要性可解释性强。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机智的小神仙儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值