【推荐系统篇】--推荐系统之之特征工程部分---构建训练集流程

原文地址:https://blog.youkuaiyun.com/LHWorldBlog/article/details/80822720

一、前述

根据前文中架构,本文我们讨论线下部分构建训练集部分。因为我们离线部分模型的选择是逻辑回归,所以我们数据必须有x和y.

二、具体流程

1.从数据库中分离出我们需要的数据。

    用户行为表(日志)

   用户历史下载表

  

   商品词表(商品的基本特征)

 

2.构建训练集中的关联特征

流程:

2.构建训练集中的基本特征

 

总结:注意特征名离散化因为如果特征不离散化会造成数据之间有关系。

三、具体构建过程

1、hive建表

真实的生产场景涉及到大概五十张表的字段,这里全部简化流程,直接给出最终的三张表:

应用词表:

 
  1. CREATE EXTERNAL TABLE IF NOT EXISTS dim_rcm_hitop_id_list_ds

  2. (

  3. hitop_id STRING,

  4. name STRING,

  5. author STRING,

  6. sversion STRING,

  7. ischarge SMALLINT,

  8. designer STRING,

  9. font STRING,

  10. icon_count INT,

  11. stars DOUBLE,

  12. price INT,

  13. file_size INT,

  14. comment_num INT,

  15. screen STRING,

  16. dlnum INT

  17. )row format delimited fields terminated by '\t';

/**
  *
  *模拟app的商品词表
  hitop_id    STRING,  应用软件ID
  name        STRING,  名称
  author      STRING,   作者
  sversion    STRING,   版本号
  ischarge    SMALLINT,  收费软件
  designer    STRING,    设计者
  font        STRING,   字体
  icon_count  INT,      有几张配图
  stars       DOUBLE,   评价星级
  price       INT,      价格
  file_size   INT,      大小
  comment_num INT,      评论数据
  screen      STRING,   分辨率
  dlnum       INT       下载数量
  */

 
用户历史下载表:

CREATE EXTERNAL TABLE IF NOT EXISTS dw_rcm_hitop_userapps_dm
(
    device_id           STRING,
    devid_applist       STRING,
    device_name         STRING,
    pay_ability         STRING
)row format delimited fields terminated by '\t';
/**
  *用户下载历史表   这里没有用户这个概念   手机设备ID就是userId
  * device_id           STRING,   手机设备ID
    devid_applist       STRING,     下载过软件列表
    device_name         STRING,     设备名称
    pay_ability         STRING      支付能力
  */

 


正负例样本(用户当前行为即日志)表:

CREATE EXTERNAL TABLE IF NOT EXISTS dw_rcm_hitop_sample2learn_dm
(
    label       STRING,
    device_id   STRING,
    hitop_id    STRING,
    screen      STRING,
    en_name     STRING,
    ch_name     STRING,
    author      STRING,
    sversion    STRING,
    mnc         STRING,
    event_local_time STRING,
    interface   STRING,
    designer    STRING,
    is_safe     INT,
    icon_count  INT,
    update_time STRING,
    stars       DOUBLE,
    comment_num INT,
    font        STRING,
    price       INT,
    file_size   INT,
    ischarge    SMALLINT,
    dlnum       INT
)row format delimited fields terminated by '\t';
/**
  * 正负例样本表 = 浏览记录+标签
  label       STRING,        Y列,-1或1代表正负例    label值实际上是批处理得出来的,用户浏览了并在一段时间内下载为正例
  device_id   STRING,        设备ID
  hitop_id    STRING,        应用ID
  screen      STRING,        手机软件需要的分辨率
  en_name     STRING,        英文名
  ch_name     STRING,        中文名
  author      STRING,        作者
  sversion    STRING,        版本
  mnc         STRING,      Mobile Network Code,移动网络号码
  event_local_time STRING,   浏览的时间
  interface   STRING,
  designer    STRING,
  is_safe     INT,
  icon_count  INT,
  update_time STRING,
  stars       DOUBLE,
  comment_num INT,
  font        STRING,
  price       INT,
  file_size   INT,
  ischarge    SMALLINT,
  dlnum       INT
  */

 2、load数据

分别往三张表load数据:

商品词表:

load data local inpath '/opt/sxt/recommender/script/applist.txt' into table dim_rcm_hitop_id_list_ds;

用户历史下载表:

load data local inpath '/opt/sxt/recommender/script/userdownload.txt' into table dw_rcm_hitop_userapps_dm;

正负例样本表:

load data local inpath '/opt/sxt/recommender/script/sample.txt' into table dw_rcm_hitop_sample2learn_dm;

 

3、构建训练数据

3.1创建临时表

创建处理数据时所需要的临时表
CREATE TABLE IF NOT EXISTS tmp_dw_rcm_hitop_prepare2train_dm    
(
    device_id           STRING,
    label               STRING,
    hitop_id            STRING,
    screen              STRING,
    ch_name             STRING,
    author              STRING,
    sversion            STRING,
    mnc                 STRING,
    interface           STRING,
    designer            STRING,
    is_safe             INT,
    icon_count          INT,
    update_date         STRING,
    stars               DOUBLE,
    comment_num         INT,
    font                STRING,
    price               INT,
    file_size           INT,
    ischarge            SMALLINT,
    dlnum               INT,
    idlist              STRING,
    device_name         STRING,
    pay_ability         STRING
)row format delimited fields terminated by '\t';

最终保存训练集的表
CREATE TABLE IF NOT EXISTS dw_rcm_hitop_prepare2train_dm
(
    label                   STRING,
    features       STRING
)row format delimited fields terminated by '\t';

3.2 训练数据预处理过程

首先将数据从正负例样本和用户历史下载表数据加载到临时表中

 
  1. INSERT OVERWRITE TABLE tmp_dw_rcm_hitop_prepare2train_dm

  2. SELECT

  3. t2.device_id,

  4. t2.label,

  5. t2.hitop_id,

  6. t2.screen,

  7. t2.ch_name,

  8. t2.author,

  9. t2.sversion,

  10. t2.mnc,

  11. t2.interface,

  12. t2.designer,

  13. t2.is_safe,

  14. t2.icon_count,

  15. to_date(t2.update_time),

  16. t2.stars,

  17. t2.comment_num,

  18. t2.font,

  19. t2.price,

  20. t2.file_size,

  21. t2.ischarge,

  22. t2.dlnum,

  23. t1.devid_applist,

  24. t1.device_name,

  25. t1.pay_ability

  26. FROM

  27. (

  28. SELECT

  29. device_id,

  30. devid_applist,

  31. device_name,

  32. pay_ability

  33. FROM

  34. dw_rcm_hitop_userapps_dm

  35. ) t1

  36. RIGHT OUTER JOIN

  37. (

  38. SELECT

  39. device_id,

  40. label,

  41. hitop_id,

  42. screen,

  43. ch_name,

  44. author,

  45. sversion,

  46. IF (mnc IN ('00','01','02','03','04','05','06','07'), mnc,'x') AS mnc,

  47. interface,

  48. designer,

  49. is_safe,

  50. IF (icon_count <= 5,icon_count,6) AS icon_count,

  51. update_time,

  52. stars,

  53. IF ( comment_num IS NULL,0,

  54. IF ( comment_num <= 10,comment_num,11)) AS comment_num,

  55. font,

  56. price,

  57. IF (file_size <= 2*1024*1024,2,

  58. IF (file_size <= 4*1024*1024,4,

  59. IF (file_size <= 6*1024*1024,6,

  60. IF (file_size <= 8*1024*1024,8,

  61. IF (file_size <= 10*1024*1024,10,

  62. IF (file_size <= 12*1024*1024,12,

  63. IF (file_size <= 14*1024*1024,14,

  64. IF (file_size <= 16*1024*1024,16,

  65. IF (file_size <= 18*1024*1024,18,

  66. IF (file_size <= 20*1024*1024,20,21)))))))))) AS file_size,

  67. ischarge,

  68. IF (dlnum IS NULL,0,

  69. IF (dlnum <= 50,50,

  70. IF (dlnum <= 100,100,

  71. IF (dlnum <= 500,500,

  72. IF (dlnum <= 1000,1000,

  73. IF (dlnum <= 5000,5000,

  74. IF (dlnum <= 10000,10000,

  75. IF (dlnum <= 20000,20000,20001)))))))) AS dlnum

  76. FROM

  77. dw_rcm_hitop_sample2learn_dm

  78. ) t2

  79. ON (t1.device_id = t2.device_id);

选择右外关联的原因是因为以用户行为为基准。

这张表得到的数据就是关联特征中的数据,截图如下:


然后再利用python脚本处理格式
这里要先讲python脚本加载到hive中
ADD FILE /opt/sxt/recommender/script/dw_rcm_hitop_prepare2train_dm.py;
可以通过list files;查看是不是python文件加载到了hive

在hive中使用python脚本处理数据的原理:
Hive会以输出流的形式将数据交给python脚本,python脚本以输入流的形式来接受数据,接受来数据以后,在python中就行一系列的数据处理,处理完毕后,又以输出流的形式交给Hive,交给了hive就说明了就处理后的数据成功保存到hive表中了。

 
  1. INSERT OVERWRITE TABLE dw_rcm_hitop_prepare2train_dm

  2. SELECT

  3. TRANSFORM (t.*)

  4. USING 'python dw_rcm_hitop_prepare2train_dm.py'

  5. AS (label,features)

  6. FROM

  7. (

  8. SELECT

  9. label,

  10. hitop_id,

  11. screen,

  12. ch_name,

  13. author,

  14. sversion,

  15. mnc,

  16. interface,

  17. designer,

  18. icon_count,

  19. update_date,

  20. stars,

  21. comment_num,

  22. font,

  23. price,

  24. file_size,

  25. ischarge,

  26. dlnum,

  27. idlist,

  28. device_name,

  29. pay_ability

  30. FROM

  31. tmp_dw_rcm_hitop_prepare2train_dm

  32. ) t;

 python处理流程:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------------
#  File Name: dw_rcm_hitop_prepare2train_dm.py
#  Copyright(C)Huawei Technologies Co.,Ltd.1998-2014.All rights reserved.
#  Describe: 
#  Input:  tmp_dw_rcm_hitop_prepare2train_dm
#  Output: dw_rcm_hitop_prepare2train_dm

import sys
import codecs
import random
import math
import time
import datetime

if __name__ == "__main__":
    random.seed(time.time())
    for l in sys.stdin:
        d = l.strip().split('\t')
        if len(d) != 21:
            continue

        # Extract data from the line
        label = d.pop(0)
        hitop_id = d.pop(0)
        screen = d.pop(0)
        ch_name = d.pop(0)
        author = d.pop(0)
        sversion = d.pop(0)
        mnc = d.pop(0)
        interface = d.pop(0)
        designer = d.pop(0)
        icon_count = d.pop(0)
        update_date = d.pop(0)
        stars = d.pop(0)
        comment_num = d.pop(0)
        font = d.pop(0)
        price = d.pop(0)
        file_size = d.pop(0)
        ischarge = d.pop(0)
        dlnum = d.pop(0)
        hitopids = d.pop(0)
        device_name = d.pop(0)
        pay_ability = d.pop(0)

        # Construct feature vector
        features = []
        features.append(("Item.id,%s" % hitop_id, 1))
        features.append(("Item.screen,%s" % screen, 1))
        features.append(("Item.name,%s" % ch_name, 1))
        features.append(("All,0",1))
        features.append(("Item.author,%s" % author, 1))
        features.append(("Item.sversion,%s" % sversion, 1))
        features.append(("Item.network,%s" % mnc, 1))
        features.append(("Item.dgner,%s" % designer, 1))
        features.append(("Item.icount,%s" % icon_count, 1))
        features.append(("Item.stars,%s" % stars, 1))
        features.append(("Item.comNum,%s" % comment_num,1))
        features.append(("Item.font,%s" % font,1))
        features.append(("Item.price,%s" % price,1))
        features.append(("Item.fsize,%s" % file_size,1))
        features.append(("Item.ischarge,%s" % ischarge,1))
        features.append(("Item.downNum,%s" % dlnum,1))

        ####User.Item and User.Item*Item
        idlist = hitopids[:-2].split(',')
        idCT = 0;
        for id in idlist:
            features.append(("User.Item*Item,%s" % id +'*'+hitop_id, 1))
            idCT += 1
            if idCT >= 3: #取每一个用户的前3个下载历史进行关联,因为用户量比较多,所以这里最后结果覆盖还是比较全的。
                break;
        features.append(("User.phone*Item,%s" % device_name + '*' + hitop_id,1))#升维
        features.append(("User.pay*Item.price,%s" % pay_ability + '*' + price,1))

        # Output

        output = "%s\t%s" % (label, ",".join([ "%s:%d" % (f, v) for f, v in features ]))#这里join相当于是把list中的数据进行拆分,然后添加上分号。
        print output

 

经过上述处理之后的数据如图所示:

 

 特征工程部分前期准备结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值