在线广告点击率预测:逻辑回归与特征选择全解析
立即解锁
发布时间: 2025-09-03 01:40:41 阅读量: 3 订阅数: 11 AIGC 

### 在线广告点击率预测:逻辑回归与特征选择全解析
#### 1. 模型训练与测试
在进行模型训练和测试时,我们可以按照以下代码操作:
```python
sgd_lr.fit(X_train_enc.toarray(), Y_train)
pred = sgd_lr.predict_proba(X_test_enc.toarray())[:, 1]
print(f'Training samples: {n_train}, AUC on testing set: {roc_auc_score(Y_test, pred):.3f}')
```
运行上述代码后,输出结果为:
```
Training samples: 100000, AUC on testing set: 0.734
```
可以看到,训练和测试过程简单快捷。
#### 2. 带正则化的逻辑回归模型训练
逻辑回归`SGDClassifier`中的`penalty`参数与模型正则化相关。正则化有两种基本形式:L1(也称为Lasso)和L2(也称为岭回归)。正则化是在原始成本函数的基础上增加一个额外的项,公式如下:
\[
J(w) = \frac{1}{m}\sum_{i = 1}^{m}-[y^{(i)}\log(\hat{y}(x^{(i)})) + (1 - y^{(i)})\log(1 - \hat{y}(x^{(i)}))] + \alpha||w||_q
\]
其中,\(\alpha\)是乘以正则化项的常数,\(q\)为1或2,分别代表L1或L2正则化。具体来说:
\[
||w||_1 = \sum_{j = 1}^{n}|w_j|
\]
训练逻辑回归模型的过程就是将成本作为权重\(w\)的函数进行最小化。如果某些权重(如\(w_i\)、\(w_j\)和\(w_k\))变得非常大,那么整个成本将由这些大权重决定。在这种情况下,学习到的模型可能只是记住了训练集,而无法推广到未见过的数据。引入正则化项是为了惩罚大权重,因为权重现在成为了要最小化的成本的一部分,从而消除过拟合。参数\(\alpha\)提供了对数损失和泛化能力之间的权衡:
- 若\(\alpha\)太小,无法压缩大权重,模型可能会出现高方差或过拟合。
- 若\(\alpha\)太大,模型可能会过度泛化,在拟合数据集方面表现不佳,即出现欠拟合。
因此,\(\alpha\)是调整以获得最佳带正则化逻辑回归模型的重要参数。
在选择L1和L2形式时,经验法则是基于是否需要进行特征选择。在机器学习分类中,特征选择是挑选出一组重要特征以构建更好模型的过程。在实际应用中,数据集中并非每个特征都包含对区分样本有用的信息,有些特征可能是冗余或无关的,可以在损失很小的情况下丢弃。在逻辑回归分类器中,只有L1正则化可以实现特征选择。
为了更好地理解,我们考虑两个权重向量\(w_1 = (1, 0)\)和\(w_2 = (0.5, 0.5)\),假设它们产生相同的对数损失,那么每个权重向量的L1和L2正则化项如下:
\[
|w_1|_1 = |1| + |0| = 1, |w_2|_1 = |0.5| + |0.5| = 1
\]
\[
|w_1|_2 = 1^2 + 0^2 = 1, |w_2|_2 = 0.5^2 + 0.5^2 = 0.5
\]
可以看出,两个向量的L1项相等,而\(w_2\)的L2项小于\(w_1\)的L2项。这表明L2正则化比L1正则化更惩罚由显著大权重和小权重组成的权重。换句话说,L2正则化倾向于所有权重的相对较小值,避免任何权重出现显著的大值和小值,而L1正则化允许一些权重具有显著的小值,一些具有显著的大值。只有L1正则化可以将一些权重压缩到接近或恰好为0,从而实现特征选择。
在`scikit-learn`中,可以通过`penalty`参数指定正则化类型,选项包括`none`(无正则化)、`"l1"`、`"l2"`和`"elasticnet"`(L1和L2的混合),通过`alpha`参数指定乘数\(\alpha\)。
#### 3. 使用L1正则化进行特征选择
我们可以按照以下步骤使用L1正则化进行特征选择:
1. 初始化一个带有L1正则化的SGD逻辑回归模型,并基于10,000个样本进行训练:
```python
sgd_lr_l1 = SGDClassifier(loss='log', penalty='l1', alpha=0.0001,
fit_intercept=True, max_iter=10,
learning_rate='constant', eta0=0.01)
sgd_lr_l1.fit(X_train_enc.toarray(), Y_train)
```
2. 获取训练模型系数的绝对值:
```python
coef_abs = np.abs(sgd_lr_l1.coef_)
print(coef_abs)
```
输出结果可能如下:
```
[[0. 0.09963329 0. ... 0. 0. 0.07431834]]
```
3. 打印底部10个系数及其值:
```python
print(np.sort(coef_abs)[0][:10])
bottom_10 = np.argsort(coef_abs)[0][:10]
```
输出结果为:
```
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
```
4. 查看这10个特征是什么:
```python
feature_names = enc.get_feature_names()
print('10 least important features are:\n', feature_names[bottom_10])
```
输出结果可能如下:
```
10 least important features are:
['x0_1001' 'x8_851897aa' 'x8_85119990' 'x8_84ebbcd4' 'x8_84eb6b0e'
'x8_84dda655' 'x8_84c2f017' 'x8_84ace234' 'x8_84a9d4ba' 'x8_84915a27']
```
这些特征分别来自`X_train`的不同列。
5. 同样地,获取顶部10个系数及其值:
```python
print(np.sort(coef_abs)[0][-10:])
top_10 = np.argsort(coef_abs)[0][-10:]
print('10 most important features are:\n', feature_names[top_10])
```
输出结果可能如下:
```
[0.67912376 0.70885933 0.79975917 0.8828797 0.98146351 0.98275124
1.08313767 1.13261091 1.18445527 1.40983505]
10 most important features are:
['x7_cef3e649' 'x3_7687a86e' 'x18_61' 'x18_15' 'x5_9c13b419'
'x5_5e3f096f' 'x2_763a42b5' 'x2_d9750ee7' 'x3_27e3c518'
'x5_1779deee']
```
#### 4. 大规模数据集的在线学习训练
到目前为止,我们的模型训练样本不超过300,000个。如果超过这个数量,内存可能会因数据过多而超载,导致程序崩溃。在线学习可以解决这个问题。SGD是从梯度下降演变而来的,它通过一次使用一个训练样本依次更新模型,而不是一次性使用整个训练集。我们可以使用在线学习技术进一步扩展SGD。
在线学习中,用于训练的新数据按顺序或实时可用,这与离线学习环境中一次性获取所有数据不同。每次加载和预处理相对较小的数据块进行训练,这样可以释放用于存储整个大型数据集的内存。除了具有更好的计算可行性外,在线学习还因其能够适应实时生成新数据并用于更新模型的情况而被广泛使用。例如,股票价格预测模型使用及时的市场数据以在线学习的方式进行更新;点击率预测模型需要包含反映用户最新行为和品味的最新数据;垃圾邮件检测器必须通过考虑动态生成的新特征来对不断变化的垃圾邮件发送者做出反应。
在`scikit-learn`中,`SGDClassifier`模块通过`partial_fit`方法实现在线学习(而`fit`方法用于离线学习)。我们可以按照以下步骤模拟在线学习环境,使用1,000,000个样本训练模型,并在另外100,000个样本上进行测试:
1. 读取数据:
```python
n_rows = 100000 * 11
df = pd.read_csv("train", nrows=n_rows)
X = df.drop(['click', 'id', 'hour', 'device_id', 'device_ip'], axis=1).values
Y = df['click'].values
n_train = 100000 * 10
X_train = X[:n_train]
Y_train = Y[
```
0
0
复制全文
相关推荐










