aiforge_python/user_portrait_analysis/activity_analysis/train.py

86 lines
3.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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()