Java 案例:利用历史大数据建模预测
下面我用一个完整可运行的 Java 案例,演示如何从历史大数据中建模并进行预测,案例选用电商场景:基于历史订单数据预测未来销量。

整体流程
历史数据 → 数据清洗 → 特征工程 → 模型训练 → 模型评估 → 在线预测
↓ ↓ ↓ ↓ ↓ ↓
CSV/DB 过滤缺失值 构建特征 线性回归/时序 RMSE 输入新特征
技术选型
| 环节 | 工具 |
|---|---|
| 大数据存储 | HDFS / Hive / MySQL |
| 数据处理 | Spark / Flink / Java Stream |
| 建模库 | Smile、Weka、DL4J、Tribuo(Java 原生) |
| 部署 | Spring Boot + 模型序列化 |
本例用 Smile(Java 生态最成熟的机器学习库)+ Spark(大数据处理)。
完整代码案例
Maven 依赖
<dependency>
<groupId>com.github.haifengl</groupId>
<artifactId>smile-core</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.12</artifactId>
<version>3.5.0</version>
</dependency>
历史数据结构
假设历史订单数据 sales_history.csv:
date,productId,price,holiday,sales
2024-01-01,1001,99.0,1,320
2024-01-02,1001,99.0,0,280
2024-01-03,1001,89.0,0,410
...
数据加载与特征工程
import smile.data.DataFrame;
import smile.io.Read;
public class DataLoader {
public static DataFrame load(String path) throws Exception {
DataFrame df = Read.csv(path);
// 去除缺失值
df = df.dropna();
// 从日期抽取特征(星期、月份)
df = df.stream().map(row -> {
String date = row.getString("date");
int dayOfWeek = java.time.LocalDate.parse(date).getDayOfWeek().getValue();
int month = java.time.LocalDate.parse(date).getMonthValue();
return new Object[]{
row.getInt("productId"),
row.getDouble("price"),
row.getInt("holiday"),
dayOfWeek,
month,
row.getInt("sales") // 目标
};
}).toArray(Object[][]::new);
// 重新封装为 DataFrame 略(示意)
return df;
}
}
使用 Smile 训练线性回归模型
import smile.data.formula.Formula;
import smile.regression.LinearModel;
import smile.regression.OLS;
import smile.data.type.StructType;
import smile.data.DataFrame;
import smile.data.Tuple;
public class SalesPredictor {
public static LinearModel train(DataFrame df) {
// 目标字段:sales;特征:price、holiday、dayOfWeek、month
Formula formula = Formula.lhs("sales");
LinearModel model = OLS.fit(formula, df);
System.out.println(model);
return model;
}
public static double predict(LinearModel model, double price,
int holiday, int dayOfWeek, int month) {
// 构造输入(字段顺序需与训练时一致)
Tuple x = Tuple.of(new Object[]{price, holiday, dayOfWeek, month},
model.schema());
return model.predict(x);
}
}
模型评估(RMSE / R²)
import smile.validation.metric.RMSE;
import smile.validation.metric.R2;
public class Evaluator {
public static void evaluate(LinearModel model, DataFrame test) {
double[] truth = test.column("sales").toDoubleArray();
double[] pred = new double[truth.length];
for (int i = 0; i < truth.length; i++) {
pred[i] = model.predict(test.get(i));
}
System.out.println("RMSE = " + RMSE.of(truth, pred));
System.out.println("R2 = " + R2.of(truth, pred));
}
}
主流程串联
public class MainApp {
public static void main(String[] args) throws Exception {
// 1. 加载历史大数据
DataFrame df = DataLoader.load("hdfs:///data/sales_history.csv");
// 2. 划分训练/测试集
DataFrame[] split = TrainTest.split(df, 0.8);
DataFrame train = split[0], test = split[1];
// 3. 训练
LinearModel model = SalesPredictor.train(train);
// 4. 评估
Evaluator.evaluate(model, test);
// 5. 在线预测
double y = SalesPredictor.predict(model, 89.0, 0, 5, 12);
System.out.println("预测销量:" + y);
// 6. 模型持久化
java.io.ObjectOutputStream oos =
new java.io.ObjectOutputStream(new java.io.FileOutputStream("model.ser"));
oos.writeObject(model);
oos.close();
}
}
如何使用大数据(Spark 预处理)
当历史数据在 TB 级别时,用 Spark 完成 ETL:
SparkSession spark = SparkSession.builder()
.appName("sales-etl").master("yarn").getOrCreate();
Dataset<Row> raw = spark.read().csv("hdfs:///data/sales_history/*.csv");
raw.createOrReplaceTempView("sales");
Dataset<Row> features = spark.sql(
"SELECT productId, price, holiday, " +
" dayofweek(date) AS dow, month(date) AS mon, sales " +
"FROM sales WHERE sales IS NOT NULL"
);
features.write().mode("overwrite")
.parquet("hdfs:///warehouse/sales_features");
将 sales_features 抽样为 Pandas/Smile 可处理的小数据集,再走上面 Java 建模流程。
进阶:更合适的模型
| 场景 | 推荐模型 | Java 实现 |
|---|---|---|
| 线性趋势 | 线性回归 | Smile OLS |
| 非线性 | 随机森林 / GBDT | Smile RandomForest / GradientTreeBoost |
| 时间序列 | ARIMA / Prophet | sfa / 调 Python 服务 |
| 深度学习 | LSTM | DJL / DeepLearning4J |
随机森林示例(只需替换训练器):
import smile.regression.RandomForest; RandomForest model = RandomForest.fit(formula, df);
工程化建议
- 数据分层:ODS → DWD → DWS → ADS,特征落 Hive/Parquet。
- 特征平台:同一份特征既供离线训练也供在线推理,避免线上线下不一致。
- 模型版本管理:MLflow / 自研元数据表存储模型指标、参数、文件路径。
- 在线服务:Spring Boot 加载
model.ser,暴露/predictREST 接口。 - 定时重训:Airflow 每日/每周触发新数据训练,评估过关后灰度上线。
- 监控:QPS、延迟、预测分布漂移(PSI)全监控。
关键代码位置对照
| 阶段 | 类 | 方法 |
|---|---|---|
| 加载 | DataLoader |
load() |
| 训练 | SalesPredictor |
train() |
| 预测 | SalesPredictor |
predict() |
| 评估 | Evaluator |
evaluate() |
| 调度 | MainApp |
main() |
如果你希望我针对你的具体场景(比如金融风控、设备故障预测、用户流失预测)给出更对口的代码,可以告诉我数据字段和目标,我再细化方案。