在数据科学和机器学习领域,聚类分析是一种无监督学习方法,用于将相似的数据点分组。本文将带你从零开始,使用Java语言实现最经典的聚类算法——KMeans。无论你是编程新手还是有一定经验的开发者,都能轻松上手!

聚类算法的目标是将一组未标记的数据点划分为若干个“簇”(Cluster),使得同一簇内的数据点彼此相似,而不同簇之间的数据点差异较大。Java聚类算法常用于客户分群、图像分割、异常检测等场景。
其中,KMeans是最简单且广泛使用的聚类算法之一。它的核心思想是:预先设定簇的数量 K,然后通过迭代不断更新簇中心,直到收敛。
下面我们将用纯 Java 编写一个简单的 KMeans 聚类程序。为了简化,我们假设数据是二维的(x, y 坐标)。
public class Point { public double x; public double y; public Point(double x, double y) { this.x = x; this.y = y; } // 计算到另一个点的欧氏距离 public double distance(Point other) { double dx = this.x - other.x; double dy = this.y - other.y; return Math.sqrt(dx * dx + dy * dy); } @Override public String toString() { return "(" + x + ", " + y + ")"; }}import java.util.*;public class KMeans { private int k; // 簇的数量 private List<Point> points; // 所有数据点 private List<Point> centroids; // 质心列表 private int maxIterations = 100; public KMeans(int k, List<Point> points) { this.k = k; this.points = points; initializeCentroids(); } // 随机初始化质心 private void initializeCentroids() { centroids = new ArrayList<>(); Random random = new Random(); for (int i = 0; i < k; i++) { int index = random.nextInt(points.size()); centroids.add(new Point(points.get(index).x, points.get(index).y)); } } // 执行聚类 public void cluster() { for (int iter = 0; iter < maxIterations; iter++) { // 步骤1:为每个点分配最近的质心 Map<Point, List<Point>> clusters = new HashMap<>(); for (Point centroid : centroids) { clusters.put(centroid, new ArrayList<>()); } for (Point p : points) { Point closestCentroid = findClosestCentroid(p); clusters.get(closestCentroid).add(p); } // 步骤2:更新质心 boolean converged = true; List<Point> newCentroids = new ArrayList<>(); for (Map.Entry<Point, List<Point>> entry : clusters.entrySet()) { List<Point> clusterPoints = entry.getValue(); if (clusterPoints.isEmpty()) continue; double sumX = 0, sumY = 0; for (Point p : clusterPoints) { sumX += p.x; sumY += p.y; } Point newCentroid = new Point(sumX / clusterPoints.size(), sumY / clusterPoints.size()); newCentroids.add(newCentroid); // 检查是否收敛 if (entry.getKey().distance(newCentroid) > 1e-4) { converged = false; } } centroids = newCentroids; if (converged) { System.out.println("算法在第 " + (iter + 1) + " 次迭代后收敛。"); break; } } } // 找到离 point 最近的质心 private Point findClosestCentroid(Point point) { Point closest = centroids.get(0); double minDist = point.distance(closest); for (int i = 1; i < centroids.size(); i++) { double dist = point.distance(centroids.get(i)); if (dist < minDist) { minDist = dist; closest = centroids.get(i); } } return closest; } // 打印结果 public void printClusters() { Map<Point, List<Point>> clusters = new HashMap<>(); for (Point centroid : centroids) { clusters.put(centroid, new ArrayList<>()); } for (Point p : points) { Point c = findClosestCentroid(p); clusters.get(c).add(p); } int clusterId = 1; for (Map.Entry<Point, List<Point>> entry : clusters.entrySet()) { System.out.println("\n簇 " + clusterId + " (质心: " + entry.getKey() + "):"); for (Point p : entry.getValue()) { System.out.println(" " + p); } clusterId++; } }}import java.util.Arrays;public class Main { public static void main(String[] args) { // 创建示例数据点 List<Point> data = Arrays.asList( new Point(1.0, 1.0), new Point(1.5, 2.0), new Point(3.0, 4.0), new Point(5.0, 7.0), new Point(3.5, 5.0), new Point(4.5, 5.0), new Point(3.5, 4.5) ); // 设置 K=2,进行聚类 KMeans kmeans = new KMeans(2, data); kmeans.cluster(); kmeans.printClusters(); }}运行上述代码后,程序会将7个点分为2个簇,并输出每个簇包含的点及其质心坐标。你可以尝试修改 K 值或添加更多数据点,观察聚类效果的变化。
通过本教程,你已经掌握了如何用 Java实现KMeans 聚类算法。虽然我们使用的是二维数据,但该算法可轻松扩展到更高维度。对于更复杂的项目,建议使用成熟的机器学习库如 Smile 或 Weka,但理解底层原理对提升你的 机器学习聚类 能力至关重要。
希望这篇 聚类分析教程 对你有所帮助!动手实践是掌握算法的关键,快去试试吧!
本文由主机测评网于2025-12-11发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025126297.html