| 项目背景
数据分析和人工智能是两个不同领域,但两者之间也有密不可分的关联。本次实战以电商用户行为为例,以人工智能算法为基础,通过用户的pv、会话次数、互动事件等行为预测用户最终是否发生加购或购买行为。
| 数据字典
user_id:用户ID。
item_id:商品ID,SPU维度。
pv:商品浏览次数。
session:会话次数
engage:互动事件
result:数据标签
数据使用CSV文件存储,分别为cart_train.csv和buy_train.csv,主要用于模型训练。predict.csv用于模型预测。
| 数据清洗
不同数据结构会有不同清洗规则,本示例的数据结构基本上符合模型训练要求,只需对同一用户同一商品的多条数据进行汇总即可。数据结构如图所示
训练文件cart_train.csv和buy_train.csv设有字段result,这是区分这条数据的用户是否发生了加购或购买行为(0代表未发生,1代表已加购或购买),这些数据必须是现实中已经发生的,这样训练的模型才有实际意义。
| 模块引用
本次开发使用Python的sklearn库,数据处理使用pandas,模型保存使用joblib,整个项目引用代码如下所示
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
import joblib
import os
import sys
# 获取当前文件所在目录
if hasattr(sys, 'frozen'):
application_path = os.path.dirname(sys.executable)
else:
application_path = os.path.dirname(os.path.abspath(__file__))
| 数据处理
数据处理主要对训练文件cart_train.csv和buy_train.csv的同一个客户同一个商品的数据进行汇总,如果数据相同情况下,有一条数据发生购买,一条数据尚未购买,汇总后的数据默认为购买。
将数据处理以函数get_data表示,示例代码如下:
def get_data(csv, style):
'''
:param csv: 需要读取的CSV文件
:param style: 选择加购或购买的类型
:return:
'''
data = pd.read_csv(csv)
# 数据处理
df_new = pd.DataFrame()
if '.pkl' not in style: # 训练模型的数据处理
gb = data.groupby(['user_id', 'item_id'])
if 'total_sum' in data.columns:
df_new['total_sum'] = gb['total'].sum()
df_new['pv_sum'] = gb['pv'].sum()
df_new['session_sum'] = gb['session'].sum()
df_new['engage_sum'] = gb['engage'].sum()
df_new['result'] = gb['result'].max()
else: # 模型预测的数据处理
df_new = data.groupby(['user_id', 'item_id'], as_index=False).sum()
return df_new
| 模型训练
数据处理完成,下一步是模型训练。训练模型的数据必须包含:训练数据(即用户的pv、会话次数、互动事件)和数据标签(即字段result,当前数据是否发生购买或加购)
将模型训练以函数get_model表示,示例代码如下:
def get_model(csv, style='cart', modle_style='randomForest'):
'''
:param csv: 导入csv文件,用于模型训练
:param style: 值为:cart or buy
:param modle_style: 值为:logistic or randomForest
:return: None
'''
df_new = get_data(csv, style)
# 数据划分,将pv_sum、session_sum、engage_sum作为X
X = df_new.iloc[:, :-1]
# 将cart或buy的数据标签作为Y
Y = df_new.iloc[:, -1]
# 训练模型
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X, Y, test_size=0.3, random_state=42)
if modle_style == 'logistic':
rfc = LogisticRegression()
else:
rfc = RandomForestClassifier(n_estimators=200, max_depth=1)
rfc.fit(Xtrain, Ytrain)
# 保存模型
model_name = f'{application_path}\\{style}2{modle_style}.pkl'
joblib.dump(rfc, model_name)
return model_name
函数get_model支持随机森林算法和逻辑回归算法,算法选择由参数modle_style表示。参数style表示选择训练购买或加购模型。
| 使用模型
模型训练成功后,下面使用模型进行预测,将其定义在函数load_model,代码如下:
def load_model(models, csv):
'''
:param models: 模型的文件路径
:param csv: 需要预测的数据
:return:
'''
data = pd.DataFrame()
m = joblib.load(models)
df_new = get_data(csv, models)
print(df_new)
data['pv_sum'] = df_new['pv']
data['session_sum'] = df_new['session']
data['engage_sum'] = df_new['engage']
# 预测数据
s = m.predict_proba(data).round(3)
print(s)
df_new['negative'] = s[:, 0]
df_new['positive'] = s[:, 1]
df_new.to_csv('result.csv', index=False)
函数load_model先读取需要预测的数据文件,并对其进行数据处理(调用函数get_data),然后通过joblib加载模型,由模型文件对数据进行预测,最后写入result.csv文件。
| 程序运行
至此,我们已完成用户行为预测分析,在 if__name__ =='__main__' 编写程序运行入口,代码如下:
if __name__ == '__main__':
# 训练模型
get_model(f'{application_path}\\cart_train.csv', 'cart')
get_model(f'{application_path}\\buy_train.csv', 'buy')
user_select = input('请选择预测模型(默认选1):1.加购预测模型,2.购买预测模型')
model_name = f'{application_path}\\buy2randomForest.pkl' if user_select == '2' else f'{application_path}\\cart2randomForest.pkl'
load_model(model_name, f'{application_path}\\predict.csv')
input('预测成功,请查看同目录的predict.csv')
| 运行结果
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
import joblib
import os
import sys
if hasattr(sys, 'frozen'):
application_path = os.path.dirname(sys.executable)
else:
application_path = os.path.dirname(os.path.abspath(__file__))
def get_data(csv, style):
'''
:param csv: 需要读取的CSV文件
:param style: 选择加购或购买的类型
:return:
'''
data = pd.read_csv(csv)
# 数据处理
df_new = pd.DataFrame()
if '.pkl' not in style:
gb = data.groupby(['user_id', 'item_id'])
if 'total_sum' in data.columns:
df_new['total_sum'] = gb['total'].sum()
df_new['pv_sum'] = gb['pv'].sum()
df_new['session_sum'] = gb['session'].sum()
df_new['engage_sum'] = gb['engage'].sum()
df_new['result'] = gb['result'].max()
else:
df_new = data.groupby(['user_id', 'item_id'], as_index=False).sum()
return df_new
def get_model(csv, style='cart', modle_style='randomForest'):
'''
:param csv: 导入csv文件,用于模型训练
:param style: 值为:cart or buy
:param modle_style: 值为:logistic or randomForest
:return: None
'''
df_new = get_data(csv, style)
# 数据划分
# 将pv_sum、session_sum、engage_sum作为X
X = df_new.iloc[:, :-1]
# 将cart或buy作为Y
Y = df_new.iloc[:, -1]
# 训练模型
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X, Y, test_size=0.3, random_state=42)
if modle_style == 'logistic':
rfc = LogisticRegression()
else:
rfc = RandomForestClassifier(n_estimators=200, max_depth=1)
rfc.fit(Xtrain, Ytrain)
# 保存模型
model_name = f'{application_path}\\{style}2{modle_style}.pkl'
joblib.dump(rfc, model_name)
return model_name
def load_model(models, csv):
'''
:param models: 模型的文件路径
:param csv: 需要预测的数据
:return:
'''
data = pd.DataFrame()
m = joblib.load(models)
df_new = get_data(csv, models)
print(df_new)
data['pv_sum'] = df_new['pv']
data['session_sum'] = df_new['session']
data['engage_sum'] = df_new['engage']
# 预测数据
s = m.predict_proba(data).round(3)
print(s)
df_new['negative'] = s[:, 0]
df_new['positive'] = s[:, 1]
df_new.to_csv('result.csv', index=False)
if __name__ == '__main__':
# 训练模型
get_model(f'{application_path}\\cart_train.csv', 'cart')
get_model(f'{application_path}\\buy_train.csv', 'buy')
user_select = input('请选择预测模型(默认选1):1.加购预测模型,2.购买预测模型')
model_name = f'{application_path}\\buy2randomForest.pkl' if user_select == '2' else f'{application_path}\\cart2randomForest.pkl'
load_model(model_name, f'{application_path}\\predict.csv')
input('预测成功,请查看同目录的predict.csv')
更多内容也可看笔者出版图书!