细化用户行为画像,为rfm(用户价值管理)分析添加每个单独提交
parent
356ae55ab0
commit
42951f9bac
@ -0,0 +1,113 @@
|
||||
package com.sztzjy.marketing.controller.stu;
|
||||
|
||||
import com.sztzjy.marketing.annotation.AnonymousAccess;
|
||||
import com.sztzjy.marketing.util.file.IFileUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @author 17803
|
||||
* @date 2024-06-17 10:29
|
||||
*/
|
||||
|
||||
@Api(tags = "用户画像模型下载数据")
|
||||
@RestController
|
||||
@RequestMapping("api/downDataByUserPortrait")
|
||||
public class DownloadDataController {
|
||||
|
||||
|
||||
@Autowired
|
||||
private IFileUtil iFileUtil;
|
||||
|
||||
|
||||
@AnonymousAccess
|
||||
@ApiOperation("RFM分析方法下载数据")
|
||||
@GetMapping("/analysisByRfmDown")
|
||||
public void analysisByRfmDown(HttpServletResponse response){
|
||||
|
||||
iFileUtil.download(response,"RFM分析方法data.xlsx");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@AnonymousAccess
|
||||
@ApiOperation("帕累托分析方法下载数据")
|
||||
@GetMapping("/analysisByPareto")
|
||||
public void analysisByPareto(HttpServletResponse response){
|
||||
|
||||
iFileUtil.download(response,"帕累托分析方法data.xlsx");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@AnonymousAccess
|
||||
@ApiOperation("波士顿矩阵分析图下载数据")
|
||||
@GetMapping("/bostonMatrixAnalysisData")
|
||||
public void bostonMatrixAnalysisData(HttpServletResponse response){
|
||||
|
||||
iFileUtil.download(response,"波士顿矩阵分析图data.xlsx");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@AnonymousAccess
|
||||
@ApiOperation("漏斗模型分析下载数据")
|
||||
@GetMapping("/analysisByFunnelModel")
|
||||
public void analysisByFunnelModel(HttpServletResponse response){
|
||||
|
||||
iFileUtil.download(response,"漏斗模型分析data.xlsx");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@AnonymousAccess
|
||||
@ApiOperation("购物篮分析下载数据")
|
||||
@GetMapping("/analysisByShopBasket")
|
||||
public void analysisByShopBasket(HttpServletResponse response){
|
||||
|
||||
iFileUtil.download(response,"购物篮分析data.xlsx");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@AnonymousAccess
|
||||
@ApiOperation("复购分析下载数据")
|
||||
@GetMapping("/analysisByRepurchase")
|
||||
public void analysisByRepurchase(HttpServletResponse response){
|
||||
|
||||
iFileUtil.download(response,"复购分析data.xlsx");
|
||||
|
||||
}
|
||||
|
||||
@AnonymousAccess
|
||||
@ApiOperation("留存分析下载数据")
|
||||
@GetMapping("/analysisByRetention")
|
||||
public void analysisByRetention(HttpServletResponse response){
|
||||
|
||||
iFileUtil.download(response,"留存分析data.xlsx");
|
||||
|
||||
}
|
||||
|
||||
@AnonymousAccess
|
||||
@ApiOperation("用户粘性分析下载数据")
|
||||
@GetMapping("/analysisByStickiness")
|
||||
public void analysisByStickiness(HttpServletResponse response){
|
||||
|
||||
iFileUtil.download(response,"用户粘性分析data.xlsx");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.sztzjy.marketing.controller.stu;
|
||||
|
||||
import com.sztzjy.marketing.annotation.AnonymousAccess;
|
||||
import com.sztzjy.marketing.entity.StuMachineLearning;
|
||||
import com.sztzjy.marketing.service.UserBehaviorProfilingByRfmService;
|
||||
import com.sztzjy.marketing.util.ResultEntity;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author 17803
|
||||
* @date 2024-06-17 13:38
|
||||
*/
|
||||
|
||||
@Api(tags = "用户行为画像分析<rfm(用户价值管理)分析>")
|
||||
@RestController
|
||||
@RequestMapping("api/userBehaviorByRFM")
|
||||
public class UserBehaviorProfilingByRFM {
|
||||
|
||||
|
||||
@Autowired
|
||||
private UserBehaviorProfilingByRfmService userBehaviorProfilingByRFMService;
|
||||
|
||||
|
||||
@AnonymousAccess
|
||||
@ApiOperation("第一步:筛选出统计样本")
|
||||
@PostMapping("/filterOutStatisSample")
|
||||
public ResultEntity filterOutStatisSample(@RequestBody StuMachineLearning stuMachineLearning) {
|
||||
|
||||
return userBehaviorProfilingByRFMService.filterOutStatisSample(stuMachineLearning);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@AnonymousAccess
|
||||
@ApiOperation("第二步:计算每个用户的RFM值")
|
||||
@PostMapping("/calculateRfm")
|
||||
public ResultEntity calculateRfm(@RequestBody StuMachineLearning stuMachineLearning) {
|
||||
|
||||
return userBehaviorProfilingByRFMService.calculateRfm(stuMachineLearning);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,22 @@
|
||||
package com.sztzjy.marketing.entity.dto;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 17803
|
||||
* @date 2024-06-17 15:03
|
||||
*/
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class StuBehaviorProfilingDTO {
|
||||
|
||||
|
||||
private Map<String,String> map;
|
||||
|
||||
private Integer count ;
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.sztzjy.marketing.service;
|
||||
|
||||
import com.sztzjy.marketing.entity.StuMachineLearning;
|
||||
import com.sztzjy.marketing.util.ResultEntity;
|
||||
|
||||
/**
|
||||
* @author 17803
|
||||
* @date 2024-06-17 13:47
|
||||
*/
|
||||
public interface UserBehaviorProfilingByRfmService {
|
||||
/**
|
||||
* 第一步:筛选出统计样本
|
||||
* @param stuMachineLearning
|
||||
* @return
|
||||
*/
|
||||
|
||||
ResultEntity filterOutStatisSample(StuMachineLearning stuMachineLearning);
|
||||
|
||||
/**
|
||||
* 计算每个用户的RFM值
|
||||
* @param stuMachineLearning
|
||||
* @return
|
||||
*/
|
||||
|
||||
ResultEntity calculateRfm(StuMachineLearning stuMachineLearning);
|
||||
}
|
@ -0,0 +1,292 @@
|
||||
package com.sztzjy.marketing.service;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.sztzjy.marketing.config.Constant;
|
||||
import com.sztzjy.marketing.entity.StuMachineLearning;
|
||||
import com.sztzjy.marketing.entity.StuMachineLearningExample;
|
||||
import com.sztzjy.marketing.entity.dto.StuBehaviorProfilingDTO;
|
||||
import com.sztzjy.marketing.mapper.StuMachineLearningMapper;
|
||||
import com.sztzjy.marketing.util.ResultEntity;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 17803
|
||||
* @date 2024-06-17 13:47
|
||||
*/
|
||||
|
||||
@Service
|
||||
public class UserBehaviorProfilingByRfmServiceImpl implements UserBehaviorProfilingByRfmService {
|
||||
|
||||
@Autowired
|
||||
private StuMachineLearningMapper machineLearningMapper;
|
||||
|
||||
/**
|
||||
* 第一步:筛选出统计样本
|
||||
*
|
||||
* @param learning
|
||||
* @return
|
||||
*/
|
||||
|
||||
@Override
|
||||
public ResultEntity filterOutStatisSample(StuMachineLearning learning) {
|
||||
|
||||
//判断结果是否正确
|
||||
StuBehaviorProfilingDTO behaviorProfilingDTO = checkAnswerByOneSub(learning);
|
||||
|
||||
//查询是否提交,已提交不做任何修改,未提交校验结果并保存,修改对应提交状态
|
||||
|
||||
StuMachineLearningExample machineLearningExample = new StuMachineLearningExample();
|
||||
machineLearningExample.createCriteria().andUserIdEqualTo(learning.getUserId()).andModuleEqualTo(learning.getModule());
|
||||
List<StuMachineLearning> machineLearningList = machineLearningMapper.selectByExample(machineLearningExample);
|
||||
|
||||
|
||||
if (!machineLearningList.isEmpty()) {
|
||||
//有用户数据
|
||||
if (machineLearningList.get(0).getOneSubState() == null) {
|
||||
machineLearningList.get(0).setOneSubState(0);
|
||||
}
|
||||
|
||||
if (machineLearningList.get(0).getOneSubState() == 1) {
|
||||
//二次提交不做任何修改
|
||||
return new ResultEntity<>(HttpStatus.OK, "提交成功!");
|
||||
}
|
||||
|
||||
//已经有数据
|
||||
StuMachineLearning machineLearning = machineLearningList.get(0);
|
||||
|
||||
|
||||
Integer id = machineLearning.getId();
|
||||
|
||||
BeanUtils.copyProperties(learning, machineLearning);
|
||||
machineLearning.setId(id);
|
||||
machineLearning.setSuccessNumber(behaviorProfilingDTO.getCount());
|
||||
machineLearning.setOneSubState(1);
|
||||
|
||||
machineLearning.setErrorField(JSON.toJSONString(behaviorProfilingDTO.getMap()));
|
||||
|
||||
machineLearningMapper.updateByPrimaryKeySelective(machineLearning);
|
||||
|
||||
return new ResultEntity<>(HttpStatus.OK, "提交成功!");
|
||||
|
||||
} else {
|
||||
|
||||
//第一次提交
|
||||
learning.setId((int) IdUtil.getSnowflakeNextId());
|
||||
learning.setSuccessNumber(behaviorProfilingDTO.getCount());
|
||||
learning.setOneSubState(1);
|
||||
learning.setErrorField(JSON.toJSONString(behaviorProfilingDTO.getMap()));
|
||||
machineLearningMapper.insertSelective(learning);
|
||||
|
||||
return new ResultEntity<>(HttpStatus.OK, "提交成功!");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算每个用户的RFM值
|
||||
* @param learning
|
||||
* @return
|
||||
*/
|
||||
|
||||
@Override
|
||||
public ResultEntity calculateRfm(StuMachineLearning learning) {
|
||||
|
||||
|
||||
//判断结果是否正确
|
||||
StuBehaviorProfilingDTO behaviorProfilingDTO = checkAnswerByTwoSub(learning);
|
||||
|
||||
//查询是否提交,已提交不做任何修改,未提交校验结果并保存,修改对应提交状态
|
||||
|
||||
StuMachineLearningExample machineLearningExample = new StuMachineLearningExample();
|
||||
machineLearningExample.createCriteria().andUserIdEqualTo(learning.getUserId()).andModuleEqualTo(learning.getModule());
|
||||
List<StuMachineLearning> machineLearningList = machineLearningMapper.selectByExample(machineLearningExample);
|
||||
|
||||
|
||||
if (!machineLearningList.isEmpty()) {
|
||||
//有用户数据
|
||||
if (machineLearningList.get(0).getTwoSubState() == null) {
|
||||
machineLearningList.get(0).setTwoSubState(-1);
|
||||
}
|
||||
|
||||
if (machineLearningList.get(0).getTwoSubState() == 1) {
|
||||
//二次提交不做任何修改
|
||||
return new ResultEntity<>(HttpStatus.OK, "提交成功!");
|
||||
}
|
||||
|
||||
//已经有数据
|
||||
StuMachineLearning machineLearning = machineLearningList.get(0);
|
||||
|
||||
|
||||
Integer id = machineLearning.getId();
|
||||
|
||||
BeanUtils.copyProperties(learning, machineLearning);
|
||||
machineLearning.setId(id);
|
||||
machineLearning.setSuccessNumber(behaviorProfilingDTO.getCount());
|
||||
machineLearning.setTwoSubState(1);
|
||||
machineLearning.setErrorField(JSON.toJSONString(behaviorProfilingDTO.getMap()));
|
||||
|
||||
machineLearningMapper.updateByPrimaryKeySelective(machineLearning);
|
||||
|
||||
return new ResultEntity<>(HttpStatus.OK, "提交成功!");
|
||||
|
||||
} else {
|
||||
|
||||
//第一次提交
|
||||
learning.setId((int) IdUtil.getSnowflakeNextId());
|
||||
learning.setSuccessNumber(behaviorProfilingDTO.getCount());
|
||||
learning.setTwoSubState(1);
|
||||
learning.setErrorField(JSON.toJSONString(behaviorProfilingDTO.getMap()));
|
||||
machineLearningMapper.insertSelective(learning);
|
||||
|
||||
return new ResultEntity<>(HttpStatus.OK, "提交成功!");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//第一步:筛选出统计样本结果校验
|
||||
|
||||
private StuBehaviorProfilingDTO checkAnswerByOneSub(StuMachineLearning learning) {
|
||||
|
||||
//用来存储错误字段和正确答案
|
||||
Map<String, String> map = new HashMap<>();
|
||||
|
||||
|
||||
//错误次数
|
||||
int count = 0;
|
||||
|
||||
|
||||
if (!Constant.FILTEROUTSTATIS_ONE.equals(learning.getStepOneA())){
|
||||
count ++;
|
||||
map.put("stepOneA",Constant.FILTEROUTSTATIS_ONE);
|
||||
}
|
||||
|
||||
if (!Constant.FILTEROUTSTATIS_TWO.equals(learning.getStepOneB())){
|
||||
count ++;
|
||||
map.put("stepOneB",Constant.FILTEROUTSTATIS_TWO);
|
||||
|
||||
}
|
||||
|
||||
if (!Constant.FILTEROUTSTATIS_TWO.equals(learning.getStepOneC())){
|
||||
count ++;
|
||||
map.put("stepOneC",Constant.FILTEROUTSTATIS_TWO);
|
||||
}
|
||||
|
||||
if (!Constant.FILTEROUTSTATIS_TWO.equals(learning.getStepOneD())){
|
||||
count ++;
|
||||
map.put("stepOneD",Constant.FILTEROUTSTATIS_TWO);
|
||||
}
|
||||
|
||||
if (!Constant.FILTEROUTSTATIS_TWO.equals(learning.getStepTwoA())){
|
||||
count ++;
|
||||
map.put("stepTwoA",Constant.FILTEROUTSTATIS_TWO);
|
||||
}
|
||||
|
||||
if (!Constant.FILTEROUTSTATIS_TWO.equals(learning.getStepTwoB())){
|
||||
count ++;
|
||||
map.put("stepTwoB",Constant.FILTEROUTSTATIS_TWO);
|
||||
}
|
||||
|
||||
if (!Constant.FILTEROUTSTATIS_TWO.equals(learning.getStepTwoC())){
|
||||
count ++;
|
||||
map.put("stepTwoC",Constant.FILTEROUTSTATIS_TWO);
|
||||
}
|
||||
|
||||
Integer number = 7 - count;
|
||||
|
||||
|
||||
StuBehaviorProfilingDTO stuBehaviorProfilingDTO = StuBehaviorProfilingDTO.builder().map(map).count(number).build();
|
||||
|
||||
return stuBehaviorProfilingDTO;
|
||||
|
||||
|
||||
}
|
||||
|
||||
private StuBehaviorProfilingDTO checkAnswerByTwoSub(StuMachineLearning learning){
|
||||
//用来存储错误字段和正确答案
|
||||
// 使用 fastjson 将 JSON 字符串转换回 Map
|
||||
Map<String, String> map = JSON.parseObject(learning.getErrorField(), HashMap.class);
|
||||
|
||||
|
||||
//错误次数
|
||||
int count = 0;
|
||||
|
||||
|
||||
if (!Constant.FILTEROUTSTATIS_THREE.equals(learning.getStepThreeA())){
|
||||
count ++;
|
||||
|
||||
map.put("stepThreeA",Constant.FILTEROUTSTATIS_THREE);
|
||||
}
|
||||
|
||||
if (!Constant.FILTEROUTSTATIS_FOUR.equals(learning.getStepThreeB())){
|
||||
count ++;
|
||||
map.put("stepThreeB",Constant.FILTEROUTSTATIS_FOUR);
|
||||
|
||||
}
|
||||
|
||||
if (!Constant.FILTEROUTSTATIS_FIVE.equals(learning.getStepThreeC())){
|
||||
count ++;
|
||||
map.put("stepThreeC",Constant.FILTEROUTSTATIS_FIVE);
|
||||
}
|
||||
|
||||
if (!Constant.FILTEROUTSTATIS_FOUR.equals(learning.getStepThreeD())){
|
||||
count ++;
|
||||
map.put("stepThreeD",Constant.FILTEROUTSTATIS_FOUR);
|
||||
}
|
||||
|
||||
if (!Constant.FILTEROUTSTATIS_SIX.equals(learning.getStepFourA())){
|
||||
count ++;
|
||||
map.put("stepFourA",Constant.FILTEROUTSTATIS_SIX);
|
||||
}
|
||||
|
||||
if (!Constant.FILTEROUTSTATIS_SEVEN.equals(learning.getStepFourB())){
|
||||
count ++;
|
||||
map.put("stepFourB",Constant.FILTEROUTSTATIS_SEVEN);
|
||||
}
|
||||
|
||||
if (!Constant.FILTEROUTSTATIS_EIGHT.equals(learning.getStepFourC())){
|
||||
count ++;
|
||||
map.put("stepFourC",Constant.FILTEROUTSTATIS_EIGHT);
|
||||
}
|
||||
if (!Constant.FILTEROUTSTATIS_EIGHT.equals(learning.getStepFourD())){
|
||||
count ++;
|
||||
map.put("stepFourD",Constant.FILTEROUTSTATIS_EIGHT);
|
||||
}
|
||||
if (!Constant.FILTEROUTSTATIS_NINE.equals(learning.getStepFiveA())){
|
||||
count ++;
|
||||
map.put("stepFiveA",Constant.FILTEROUTSTATIS_NINE);
|
||||
}
|
||||
|
||||
|
||||
Integer number = 9 - count;
|
||||
|
||||
//获取上一次得分
|
||||
|
||||
Integer sum = learning.getSuccessNumber() + number;
|
||||
|
||||
|
||||
//拼接上一次错误字段
|
||||
learning.getErrorField();
|
||||
|
||||
|
||||
StuBehaviorProfilingDTO stuBehaviorProfilingDTO = StuBehaviorProfilingDTO.builder().map(map).count(sum).build();
|
||||
|
||||
return stuBehaviorProfilingDTO;
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue