O2O优惠券预测

阿里云天池大赛-赛题解析
视频讲解,阿里云平台使用简介:https://edu.aliyun.com/course/3111998/lesson/341815283
重点思路参考:博客讲解
在这里插入图片描述
在这里插入图片描述

1.数据探索

代码连接:https://tianchi.aliyun.com/notebook/129415
数据简介:赛题提供用户在2016年1月1日至2016年6月30日之间真实线上线下消费行为,预测用户在2016年7月领取优惠券后15天以内的使用情况。
首先,O2O即Online To Offline,也即将线下商务的机会与互联网结合在了一起,让互联网成为线下交易的前台。这样线下服务就可以用线上来揽客,消费者可以用线上来筛选服务,还有成交可以在线结算,很快达到规模。

其次,题目给出了两个训练集 online 和 offline,分别为线上数据和线下数据。从这两个训练集中,我们可以提取到:用户相关的特征,商家相关的特征,优惠劵相关的特征,用户-商家交互特征。提取到的特征越多,对模型的训练结果提升会相应增多,所以应该尽可能提取多一些特征。

另外,赛题的目标是对于用户2016年1月1日至2016年6月30日之间真实线上线下消费行为进行训练,对用户在2016年7月领取优惠券后15天以内的使用情况进行预测。我们在训练集提取的诸多特征中,测试集里可能无法提取到,此时需要对数据集进行滑窗操作,即:从前面时间段的数据提取特征对后面时间段的数据进行预测。

最后,我们可以发现:赛题提供的预测集中,包含了同一个用户在整个7月份里的优惠券领取情况,这实际上是一种leakage,比如存在这种情况:某一个用户在7月10日领取了某优惠券,然后在7月12日和7月15日又领取了相同的优惠券,那么7月10日领取的优惠券被核销的可能性就很大了。我们在做特征工程时可以提取一些相关的特征。【加入这部分特征后,AUC会有显著提升,但这些特征在实际业务中是无法获取到的。】

常见库导入缩写习惯:

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from datetime import date
import datetime as dt
from scipy import stats

1.1.画箱形图示例

fig = plt.figure(figsize=(4, 6))  # 指定绘图对象宽度和高度
sns.boxplot(dftrain[(dftrain.label>=0)&(dftrain.distance>=0)]['distance'],orient="v", width=0.5)
plt.show()

1.2.直方图和QQ图

plt.figure(figsize=(10,5))
# ax=plt.subplot(1,2,1)
sns.distplot(
    dftrain[(dftrain.label>=0)&(dftrain.distance>=0)]['distance'],
    fit=stats.norm) # 拟合正态分布曲线
plt.show()

plt.figure(figsize=(10,5))
# ax=plt.subplot(1,2,2)
res = stats.probplot(dftrain[(dftrain.label>=0)&(dftrain.distance>=0)]['distance'], plot=plt)
plt.show()

1.3.概率图

stats.probplot 是 SciPy 库中用于生成概率图(Probability Plot)的核心函数,主要用于检验数据是否符合特定理论分布(如正态分布)。以下是其核心含义和使用方法的详细说明:

plt.figure(figsize=(10,5))
res = stats.probplot(dftrain[(dftrain.label>=0)&(dftrain.discount_rate>=0)]['discount_rate'], plot=plt)
plt.show()

1.4.对比分布

ax = sns.kdeplot(dftrain[(dftrain.label>=0)&(dftrain.discount_rate>=0)]['discount_rate'], color="Red", shade=True)
ax = sns.kdeplot(dftest[(dftest.discount_rate>=0)]['discount_rate'], color="Blue", shade=True)
ax.set_xlabel('discount_rate')
ax.set_ylabel("Frequency")
ax = ax.legend(["train","test"])
plt.show()

seaborn.kdeplot() 是 Seaborn 库中用于绘制核密度估计图(Kernel Density Estimate Plot)的核心函数。它通过平滑的曲线展示单变量或双变量数据的概率密度分布,是数据探索和统计建模中常用的可视化工具。以下是其核心含义、参数及使用场景的详细说明:

1.5.可视化线性关系

plt.figure(figsize=(8,4))
sns.regplot(x='distance', y='label', data=dftrain[(dftrain.label>=0)&(dftrain.distance>=0)][['distance','label']], ax=ax, 
            scatter_kws={'marker':'.','s':3,'alpha':0.3},
            line_kws={'color':'k'});
plt.xlabel('distance')
plt.ylabel('label')

seaborn.regplot() 是 Seaborn 库中用于绘制回归分析图的核心函数,它通过散点图展示两个变量之间的关系,并叠加一条回归线(默认线性回归)以量化这种关系的趋势。

2.特征工程

代码链接:https://tianchi.aliyun.com/notebook/129421

2.1.特征工程思路

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2.代码

画特征相关性图

plt.figure(figsize=(20, 16))  
column = traindf.columns.tolist()  
mcorr = traindf[column].corr(method="spearman")  
mask = np.zeros_like(mcorr, dtype=np.bool_)  
mask[np.triu_indices_from(mask)] = True  
cmap = sns.diverging_palette(220, 10, as_cmap=True)  
g = sns.heatmap(mcorr, mask=mask, cmap=cmap, square=True, annot=True, fmt='0.2f')  
plt.show()

preprocessing.MinMaxScaler() 是 Scikit-learn 库中的一个数据预处理工具,用于将特征缩放到指定的范围内(默认是 [0, 1])。它通过线性变换将每个特征的值重新映射到目标范围,适用于需要统一特征量纲的场景(如神经网络、支持向量机等)。

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))  # 默认范围是 [0, 1]
# 假设 X_train 是训练数据,X_test 是测试数据
scaler.fit(X_train)          # 计算训练数据的最小值和范围
X_train_scaled = scaler.transform(X_train)  # 转换训练数据
X_test_scaled = scaler.transform(X_test)    # 转换测试数据

3.模型训练

代码链接:https://tianchi.aliyun.com/notebook/129424

3.1.决策树

具体参考《统计学习方法》
在这里插入图片描述

3.2.模型融合

在这里插入图片描述

3.3.计算auc

核心原理
AUC(Area Under the ROC Curve)是衡量分类模型性能的重要指标,其值介于0.5(随机分类)和1(完美分类)之间。计算AUC的核心是量化正负样本的排序质量,即正样本的预测得分是否普遍高于负样本。
两种主流计算方法
在这里插入图片描述
在这里插入图片描述
代码实现(含平局处理)

import numpy as np
from sklearn.metrics import roc_auc_score

def manual_auc(y_true, y_scores):
    # 将样本按预测得分降序排序,同时保持真实标签的顺序
    sorted_indices = np.argsort(-y_scores)
    y_true_sorted = y_true[sorted_indices]
    
    # 初始化正样本计数和rank总和
    positive_count = 0
    rank_sum = 0
    
    # 遍历排序后的样本,处理平局
    for i in range(len(y_true_sorted)):
        if y_true_sorted[i] == 1:
            positive_count += 1
            # 计算当前正样本的rank(考虑平局)
            current_rank = i + 1  # 索引从0开始,rank从1开始
            # 统计与当前正样本得分相同的后续正样本数
            j = i
            while j < len(y_true_sorted) and y_scores[sorted_indices[j]] == y_scores[sorted_indices[i]]:
                j += 1
            # 平均rank(处理平局)
            avg_rank = (i + 1 + j) // 2
            rank_sum += avg_rank
            # 跳过平局的后续样本
            i = j - 1
    
    # 计算总的正负样本对数
    n_pos = positive_count
    n_neg = len(y_true) - n_pos
    if n_pos == 0 or n_neg == 0:
        return 0.5  # 无正或负样本时返回0.5
    
    # 计算AUC(概率排序法)
    auc = (rank_sum - n_pos * (n_pos + 1) / 2) / (n_pos * n_neg)
    return auc

# 示例数据(含平局)
y_true = np.array([0, 0, 1, 1, 1])
y_scores = np.array([0.8, 0.6, 0.7, 0.7, 0.5])

# 手动计算AUC
manual_auc_value = manual_auc(y_true, y_scores)
print(f"手动实现的AUC值: {manual_auc_value:.4f}")

# 使用sklearn库计算AUC
sklearn_auc_value = roc_auc_score(y_true, y_scores)
print(f"使用sklearn计算的AUC值: {sklearn_auc_value:.4f}")

特殊情况:
若所有样本预测得分相同,AUC=0.5(随机分类)。
若正样本预测得分均高于负样本,AUC=1(完美分类)。
总结
推荐方法:优先使用sklearn.metrics.roc_auc_score(底层已优化平局处理)。
手动实现:需严格处理平局和边界条件,否则可能导致微小误差。
物理意义:AUC本质是“随机选取一个正样本和一个负样本,正样本得分高于负样本的概率”。

4.模型验证

代码链接:https://tianchi.aliyun.com/notebook/129425

5.赛题实践

代码链接:https://tianchi.aliyun.com/notebook/129434

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值