10- 天猫用户复购预测 (机器学习集成算法) (项目十) *

news2024/9/24 7:17:29

项目难点

  •  merchant:  商人
  • 重命名列名:  user_log.rename(columns={'seller_id':'merchant_id'}, inplace=True)
  • 数据类型转换:  user_log['item_id'] = user_log['item_id'].astype('int32')
  • 主要使用方法: xgboost, lightbm

  • 竞赛地址:  天猫复购预测之挑战Baseline_学习赛_天池大赛-阿里云天池

项目简介:

阿里巴巴天池天猫复购预测的机器学习项目, 使用数据分析, 通过机器学习中的线性分类算法, 进行建模, 从而预测消费者行为, 复购情况 .

  • 数据分析
  • 特征工程
  • 算法使用
  • 算法集成

1  数据处理

1.1  模型导入

import gc    # 垃圾回收
import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings('ignore')

# 导入分析库
# 数据拆分
from sklearn.model_selection import train_test_split
# 同分布数据拆分
from sklearn.model_selection import StratifiedGroupKFold
import lightgbm as lgb
import xgboost as xgb

1.2  加载数据

%%time
# 加载数据
# 用户行为日志
user_log = pd.read_csv('./data_format1/user_log_format1.csv', dtype = {'time_stamp':'str'})
# 用户画像
user_info = pd.read_csv('./data_format1/user_info_format1.csv')
# 训练数据和测试数据
train_data = pd.read_csv('./data_format1/train_format1.csv')
test_data = pd.read_csv('./data_format1/test_format1.csv')

1.3  查看数据

print('---data shape---')     
for data in [user_log, user_info, train_data, test_data]:
    print(data.shape)

        

print('---data info ---')
for data in [user_log, user_info, train_data, test_data]:
    print(data.info())

         

display(user_info.head())

        

display(train_data.head(),test_data.head())

        

1.4  数据集成

train_data['origin'] = 'train'
test_data['origin'] = 'test'
# 集成
all_data = pd.concat([train_data, test_data], ignore_index=True, sort=False)
# prob测试数据中特有的一列
all_data.drop(['prob'], axis=1, inplace=True) # 删除概率这一列
display(all_data.head(),all_data.shape)

        

# 连接user_info表,通过user_id关联
all_data = all_data.merge(user_info, on='user_id', how='left')
display(all_data.shape,all_data.head())

        

# 使用 merchant_id(原列名seller_id)
user_log.rename(columns={'seller_id':'merchant_id'}, inplace=True)
del train_data,test_data,user_info
gc.collect()

1.5  数据类型转换

%%time
display(user_log.info())

        

%%time
display(user_log.head())

        

%%time
# 用户行为数据类型转换
user_log['user_id'] = user_log['user_id'].astype('int32')
user_log['merchant_id'] = user_log['merchant_id'].astype('int32')
user_log['item_id'] = user_log['item_id'].astype('int32')
user_log['cat_id'] = user_log['cat_id'].astype('int32')
user_log['brand_id'].fillna(0, inplace=True)
user_log['brand_id'] = user_log['brand_id'].astype('int32')
user_log['time_stamp'] = pd.to_datetime(user_log['time_stamp'], format='%H%M')
user_log['action_type'] = user_log['action_type'].astype('int32')
display(user_log.info(),user_log.head())

        

display(all_data.isnull().sum())

        

# 缺失值填充
all_data['age_range'].fillna(0, inplace=True)
all_data['gender'].fillna(2, inplace=True)
all_data.isnull().sum()

        

all_data.info()

        

all_data['age_range'] = all_data['age_range'].astype('int8')
all_data['gender'] = all_data['gender'].astype('int8')
all_data['label'] = all_data['label'].astype('str')
all_data['user_id'] = all_data['user_id'].astype('int32')
all_data['merchant_id'] = all_data['merchant_id'].astype('int32')
all_data.info()

        

1.6  用户特征工程(5min)

%%time
##### 特征处理
##### User特征处理
groups = user_log.groupby(['user_id'])

# 用户交互行为数量 u1
temp = groups.size().reset_index().rename(columns={0:'u1'})
all_data = all_data.merge(temp, on='user_id', how='left')

# 细分
# 使用 agg 基于列的聚合操作,统计唯一值个数 item_id, cat_id, merchant_id, brand_id
# 用户,交互行为:点了多少商品呢?
temp = groups['item_id'].agg([('u2', 'nunique')]).reset_index()
all_data = all_data.merge(temp, on='user_id', how='left')

# 用户,交互行为,具体统计:类目多少
temp = groups['cat_id'].agg([('u3', 'nunique')]).reset_index()
all_data = all_data.merge(temp, on='user_id', how='left')

temp = groups['merchant_id'].agg([('u4', 'nunique')]).reset_index()
all_data = all_data.merge(temp, on='user_id', how='left')

temp = groups['brand_id'].agg([('u5', 'nunique')]).reset_index()
all_data = all_data.merge(temp, on='user_id', how='left')


# 购物时间间隔特征 u6 按照小时
temp = groups['time_stamp'].agg([('F_time', 'min'), ('B_time', 'max')]).reset_index()
temp['u6'] = (temp['B_time'] - temp['F_time']).dt.seconds/3600
all_data = all_data.merge(temp[['user_id', 'u6']], on='user_id', how='left')


# 统计操作类型为0,1,2,3的个数
temp = groups['action_type'].value_counts().unstack().reset_index().rename(
    columns={0:'u7', 1:'u8', 2:'u9', 3:'u10'})
all_data = all_data.merge(temp, on='user_id', how='left')

del temp,groups
gc.collect()
all_data.head()

        

1.7  店铺特征工程(5min)

%%time
##### 商家特征处理
groups = user_log.groupby(['merchant_id'])

# 商家被交互行为数量 m1
temp = groups.size().reset_index().rename(columns={0:'m1'})
all_data = all_data.merge(temp, on='merchant_id', how='left')

# 统计商家被交互的 user_id, item_id, cat_id, brand_id 唯一值
temp = groups['user_id', 'item_id', 'cat_id', 'brand_id'].nunique().reset_index().rename(
    columns={
    'user_id':'m2',
    'item_id':'m3', 
    'cat_id':'m4', 
    'brand_id':'m5'})
all_data = all_data.merge(temp, on='merchant_id', how='left')

# 统计商家被交互的 action_type 唯一值
temp = groups['action_type'].value_counts().unstack().reset_index().rename(  
    columns={0:'m6', 1:'m7', 2:'m8', 3:'m9'})
all_data = all_data.merge(temp, on='merchant_id', how='left')

del temp
gc.collect()
display(all_data.tail())

        

1.8  用户和店铺联合特征工程(4min)

%%time
##### 用户+商户特征
groups = user_log.groupby(['user_id', 'merchant_id'])

# 用户在不同商家交互统计
temp = groups.size().reset_index().rename(columns={0:'um1'})
all_data = all_data.merge(temp, on=['user_id', 'merchant_id'], how='left')

# 统计用户在不同商家交互的 item_id, cat_id, brand_id 唯一值
temp = groups['item_id', 'cat_id', 'brand_id'].nunique().reset_index().rename(
    columns={
    'item_id':'um2',
    'cat_id':'um3',
    'brand_id':'um4'})
all_data = all_data.merge(temp, on=['user_id', 'merchant_id'], how='left')

# 统计用户在不同商家交互的 action_type 唯一值
temp = groups['action_type'].value_counts().unstack().reset_index().rename(
    columns={
    0:'um5',
    1:'um6',
    2:'um7',
    3:'um8'})
all_data = all_data.merge(temp, on=['user_id', 'merchant_id'], how='left')

# 统计用户在不同商家购物时间间隔特征 um9 按照小时
temp = groups['time_stamp'].agg([('F_time', 'min'), ('B_time', 'max')]).reset_index()
temp['um9'] = (temp['B_time'] - temp['F_time']).dt.seconds/3600
all_data = all_data.merge(temp[['user_id','merchant_id','um9']], on=['user_id', 'merchant_id'], how='left')

del temp,groups
gc.collect()
display(all_data.head())

        

1.9  购买点击比

all_data['r1'] = all_data['u9']/all_data['u7']    # 用户购买点击比
all_data['r2'] = all_data['m8']/all_data['m6']    # 商家购买点击比
all_data['r3'] = all_data['um7']/all_data['um5']  # 不同用户不同商家购买点击比
display(all_data.head())

        

1.10  空数据填充

display(all_data.isnull().sum())

        

all_data.fillna(0, inplace=True)
all_data.isnull().sum()

1.11  年龄性别类别型转换

all_data['age_range']

        

%%time
# 修改age_range字段名称为 age_0, age_1, age_2... age_8
# 独立编码
temp = pd.get_dummies(all_data['age_range'], prefix='age')
display(temp.head(10))
all_data = pd.concat([all_data, temp], axis=1)

        

# 性别转换
temp = pd.get_dummies(all_data['gender'], prefix='g')
all_data = pd.concat([all_data, temp], axis=1) # 列进行合并

# 删除原数据
all_data.drop(['age_range', 'gender'], axis=1, inplace=True)

del temp
gc.collect()
all_data.head()

        

1.12  数据存储

%%time
# train_data、test-data
train_data = all_data[all_data['origin'] == 'train'].drop(['origin'], axis=1)
test_data = all_data[all_data['origin'] == 'test'].drop(['label', 'origin'], axis=1)

train_data.to_csv('train_data.csv')
test_data.to_csv('test_data.csv')

2  算法建模预测

# 训练数据和目标值
train_X, train_y = train_data.drop(['label'], axis=1), train_data['label']

# 数据拆分保留20%作为测试数据
X_train, X_valid, y_train, y_valid = train_test_split(train_X, train_y, test_size=.2)

2.1  LGB 模型

def lgb_train(X_train, y_train, X_valid, y_valid, verbose=True):
    model_lgb = lgb.LGBMClassifier(
        max_depth=10, # 8 # 树最大的深度
        n_estimators=5000, # 集成算法,树数量
        min_child_weight=100, 
        colsample_bytree=0.7, # 特征筛选
        subsample=0.9,  # 样本采样比例
        learning_rate=0.1) # 学习率

    model_lgb.fit(
        X_train, 
        y_train,
        eval_metric='auc',
        eval_set=[(X_train, y_train), (X_valid, y_valid)],
        verbose=verbose, # 是否打印输出训练过程
        early_stopping_rounds=10) # 早停,等10轮决策,评价指标不在变化,停止

    print(model_lgb.best_score_['valid_1']['auc'])
    return model_lgb
X_train

        

model_lgb = lgb_train(X_train.values, y_train, X_valid.values, y_valid, verbose=True)

        

%%time
prob = model_lgb.predict_proba(test_data.values) # 预测
submission = pd.read_csv('./data_format1/test_format1.csv')

# 复购的概率
submission['prob'] = pd.Series(prob[:,1]) # 预测数据赋值给提交数据
display(submission.head())
submission.to_csv('submission_lgb.csv', index=False)

del submission
gc.collect()

        

2.2  XGB 模型

def xgb_train(X_train, y_train, X_valid, y_valid, verbose=True):
    model_xgb = xgb.XGBClassifier(
        max_depth=10, # raw8
        n_estimators=5000,
        min_child_weight=300, 
        colsample_bytree=0.7, 
        subsample=0.9, 
        learing_rate=0.1)
    
    model_xgb.fit(
        X_train, 
        y_train,
        eval_metric='auc',
        eval_set=[(X_train, y_train), (X_valid, y_valid)],
        verbose=verbose,
        early_stopping_rounds=10)  # 早停法,如果auc在10epoch没有进步就stop
    print(model_xgb.best_score)
    return model_xgb

模型训练

model_xgb = xgb_train(X_train, y_train, X_valid, y_valid, verbose=False)

模型预测

%%time
prob = model_xgb.predict_proba(test_data)
submission = pd.read_csv('./data_format1/test_format1.csv')
submission['prob'] = pd.Series(prob[:,1])
submission.to_csv('submission_xgb.csv', index=False)
display(submission.head())
del submission
gc.collect()

3  交叉验证多轮建模

# 构造训练集和测试集
def get_train_test_datas(train_df,label_df):
    skv = StratifiedKFold(n_splits=10, shuffle=True)
    trainX = []
    trainY = []
    testX = []
    testY = []
    # 索引:训练数据索引train_index,目标值的索引test_index
    for train_index, test_index in skv.split(X=train_df, y=label_df):  # 10轮for循环
        
        train_x, train_y, test_x, test_y = train_df.iloc[train_index, :], label_df.iloc[train_index], \
                                            train_df.iloc[test_index, :], label_df.iloc[test_index]

        trainX.append(train_x)
        trainY.append(train_y)
        testX.append(test_x)
        testY.append(test_y)
    return trainX, testX, trainY, testY

3.1  LGB 模型(1min)

%%time
train_X, train_y = train_data.drop(['label'], axis=1), train_data['label']

# 拆分为10份训练数据和验证数据
X_train, X_valid, y_train, y_valid = get_train_test_datas(train_X, train_y)

print('----训练数据,长度',len(X_train))
print('----验证数据,长度',len(X_valid))

pred_lgbms = [] # 列表,接受目标值,10轮,平均值

for i in range(10):
    print('\n=========LGB training use Data {}/10===========\n'.format(i+1))
    model_lgb = lgb.LGBMClassifier(
        max_depth=10, # 8
        n_estimators=1000,
        min_child_weight=100,
        colsample_bytree=0.7,
        subsample=0.9,
        learning_rate=0.05)

    model_lgb.fit(
        X_train[i].values, 
        y_train[i],
        eval_metric='auc',
        eval_set=[(X_train[i].values, y_train[i]), (X_valid[i].values, y_valid[i])],
        verbose=False,
        early_stopping_rounds=10)

    print(model_lgb.best_score_['valid_1']['auc'])
    pred = model_lgb.predict_proba(test_data.values)
    pred = pd.DataFrame(pred[:,1]) # 将预测概率(复购)去处理,转换成DataFrame
    pred_lgbms.append(pred)

# 求10轮平均值生成预测结果,保存
# 每一轮的结果,作为一列,进行了添加
pred_lgbms = pd.concat(pred_lgbms, axis=1) # 级联,列进行级联

# 加载提交数据
submission = pd.read_csv('./data_format1/test_format1.csv')
submission['prob'] = pred_lgbms.mean(axis=1) # 10轮训练的平均值
submission.to_csv('submission_KFold_lgb.csv', index=False)

3.2  XGB 模型(4min)

# 构造训练集和测试集
def get_train_test_datas(train_df,label_df):
    skv = StratifiedKFold(n_splits=20, shuffle=True)
    trainX = []
    trainY = []
    testX = []
    testY = []
    # 索引:训练数据索引train_index,目标值的索引test_index
    for train_index, test_index in skv.split(X=train_df, y=label_df):# 10轮for循环
        
        train_x, train_y, test_x, test_y = train_df.iloc[train_index, :], label_df.iloc[train_index], \
                                           train_df.iloc[test_index, :], label_df.iloc[test_index]

        trainX.append(train_x)
        trainY.append(train_y)
        testX.append(test_x)
        testY.append(test_y)
    return trainX, testX, trainY, testY
%%time
train_X, train_y = train_data.drop(['label'], axis=1), train_data['label']

# 拆分为20份训练数据和验证数据
X_train, X_valid, y_train, y_valid = get_train_test_datas(train_X, train_y)

print('------数据长度',len(X_train),len(y_train))

pred_xgbs = []
for i in range(20):
    print('\n============XGB training use Data {}/20========\n'.format(i+1))
    model_xgb = xgb.XGBClassifier(
        max_depth=10, # raw8
        n_estimators=5000,
        min_child_weight=200, 
        colsample_bytree=0.7, 
        subsample=0.9,
        learning_rate = 0.1)

    model_xgb.fit(
        X_train[i], 
        y_train[i],
        eval_metric='auc',
        eval_set=[(X_train[i], y_train[i]), (X_valid[i], y_valid[i])],
        verbose=False,
        early_stopping_rounds=10 # 早停法,如果auc在10epoch没有进步就stop
    )    

    print(model_xgb.best_score)

    pred = model_xgb.predict_proba(test_data)
    pred = pd.DataFrame(pred[:,1])
    pred_xgbs.append(pred)

# 求20轮平均值生成预测结果,保存
pred_xgbs = pd.concat(pred_xgbs, axis=1)
submission = pd.read_csv('./data_format1/test_format1.csv')
submission['prob'] = pred_xgbs.mean(axis=1)
submission.to_csv('submission_KFold_xgb.csv', index=False)

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

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

相关文章

java并发编程原理1(原子性,可见行,有序性,volatile,synchronized)

一、原子性: 1.1 Java中如何实现线程安全? 多线程操作共享数据出现的问题。 锁: 悲观锁:synchronized,lock乐观锁:CAS 可以根据业务情况,选择ThreadLocal,让每个线程玩自己的数据。 1.2 C…

内大-oj练习题(2期)

内大oj2期 1. 输出一个数的质数因子2. 寻找完数3. 圆的面积4. 求同存异5. 2的k进制数6. 输出排序序列6. DNA算法1. 输出一个数的质数因子 介绍 因子,例如 33=9 (3就是因子); 19=9(1,9就是因子) 质数, 只能被1和本身整除的数 题目 代码 #include <iostream>

Windows7下使用VMware11.1.1安装ubuntu-16.04.7

一、说明二、安装说明三、安装步骤详解1、先安装VMware软件2、创建虚拟机3、编辑虚拟机4、开启虚拟机&#xff0c;初始化Linux系统一、说明 虽然VMware和ubuntu最新版已经很高了&#xff0c;我这电脑由于是win7配值还低&#xff0c;所以采用低版本来安装 VMware版本&#xff1…

C++Primer15.5节练习

练习15.18&#xff1a; Base* p &d1&#xff1a;合法 p &d2&#xff1a;不合法&#xff0c;只有当派生类公有地继承基类时&#xff0c;用户代码才能使用派生类向基类的转换 p &d3&#xff1a;不合法&#xff0c;只有当派生类公有地继承基类时&#xff0…

ChatGpt与Google 谁能给出最好的回答

ChatGPT由于其先进的会话和技术功能而越来越受欢迎。你可以问聊天机器人任何你想问的问题&#xff0c;它会在几秒钟内输出答案。虽然它不是一个搜索引擎&#xff0c;你应该使用ChatGPT作为你的信息来源而不是谷歌&#xff0c;百度吗? 我们来根据国外的一场测试来看一下 ChatG…

spring注解方式整合Dubbo

系列文章目录 文章目录系列文章目录一、创建一个父工程项目二、创建子模块(dubbo-api模块)二、创建子模块(dubbo-provider模块)三、创建子模块(dubbo-consumer模块)总结一、创建一个父工程项目 这里我们通过Spring Initializer 来帮我们构建一个spring-dubbo这个父项目,点击nex…

python进阶--Numyp库(一)

一、Numpy库介绍 NumPy&#xff08;Numerical Python&#xff09;是Python的⼀种开源的数值计算扩展。提供多维数组对象&#xff0c;各种派⽣对象&#xff08;如掩码数组和矩阵&#xff09;&#xff0c;这种⼯具可⽤来存储和处理⼤型矩阵&#xff0c;⽐Python⾃身的嵌套列表&am…

【Redis 高级】- 持久化 - RDB

【Redis 高级】- 持久化 - RDB &#x1f451;什么是持久化呢&#xff1f; 那当然是够持久呀&#xff0c;这个持久如果在你不主动去删除的情况下&#xff0c;它就一直存在的。 &#x1f3b7;那么这有什么用呢&#xff1f; 举个栗子&#xff1a;我们在用 PowerPoint 在写价值 …

WEB系列(二)-----------XSS

XSS原理及基础 定义 恶意攻击者会往Web页面里插入JS代码,当用户点击网页时.镶嵌的JS代码就会执行,从而达到恶意的特殊目的. 原因 程序对输入和输出的控制不够严格&#xff0c;导致payload输出到前段时被浏览器当做有效代码执行从而产生危害。 分类 存储型反射型DOM型 测…

常见排序算法--Java实现

常见排序算法--Java实现插入排序直接插入排序折半插入排序希尔排序交换排序冒泡排序快速排序选择排序直接选择排序堆排序归并排序基数排序各种排序方法比较在网上找了些排序算法的资料。此篇笔记本人总结比较&#xff0c;简单注释&#xff0c;觉得比较好理解&#xff0c;且相对…

四大步骤,教你彻底关闭Win10自动更新

文章目录一、禁用Windows Update服务二、在组策略里关闭Win10自动更新相关服务三、禁用任务计划里边的Win10自动更新四、在注册表中关闭Win10自动更新参考资料一、禁用Windows Update服务 1、同时按下键盘 Win R&#xff0c;打开运行对话框&#xff0c;然后输入命令 services…

C语言运算符优先级和结合性一览表

所谓优先级就是当一个表达式中有多个运算符时&#xff0c;先计算谁&#xff0c;后计算谁。 运算符的优先级从高到低大致是&#xff1a;单目运算符、算术运算符、关系运算符、逻辑运算符、条件运算符、赋值运算符()和逗号运算符 简单记就是&#xff1a;&#xff01; > 算术运…

一起学 pixijs(1):常见图形的绘制

大家好&#xff0c;我是前端西瓜哥。 pixijs 是一个强大的 Web Canvas 2D 库&#xff0c;以其强大性能而著称。其底层使用了 WebGL 实现了硬件加速&#xff0c;当然如果不支持的话&#xff0c;也能回退为 Canvas。 本文使用的 pixijs 版本为 7.1.2。 Application Applicati…

【LeetCode】剑指 Offer 08. 二叉树的下一个节点 p65 -- Java Version

题目链接&#xff1a;无题目链接&#xff0c;不知道为啥力扣上找不到这一题。 1. 题目介绍&#xff08;08. 二叉树的下一个节点&#xff09; 题目&#xff1a;给定一个二叉树和其中的一个节点&#xff0c;请找出中序遍历顺序的下一个节点并且返回。注意&#xff0c;树中的节点…

linux线程阻塞中CPU的占用率

linux线程阻塞中CPU的占用率 一、简介 总所周知Linux系统下&#xff0c;我们编写的程序进入阻塞后&#xff0c;系统把任务挂起&#xff0c;交给内核进行处理&#xff0c;此时我们的进程CPU占用率不高&#xff0c;可以说是占用率0.0%&#xff0c;让CPU资源交给其他进程处理&am…

【算法】三道算法题目单词拆分,填充每个节点的下一个右侧节点指针以及组合总和

算法第一道算法题&#xff1a;单词拆分java解答参考第二道算法题&#xff1a;填充每个节点的下一个右侧节点指针java 解答参考第三道算法题&#xff1a;组合总和java解答参考大家好&#xff0c;我是小冷。 今天还是继续学习算法技术知识吧 第一道算法题&#xff1a;单词拆分 …

Docker - 镜像操作命令

镜像名称一般分为两部分组成:[repository]:[tag]在没有指定tag时&#xff0c;默认是latest&#xff0c;代表最新版本的镜像1.下载docker镜像 docker pull repository:tag2.查看本地所有镜像 docker images3.创建镜像别名 docker tag repository:tag repository111:tag4.查看镜像…

java面试题-集合篇

Collection1.Collection有哪些类&#xff1f;Java集合框架中的Collection接口是所有集合类的基础接口&#xff0c;定义了一些基本的集合操作&#xff0c;如添加元素、删除元素、判断是否包含某个元素等。常见的集合类包括List、Set和Queue。ListList接口定义了按照索引访问和操…

Module理解及使用

ES6的模块化设计思想是静态化&#xff0c;也就是说&#xff0c;在编译的时候确定模块的依赖关系&#xff0c;以及输出输出入的变量。而CommonJS和AMD模块都是在运行时确定的。ES6的模块不是对象&#xff0c;而是通过export显示指定输出的代码&#xff0c;再通过import命令输入。…

ES6新特性详解

文章目录1. let和const1.1 let声明变量1.2 const声明常量2. 模板字符串3. 解构赋值3.1 数组的解构赋值3.2 对象的解构赋值4. 函数扩展4.1 参数默认值4.2 剩余参数4.3 箭头函数5. 对象扩展5.1 对象简写5.2 属性名表达式5.3 扩展运算符6. Symbol7. Iterator和Generator7.1 Iterat…