我来为您提供一个Java指标预测的完整案例,使用简单的线性回归算法来预测数据趋势。

案例:销售数据预测系统
线性回归预测模型
import java.util.ArrayList;
import java.util.List;
public class LinearRegressionPredictor {
private double slope; // 斜率
private double intercept; // 截距
private double[] xValues;
private double[] yValues;
/**
* 训练线性回归模型
* @param x X轴数据(时间/序列)
* @param y Y轴数据(指标值)
*/
public void train(double[] x, double[] y) {
if (x.length != y.length || x.length < 2) {
throw new IllegalArgumentException("数据长度不足或数据不匹配");
}
this.xValues = x;
this.yValues = y;
int n = x.length;
double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
for (int i = 0; i < n; i++) {
sumX += x[i];
sumY += y[i];
sumXY += x[i] * y[i];
sumX2 += x[i] * x[i];
}
// 计算斜率和截距
slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
intercept = (sumY - slope * sumX) / n;
System.out.println("模型训练完成:");
System.out.printf("斜率: %.4f, 截距: %.4f\n", slope, intercept);
}
/**
* 预测未来值
* @param futureX 未来的X值
* @return 预测的Y值
*/
public double predict(double futureX) {
return slope * futureX + intercept;
}
/**
* 批量预测未来多个值
* @param futureSteps 预测步数
* @return 预测值数组
*/
public double[] predictFuture(int futureSteps) {
double[] predictions = new double[futureSteps];
double lastX = xValues[xValues.length - 1];
for (int i = 0; i < futureSteps; i++) {
predictions[i] = predict(lastX + i + 1);
}
return predictions;
}
/**
* 计算R平方(拟合优度)
*/
public double calculateR2() {
double meanY = 0;
for (double y : yValues) {
meanY += y;
}
meanY /= yValues.length;
double ssRes = 0, ssTot = 0;
for (int i = 0; i < yValues.length; i++) {
double predicted = predict(xValues[i]);
ssRes += Math.pow(yValues[i] - predicted, 2);
ssTot += Math.pow(yValues[i] - meanY, 2);
}
return 1 - (ssRes / ssTot);
}
}
时间序列数据处理器
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.*;
public class TimeSeriesProcessor {
private List<DataPoint> dataPoints;
public TimeSeriesProcessor() {
this.dataPoints = new ArrayList<>();
}
/**
* 添加数据点
*/
public void addDataPoint(LocalDate date, double value) {
dataPoints.add(new DataPoint(date, value));
}
/**
* 将日期转换为数值序列
*/
public double[] convertToNumericArray() {
double[] numericValues = new double[dataPoints.size()];
LocalDate startDate = dataPoints.get(0).getDate();
for (int i = 0; i < dataPoints.size(); i++) {
long daysDiff = ChronoUnit.DAYS.between(startDate, dataPoints.get(i).getDate());
numericValues[i] = daysDiff;
}
return numericValues;
}
/**
* 获取指标值数组
*/
public double[] getValueArray() {
return dataPoints.stream()
.mapToDouble(DataPoint::getValue)
.toArray();
}
/**
* 数据平滑处理(移动平均)
*/
public double[] movingAverage(int windowSize) {
double[] values = getValueArray();
double[] smoothed = new double[values.length - windowSize + 1];
for (int i = 0; i < smoothed.length; i++) {
double sum = 0;
for (int j = 0; j < windowSize; j++) {
sum += values[i + j];
}
smoothed[i] = sum / windowSize;
}
return smoothed;
}
// 数据点内部类
private static class DataPoint {
private LocalDate date;
private double value;
public DataPoint(LocalDate date, double value) {
this.date = date;
this.value = value;
}
public LocalDate getDate() { return date; }
public double getValue() { return value; }
}
}
异常检测和预警系统
import java.util.*;
public class AnomalyDetectionSystem {
private LinearRegressionPredictor predictor;
private double threshold;
public AnomalyDetectionSystem(double threshold) {
this.predictor = new LinearRegressionPredictor();
this.threshold = threshold;
}
/**
* 检测异常值
*/
public List<AnomalyResult> detectAnomalies(double[] x, double[] y) {
List<AnomalyResult> anomalies = new ArrayList<>();
predictor.train(x, y);
double[] residuals = new double[y.length];
double meanResidual = 0;
// 计算残差
for (int i = 0; i < y.length; i++) {
double predicted = predictor.predict(x[i]);
residuals[i] = Math.abs(y[i] - predicted);
meanResidual += residuals[i];
}
meanResidual /= y.length;
// 检测异常
for (int i = 0; i < y.length; i++) {
if (residuals[i] > threshold * meanResidual) {
anomalies.add(new AnomalyResult(
x[i], y[i], predictor.predict(x[i]),
"异常值检测", residuals[i]
));
}
}
return anomalies;
}
/**
* 生成预警报告
*/
public String generateAlertReport(List<AnomalyResult> anomalies) {
StringBuilder report = new StringBuilder();
report.append("=== 异常预警报告 ===\n");
report.append("检测时间: ").append(new Date()).append("\n\n");
if (anomalies.isEmpty()) {
report.append("状态: 正常,未检测到异常\n");
} else {
report.append("检测到 ").append(anomalies.size()).append(" 个异常点:\n");
for (AnomalyResult anomaly : anomalies) {
report.append(anomaly.toString()).append("\n");
}
}
return report.toString();
}
// 异常结果内部类
public static class AnomalyResult {
private double x;
private double actualValue;
private double predictedValue;
private String reason;
private double deviation;
public AnomalyResult(double x, double actual, double predicted,
String reason, double deviation) {
this.x = x;
this.actualValue = actual;
this.predictedValue = predicted;
this.reason = reason;
this.deviation = deviation;
}
@Override
public String toString() {
return String.format("x=%.0f: 实际值=%.2f, 预测值=%.2f, 偏差=%.2f, 原因=%s",
x, actualValue, predictedValue, deviation, reason);
}
}
}
完整示例:销售预测系统
import java.time.LocalDate;
import java.util.*;
public class SalesPredictionSystem {
public static void main(String[] args) {
// 创建时间序列处理器
TimeSeriesProcessor processor = new TimeSeriesProcessor();
// 模拟历史销售数据(过去12个月)
System.out.println("=== 销售数据 ===");
LocalDate startDate = LocalDate.of(2023, 1, 1);
double[] salesData = {100, 110, 120, 115, 130, 140,
135, 145, 155, 150, 160, 170};
for (int i = 0; i < salesData.length; i++) {
LocalDate date = startDate.plusMonths(i);
processor.addDataPoint(date, salesData[i]);
System.out.printf("月份: %s, 销售额: %.0f\n", date, salesData[i]);
}
// 训练预测模型
System.out.println("\n=== 模型训练 ===");
LinearRegressionPredictor predictor = new LinearRegressionPredictor();
double[] xValues = processor.convertToNumericArray();
double[] yValues = processor.getValueArray();
predictor.train(xValues, yValues);
// 计算R平方值
double r2 = predictor.calculateR2();
System.out.printf("R平方值(拟合优度): %.4f\n", r2);
// 预测未来3个月
System.out.println("\n=== 预测未来3个月 ===");
double[] futurePredictions = predictor.predictFuture(3);
for (int i = 0; i < futurePredictions.length; i++) {
LocalDate futureDate = startDate.plusMonths(salesData.length + i);
System.out.printf("预测月份: %s, 预测销售额: %.0f\n",
futureDate, futurePredictions[i]);
}
// 异常检测
System.out.println("\n=== 异常检测 ===");
AnomalyDetectionSystem detectionSystem = new AnomalyDetectionSystem(2.0);
List<AnomalyDetectionSystem.AnomalyResult> anomalies =
detectionSystem.detectAnomalies(xValues, yValues);
System.out.println(detectionSystem.generateAlertReport(anomalies));
// 数据平滑处理
System.out.println("=== 3个月移动平均 ===");
double[] smoothedData = processor.movingAverage(3);
System.out.println("平滑后的数据: " + Arrays.toString(smoothedData));
// 趋势分析报告
System.out.println("\n=== 趋势分析报告 ===");
generateTrendReport(predictor, salesData, r2);
}
/**
* 生成趋势分析报告
*/
private static void generateTrendReport(LinearRegressionPredictor predictor,
double[] historicalData, double r2) {
System.out.println("销售趋势分析:");
System.out.printf("模型斜率为 %.2f,表示每月平均增长 ", predictor.getSlope());
System.out.printf("从 %.0f 开始基准线", predictor.getIntercept());
if (predictor.getSlope() > 0) {
System.out.println("\n趋势: 上升趋势 ↑");
} else if (predictor.getSlope() < 0) {
System.out.println("\n趋势: 下降趋势 ↓");
} else {
System.out.println("\n趋势: 稳定趋势 →");
}
if (r2 > 0.8) {
System.out.println("模型预测准确性: 高 (R² > 0.8)");
} else if (r2 > 0.6) {
System.out.println("模型预测准确性: 中等 (R² > 0.6)");
} else {
System.out.println("模型预测准确性: 低 (R² < 0.6)");
}
}
}
使用说明和扩展建议
## 使用说明 1. **数据准备**:将您的指标数据按时间顺序输入 2. **模型训练**:调用 `train()` 方法训练模型 3. **预测未来**:使用 `predict()` 或 `predictFuture()` 方法 4. **异常检测**:自动检测数据中的异常值 5. **结果分析**:通过 R² 值评估预测可靠性 ## 扩展方向 1. **添加更多算法**: - 多项式回归 - 指数平滑 - ARIMA 时间序列模型 2. **数据可视化**: - 集成 JFreeChart 或 JavaFX - 生成趋势图表 3. **数据库支持**: - 从数据库读取历史数据 - 存储预测结果 4. **Web接口**: - 使用 Spring Boot 创建 REST API - 提供预测服务
这个完整的指标预测系统包括了数据预处理、线性回归预测、异常检测和趋势分析功能,可以直接用于销售、库存、流量等各种业务指标的预测场景。