Predict Podcast Listening Time-(回归+特征工程+xgb)

Predict Podcast Listening Time

题意:

给你没个播客的信息,让你预测观众的聆听时间。

数据处理:

1.构造新特征收听效率进行分组
2.对数据异常处理
3.对时间情绪等进行数值编码
4.求某特征值求多项式特征
5.生成特征组合
6.交叉验证并encoder编码

建立模型:

1.创建xgb训练回调函数,动态调整学习率
2.DMatrix优化数据,训练模型

代码:
import numpy as np
import pandas as pd
import os
import os
import warnings
import numpy as np
import pandas as pd
import xgboost as xgb
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import KFold
from sklearn.preprocessing import LabelEncoder
from cuml.preprocessing import TargetEncoder
from itertools import combinations
from tqdm.auto import tqdmfor dirname, _, filenames in os.walk('/kaggle/input'):for filename in filenames:print(os.path.join(dirname, filename))os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' #仅输出错误日志
warnings.simplefilter('ignore') #忽略警告日志
pd.options.mode.copy_on_write = True #数据仅存一份,其他是视图# 探索性数据分析 (EDA)
def basic_eda(df, name="Dataset"):print(f"\n----- {name} EDA -----")print(df.shape)print(df.info())print(df.describe())print(df.isnull().sum().sort_values(ascending=False).head(10)) # 缺失值降序查看10print(f"Duplicated rows: {df.duplicated().sum()}") # 查看重复行的个数#查看缺失值的热力图plt.figure(figsize=(10, 6)) #大小10×6sns.heatmap(df.isnull(), cbar=False, cmap="viridis") #绘制热力图plt.title(f'Missing Values Heatmap - {name}')plt.show()# df.isnull(): 输入布尔矩阵# cbar = False: 关闭颜色条# cmap = "viridis": 使用Viridis颜色映射(黄 - 绿 - 蓝渐变)# plt.title(...): 设置标题# plt.show(): 显示图像# 黄色区域表示缺失值# 深色区域表示无缺失值# 横向条纹:某列存在大量缺失值# 纵向条纹:某行存在多个缺失值# 特征组合生成
def process_combinations_fast(df, columns_to_encode, pair_sizes, max_batch_size=2000):# columns_to_encode: 需要生成组合特征的列名列表# pair_sizes: 组合大小列表(如[2, 3]表示生成2列和3列的组合)# max_batch_size: 每批处理的最大组合数(默认2000,避免内存溢出)# 将指定列转换为字符串类型,为后续拼接操作做准备(字符串拼接更直观)。str_df = df[columns_to_encode].astype(str)# 创建LabelEncoder实例,用于将拼接后的字符串编码为数值。le = LabelEncoder()total_new_cols = 0# 遍历每个组合大小 r(如先处理所有2列组合,再处理3列组合)。for r in pair_sizes:print(f"\nProcessing {r}-combinations...")# 计算从 columns_to_encode 列中选取 r 列的组合总数。n_combinations = np.math.comb(len(columns_to_encode), r)print(f"Total {r}-combinations: {n_combinations}")# 使用itertools.combinations生成所有可能的列组合迭代器。combos_iter = combinations(columns_to_encode, r)# 初始化两个列表:# batch_cols: 存储当前批次的列组合(如[['A', 'B'], ['A', 'C']]# batch_names: 存储对应的新列名(如['A+B', 'A+C']batch_cols, batch_names = [], []#创建进度条,总长度为组合总数 n_combinations。with tqdm(total=n_combinations) as pbar:# 进入无限循环,直到处理完所有组合。每次循环开始时清空批次列表。while True:batch_cols.clear()batch_names.clear()# 从迭代器中获取最多max_batch_size个组合:# next(combos_iter): 获取下一个组合(如('A', 'B')# 转换为列表并添加到batch_cols# 生成新列名(如'A+B')并添加到batch_names# 迭代器耗尽时触发StopIteration,退出循环for _ in range(max_batch_size):try:cols = next(combos_iter)batch_cols.append(list(cols))batch_names.append('+'.join(cols))except StopIteration:break# 如果当前批次为空,说明所有组合已处理完毕,退出循环。if not batch_cols:break# 遍历当前批次的所有组合:# 字符串拼接:将组合内的列值按行拼接(如'A_val' + 'B_val')# 标签编码:将拼接后的字符串转换为数值,并加1(避免0值)# 更新进度条:每处理一个组合,进度条前进1for cols, new_name in zip(batch_cols, batch_names):result = str_df[cols[0]].copy()for col in cols[1:]:result += str_df[col]df[new_name] = le.fit_transform(result) + 1pbar.update(1)# 累计当前批次生成的新列数。total_new_cols += len(batch_cols)#打印当前组合大小的处理结果及总列数。print(f"Completed {r}-combinations. Total columns now: {len(df.columns)}")return df# 动态调整学习率,115轮次前0.05,之后0.01
def learning_rate_scheduler(epoch):return 0.05 if epoch < 115 else 0.01# 数据预处理
df_train = pd.read_csv("/kaggle/input/playground-series-s5e4/train.csv")
df_test = pd.read_csv('/kaggle/input/playground-series-s5e4/test.csv')
df = pd.concat([df_train, df_test], axis=0, ignore_index=True)
df.drop(columns=['id'], inplace=True)
df = df.drop_duplicates()# 新特征:收听效率 = 收听时长 / 节目时长
df1 = df.copy()
df1["Listening_Eff"] = df1["Listening_Time_minutes"] / df1["Episode_Length_minutes"]
genre = df1.groupby("Genre")["Listening_Eff"].mean().sort_values(ascending=False)
# 功能:按 Genre(流派)分组,计算每组的 Listening_Eff 均值,并按降序排列。
# 操作分解:
# 分组:df1.groupby("Genre") 将数据按流派划分。
# 列选择:["Listening_Eff"] 指定计算目标列为收听效率。
# 聚合:.mean() 计算每组的平均效率。
# 排序:.sort_values(ascending=False) 按效率值从高到低排序。
# 输出示例:
# Genre
# Comedy        0.82
# Drama         0.78
# Education     0.75
# ...
# Name: Listening_Eff, dtype: float64print(genre)# 展示关系图
plt.figure(figsize=(10, 6))
sns.barplot(x=genre.values, y=genre.index, palette="viridis")
plt.title("Average Listening Efficiency by Genre")
plt.xlabel("Listening_Time Eff")
plt.ylabel("Genre")
plt.show()#进行eda查看
basic_eda(df, "Combined Dataset")# 异常值处理
df['Episode_Length_minutes'] = np.clip(df['Episode_Length_minutes'], 0, 120) #节目时常限制在0-120
df['Host_Popularity_percentage'] = np.clip(df['Host_Popularity_percentage'], 20, 100) #将主持人热度百分比限制在[20, 100]
df['Guest_Popularity_percentage'] = np.clip(df['Guest_Popularity_percentage'], 0, 100) #将嘉宾热度百分比限制在 [0, 100]
df.loc[df['Number_of_Ads'] > 3, 'Number_of_Ads'] = 0 #将广告数量超过3个的节目标记为0# 特征编码
# 自定义分类变量映射,然后应用映射
day_mapping = {'Monday':1, 'Tuesday':2, 'Wednesday':3, 'Thursday':4, 'Friday':5, 'Saturday':6, 'Sunday':7} #一周换为有序值
time_mapping = {'Morning':1, 'Afternoon':2, 'Evening':3, 'Night':4} #一天的时间换为有序数值
sentiment_mapping = {'Negative':1, 'Neutral':2, 'Positive':3} #将情感极性转换为有序数值# 应用映射
df['Publication_Day'] = df['Publication_Day'].map(day_mapping)
df['Publication_Time'] = df['Publication_Time'].map(time_mapping)
df['Episode_Sentiment'] = df['Episode_Sentiment'].map(sentiment_mapping)# 修正Episode_Title(移除"Episode "前缀并转为整数)
# 目标:从剧集标题中提取编号并转为整数
# 操作分解:
# 字符串替换:删除标题中的"Episode "前缀
# 类型转换:将结果转为整型(如"123"123)
df['Episode_Title'] = df['Episode_Title'].str.replace('Episode ', '', regex=True).astype(int)# 对剩余分类列进行标签编码
# 功能:创建Scikit-learn的LabelEncoder实例。
# 核心作用:将分类标签转换为0-based的整数编码(如['A','B','A'][0,1,0])。
le = LabelEncoder()
for col in df.select_dtypes('object').columns: # 自动选择数据框中所有object类型的列(通常是字符串或混合类型列)。df[col] = le.fit_transform(df[col]) + 1# 特征工程
# 多项式特征
for col in ['Episode_Length_minutes']:df[f"{col}_sqrt"] = np.sqrt(df[col]) # 平方根df[f"{col}_squared"] = df[col] ** 2 # 平方# 分组均值编码(Target Encoding)
group_cols = ['Episode_Sentiment', 'Genre', 'Publication_Day', 'Podcast_Name', 'Episode_Title','Guest_Popularity_percentage', 'Host_Popularity_percentage', 'Number_of_Ads']# 使用tqdm库为循环添加进度条,提升大数据处理时的用户体验
for col in tqdm(group_cols, desc="Creating group mean features"):df[f"{col}_EP"] = df.groupby(col)['Episode_Length_minutes'].transform('mean')
# 分组:df.groupby(col) 按当前列分组(如按Genre分组)
# 聚合计算:['Episode_Length_minutes'].transform('mean') 计算每组的节目时长均值
# 特征映射:将均值结果广播回原始数据框的每一行
# 对齐机制:保证新列与原始数据框行索引完全一致
# 内存高效:相比apply方法,transform在大数据集上性能更优# 生成组合特征
combo_columns = ['Episode_Length_minutes', 'Episode_Title', 'Publication_Time', 'Host_Popularity_percentage','Number_of_Ads', 'Episode_Sentiment', 'Publication_Day', 'Podcast_Name', 'Genre', 'Guest_Popularity_percentage']
df = process_combinations_fast(df, combo_columns, pair_sizes=[2, 3, 5, 7], max_batch_size=1000)# 降低数据精度节省内存
df = df.astype('float32')# 模型训练与预测
# 分割数据集
df_train = df.iloc[:-len(df_test)]
df_test = df.iloc[-len(df_test):].reset_index(drop=True)
df_train = df_train[df_train['Listening_Time_minutes'].notnull()]
target = df_train.pop('Listening_Time_minutes')
df_test = df_test.drop(columns=['Listening_Time_minutes'])# 交叉验证设置
# n_splits=7:将数据划分为7个互斥的子集(folds)
# shuffle=True:划分前打乱数据顺序(防止数据固有顺序影响验证)
# random_state=seed:确保每次运行洗牌结果一致
seed = 42
cv = KFold(n_splits=7, random_state=seed, shuffle=True)
pred_test = np.zeros((250000,)) #创建形状为(250000,)的全零数组params = {'objective': 'reg:squarederror','eval_metric': 'rmse','seed': seed,'max_depth': 19,'learning_rate': 0.03,'min_child_weight': 50,'reg_alpha': 5,'reg_lambda': 1,'subsample': 0.85,'colsample_bytree': 0.6,'colsample_bynode': 0.5,'device': "cuda"
}# 功能:创建XGBoost训练回调函数,用于动态调整学习率
# LearningRateScheduler: XGBoost内置的回调类
# learning_rate_scheduler: 用户自定义的学习率计算函数
lr_callback = xgb.callback.LearningRateScheduler(learning_rate_scheduler)# 交叉验证循环
for fold, (idx_train, idx_valid) in enumerate(cv.split(df_train)):print(f"\n--- Fold {fold + 1} ---")# 分割训练/验证集X_train, y_train = df_train.iloc[idx_train], target.iloc[idx_train]X_valid, y_valid = df_train.iloc[idx_valid], target.iloc[idx_valid]X_test = df_test[X_train.columns].copy()# 初始化编码器features = df_train.columnsencoder = TargetEncoder(n_folds=5, seed=seed, stat="mean")# Apply Target Encodingfor col in tqdm(features[:20], desc="Target Encoding first 20 features"): # 前20列单独处理# 拟合编码器(自动处理交叉验证)X_train[f"{col}_te1"] = encoder.fit_transform(X_train[[col]], y_train)# 验证集和测试集使用相同编码器X_valid[f"{col}_te1"] = encoder.transform(X_valid[[col]])X_test[f"{col}_te1"] = encoder.transform(X_test[[col]])for col in tqdm(features[20:], desc="Target Encoding remaining features"):# 拟合编码器(自动处理交叉验证)X_train[col] = encoder.fit_transform(X_train[[col]], y_train)# 验证集和测试集使用相同编码器X_valid[col] = encoder.transform(X_valid[[col]])X_test[col] = encoder.transform(X_test[[col]])# 创建DMatrix(XGBoost专用数据结构)# DMatrix是XGBoost定制的高性能数据结构,专为梯度提升算法优化dtrain = xgb.DMatrix(X_train, label=y_train)dval = xgb.DMatrix(X_valid, label=y_valid)dtest = xgb.DMatrix(X_test)# 训练模型(带早停和自定义学习率调度)model = xgb.train(params=params,dtrain=dtrain,num_boost_round=1_000_000,evals=[(dtrain, 'train'), (dval, 'validation')],early_stopping_rounds=30,verbose_eval=500,callbacks=[lr_callback])# 预测并累积结果val_pred = model.predict(dval)pred_test += np.clip(model.predict(dtest), 0, 120) # 限制预测值范围print("-" * 70)pred_test /= 7 # 平均7折结果# 生成提交文件
df_sub = pd.read_csv("/kaggle/input/playground-series-s5e4/sample_submission.csv")
df_sub['Listening_Time_minutes'] = pred_test
df_sub.to_csv('submission.csv', index=False)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/81226.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Class类的详细说明

Class类的详细说明 Class 类是Java反射机制的核心&#xff0c;每个Java类或接口在JVM中都有一个对应的 Class 对象&#xff0c;用于表示该类的元数据&#xff08;如类名、方法、字段、构造器等&#xff09;。以下是其核心知识点&#xff1a; 1. 获取Class对象的三种方式 方式…

[逆向工程]C++实现DLL注入:原理、实现与防御全解析(二十五)

[逆向工程]C实现DLL注入&#xff1a;原理、实现与防御全解析&#xff08;二十五&#xff09; 引言 DLL注入&#xff08;DLL Injection&#xff09;是Windows系统下实现进程间通信、功能扩展、监控调试的核心技术之一。本文将从原理分析、代码实现、实战调试到防御方案&#x…

【ROS2实战】在中国地区 Ubuntu 22.04 上安装 ROS 2 Humble 教程

本文介绍如何在中国大陆环境下顺利安装 ROS 2 Humble&#xff0c;包括使用清华镜像源、解决 locale 和 GPG 密钥问题、安装 ROS 软件包以及配置自动环境加载。 &#x1f31f; ROS 2 版本简介 ROS 2 是机器人操作系统的第二代版本&#xff0c;目前主要有两个长期支持&#xff0…

嵌入式学习笔记 - STM32 ADC 模块工作模式总结

ADC 模式总结&#xff1a; 一 单ADC模式&#xff08;是指ADC1,ADC2,ADC3中只有一个ADC被使用&#xff09; ①单通道&#xff1a; 非连续模式&#xff1a;非连续的意思就是单次&#xff0c;一次转换完成后就停止转换&#xff0c;除非再次被软件或者被外部触发启动&#xff1b…

Python训练打卡Day26

函数专题1&#xff1a;函数定义与参数 知识点回顾&#xff1a; 函数的定义变量作用域&#xff1a;局部变量和全局变量函数的参数类型&#xff1a;位置参数、默认参数、不定参数传递参数的手段&#xff1a;关键词参数传递参数的顺序&#xff1a;同时出现三种参数类型时 到目前为…

使用Docker部署Nacos

sudo systemctl start docker sudo systemctl enable docker docker --version 步骤 2: 拉取 Nacos Docker 镜像 拉取 Nacos 镜像&#xff1a; 你可以从 Docker Hub 上拉取官方的 Nacos 镜像&#xff0c;使用以下命令&#xff1a; docker pull nacos/nacos-server 这会从 …

Ubuntu 添加系统调用

实验内容 通过内核编译法添加一个不用传递参数的系统调用&#xff0c;其功能可自定义。 &#xff08;1&#xff09;添加系统调用号&#xff0c;系统会根据这个号找到syscall_table中的相应表项。具体做法是在syscall_64.tbl文件中添加系统调用号和调用函数的对应关系。 &#…

Javascript:WebAPI

获取网页元素 queryselector queryselector是 JavaScript 中用于选择 DOM 元素的重要方法&#xff0c;它允许使用 CSS 选择器语法来查找页面中的元素。 一般queryselector获取的元素都是html中第一个选择器的元素 支持选择器类型&#xff1a;类选择器(.class) &#xff0c…

十二、Hive 函数

作者&#xff1a;IvanCodes 日期&#xff1a;2025年5月1日 专栏&#xff1a;Hive教程 在数据处理的广阔天地中&#xff0c;我们常常需要对数据进行转换、计算、清洗或提取特定信息。Hive 提供了强大的内置运算符和丰富的内置函数库&#xff0c;它们就像魔法师手中的魔法棒&…

Linux之Nginx安装及配置原理篇(一)

Nginx安装及配置 前情回顾 首先针对Nginx进程模型&#xff0c;我们回顾一下它的原理机制&#xff0c;我们知道它是通过Master通过fork分发任务节点给予work节点&#xff0c;然后work节点触发了event事件&#xff0c;之后通过一个access_muttex互斥锁&#xff0c;来单线程调用我…

嵌入式培训之数据结构学习(五)栈与队列

一、栈 &#xff08;一&#xff09;栈的基本概念 1、栈的定义&#xff1a; 注&#xff1a;线性表中的栈在堆区&#xff08;因为是malloc来的&#xff09;&#xff1b;系统中的栈区存储局部变量、函数形参、函数返回值地址。 2、栈顶和栈底&#xff1a; 允许插入和删除的一端…

深度学习---知识蒸馏(Knowledge Distillation, KD)

一、知识蒸馏的本质与起源 定义&#xff1a; 知识蒸馏是一种模型压缩与迁移技术&#xff0c;通过将复杂高性能的教师模型&#xff08;Teacher Model&#xff09;所学的“知识”迁移到轻量级的学生模型&#xff08;Student Model&#xff09;&#xff0c;使学生模型在参数量和计…

ARP Detection MAC-Address Static

一、ARP Detection&#xff08;ARP检测&#xff09; ✅ 定义&#xff1a; ARP检测是一种防止ARP欺骗攻击的安全机制。它通过监控或验证网络中的ARP报文&#xff0c;来判断是否存在伪造的ARP信息。 &#x1f50d; 工作原理&#xff1a; 网络设备&#xff08;如交换机&#xf…

基于 Python 的界面程序复现:标准干涉槽型设计计算及仿真

基于 Python 的界面程序复现&#xff1a;标准干涉槽型设计计算及仿真 在工业设计与制造领域&#xff0c;刀具的设计与优化是提高生产效率和产品质量的关键环节之一。本文将介绍如何使用 Python 复现一个用于标准干涉槽型设计计算及仿真的界面程序&#xff0c;旨在帮助工程师和…

Python绘制南丁格尔玫瑰图:从入门到实战

Python绘制南丁格尔玫瑰图&#xff1a;从入门到实战 引言 南丁格尔玫瑰图&#xff08;Nightingale Rose Chart&#xff09;&#xff0c;也被称为极区图&#xff08;Polar Area Chart&#xff09;&#xff0c;是一种独特的数据可视化方式。这种图表由弗洛伦斯南丁格尔&#xff…

计算机操作系统概要

不谋万世者&#xff0c;不⾜谋⼀时。不谋全局者 &#xff0c;足谋⼀域 。 ——陈澹然《寤⾔》《迁都建藩议》 操作系统 一.对文件简单操作的常用基础指令 ls ls 选项 目录或⽂件名:罗列当前⽬录下的⽂件 -l&#xff1a;以长格式显示⽂件和⽬录的详细信息 -a 或 --all&…

<PLC><视觉><机器人>基于海康威视视觉检测和UR机械臂,如何实现N点标定?

前言 本系列是关于PLC相关的博文,包括PLC编程、PLC与上位机通讯、PLC与下位驱动、仪器仪表等通讯、PLC指令解析等相关内容。 PLC品牌包括但不限于西门子、三菱等国外品牌,汇川、信捷等国内品牌。 除了PLC为主要内容外,相关设备如触摸屏(HMI)、交换机等工控产品,如果有…

从专家编码到神经网络学习:DTM 的符号操作新范式

1st author: Paul Soulos paper: Differentiable Tree Operations Promote Compositional Generalization ICML 2023 code: psoulos/dtm: Differentiable Tree Machine 1. 问题与思路 现代深度学习在连续向量空间中取得了巨大成功&#xff0c;然而在处理具有显式结构&#x…

微信小程序第三方代开发模式技术调研与实践总结

🚀 微信小程序第三方代开发模式技术调研与实践总结 📖 前言 随着企业对私有化品牌运营诉求的增加,许多大型客户希望将原本由 SaaS 平台统一提供的小程序迁移至自有主体(AppID)下运行,同时又希望继续沿用 SaaS 平台的业务服务与数据托管方式。微信开放平台提供的“小程…

开启智能未来:DeepSeek赋能行业变革之路

前言 在人工智能重构生产关系的2025年&#xff0c;DeepSeek以其革命性的推理能力和Python生态的技术延展性&#xff0c;正在重塑内容创作与数据智能的边界。本书以"工具迭代思维升维"为双轮驱动&#xff0c;构建从认知突破到商业落地的完整知识图谱。 DeepSeek的崛…