用户套餐个性化推荐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的数据进行训练预测。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现个性化视频推荐的代码会比较复杂,需要涉及到数据的收集、清洗、建模和推荐算法的实现。下面是一个简单的代码示例,仅供参考: ```python import pandas as pd from sklearn.feature_extraction.text import CountVectorizer from sklearn.metrics.pairwise import cosine_similarity # 读取用户行为数据 user_data = pd.read_csv("user_data.csv") # 构建用户-视频矩阵 user_video_matrix = user_data.pivot_table(index='user_id', columns='video_id', values='rating') # 填充缺失值,表示用户未对该视频进行评分 user_video_matrix = user_video_matrix.fillna(0) # 计算用户-视频的余弦相似度 user_sim_matrix = cosine_similarity(user_video_matrix) # 定义推荐函数 def recommend_videos(user_id, user_sim_matrix, user_video_matrix, top_k=10): # 找到与目标用户相似度最高的用户 sim_users = user_sim_matrix[user_id] top_sim_users = sim_users.argsort()[-top_k-1:-1][::-1] # 从相似用户推荐未观看过的视频 user_videos = user_video_matrix.loc[user_id] recommendations = [] for user in top_sim_users: sim = sim_users[user] sim_user_videos = user_video_matrix.loc[user] for video in sim_user_videos.index: if user_videos[video] == 0 and sim_user_videos[video] > 0: recommendations.append((video, sim*sim_user_videos[video])) # 按照推荐分数排序 recommendations = sorted(recommendations, key=lambda x: x[1], reverse=True) return recommendations[:top_k] # 示例:对用户1进行视频推荐 recommendations = recommend_videos(user_id=1, user_sim_matrix=user_sim_matrix, user_video_matrix=user_video_matrix, top_k=10) print(recommendations) ``` 需要注意的是,这只是一个简单的示例代码,实际实现中需要根据数据来源和推荐算法的具体情况进行相应的调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值