用户套餐个性化推荐TOP方案学习

赛题

比赛来源:https://www.datafountain.cn/competitions/311/details/data-evaluation

感谢大佬开源:

TOP2方案: 用户套餐个性化匹配TOP2

本博客只是单纯的对TOP方案进行整理学习。

要求

此题利用已有的用户属性(如个人基本信息、用户画像信息等)、终端属性(如终端品牌等)、业务属性、消费习惯及偏好匹配用户最合适的套餐

数据说明

字段中文名数据类型说明
USERID用户IDVARCHAR2(50)用户编码,标识用户的唯一字段
current_type套餐VARCHAR2(500)/
service_type套餐类型VARCHAR2(10)0:23G融合,1:2I2C,2:2G,3:3G,4:4G
is_mix_service是否固移融合套餐VARCHAR2(10)1.是 0.否
online_time在网时长VARCHAR2(50)/
1_total_fee当月总出账金额_月NUMBER单位:元
2_total_fee当月前1月总出账金额_月NUMBER单位:元
3_total_fee当月前2月总出账金额_月NUMBER 单位:元
4_total_fee当月前3月总出账金额_月NUMBER单位:元
month_traffic当月累计-流量NUMBER单位:MB
many_over_bill连续超套VARCHAR2(500)1-是,0-否
contract_type合约类型VARCHAR2(500)ZBG_DIM.DIM_CBSS_ACTIVITY_TYPE
contract_time合约时长VARCHAR2(500)/
is_promise_low_consume是否承诺低消用户VARCHAR2(500)1.是 0.否
net_service网络口径用户VARCHAR2(500)20AAAAAA-2G
pay_times交费次数NUMBER单位:次
pay_num交费金额NUMBER单位:元
last_month_traffic上月结转流量NUMBER单位:MB
local_trafffic_month月累计-本地数据流量NUMBER单位:MB
local_caller_time本地语音主叫通话时长NUMBER单位:分钟
service1_caller_time套外主叫通话时长NUMBER单位:分钟
service2_caller_timeService2_caller_timeNUMBER单位:分钟
gender性别varchar2(100)01.男 02女
age年龄varchar2(100)/
complaint_level投诉重要性VARCHAR2(1000)1:普通,2:重要,3:重大
former_complaint_num交费金历史投诉总量NUMBER单位:次
former_complaint_fee历史执行补救费用交费金额NUMBER单位:分

数据探索

TOP2解决方案

导入必要的库:

import pandas as pd
import numpy as np
from gensim.corpora import WikiCorpus
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence
import multiprocessing

亮点1-利用word2vec

围绕以下数据进行词嵌入

1_total_fee当月总出账金额_月NUMBER单位:元
2_total_fee当月前1月总出账金额_月NUMBER单位:元
3_total_fee当月前2月总出账金额_月NUMBER 单位:元
4_total_fee当月前3月总出账金额_月NUMBER单位:元

读取并合并数据:


path = '../raw_data/'
save_path = '../gen_data/'
train_1 = pd.read_csv(path+'train_1.csv')  # 初赛数据
train_2 = pd.read_csv(path+'train_2.csv')	# 复赛数据
test = pd.read_csv(path+'test_2.csv')		# 复赛测试集
data = pd.concat([train_1,train_2,test]).reset_index(drop=True).sample(frac=1,random_state=2010).fillna(0)
data = data.replace('\\N',999)

将每个用户的四个月出账金额组成一个句子:

sentence = []
for line in list(data[['1_total_fee','2_total_fee','3_total_fee','4_total_fee']].values):   
#     [str(n) for n in line]  这样更快
    sentence.append([str(float(l)) for idx, l in enumerate(line)])

sentence是个二维数组,结果如下:

在这里插入图片描述
训练词向量模型:

print('training')
model = Word2Vec(sentence,size=L, window=2, min_count=1, workers=multiprocessing.cpu_count(),iter=10)
print('outputing')

利用已经训练好的模型,将每个词(数据)保存起来:


for fea in ['1_total_fee', '2_total_fee', '3_total_fee', '4_total_fee']:
    # 利用set将 data['1_total_fee'].values 数据去重,逐个输入模型,算出相应的词向量(10维)
    values = set(data['1_total_fee'].values)
    w2v = []
    for i in values:
        a = [i]
        # 利用append将多个元素加入list
        a.extend(model[str(float(i))])
        w2v.append(a)
    out_df = pd.DataFrame(w2v)
    
    # 添加列名
    name = [fea]
    for i in range(L):
        name.append(name[0] + 'W' + str(i))
    out_df.columns = name
    # 保存结果,后期通过merge利用此结果
    out_df.to_csv(save_path  + fea + '.csv', index=False)

亮点2-预测概率作为新的特征

将上述的词向量merge带训练数据中:

w2v_features = []
for col in  ['1_total_fee', '2_total_fee', '3_total_fee', '4_total_fee']:
    df =pd.read_csv(save_path+'/'+col+'.csv')
    df.drop_duplicates([col], inplace=True)
    feat_name = list(df)  # 获取列名
    feat_name.remove(col)  # 移除列名中的 1_total_fee
    w2v_features += feat_name
    data = pd.merge(data, df, on=col, how='left')

TOP2中的业务特征,本文只对计数特征进行总结

# 计算特征具体取值出现的个数
count_feature_list = []
def feature_count(data, features=[]):
    if len(set(features)) != len(features):
        print('equal feature !!!!')
        return data
    new_feature = 'count'
    for i in features:
        new_feature += '_' + i.replace('add_', '')
    try:
        del data[new_feature]
    except:
        pass
    temp = data.groupby(features).size().reset_index().rename(columns={0: new_feature})
#     print(temp)
    data = data.merge(temp, 'left', on=features)
    
    count_feature_list.append(new_feature)
    return data

计算以下特征以及组合特征的计数特征

data = feature_count(data, ['1_total_fee'])
data = feature_count(data, ['2_total_fee'])
data = feature_count(data, ['3_total_fee'])
data = feature_count(data, ['4_total_fee'])

data = feature_count(data, ['former_complaint_fee'])

data = feature_count(data, ['pay_num'])
data = feature_count(data, ['contract_time'])
data = feature_count(data, ['last_month_traffic'])
data = feature_count(data, ['online_time'])

for i in ['service_type', 'contract_type']:
    data = feature_count(data, [i, '1_total_fee'])
    data = feature_count(data, [i, '2_total_fee'])
    data = feature_count(data, [i, '3_total_fee'])
    data = feature_count(data, [i, '4_total_fee'])

    data = feature_count(data, [i, 'former_complaint_fee'])

    data = feature_count(data, [i, 'pay_num'])
    data = feature_count(data, [i, 'contract_time'])
    data = feature_count(data, [i, 'last_month_traffic'])
    data = feature_count(data, [i, 'online_time'])

将业务特征和词向量特征输入到Lightgbm模型,进行训练。

lgb_model = lgb.LGBMClassifier(
    n_estimators=10,
    boosting_type="gbdt",  
    objective='multiclass',  
    silent=False,
    random_state=2018, n_jobs=-1
)
lgb_model.fit(train_x, train_y.values,eval_set=[(train_x.iloc[:1000, :],train_y.values[:1000])], categorical_feature=cate_feature,verbose=1)
print(lgb_model.best_score_)

预测时,采用predict_proba进行预测。

train_proba = lgb_model.predict_proba(test_x[feature])
test_proba = lgb_model.predict_proba(data[data.label == 0][feature])
print(len(train_proba), len(test_proba))
print(train_proba)

预测结果是11个类别的概率:
在这里插入图片描述
将每条数据的预测概率作为新的特征加入到Lightgbm模型中。

亮点3 - 不同的数据用不同的模型预测

观察发现套餐类型数据分布如下:

在这里插入图片描述

其中 0:23G融合,1:2I2C,2:2G,3:3G,4:4G

真实场景中只有1,3,4三类。因此将3、4类归为1类:

data.loc[data['service_type'] == 3, 'service_type'] = 4

此时service_type只有两类:1和4。针对这两类分别训练模型。

模型一:取出service_type==1的数据进行训练预测。

模型一:取出service_type==4的数据进行训练预测。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值