基于逻辑回归的点击率预测
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 随机梯度下降训练逻辑回归模型
-
定义
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
-
在
train_logistic_regression函数中调用update_weights_sgd函数更新权重。 - 使用训练好的模型进行预测并评估性能。
7.2 带正则化的逻辑回归模型训练
-
选择合适的正则化类型(L1 或 L2)和正则化参数
alpha。 -
使用
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)
- 使用训练数据拟合模型。
-
使用
transform方法进行特征选择。
7.3 在线学习处理大规模数据集
-
使用
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)
- 按顺序加载和预处理小批量数据。
-
使用
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])
- 使用测试数据评估模型性能。
7.4 处理多类分类问题
- 准备多类数据集,如新闻主题数据集。
-
使用
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)
-
使用
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)
- 使用最优模型进行预测并评估性能。
7.5 随机森林特征选择
-
使用
RandomForestClassifier初始化模型。
from sklearn.ensemble import RandomForestClassifier
random_forest = RandomForestClassifier(n_estimators=100, criterion='gini', min_samples_split=30, n_jobs=-1)
- 使用训练数据拟合模型。
-
根据
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:])
- 选择重要特征并更新数据集。
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[结束]
总结
本文详细介绍了基于逻辑回归的点击率预测技术,包括随机梯度下降、正则化、在线学习、多类分类处理和随机森林特征选择等。通过对这些技术的原理、优点、缺点和适用场景的分析,我们可以根据具体需求选择合适的技术。同时,我们还提供了详细的操作步骤和代码示例,方便大家在实际应用中使用。未来,我们可以进一步探索模型融合、特征工程等方向,不断提升点击率预测的性能和效果。
超级会员免费看
1575

被折叠的 条评论
为什么被折叠?



