13、基于逻辑回归的点击率预测

基于逻辑回归的点击率预测

1. 随机梯度下降训练逻辑回归模型

在基于梯度下降的逻辑回归模型中,每次迭代都会使用所有训练样本更新权重。若训练样本数量庞大,整个训练过程会变得极为耗时且计算成本高昂。

为解决这一问题,可采用随机梯度下降(SGD)。每次更新权重时,仅使用一个训练样本,而非整个训练集。模型根据单个训练样本计算的误差进行一步更新,遍历完所有样本即完成一次迭代。SGD 通常在几次迭代(通常少于 10 次)内就能收敛,比梯度下降快得多。

以下是实现 SGD 逻辑回归的代码:

def update_weights_sgd(X_train, y_train, weights, learning_rate):
    """ One weight update iteration: moving weights by one
        step based on each individual sample
    Args:
        X_train, y_train (numpy.ndarray, training data set)
        weights (numpy.ndarray)
        learning_rate (float)
    Returns:
        numpy.ndarray, updated weights
    """
    for X_each, y_each in zip(X_train, y_train):
        prediction = compute_prediction(X_each, weights)
        weights_delta = X_each.T * (y_each - prediction)
        weights += learning_rate * weights_delta
    return weights

train_logistic_regression 函数中,将 weights = update_weights_gd(X_train, y_train, weights, learning_rate) 替换为 weights = update_weights_sgd(X_train, y_train, weights, learning_rate)

下面通过实验验证 SGD 的效果:

import timeit
from sklearn.metrics import roc_auc_score

# 使用 10000 个训练样本
start_time = timeit.default_timer()
weights = train_logistic_regression(X_train_10k, y_train_10k, max_iter=5, learning_rate=0.01, fit_intercept=True)
print("--- %0.3fs seconds ---" % (timeit.default_timer() - start_time))
predictions = predict(X_test_10k, weights)
print('The ROC AUC on testing set is: {0:.3f}'.format(roc_auc_score(y_test, predictions)))

# 使用 100000 个训练样本
start_time = timeit.default_timer()
weights = train_logistic_regression(X_train_100k, y_train_100k, max_iter=5, learning_rate=0.01, fit_intercept=True)
print("--- %0.3fs seconds ---" % (timeit.default_timer() - start_time))
X_dict_test, y_test_next10k = read_ad_click_data(10000, 100000)
X_test_next10k = dict_one_hot_encoder.transform(X_dict_test)
predictions = predict(X_test_next10k, weights)
print('The ROC AUC on testing set is: {0:.3f}'.format(roc_auc_score(y_test_next10k, predictions)))

实验结果表明,SGD 不仅训练速度快,而且在测试集上的性能也更好。

我们还可以使用 scikit-learn 的 SGDClassifier 实现 SGD 逻辑回归:

from sklearn.linear_model import SGDClassifier

sgd_lr = SGDClassifier(loss='log', penalty=None, fit_intercept=True, n_iter=5, learning_rate='constant', eta0=0.01)
sgd_lr.fit(X_train_100k, y_train_100k)
predictions = sgd_lr.predict_proba(X_test_next10k)[:, 1]
print('The ROC AUC on testing set is: {0:.3f}'.format(roc_auc_score(y_test_next10k, predictions)))
2. 带正则化的逻辑回归模型训练

逻辑回归 SGDClassifier 中的 penalty 参数与模型正则化有关。正则化有两种基本形式:L1 和 L2。正则化是在原始成本函数基础上增加的一项。

训练逻辑回归模型是降低成本作为权重 w 的函数的过程。若某些权重过大,模型可能会过拟合,即只记住训练集而无法泛化到未见过的数据。正则化项用于惩罚大权重,从而消除过拟合。参数 α 提供了对数损失和泛化之间的权衡。

选择 L1 还是 L2 正则化取决于是否需要特征选择。在逻辑回归分类器中,只有 L1 正则化可以实现特征选择。因为 L1 正则化允许一些权重接近或等于 0,从而可以筛选出重要特征。

以下是使用 L1 正则化进行特征选择的代码:

from sklearn.linear_model import SGDClassifier

l1_feature_selector = SGDClassifier(loss='log', penalty='l1', alpha=0.0001, fit_intercept=True, n_iter=5, learning_rate='constant', eta0=0.01)
l1_feature_selector.fit(X_train_10k, y_train_10k)
X_train_10k_selected = l1_feature_selector.transform(X_train_10k)
print(X_train_10k_selected.shape)

通过上述代码,我们可以看到从原始的 2820 个特征中选择了 574 个最重要的特征。

3. 在线学习处理大规模数据集

之前我们的模型训练基于 100000 个样本,若数据量更大,内存会过载。在线学习可以解决这个问题。

在线学习中,训练数据按顺序或实时提供,每次只加载和预处理一小部分数据进行训练,释放了用于存储整个大型数据集的内存。此外,在线学习还适用于需要实时更新模型的场景,如股票价格预测、点击率预测和垃圾邮件检测等。

以下是使用 scikit-learn 的 SGDClassifier 进行在线学习的代码:

from sklearn.linear_model import SGDClassifier
import timeit
from sklearn.metrics import roc_auc_score

sgd_lr = SGDClassifier(loss='log', penalty=None, fit_intercept=True, n_iter=1, learning_rate='constant', eta0=0.01)
start_time = timeit.default_timer()
for i in range(10):
    X_dict_train, y_train_every_100k = read_ad_click_data(100000, i * 100000)
    X_train_every_100k = dict_one_hot_encoder.transform(X_dict_train)
    sgd_lr.partial_fit(X_train_every_100k, y_train_every_100k, classes=[0, 1])

X_dict_test, y_test_next10k = read_ad_click_data(10000, (i + 1) * 100000)
X_test_next10k = dict_one_hot_encoder.transform(X_dict_test)
predictions = sgd_lr.predict_proba(X_test_next10k)[:, 1]
print('The ROC AUC on testing set is: {0:.3f}'.format(roc_auc_score(y_test_next10k, predictions)))
print("--- %0.3fs seconds ---" % (timeit.default_timer() - start_time))

通过在线学习,基于 1000000 个样本的训练变得计算有效。

4. 处理多类分类问题

逻辑回归处理多类分类问题时,也称为多项式逻辑回归或软最大回归。在二分类问题中,模型由一个权重向量 w 表示;在 K 类问题中,模型由 K 个权重向量 w1, w2, ..., wK 表示。

以下是使用新闻主题数据集进行多类逻辑回归实验的代码:

from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import SGDClassifier

data_train = fetch_20newsgroups(subset='train', categories=None, random_state=42)
data_test = fetch_20newsgroups(subset='test', categories=None, random_state=42)
cleaned_train = clean_text(data_train.data)
label_train = data_train.target
cleaned_test = clean_text(data_test.data)
label_test = data_test.target

tfidf_vectorizer = TfidfVectorizer(sublinear_tf=True, max_df=0.5, stop_words='english', max_features=40000)
term_docs_train = tfidf_vectorizer.fit_transform(cleaned_train)
term_docs_test = tfidf_vectorizer.transform(cleaned_test)

parameters = {'penalty': ['l2', None], 'alpha': [1e-07, 1e-06, 1e-05, 1e-04], 'eta0': [0.01, 0.1, 1, 10]}
sgd_lr = SGDClassifier(loss='log', learning_rate='constant', eta0=0.01, fit_intercept=True, n_iter=10)
grid_search = GridSearchCV(sgd_lr, parameters, n_jobs=-1, cv=3)
grid_search.fit(term_docs_train, label_train)
print(grid_search.best_params_)

sgd_lr_best = grid_search.best_estimator_
accuracy = sgd_lr_best.score(term_docs_test, label_test)
print('The accuracy on testing set is: {0:.1f}%'.format(accuracy*100))
5. 随机森林进行特征选择

除了 L1 正则化逻辑回归,随机森林也是常用的特征选择技术。随机森林是基于一组决策树的集成学习方法,每个树在搜索最佳分割点时考虑特征的随机子集。特征在树节点中出现的频率越高,其重要性就越高。

以下是使用随机森林进行特征选择的代码:

from sklearn.ensemble import RandomForestClassifier
import numpy as np

random_forest = RandomForestClassifier(n_estimators=100, criterion='gini', min_samples_split=30, n_jobs=-1)
random_forest.fit(X_train_10k, y_train_10k)

# 查看最不重要的 10 个特征
print(np.sort(random_forest.feature_importances_)[:10])
print(np.argsort(random_forest.feature_importances_)[:10])

# 查看最重要的 10 个特征
print(np.sort(random_forest.feature_importances_)[-10:])
print(np.argsort(random_forest.feature_importances_)[-10:])

# 选择前 500 个特征
top500_feature = np.argsort(random_forest.feature_importances_)[-500:]
X_train_10k_selected = X_train_10k[:, top500_feature]
print(X_train_10k_selected.shape)
总结

本文围绕逻辑回归在点击率预测中的应用展开,介绍了随机梯度下降训练、正则化、在线学习、多类分类处理以及随机森林特征选择等技术。这些技术可以提高逻辑回归模型的性能和效率,使其适用于大规模数据集。通过实验验证,这些技术在实际应用中具有良好的效果。

流程图

graph LR
    A[开始] --> B[数据准备]
    B --> C[随机梯度下降训练]
    C --> D[带正则化训练]
    D --> E[在线学习]
    E --> F[多类分类处理]
    F --> G[随机森林特征选择]
    G --> H[结束]

表格

技术 优点 应用场景
随机梯度下降 训练速度快,适用于大规模数据集 大规模点击率预测
正则化 消除过拟合,可进行特征选择 避免模型过拟合
在线学习 处理大规模数据,实时更新模型 实时数据更新场景
多类分类处理 处理多类问题 新闻主题分类等
随机森林特征选择 筛选重要特征 特征选择

基于逻辑回归的点击率预测

6. 技术对比与总结

在前面的内容中,我们介绍了多种用于点击率预测的技术,下面对这些技术进行对比总结,以便更好地理解它们的特点和适用场景。

技术名称 原理 优点 缺点 适用场景
随机梯度下降(SGD) 每次迭代仅使用一个训练样本更新权重 收敛速度快,计算效率高,适合大规模数据集 可能会在最优解附近震荡 大规模数据集的快速训练
正则化(L1 和 L2) 在成本函数中添加额外项惩罚大权重 消除过拟合,L1 可进行特征选择 可能需要调整正则化参数 避免模型过拟合,筛选重要特征
在线学习 按顺序或实时处理新数据更新模型 适应实时数据更新,节省内存 需要持续获取新数据 实时数据更新场景,如股票预测、点击率预测
多类逻辑回归(软最大回归) 使用 K 个权重向量处理 K 类分类问题 能够处理多类分类问题 计算复杂度相对较高 新闻主题分类、图像分类等多类场景
随机森林特征选择 根据特征在树节点中的出现频率评估重要性 可有效筛选重要特征 计算成本较高 特征选择,减少数据维度

从上述表格可以看出,每种技术都有其独特的优势和适用场景。在实际应用中,我们需要根据数据集的规模、问题的复杂度以及具体的需求来选择合适的技术或技术组合。

7. 操作步骤总结

为了方便大家在实际应用中使用这些技术,下面总结了各个技术的操作步骤。

7.1 随机梯度下降训练逻辑回归模型
  1. 定义 update_weights_sgd 函数,实现基于单个样本的权重更新。
def update_weights_sgd(X_train, y_train, weights, learning_rate):
    """ One weight update iteration: moving weights by one
        step based on each individual sample
    Args:
        X_train, y_train (numpy.ndarray, training data set)
        weights (numpy.ndarray)
        learning_rate (float)
    Returns:
        numpy.ndarray, updated weights
    """
    for X_each, y_each in zip(X_train, y_train):
        prediction = compute_prediction(X_each, weights)
        weights_delta = X_each.T * (y_each - prediction)
        weights += learning_rate * weights_delta
    return weights
  1. train_logistic_regression 函数中调用 update_weights_sgd 函数更新权重。
  2. 使用训练好的模型进行预测并评估性能。
7.2 带正则化的逻辑回归模型训练
  1. 选择合适的正则化类型(L1 或 L2)和正则化参数 alpha
  2. 使用 SGDClassifier 初始化模型,并设置 penalty alpha 参数。
from sklearn.linear_model import SGDClassifier

l1_feature_selector = SGDClassifier(loss='log', penalty='l1', alpha=0.0001, fit_intercept=True, n_iter=5, learning_rate='constant', eta0=0.01)
  1. 使用训练数据拟合模型。
  2. 使用 transform 方法进行特征选择。
7.3 在线学习处理大规模数据集
  1. 使用 SGDClassifier 初始化模型。
from sklearn.linear_model import SGDClassifier

sgd_lr = SGDClassifier(loss='log', penalty=None, fit_intercept=True, n_iter=1, learning_rate='constant', eta0=0.01)
  1. 按顺序加载和预处理小批量数据。
  2. 使用 partial_fit 方法更新模型。
for i in range(10):
    X_dict_train, y_train_every_100k = read_ad_click_data(100000, i * 100000)
    X_train_every_100k = dict_one_hot_encoder.transform(X_dict_train)
    sgd_lr.partial_fit(X_train_every_100k, y_train_every_100k, classes=[0, 1])
  1. 使用测试数据评估模型性能。
7.4 处理多类分类问题
  1. 准备多类数据集,如新闻主题数据集。
  2. 使用 TfidfVectorizer 进行特征提取。
from sklearn.feature_extraction.text import TfidfVectorizer

tfidf_vectorizer = TfidfVectorizer(sublinear_tf=True, max_df=0.5, stop_words='english', max_features=40000)
term_docs_train = tfidf_vectorizer.fit_transform(cleaned_train)
term_docs_test = tfidf_vectorizer.transform(cleaned_test)
  1. 使用 GridSearchCV 进行参数调优。
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import SGDClassifier

parameters = {'penalty': ['l2', None], 'alpha': [1e-07, 1e-06, 1e-05, 1e-04], 'eta0': [0.01, 0.1, 1, 10]}
sgd_lr = SGDClassifier(loss='log', learning_rate='constant', eta0=0.01, fit_intercept=True, n_iter=10)
grid_search = GridSearchCV(sgd_lr, parameters, n_jobs=-1, cv=3)
grid_search.fit(term_docs_train, label_train)
  1. 使用最优模型进行预测并评估性能。
7.5 随机森林特征选择
  1. 使用 RandomForestClassifier 初始化模型。
from sklearn.ensemble import RandomForestClassifier

random_forest = RandomForestClassifier(n_estimators=100, criterion='gini', min_samples_split=30, n_jobs=-1)
  1. 使用训练数据拟合模型。
  2. 根据 feature_importances_ 属性评估特征重要性。
print(np.sort(random_forest.feature_importances_)[:10])
print(np.argsort(random_forest.feature_importances_)[:10])
print(np.sort(random_forest.feature_importances_)[-10:])
print(np.argsort(random_forest.feature_importances_)[-10:])
  1. 选择重要特征并更新数据集。
top500_feature = np.argsort(random_forest.feature_importances_)[-500:]
X_train_10k_selected = X_train_10k[:, top500_feature]
8. 未来展望

随着数据量的不断增长和业务需求的不断变化,点击率预测领域将面临更多的挑战和机遇。未来,我们可以从以下几个方面进一步探索和优化:

  • 模型融合 :将多种不同的模型进行融合,如逻辑回归与深度学习模型(如神经网络)相结合,充分发挥各自的优势,提高预测的准确性。
  • 特征工程 :深入挖掘数据中的潜在特征,结合领域知识和先进的特征提取技术,创造更有价值的特征,提升模型性能。
  • 实时性优化 :在在线学习的基础上,进一步优化模型的实时更新机制,减少延迟,更好地适应实时数据的变化。
  • 可解释性增强 :随着模型复杂度的增加,模型的可解释性变得越来越重要。未来需要研究如何提高逻辑回归等模型的可解释性,以便更好地理解模型的决策过程。

总之,点击率预测是一个充满挑战和机遇的领域,通过不断地探索和创新,我们可以开发出更高效、更准确的预测模型,为业务决策提供有力支持。

流程图

graph LR
    A[选择技术] --> B{技术类型}
    B --> |随机梯度下降| C[定义更新函数]
    B --> |正则化| D[选择正则化类型和参数]
    B --> |在线学习| E[初始化模型]
    B --> |多类分类| F[准备数据集和特征提取]
    B --> |随机森林特征选择| G[初始化随机森林模型]
    C --> H[训练模型]
    D --> H
    E --> I[按顺序更新模型]
    F --> J[参数调优]
    G --> K[评估特征重要性]
    H --> L[评估性能]
    I --> L
    J --> L
    K --> M[选择重要特征]
    M --> L
    L --> N[结束]

总结

本文详细介绍了基于逻辑回归的点击率预测技术,包括随机梯度下降、正则化、在线学习、多类分类处理和随机森林特征选择等。通过对这些技术的原理、优点、缺点和适用场景的分析,我们可以根据具体需求选择合适的技术。同时,我们还提供了详细的操作步骤和代码示例,方便大家在实际应用中使用。未来,我们可以进一步探索模型融合、特征工程等方向,不断提升点击率预测的性能和效果。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值