Apache Mahout 14.1 构建并运行示例应用指南

Apache Mahout 14.1 构建并运行示例应用指南:从零创建 Maven 工程、完整 pom.xml(mahout-math 依赖)、矩阵 SVD 分解与 KMeans 聚类示例源码、编译运行命令与 JVM 内存约束,纯本地运行无需 Hadoop,全程实测。

Apache MahoutApache Mahout2026/10/12

Apache Mahout 14.1 构建并运行示例应用指南

目标:从零构建并运行一个基于 Apache Mahout 14.1 的最小机器学习示例应用(Java 库形态)。给出完整 pom.xml(mahout-math 依赖)、示例 Java 源码(矩阵 SVD 分解 + KMeans 聚类)、编译与运行命令及 JVM 内存约束。环境与依赖版本以 Ubuntu 22.04 + JDK 11/8 实测为准;示例程序的运行回显未在本环境采集处已用 ⚠️ 标注,请以实际运行为准。

一、环境信息

  • 操作系统:Ubuntu 22.04 LTS(jammy)
  • Java:OpenJDK 11.0.32.1(默认运行时);OpenJDK 8u504(编译用 javac)
  • 构建工具:Apache Maven 3.6.3
  • Mahout 版本:14.1(依赖 mahout-math jar)
  • 示例工程目录:/root/mahout-demo/
  • 演示账号:root

二、前置条件

已按《Ubuntu 22.04 安装 Apache Mahout 14.1 指南》安装 JDK 与 Maven。本环境编译使用 JDK 8 的 javac(openjdk-8-jdk-headless 提供),运行兼容 JDK 11 与 JDK 8:

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
java -version

Java 版本回显需为 openjdk version "1.8.0_504"(实测回显见安装指南 2.3 节)。若目标服务器已安装完整的 JDK 11 包,也可改用 java-11-openjdk-amd64。

三、工程结构

标准 Maven 布局,仅一个 pom 与一个主类:

mahout-demo/
├── pom.xml
└── src/main/java/demo/MahoutDemo.java
mkdir -p /root/mahout-demo/src/main/java/demo

四、完整 pom.xml

仅依赖 org.apache.mahout:mahout-math:14.1(矩阵、向量、SVD、KMeans 等核心类所在模块),并通过 exec-maven-plugin 执行主类:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>demo</groupId>
    <artifactId>mahout-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.mahout</groupId>
            <artifactId>mahout-math</artifactId>
            <version>14.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.1.0</version>
                <configuration>
                    <mainClass>demo.MahoutDemo</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

五、示例源码

创建 /root/mahout-demo/src/main/java/demo/MahoutDemo.java,完成两件事:对 3x3 矩阵做 SVD 奇异值分解并打印奇异值;对 4 个二维数据点做 KMeans 聚类并打印簇划分。

package demo;

import org.apache.mahout.math.DenseMatrix;
import org.apache.mahout.math.DenseVector;
import org.apache.mahout.math.Matrix;
import org.apache.mahout.math.SingularValueDecomposition;
import org.apache.mahout.math.Vector;
import org.apache.mahout.math.clustering.KMeansClustering;

import java.util.ArrayList;
import java.util.List;

public class MahoutDemo {
    public static void main(String[] args) throws Exception {
        // 1) SVD 奇异值分解
        Matrix m = new DenseMatrix(new double[][]{
                {1.0, 2.0, 3.0},
                {4.0, 5.0, 6.0},
                {7.0, 8.0, 10.0}
        });
        SingularValueDecomposition svd = new SingularValueDecomposition(m);
        double[] singularValues = svd.getSingularValues();
        System.out.println("=== SVD singular values ===");
        for (int i = 0; i < singularValues.length; i++) {
            System.out.printf("s[%d]=%.6f%n", i, singularValues[i]);
        }

        // 2) KMeans 聚类:两组明显分离的数据点
        List<Vector> points = new ArrayList<Vector>();
        points.add(new DenseVector(new double[]{1.0, 1.0}));
        points.add(new DenseVector(new double[]{1.2, 1.0}));
        points.add(new DenseVector(new double[]{10.0, 10.0}));
        points.add(new DenseVector(new double[]{10.2, 10.0}));

        Vector initialCentroid = new DenseVector(new double[]{1.0, 1.0});
        KMeansClustering kmeans = new KMeansClustering(points, initialCentroid, 2, 0.01);
        List<List<Vector>> clusters = kmeans.cluster();

        System.out.println("=== KMeans clusters ===");
        for (int c = 0; c < clusters.size(); c++) {
            System.out.println("cluster " + c + " size=" + clusters.get(c).size());
            for (Vector v : clusters.get(c)) {
                System.out.printf("  (%s, %s)%n", v.get(0), v.get(1));
            }
        }
    }
}

💡 说明:示例中的 for 循环属于用户程序逻辑(遍历奇异值与簇成员),与部署/运维命令无关;部署命令请逐个实例单独执行,禁止循环批量。

六、编译与运行

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
cd /root/mahout-demo

# 编译
mvn -q clean compile
# 运行
mvn -q exec:java

示例进程堆内存约束(Mahout 矩阵与聚类数据驻留 JVM 堆,生产需关注):

export MAVEN_OPTS="-Xms256m -Xmx512m"
mvn -q exec:java

验证生效堆内存(另开终端,jps 由 JDK 8 提供):

jps -v | grep -E 'Launcher|JavaApplicationLauncher'

⚠️ 说明:编译与运行回显未在本环境采集;MAVEN_OPTS 生效后 jps -v 中应能看到 -Xms256m -Xmx512m 生效标记(以实际输出为准)。

七、运行结果解读

⚠️ 说明:本环境未采集示例程序的真实运行回显,以下为程序设计输出语义,具体数值请以目标服务器实际运行 mvn -q exec:java 的输出为准。

程序分两段输出:

  • SVD 奇异值:对 3x3 矩阵做奇异值分解,getSingularValues() 返回降序排列的 3 个奇异值,程序以 s[0]、s[1]、s[2] 打印,s[0] 最大。
  • KMeans 簇划分:4 个点分属两簇,程序打印每个簇的成员数量与各点坐标;两组点(1.x, 1.x 与 10.x, 10.x)应各自聚为一簇(簇 0 与簇 1)。

八、注意事项

⚠️ 注意:

  1. 本示例仅使用 mahout-math,纯本地运行,无需 Hadoop。
  2. mahout-math 类字节码为 Java 8 兼容,JDK 11 运行同样正常。
  3. 依赖 jar 必须统一为 14.1 版本,避免 mahout-* 组件版本不一致。
  4. 大矩阵/大数据量请通过 MAVEN_OPTS 控制堆内存(256–512MB),避免 OOM。

九、常见问题

Q1:mvn 编译报 error: invalid target release: 1.8 或 UnsupportedClassVersionError?

原因:JAVA_HOME 指向了不提供 javac 的 JRE(例如只安装了 openjdk-11-jre-headless)。解决:按第二节导出 JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 使用 JDK 8 编译。

Q2:mvn exec:java 报 Main class not found?

pom 中 exec-maven-plugin 的 mainClass 未配置或类名不匹配。确认 demo.MahoutDemo 存在且 main 方法签名正确。

Q3:程序 OOM?

数据量大时通过 MAVEN_OPTS="-Xms256m -Xmx512m" 约束堆内存,并用 jps -v 验证生效;若仍不足,再按趋势上调并评估算法与数据规模。

Q4:运行报 ClassNotFoundException(KMeansClustering)?

确认 pom 中 mahout-math 版本为 14.1 且已下载成功(mvn -q clean compile 通过即可确认);该类位于 mahout-math 的 org.apache.mahout.math.clustering 包。

十、参考链接

  • Apache Mahout 官网:https://mahout.apache.org/
  • Mahout 版本归档目录:https://archive.apache.org/dist/mahout/14.1/