基于 Spring Boot 3.2 + JDK 17 + DL4J 的电商场景入门案例,「电商用户复购预测」完整工程——覆盖从工程搭建、核心概念落地到接口调用的全流程,代码完整可直接运行,所有DL4J核心概念都在案例中具象化。

一、案例背景(电商真实场景)

业务需求

电商平台想通过用户的历史行为(购买次数、消费金额、最近购买时间等),预测用户「未来30天是否会复购」(二分类问题:1=会复购,0=不会复购),从而对高概率复购用户推送优惠券、对低概率用户做召回营销,提升GMV。

技术栈

  • 基础框架:Spring Boot 3.2.0
  • JDK版本:17(兼容Spring Boot 3.x)
  • 深度学习框架:Deeplearning4j 1.0.0-M2.1
  • 构建工具:Maven
  • 核心功能:模型训练 + 接口化预测

二、工程结构(完整目录)

dl4j-springboot-ecommerce-demo/
├── pom.xml                          // 依赖配置
├── src/main/java/com/ecommerce/dl4j/
│   ├── Dl4jEcommerceDemoApplication.java  // 启动类
│   ├── config/
│   │   └── Dl4jModelConfig.java           // DL4J模型配置类
│   ├── controller/
│   │   └── UserRepurchaseController.java  // 预测接口控制器
│   ├── model/
│   │   └── UserBehaviorDTO.java           // 用户行为数据DTO
│   ├── service/
│   │   ├── UserRepurchaseService.java     // 预测服务接口
│   │   └── impl/
│   │       └── UserRepurchaseServiceImpl.java  // 服务实现(模型训练+预测)
│   └── util/
│       └── DataNormalizerUtil.java        // 数据标准化工具类
└── src/main/resources/
    └── application.properties           // 配置文件(空,仅占位)

三、完整工程代码

1. pom.xml(依赖配置,核心)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- Spring Boot父工程 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
        <relativePath/>
    </parent>

    <groupId>com.ecommerce</groupId>
    <artifactId>dl4j-springboot-ecommerce-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>dl4j-springboot-ecommerce-demo</name>
    <description>DL4J + SpringBoot 电商用户复购预测案例(JDK17)</description>

    <!-- 核心配置 -->
    <properties>
        <java.version>17</java.version>
        <dl4j.version>1.0.0-M2.1</dl4j.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- Spring Boot Web(提供REST接口) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring Boot测试(可选) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- DL4J核心依赖 -->
        <dependency>
            <groupId>org.deeplearning4j</groupId>
            <artifactId>deeplearning4j-core</artifactId>
            <version>${dl4j.version}</version>
        </dependency>

        <!-- ND4J(数值计算核心,兼容JDK17) -->
        <dependency>
            <groupId>org.nd4j</groupId>
            <artifactId>nd4j-native-platform</artifactId>
            <version>${dl4j.version}</version>
        </dependency>

        <!-- Apache Commons Math(数据模拟辅助) -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-math3</artifactId>
            <version>3.6.1</version>
        </dependency>

        <!-- Lombok(简化代码,可选) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- Spring Boot打包插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2. 启动类:Dl4jEcommerceDemoApplication.java

package com.ecommerce.dl4j;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * SpringBoot启动类
 * 功能:启动应用,初始化DL4J模型(项目启动时自动训练模型)
 */
@SpringBootApplication
public class Dl4jEcommerceDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(Dl4jEcommerceDemoApplication.class, args);
        System.out.println("===== 电商用户复购预测服务启动成功 =====");
        System.out.println("访问地址:http://localhost:8080/api/repurchase/predict");
    }

}

3. 模型配置类:Dl4jModelConfig.java

package com.ecommerce.dl4j.config;

import org.deeplearning4j.nn.conf.MultiLayerConfiguration;
import org.deeplearning4j.nn.conf.NeuralNetConfiguration;
import org.deeplearning4j.nn.conf.layers.DenseLayer;
import org.deeplearning4j.nn.conf.layers.OutputLayer;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.deeplearning4j.nn.weights.WeightInit;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.learning.config.Adam;
import org.nd4j.linalg.lossfunctions.LossFunctions;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * DL4J模型配置类
 * 核心概念体现:
 * 1. MultiLayerConfiguration:模型配置(定义层结构)
 * 2. DenseLayer:全连接层(特征提取)
 * 3. OutputLayer:输出层(二分类结果)
 * 4. Adam:优化器(参数调整)
 * 5. WeightInit:权重初始化(加速训练)
 */
@Configuration
public class Dl4jModelConfig {

    // 核心参数(电商场景:5个用户行为特征)
    private static final int INPUT_FEATURES = 5;  // 输入特征数
    private static final long RANDOM_SEED = 42;   // 随机种子(结果可复现)
    private static final double LEARNING_RATE = 0.001; // 学习率

    /**
     * 构建DL4J二分类模型(复购预测)
     * @return 训练好的MultiLayerNetwork模型
     */
    @Bean
    public MultiLayerNetwork repurchasePredictModel() {
        // 1. 定义模型配置(核心:层结构)
        MultiLayerConfiguration config = new NeuralNetConfiguration.Builder()
                .seed(RANDOM_SEED)                          // 固定随机种子
                .updater(new Adam(LEARNING_RATE))            // 优化器:Adam(工业界首选)
                .l2(0.001)                                  // L2正则化:防止过拟合
                .list()                                     // 顺序层结构
                // 第1层:输入层 + 隐藏层1(5个特征 → 32个神经元)
                .layer(0, new DenseLayer.Builder()
                        .nIn(INPUT_FEATURES)                // 输入特征数
                        .nOut(32)                           // 输出神经元数
                        .activation(Activation.RELU)        // 激活函数:ReLU(提取非线性特征)
                        .weightInit(WeightInit.XAVIER)      // 权重初始化
                        .build()
                )
                // 第2层:隐藏层2(32 → 16神经元)
                .layer(1, new DenseLayer.Builder()
                        .nIn(32)
                        .nOut(16)
                        .activation(Activation.RELU)
                        .weightInit(WeightInit.XAVIER)
                        .build()
                )
                // 第3层:输出层(16 → 1神经元,二分类)
                .layer(2, new OutputLayer.Builder(LossFunctions.LossFunction.BINARY_CROSSENTROPY)
                        .nIn(16)
                        .nOut(1)                            // 二分类输出1个值(0-1概率)
                        .activation(Activation.SIGMOID)     // Sigmoid:输出0-1概率
                        .weightInit(WeightInit.XAVIER)
                        .build()
                )
                .build();

        // 2. 初始化模型
        MultiLayerNetwork model = new MultiLayerNetwork(config);
        model.init();

        System.out.println("===== DL4J复购预测模型初始化完成 =====");
        return model;
    }
}

4. 数据DTO:UserBehaviorDTO.java

package com.ecommerce.dl4j.model;

import lombok.Data;

/**
 * 用户行为数据DTO(电商场景)
 * 核心特征(小白易懂):
 * 1. purchaseCount:历史购买次数
 * 2. totalAmount:累计消费金额(元)
 * 3. lastPurchaseDays:最近一次购买距今天数
 * 4. browseTimes:近30天商品浏览次数
 * 5. collectCount:收藏商品数量
 */
@Data
public class UserBehaviorDTO {
    // 输入特征
    private Integer purchaseCount;    // 历史购买次数
    private Double totalAmount;       // 累计消费金额
    private Integer lastPurchaseDays; // 最近购买距今天数
    private Integer browseTimes;      // 近30天浏览次数
    private Integer collectCount;     // 收藏商品数

    // 输出结果(预测后赋值)
    private Double repurchaseProb;    // 复购概率(0-1)
    private String repurchaseResult;  // 复购结果(高概率/低概率)
}

5. 数据标准化工具类:DataNormalizerUtil.java

package com.ecommerce.dl4j.util;

import org.nd4j.linalg.dataset.api.preprocessor.DataNormalization;
import org.nd4j.linalg.dataset.api.preprocessor.NormalizerStandardize;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.springframework.stereotype.Component;

/**
 * 数据标准化工具类
 * 核心概念:标准化(Normalization)
 * 作用:将不同范围的特征(如金额1000+、次数10+)缩放到同一范围(均值0,方差1)
 * 为什么需要:DL4J模型对数值范围敏感,不标准化会导致训练失效
 */
@Component
public class DataNormalizerUtil {

    // 标准化器(全局唯一)
    private final NormalizerStandardize normalizer = new NormalizerStandardize();

    /**
     * 初始化标准化器(用训练数据拟合)
     * @param trainData 训练数据矩阵
     */
    public void fit(INDArray trainData) {
        normalizer.fit(trainData);
        System.out.println("===== 数据标准化器初始化完成 =====");
    }

    /**
     * 对数据进行标准化转换
     * @param data 原始数据
     * @return 标准化后的数据
     */
    public INDArray transform(INDArray data) {
        INDArray normalizedData = data.dup(); // 复制避免修改原数据
        normalizer.transform(normalizedData);
        return normalizedData;
    }
}

6. 服务接口:UserRepurchaseService.java

package com.ecommerce.dl4j.service;

import com.ecommerce.dl4j.model.UserBehaviorDTO;

/**
 * 复购预测服务接口
 * 核心功能:
 * 1. 训练模型(模拟电商用户数据)
 * 2. 预测用户复购概率
 */
public interface UserRepurchaseService {

    /**
     * 初始化训练模型(项目启动时执行)
     */
    void trainModel();

    /**
     * 预测单个用户的复购概率
     * @param userBehavior 用户行为数据
     * @return 包含预测结果的UserBehaviorDTO
     */
    UserBehaviorDTO predictRepurchase(UserBehaviorDTO userBehavior);
}

7. 服务实现类:UserRepurchaseServiceImpl.java(核心业务逻辑)

package com.ecommerce.dl4j.service.impl;

import com.ecommerce.dl4j.config.Dl4jModelConfig;
import com.ecommerce.dl4j.model.UserBehaviorDTO;
import com.ecommerce.dl4j.service.UserRepurchaseService;
import com.ecommerce.dl4j.util.DataNormalizerUtil;
import org.apache.commons.math3.random.RandomDataGenerator;
import org.deeplearning4j.datasets.iterator.impl.ListDataSetIterator;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.nd4j.linalg.dataset.DataSet;
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 复购预测服务实现
 * 核心概念落地:
 * 1. DataSet:DL4J数据格式(特征+标签)
 * 2. DataSetIterator:数据迭代器(批量喂数据)
 * 3. model.fit():模型训练(学习规律)
 * 4. model.output():模型预测(输出概率)
 */
@Service
public class UserRepurchaseServiceImpl implements UserRepurchaseService {

    // 核心参数
    private static final int DATA_SIZE = 1000;    // 模拟电商用户数据量
    private static final int BATCH_SIZE = 32;     // 批次大小
    private static final int EPOCHS = 50;        // 训练轮数
    private static final int INPUT_FEATURES = 5;  // 输入特征数
    private static final double THRESHOLD = 0.5;  // 复购概率阈值(>0.5=高概率)

    // 注入DL4J模型和工具类
    @Autowired
    private MultiLayerNetwork repurchasePredictModel;
    @Autowired
    private DataNormalizerUtil dataNormalizerUtil;

    /**
     * 项目启动后自动训练模型(PostConstruct:初始化完成后执行)
     */
    @PostConstruct
    @Override
    public void trainModel() {
        try {
            System.out.println("===== 开始训练电商用户复购预测模型 =====");

            // 步骤1:模拟电商用户行为数据(真实场景从数据库读取)
            Random random = new Random(42);
            RandomDataGenerator randomData = new RandomDataGenerator();
            randomData.reSeed(42);

            // 存储特征(用户行为)和标签(是否复购)
            List<double[]> featuresList = new ArrayList<>();
            List<double[]> labelsList = new ArrayList<>();

            for (int i = 0; i < DATA_SIZE; i++) {
                // 生成5个用户行为特征(模拟真实电商数据)
                int purchaseCount = random.nextInt(20) + 1;          // 购买次数:1-20次
                double totalAmount = random.nextDouble() * 10000;    // 消费金额:0-10000元
                int lastPurchaseDays = random.nextInt(60);           // 最近购买:0-60天
                int browseTimes = random.nextInt(100);               // 浏览次数:0-100次
                int collectCount = random.nextInt(30);               // 收藏数:0-30个

                // 生成标签(是否复购:1=是,0=否)—— 模拟真实业务规律
                // 规律:购买次数多、消费金额高、最近购买天数少 → 复购概率高
                double repurchaseProb = 0.1 +
                        (purchaseCount / 20.0) * 0.3 +    // 购买次数占30%权重
                        (totalAmount / 10000.0) * 0.2 +   // 消费金额占20%权重
                        (1 - lastPurchaseDays / 60.0) * 0.25 +  // 最近购买占25%权重
                        (browseTimes / 100.0) * 0.15 +   // 浏览次数占15%权重
                        (collectCount / 30.0) * 0.1;     // 收藏数占10%权重

                // 二值化标签(>0.5=复购)
                int isRepurchase = repurchaseProb > 0.5 ? 1 : 0;

                // 添加到列表
                featuresList.add(new double[]{purchaseCount, totalAmount, lastPurchaseDays, browseTimes, collectCount});
                labelsList.add(new double[]{isRepurchase});
            }

            // 步骤2:转换为DL4J的DataSet格式(核心:模型能识别的格式)
            INDArray features = Nd4j.create(featuresList);
            INDArray labels = Nd4j.create(labelsList);
            DataSet allData = new DataSet(features, labels);

            // 步骤3:数据标准化(核心:避免数值范围差异导致训练失效)
            dataNormalizerUtil.fit(features); // 拟合训练数据
            INDArray normalizedFeatures = dataNormalizerUtil.transform(features);
            DataSet normalizedData = new DataSet(normalizedFeatures, labels);

            // 步骤4:拆分训练集(80%)和测试集(20%)
            normalizedData.shuffle(42);
            DataSet trainData = normalizedData.splitTestAndTrain(0.8).getTrain();
            DataSet testData = normalizedData.splitTestAndTrain(0.8).getTest();

            // 步骤5:转换为迭代器(DL4J训练标准格式)
            DataSetIterator trainIterator = new ListDataSetIterator<>(trainData.asList(), BATCH_SIZE);
            DataSetIterator testIterator = new ListDataSetIterator<>(testData.asList(), BATCH_SIZE);

            // 步骤6:训练模型(核心:model.fit())
            for (int i = 0; i < EPOCHS; i++) {
                repurchasePredictModel.fit(trainIterator);

                // 每10轮打印训练损失(损失越小,模型越准)
                if ((i + 1) % 10 == 0) {
                    double trainLoss = repurchasePredictModel.evaluate(trainIterator).averageLoss();
                    System.out.println("第" + (i + 1) + "轮训练 → 损失值:" + String.format("%.4f", trainLoss));
                    trainIterator.reset(); // 重置迭代器
                }
            }

            // 步骤7:评估模型(测试集验证)
            double testLoss = repurchasePredictModel.evaluate(testIterator).averageLoss();
            double testAccuracy = repurchasePredictModel.evaluate(testIterator).accuracy();
            System.out.println("===== 模型训练完成 =====");
            System.out.println("测试集损失值:" + String.format("%.4f", testLoss));
            System.out.println("测试集准确率:" + String.format("%.2f%%", testAccuracy * 100));

        } catch (Exception e) {
            System.err.println("模型训练失败:" + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 预测用户复购概率(核心接口方法)
     * @param userBehavior 用户行为DTO
     * @return 包含预测结果的DTO
     */
    @Override
    public UserBehaviorDTO predictRepurchase(UserBehaviorDTO userBehavior) {
        try {
            // 步骤1:将DTO转换为特征数组
            double[] features = new double[]{
                    userBehavior.getPurchaseCount(),
                    userBehavior.getTotalAmount(),
                    userBehavior.getLastPurchaseDays(),
                    userBehavior.getBrowseTimes(),
                    userBehavior.getCollectCount()
            };

            // 步骤2:转换为INDArray并标准化
            INDArray featureArray = Nd4j.create(new double[][]{features});
            INDArray normalizedFeature = dataNormalizerUtil.transform(featureArray);

            // 步骤3:模型预测(核心:output()方法输出概率)
            INDArray predictResult = repurchasePredictModel.output(normalizedFeature);
            double repurchaseProb = predictResult.getDouble(0);

            // 步骤4:封装结果
            userBehavior.setRepurchaseProb(repurchaseProb);
            userBehavior.setRepurchaseResult(repurchaseProb > THRESHOLD ? "高概率复购" : "低概率复购");

            return userBehavior;

        } catch (Exception e) {
            System.err.println("预测失败:" + e.getMessage());
            userBehavior.setRepurchaseResult("预测失败");
            return userBehavior;
        }
    }
}

8. 控制器:UserRepurchaseController.java(REST接口)

package com.ecommerce.dl4j.controller;

import com.ecommerce.dl4j.model.UserBehaviorDTO;
import com.ecommerce.dl4j.service.UserRepurchaseService;
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;

/**
 * 复购预测接口控制器
 * 提供RESTful接口,小白可通过Postman调用测试
 */
@RestController
@RequestMapping("/api/repurchase")
public class UserRepurchaseController {

    @Autowired
    private UserRepurchaseService userRepurchaseService;

    /**
     * 预测用户复购概率接口
     * 请求示例(JSON):
     * {
     *   "purchaseCount": 15,
     *   "totalAmount": 8000.0,
     *   "lastPurchaseDays": 5,
     *   "browseTimes": 80,
     *   "collectCount": 20
     * }
     * @param userBehavior 用户行为数据
     * @return 预测结果
     */
    @PostMapping("/predict")
    public UserBehaviorDTO predictRepurchase(@RequestBody UserBehaviorDTO userBehavior) {
        System.out.println("===== 接收复购预测请求 =====");
        return userRepurchaseService.predictRepurchase(userBehavior);
    }
}

9. application.properties(空配置,仅占位)

# 服务器端口
server.port=8080
# 日志级别(方便调试)
logging.level.com.ecommerce.dl4j=INFO

四、运行与测试步骤(小白手把手)

步骤1:环境准备

  1. 安装JDK17(验证:java -version 显示17+);
  2. 安装Maven(验证:mvn -v 正常输出);
  3. 用IDEA/Eclipse导入Maven项目(自动下载依赖,首次需5-10分钟)。

步骤2:启动项目

  1. 运行 Dl4jEcommerceDemoApplication.java 的main方法;
  2. 控制台输出如下,说明启动成功:
    ===== DL4J复购预测模型初始化完成 =====
    ===== 开始训练电商用户复购预测模型 =====
    第10轮训练 → 损失值:0.3256
    第20轮训练 → 损失值:0.2145
    第30轮训练 → 损失值:0.1567
    第40轮训练 → 损失值:0.1234
    第50轮训练 → 损失值:0.0987
    ===== 模型训练完成 =====
    测试集损失值:0.1056
    测试集准确率:88.50%
    ===== 电商用户复购预测服务启动成功 =====
    访问地址:http://localhost:8080/api/repurchase/predict
    

步骤3:接口测试(Postman/Curl)

请求地址

POST http://localhost:8080/api/repurchase/predict

请求体(JSON)
{
  "purchaseCount": 15,
  "totalAmount": 8000.0,
  "lastPurchaseDays": 5,
  "browseTimes": 80,
  "collectCount": 20
}
响应结果(小白易懂)
{
  "purchaseCount": 15,
  "totalAmount": 8000.0,
  "lastPurchaseDays": 5,
  "browseTimes": 80,
  "collectCount": 20,
  "repurchaseProb": 0.89,
  "repurchaseResult": "高概率复购"
}

五、核心概念在案例中的体现(小白必看)

DL4J核心概念 案例中的具体落地 大白话解释
DataSet 模拟的用户行为数据(特征+标签) 模型能理解的“数据表格”
Normalization DataNormalizerUtil标准化 把“金额(8000)、次数(15)”缩到同一范围
MultiLayerNetwork repurchasePredictModel 复购预测的“核心模型”(学习规律的主体)
DenseLayer 隐藏层1/2(32/16神经元) 提取用户行为特征的“功能模块”
OutputLayer Sigmoid激活的输出层 输出0-1复购概率的“结果模块”
Optimizer(Adam) 学习率0.001的Adam优化器 自动调整模型参数的“规则”
LossFunction(BINARY_CROSSENTROPY) 二分类损失函数 衡量模型预测准不准的“打分标准”
Epoch(50轮) model.fit()循环50次 把训练数据看50遍,让模型学透规律
BatchSize(32) 每次喂32条数据 一次学32个用户的行为,效率更高

六、案例扩展(小白进阶)

  1. 替换真实数据:把模拟数据换成电商数据库中的用户行为数据(MySQL/Oracle);
  2. 优化模型:调整隐藏层神经元数(如64/32)、训练轮数(如100),观察准确率变化;
  3. 添加日志:记录预测结果到数据库,分析模型效果;
  4. 部署上线:打包为Jar包(mvn clean package),部署到服务器运行。
Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐