本文主要是介绍DataFountain-大型多人在线角色扮演游戏中玩家充值金额预测(baseline),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
写在前面 :这个竞赛是DataFountain的一个训练赛,持续的时间也是比较长,不清楚后面会卷到多少分去。我也是前天才看到,想着做着玩儿玩儿,真正把数据下载下来才发现整个数据还是比较杂乱的,所以提供这个baseline希望给大家提供一点参考。目前的话我是0.65分左右排第3,这个baseline大概能到0.6左右。baseline比较粗糙,希望有大佬指点一二!
打个广告 : 目前的话我没有固定的做竞赛队友,一直是单打独斗,希望能找几个队友一起做数据竞赛(CV, NLP,数据分析都可以),一起学习进步。缺队友的友友可以私信我哦(本人现在研一,计科专业)!
赛题我就不重复了, 可以直接点赛题链接
数据处理
目前的话数据处理的部分还是比较粗糙的
import pandas as pd
pd.set_option('display.max_columns',None)
pd.set_option('display.max_rows',None)
import numpy as np
from sklearn.model_selection import KFold
import sys
np.set_printoptions(threshold=sys.maxsize)
from sklearn.model_selection import train_test_split
from lightgbm import LGBMRegressor as LGBR
from sklearn.model_selection import GridSearchCV
from sklearn.preprocessing import StandardScaler
import warnings
warnings.filterwarnings("ignore")df2 = pd.read_csv("../raw_data/role_consume_op.csv")
df3 = pd.read_csv("../raw_data/role_evolve_op.csv")
df7 = pd.read_csv("../raw_data/role_pay.csv")
df8 = pd.read_csv("../out_put/submission_sample.csv")
role_id = list(df7['role_id'].unique())
test_id = list(df8['role_id'])df3 = df3[df3["role_id"].isin(role_id)]
df2 = df2[df2["role_id"].isin(role_id)]df2["day"] = df2["dt"].apply(lambda x: x[7:8])
for i in role_id:df3.loc[df3["role_id"] == i, "day"] = df3[df3["role_id"] == i]["dt"].apply(lambda x: x[9:10])
处理df7-role_pay.csv
role_pay.csv 这个文件是一部分用户的充值文件,包含了这部分用户的前面7天的充值金额,赛题是让去预测第8天的充值金额。其他文件虽然提供了前面7天的游戏用户的一些行为特征,但是没有提供第8天的。
我的想法就是用滑动窗口的思想构造一个前6天预测第7天的训练集, 然后用2-7天的充值金额做测试集去预测第8天的充值金额。然后将前面7天用户的行为特征拼接到滑动窗口创建的特征集后面一起训练。
df_train_1 = pd.DataFrame()
for i in role_id:df7_one_day = df7[df7["role_id"]==i]["dt"].map(lambda x : x[9:10])df_train_1 = pd.concat([df_train_1, df7_one_day], axis=0)df_train_1 = df_train_1.sort_index()
df7["day"] = df_train_1
df7 = df7.iloc[:,[0, 1, 4]]ds = dict()
for i in role_id:ds[i] = [0 for i in range(7)]for i in df7.values:ds[i[0]][int(i[2])-2] += i[1]
处理df2-role_consume_op.csv
role_consume_op.csv这个表的内容记录的是一部分游戏用户对游戏中一些货币的消耗情况,我的想法就是只选取每个用户每天最终level, 每种货币的消耗的总量,每天的最终现存值当作特征,具体代码如下
yhl_2 = pd.DataFrame()
for i in role_id:df2_role = df2[df2["role_id"] == i]for j in ["2", "3", "4", "5", "6", "7", "8"]:cols = df2_role.columnsdf2_role_days = df2_role[df2_role["day"]==j]if list(df2_role_days.values) == []:df2_role_days = pd.DataFrame([[i, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, j]])df2_role_days.columns = colslevel = df2_role_days["level"].values[-1]use_t1 = df2_role_days["use_t1"].sum()use_t2 = df2_role_days["use_t2"].sum()remain_t1 = df2_role_days["remain_t1"].values[-1]remain_t2 = df2_role_days["remain_t2"].values[-1]df2_yhl = pd.DataFrame([[i, level, use_t1,use_t2,remain_t1, remain_t2,df2_role_days["day"].values[-1]]])yhl_2 = pd.concat([yhl_2, df2_yhl], axis=0)df_yhl_2 = yhl_2.iloc[:, [1, 2, 3, 4, 5]].values
df_yhl_2 = df_yhl_2.reshape(-1, 35)
df3-role_evolve_op.csv(感觉加上效果更差了, 可能是这个方式构造的特征太稀疏了)
这个表记录的是一部分游戏用户消耗各种道具的信息。升级类型type只有几种,可以看作类型变量,游戏用户有什么升级类型就记为1, 然后是对每天消耗道具量求和,其他的信息还没找到合适的使用方式。(但是加上这个表效果好像没啥变化)
yhl_3 = pd.DataFrame()
for i in role_id:df3_role = df3[df3["role_id"] == i]for j in ["2", "3", "4", "5", "6", "7", "8"]:cols = df3_role.columnsdf3_role_days = df3_role[df3_role["day"]==j]if list(df3_role_days.values) == []:df3_role_days = pd.DataFrame([[i, 0, 0, 0, 0, 0, 0, 0, j]])df3_role_days.columns = colsfea = []type_ = set(list(df3_role_days["type"].values))fea_type = [0 for i in range(11)]for j in type_:fea_type[j-1] = 1num = [df3_role_days["num"].sum()]fea += [i]fea += fea_typefea += numfea += [df3_role_days["day"].values[-1]]df3_yhl = pd.DataFrame([fea])yhl_3 = pd.concat([yhl_3, df3_yhl], axis=0)df_yhl_3 = yhl_3.iloc[:, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]].values
df_yhl_3 = df_yhl_3.reshape(-1, 84)
另外几个行为数据文件差不多也是这个处理方式, 就不贴出来了!
滑动窗口构建训练集
用前6天的充值记录 + df2 + df3 构造的每天游戏用户的行为做特征,第7天的充值做label
用2-7天的充值记录 + df2 + df3 构造的每天游戏用户的行为做特征,去预测第8天的充值
x, y = [], []
for idx, i in enumerate(role_id):x.append(ds[i][:-1] + list(df_yhl_2[idx])[:30] + list(df_yhl_3[idx])[:72]+list(df_yhl_4[idx])[:36] + list(df_yhl_5[idx])[:24])y.append(ds[i][-1])
x = np.array(x)
y = np.array(y)
display(x.shape, y.shape)scaler = StandardScaler()
scaler = scaler.fit(x)
x = scaler.transform(x)x_test = []
for idx, i in enumerate(role_id):x_test.append(ds[i][1:] + list(df_yhl_2[idx])[5:] + list(df_yhl_3[idx])[12:] +list(df_yhl_4[idx])[6:] + list(df_yhl_5[idx])[4:])
display(np.array(x_test).shape)
x_test = scaler.transform(x_test)
训练
训练这里应该做做交叉验证和特征筛选的, 毕竟拼接了太多特征,有没有用还不知道。
x_tr, x_te, y_tr, y_te = train_test_split(x, y, test_size=0.2, random_state=2023)
clf = LGBR(verbose= -1)
cv_params = {"max_depth" : [3, 7, 13],"n_estimators" : [300, 700, 1000],"learning_rate" : [0.005, 0.01,0.02]
}
eval_set = [(x_te, y_te)]
clf_search = GridSearchCV(clf, param_grid=cv_params, scoring='neg_mean_squared_error',n_jobs=-1, cv=5)clf_search.fit(x_tr, y_tr, eval_set=eval_set)
print(clf_search.best_params_)
预测结果
前面的用户充值记录只有1200多个用户, 但是要预测近4000名用户, 我是默认了充值记录没有的用户第8天也不充值,其实可以先做模型利用用户行为特征去预测一个用户是否充值,这样比直接记0会更好。还有就是这个数据是真实的数据,充值金额应该也可以做做文章!!
这篇关于DataFountain-大型多人在线角色扮演游戏中玩家充值金额预测(baseline)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!