阿里云天池大赛-赛题解析
视频讲解,阿里云平台使用简介: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
736

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



