86 lines
3.6 KiB
Python
86 lines
3.6 KiB
Python
import pickle
|
||
import warnings
|
||
import pandas as pd
|
||
from sklearn.cluster import KMeans
|
||
from config import logger
|
||
from config import RANDOM_SEED
|
||
from data_process import get_rfm_data, save_train_result_to_pgsql
|
||
from config import activity_analysis_path
|
||
warnings.filterwarnings('ignore')
|
||
|
||
|
||
def iflabel(x):
|
||
if x == "高高高":
|
||
return 5
|
||
elif x == "高低高":
|
||
return 4
|
||
elif x == "高高低":
|
||
return 4
|
||
elif x == "高低低":
|
||
return 3
|
||
elif x == "低高高":
|
||
return 4
|
||
elif x == "低低高":
|
||
return 2
|
||
elif x == "低高低":
|
||
return 2
|
||
elif x == "低低低":
|
||
return 1
|
||
|
||
|
||
def train():
|
||
"""
|
||
用户活跃度分析模型训练
|
||
"""
|
||
logger.info('开始训练用户活跃度分析模型...')
|
||
|
||
df_rfm = get_rfm_data()
|
||
rfm_cluster = df_rfm.copy()
|
||
# 根据 R,F,M 值将所有数据分为 8 类
|
||
Cluster = df_rfm[["R", "F", "M"]].values
|
||
kmeans_model = KMeans(n_clusters=8, random_state=RANDOM_SEED).fit(Cluster)
|
||
|
||
rfm_cluster["label"] = kmeans_model.labels_
|
||
|
||
# 此处计算均值 RFM 模型,每个用户的R、F、M值同总体均值进行比较,比均值高的就为“高”,低的就标明“低”,然后通过三个指标的高低来打标签。
|
||
df_rfm_mean = rfm_cluster[["label", "R", "F", "M"]].groupby("label").agg("mean")
|
||
df_rfm_mean["IFR"] = df_rfm_mean["R"].apply(lambda x: "高" if x > df_rfm_mean["R"].mean() else "低")
|
||
df_rfm_mean["IFF"] = df_rfm_mean["F"].apply(lambda x: "高" if x > df_rfm_mean["F"].mean() else "低")
|
||
df_rfm_mean["IFM"] = df_rfm_mean["M"].apply(lambda x: "高" if x > df_rfm_mean["M"].mean() else "低")
|
||
|
||
# 方法和上面一样,#将三个指标合并起来,生成临时列temp,表示RFM综合指标
|
||
df_rfm_mean["temp"] = df_rfm_mean["IFR"] + df_rfm_mean["IFF"] + df_rfm_mean["IFM"]
|
||
# 对指标进行综合判断
|
||
df_rfm_mean["label"] = df_rfm_mean["temp"].apply(lambda x: iflabel(x))
|
||
# 此处在使用聚类RFM模型,比较的时候使用总体均值进行比较
|
||
rfm_cluster["IFR"] = rfm_cluster["R"].apply(lambda x: "高" if x > df_rfm_mean["R"].mean() else "低")
|
||
rfm_cluster["IFF"] = rfm_cluster["F"].apply(lambda x: "高" if x > df_rfm_mean["F"].mean() else "低")
|
||
rfm_cluster["IFM"] = rfm_cluster["M"].apply(lambda x: "高" if x > df_rfm_mean["M"].mean() else "低")
|
||
# 方法和上面一样,将三个指标合并起来,生成临时列temp,表示RFM综合指标
|
||
rfm_cluster["temp"] = rfm_cluster["IFR"] + rfm_cluster["IFF"] + rfm_cluster["IFM"]
|
||
# 根据定义的打分规则给每个用户进行打分,1-5分
|
||
rfm_cluster["label"] = rfm_cluster["temp"].apply(lambda x: iflabel(x))
|
||
|
||
result = rfm_cluster[['label']]
|
||
|
||
result_csv = pd.DataFrame(list(result.index), index=range(len(list(result.index))), columns=['user_id'])
|
||
result_csv['activity'] = list(result.values.reshape(1, len(list(result.index)))[0])
|
||
# 将用户 id 和活跃度分值提取出来并创新建立一个表
|
||
result_csv['user_id'] = result_csv['user_id'].astype(int)
|
||
result_csv['activity'] = result_csv['activity'].astype(int)
|
||
result_dict = dict(zip(result_csv['user_id'], result_csv['activity']))
|
||
|
||
# 将训练结果保存到数据库
|
||
save_train_result_to_pgsql(result_csv)
|
||
|
||
# 保存模型和结果
|
||
pickle.dump(kmeans_model, open(activity_analysis_path + 'results/user_activity_model.pkl', 'wb'))
|
||
pickle.dump(result_dict, open(activity_analysis_path + 'results/user_activity_dict.pkl', 'wb'))
|
||
|
||
logger.info('用户活跃度分析模型训练完成')
|
||
return result_dict
|
||
|
||
|
||
if __name__ == '__main__':
|
||
train()
|