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.pswp.cn/pingmian/81226.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/81226.shtml
英文地址,請注明出處:http://en.pswp.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的崛…