本文目录导读:

我来给你一个完整的Java历史大数据建模预测案例,从数据准备到模型部署的全流程。
整体架构设计
// 核心架构组件
public class PredictionSystem {
private DataLoader dataLoader;
private FeatureEngineering featureEngineer;
private ModelTrainer modelTrainer;
private ModelEvaluator modelEvaluator;
private PredictionService predictionService;
}
完整实现示例(以销售预测为例)
数据准备模块
import org.apache.spark.sql.*;
import org.apache.spark.sql.types.*;
public class DataLoader {
// 加载历史销售数据
public Dataset<Row> loadHistoricalData(String filePath) {
SparkSession spark = SparkSession.builder()
.appName("SalesPrediction")
.master("local[*]")
.getOrCreate();
// 定义数据结构
StructType schema = new StructType()
.add("date", DataTypes.DateType)
.add("product_id", DataTypes.StringType)
.add("category", DataTypes.StringType)
.add("price", DataTypes.DoubleType)
.add("quantity", DataTypes.IntegerType)
.add("sales_amount", DataTypes.DoubleType)
.add("customer_rating", DataTypes.DoubleType)
.add("promotion_flag", DataTypes.BooleanType);
// 读取CSV数据
Dataset<Row> df = spark.read()
.option("header", "true")
.schema(schema)
.csv(filePath);
// 数据清洗
df = cleanData(df);
return df;
}
private Dataset<Row> cleanData(Dataset<Row> df) {
// 处理缺失值
df = df.na().fill(0);
// 去除异常值
df = df.filter(col("sales_amount").gt(0));
// 去重
df = df.dropDuplicates();
return df;
}
}
特征工程模块
import org.apache.spark.ml.feature.*;
import org.apache.spark.sql.expressions.Window;
import static org.apache.spark.sql.functions.*;
public class FeatureEngineering {
public Dataset<Row> createFeatures(Dataset<Row> df) {
Dataset<Row> featured = df;
// 1. 时间特征
featured = featured
.withColumn("year", year(col("date")))
.withColumn("month", month(col("date")))
.withColumn("day", dayofmonth(col("date")))
.withColumn("weekday", dayofweek(col("date")))
.withColumn("is_weekend",
when(col("weekday").isin(1, 7), 1).otherwise(0));
// 2. 滞后特征(历史销量)
WindowSpec windowSpec = Window
.partitionBy("product_id")
.orderBy("date")
.rowsBetween(-7, -1);
featured = featured
.withColumn("lag_7_sales",
avg("sales_amount").over(windowSpec))
.withColumn("lag_7_quantity",
sum("quantity").over(windowSpec));
// 3. 滚动统计特征
WindowSpec rollingWindow = Window
.partitionBy("product_id")
.orderBy("date")
.rowsBetween(-30, -1);
featured = featured
.withColumn("30d_avg_sales",
avg("sales_amount").over(rollingWindow))
.withColumn("30d_max_sales",
max("sales_amount").over(rollingWindow))
.withColumn("30d_std_sales",
stddev("sales_amount").over(rollingWindow));
// 4. 商品特征编码
StringIndexer indexer = new StringIndexer()
.setInputCol("category")
.setOutputCol("category_index");
featured = indexer.fit(featured).transform(featured);
// 5. One-Hot编码
OneHotEncoder encoder = new OneHotEncoder()
.setInputCol("category_index")
.setOutputCol("category_encoded");
featured = encoder.fit(featured).transform(featured);
return featured;
}
}
模型训练和预测模块
import org.apache.spark.ml.Pipeline;
import org.apache.spark.ml.PipelineModel;
import org.apache.spark.ml.evaluation.RegressionEvaluator;
import org.apache.spark.ml.feature.VectorAssembler;
import org.apache.spark.ml.tuning.*;
import org.apache.spark.ml.regression.*;
public class SalesPredictionModel {
private PipelineModel model;
// 训练模型
public void trainModel(Dataset<Row> trainingData) {
// 特征列
String[] featureColumns = {
"year", "month", "day", "weekday",
"is_weekend", "price", "lag_7_sales",
"lag_7_quantity", "30d_avg_sales",
"30d_max_sales", "30d_std_sales",
"category_encoded"
};
// 组装特征向量
VectorAssembler assembler = new VectorAssembler()
.setInputCols(featureColumns)
.setOutputCol("features");
// 选择多个模型进行对比
// 方案1: 随机森林回归
RandomForestRegressor rf = new RandomForestRegressor()
.setLabelCol("sales_amount")
.setFeaturesCol("features")
.setNumTrees(100)
.setMaxDepth(10);
// 方案2: 梯度提升回归
GBTRegressor gbt = new GBTRegressor()
.setLabelCol("sales_amount")
.setFeaturesCol("features")
.setMaxIter(100)
.setMaxDepth(5);
// 方案3: 线性回归
LinearRegression lr = new LinearRegression()
.setLabelCol("sales_amount")
.setFeaturesCol("features");
// 创建Pipeline
Pipeline pipeline = new Pipeline().setStages(
new PipelineStage[]{assembler, rf});
// 使用交叉验证调优
CrossValidator cv = createCrossValidator(pipeline,
trainingData.count() > 50000 ? trainingData.sample(0.3) : trainingData);
CrossValidatorModel cvModel = cv.fit(trainingData);
this.model = cvModel.bestModel();
// 评估模型
Evaluator evaluator = new Evaluator();
Map<String, Double> metrics = evaluator.evaluateModel(
cvModel.bestModel(), trainingData);
System.out.println("Model Metrics: " + metrics);
}
private CrossValidator createCrossValidator(Pipeline pipeline, Dataset<Row> data) {
// 参数网格
ParamGridBuilder gridBuilder = new ParamGridBuilder();
// 不同模型的参数搜索空间
for (Param<?> param : pipeline.getStages())
if (param instanceof RandomForestRegressor) {
RandomForestRegressor rf = (RandomForestRegressor) param;
gridBuilder = gridBuilder
.addGrid(rf.numTrees(), new int[]{50, 100, 150})
.addGrid(rf.maxDepth(), new int[]{5, 10, 15});
} else if (param instanceof GBTRegressor) {
GBTRegressor gbt = (GBTRegressor) param;
gridBuilder = gridBuilder
.addGrid(gbt.maxIter(), new int[]{50, 100})
.addGrid(gbt.maxDepth(), new int[]{3, 5});
}
Param[] paramGrid = gridBuilder.build();
// 评估器
RegressionEvaluator evaluator = new RegressionEvaluator()
.setLabelCol("sales_amount")
.setPredictionCol("prediction")
.setMetricName("rmse");
// 创建交叉验证器
return new CrossValidator()
.setEstimator(pipeline)
.setEvaluator(evaluator)
.setEstimatorParamMaps(paramGrid)
.setNumFolds(5)
.setParallelism(4);
}
// 预测新数据
public double predict(Dataset<Row> newData) {
if (model == null) {
throw new IllegalStateException("Model not trained yet!");
}
Dataset<Row> predictions = model.transform(newData);
// 返回预测结果
return predictions.first().getDouble(
predictions.schema().fieldIndex("prediction"));
}
// 批量预测
public Dataset<Row> batchPredict(Dataset<Row> newData) {
return model.transform(newData);
}
}
模型评估模块
public class ModelEvaluator {
public void evaluateModel(PipelineModel model, Dataset<Row> testData) {
// 预测
Dataset<Row> predictions = model.transform(testData);
// 计算多个指标
double rmse = calculateRMSE(predictions);
double mae = calculateMAE(predictions);
double r2 = calculateR2(predictions);
double mape = calculateMAPE(predictions);
System.out.println("=== Model Evaluation Metrics ===");
System.out.println("RMSE: " + rmse);
System.out.println("MAE: " + mae);
System.out.println("R² Score: " + r2);
System.out.println("MAPE: " + mape + "%");
// 绘制残差分析
plotResiduals(predictions);
}
private double calculateRMSE(Dataset<Row> predictions) {
double sumSquared = predictions
.selectExpr("(prediction - sales_amount) * (prediction - sales_amount) as squared_error")
.agg("squared_error" -> "sum")
.first().getDouble(0);
long count = predictions.count();
return Math.sqrt(sumSquared / count);
}
private double calculateMAPE(Dataset<Row> predictions) {
// 避免除零
Dataset<Row> filtered = predictions.filter(col("sales_amount").gt(0));
double sumMAPE = filtered
.selectExpr("ABS((prediction - sales_amount) / sales_amount) * 100 as mape")
.agg("mape" -> "sum")
.first().getDouble(0);
long count = filtered.count();
return sumMAPE / count;
}
}
主程序入口
public class MainApplication {
public static void main(String[] args) throws Exception {
// 1. 加载数据
DataLoader loader = new DataLoader();
Dataset<Row> historicalData = loader.loadHistoricalData(
"historical_sales_data.csv");
// 2. 特征工程
FeatureEngineering fe = new FeatureEngineering();
Dataset<Row> featuredData = fe.createFeatures(historicalData);
// 3. 数据划分
Dataset<Row>[] splits = featuredData.randomSplit(
new double[]{0.8, 0.2}, 12345);
Dataset<Row> trainingData = splits[0];
Dataset<Row> testData = splits[1];
// 4. 训练模型
SalesPredictionModel model = new SalesPredictionModel();
model.trainModel(trainingData);
// 5. 评估模型
ModelEvaluator evaluator = new ModelEvaluator();
evaluator.evaluateModel(model.getBestModel(), testData);
// 6. 预测未来销售
Dataset<Row> futureData = prepareFutureData();
Dataset<Row> predictions = model.batchPredict(futureData);
// 7. 输出预测结果
predictions.show();
// 8. 保存模型
model.saveModel("path/to/save/model");
}
}
高级预测技术
时间序列预测(使用Prophet)
import com.facebook.swift.reflect.annotations.Prophet;
import org.apache.spark.sql.DataFrameReader;
import com.facebook.swift.reflect.annotations.ProphetParameters;
public class TimeSeriesPrediction {
public Dataset<Row> predictWithProphet(Dataset<Row> history) {
// Prophet模型
Prophet prophet = Prophet.builder()
.setUri("http://localhost:8080")
.setModelName("sales_forecast")
.build();
prophet.setGrowth("linear");
prophet.setChangepointPriorScale(0.5);
prophet.setWeeklySeasonality(7);
prophet.setYearlySeasonality(12);
// 添加先验知识
prophet.addSeasonalityParameters(
ProphetParameters.seasonality()
.name("promotion")
.period(30)
.fourierOrder(3)
.priorScale(10.0)
.build()
);
// 训练和预测
return prophet.fit(history).predict();
}
}
深度学习预测(使用Deeplearning4j或TensorFlow)
public class DeepLearningPrediction {
public MultiLayerNetwork createLSTMModel(int inputSize, int hiddenSize) {
MultiLayerConfiguration config = new NeuralNetConfiguration.Builder()
.seed(123)
.weightInit(WeightInit.XAVIER)
.updater(new Adam(0.001))
.list()
.layer(0, new GravesLSTM.Builder()
.nIn(inputSize)
.nOut(hiddenSize)
.activation(Activation.TANH)
.build())
.layer(1, new GravesLSTM.Builder()
.nIn(hiddenSize)
.nOut(hiddenSize)
.activation(Activation.TANH)
.build())
.layer(2, new DenseLayer.Builder()
.nIn(hiddenSize)
.nOut(1)
.activation(Activation.IDENTITY)
.build())
.build();
return new MultiLayerNetwork(config);
}
}
部署与实时预测
public class PredictionService {
private PipelineModel model;
public PredictionService(String modelPath) {
this.model = PipelineModel.load(modelPath);
}
// REST API接口
@RestController
public class PredictionController {
@PostMapping("/predict")
public ApiResponse predict(@RequestBody PredictionRequest request) {
try {
// 构建特征
Dataset<Row> featureData = buildFeatureData(request);
// 预测
Dataset<Row> prediction = model.transform(featureData);
// 返回结果
return Response.ok(prediction).build();
} catch (Exception e) {
return Response.error(e.getMessage());
}
}
// 批量预测接口
@PostMapping("/predict/batch")
public ApiResponse predictBatch(@RequestBody BatchPredictionRequest request) {
List<PredictionResult> results = new ArrayList<>();
for (PredictionData data : request.getData()) {
PredictionResult result = predictSingle(data);
results.add(result);
}
return Response.ok(results).build();
}
}
// Stream实时预测
public void streamPrediction(StreamingQuery stream) {
// 使用Spark Streaming或Flink
StreamingQuery query = stream
.writeStream()
.outputMode("append")
.foreachBatch((batchDF, id) -> {
Dataset<Row> predictions = model.transform(batchDF);
savePredictions(predictions);
})
.start();
}
}
关键优化建议
- 数据质量:确保数据清洗和特征工程的准确性
- 模型选择:根据业务场景选择适合的模型
- 参数调优:使用网格搜索和交叉验证
- 性能优化:使用Spark的并行处理能力
- 模型监控:定期更新和再训练模型
应用场景
- 销售预测
- 库存管理
- 客户流失预测
- 异常检测
- 风险评估
这个完整案例覆盖了从数据准备到模型部署的全生命周期,你可以根据实际业务需求进行调整和扩展。