K均值聚类算法的Java版实现代码示例

让我来详细讲解“K均值聚类算法的Java版实现代码示例”的完整攻略。

1. K均值聚类算法简介

K均值聚类算法是一种常用的无监督机器学习算法,常用于数据挖掘、图像分割以及客户分类等场景中。它的基本原理是:将n个数据点划分成k个簇,使得每个点都属于其最近的中心点所在的簇,这些中心点是通过簇内点的平均值计算而得。

2. Java代码示例说明

对于Java程序员来说,实现K均值聚类算法可能并不容易,因此我们来看一下下面的Java代码示例说明。

2.1 示例一

public class KMeans {

    public static void main(String[] args) {
        int k = 3; // 设置簇的数目
        double[][] data = {{1.0, 1.0}, {1.5, 2.0}, {3.0, 4.0}, {5.0, 7.0}, {3.5, 5.0}, {4.5, 5.0}, {3.5, 4.5}}; // 将数据划分成2个簇

        int[] labels = cluster(data, k); // 聚类操作

        for (int i = 0; i < labels.length; i++) {
            System.out.println(Arrays.toString(data[i]) + " belongs to cluster " + labels[i]);
        }
    }

    public static int[] cluster(double[][] data, int k) {
        int n = data.length;
        int[] labels = new int[n];
        boolean changed = true;
        int[] centers = new int[k];
        for (int i = 0; i < k; i++) {
            centers[i] = (int) (Math.random() * n); // 随机生成聚类中心
        }
        while (changed) {
            changed = false;
            for (int i = 0; i < n; i++) {
                double minDist = Double.MAX_VALUE;
                for (int j = 0; j < k; j++) {
                    double dist = getDist(data[i], data[centers[j]]); // 计算数据点距离各聚类中心的距离
                    if (dist < minDist) {
                        labels[i] = j;
                        minDist = dist;
                    }
                }
            }
            for (int j = 0; j < k; j++) {
                double[] newCenter = new double[data[0].length];
                int count = 0;
                for (int i = 0; i < n; i++) {
                    if (labels[i] == j) {
                        for (int d = 0; d < newCenter.length; d++) {
                            newCenter[d] += data[i][d];
                        }
                        count++;
                    }
                }
                for (int d = 0; d < newCenter.length; d++) {
                    newCenter[d] /= count; // 更新聚类中心
                }
                if (getDist(data[centers[j]], newCenter) > 0.0001) {
                    changed = true;
                }
                centers[j] = findNearest(newCenter, data); // 找到数据中最近的点作为新的聚类中心
            }
        }
        return labels;
    }

    private static double getDist(double[] a, double[] b) {
        double dist = 0.0;
        for (int i = 0; i < a.length; i++) {
            dist += (a[i] - b[i]) * (a[i] - b[i]);
        }
        return Math.sqrt(dist);
    }

    private static int findNearest(double[] center, double[][] data) {
        int index = 0;
        double minDist = Double.MAX_VALUE;
        for (int i = 0; i < data.length; i++) {
            double dist = getDist(center, data[i]);
            if (dist < minDist) {
                index = i;
                minDist = dist;
            }
        }
        return index;
    }
}

代码解析:

该示例中,我们首先定义了一个KMeans类,其中包含了聚类方法cluster、计算两点距离的方法getDist,以及找到离给定点最近的点的方法findNearest等。在main方法中我们设置数据点数目和簇的数目,然后调用cluster方法进行聚类操作。在聚类结束后,我们将每个数据点的标签以及对应的簇打印出来。

2.2 示例二

下面是一个更为完整的Java代码示例:

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

public class KMeans {

    private final int k;

    private final int maxIter;

    private final List<double[]> data;

    private final List<c> centers;

    public KMeans(int k, int maxIter, List<double[]> data) {
        this.k = k;
        this.maxIter = maxIter;
        this.data = data;
        this.centers = new ArrayList<>();
    }

    public void run() {
        initialCenters();
        for (int i = 0; i < maxIter; i++) {
            cluster();
            updateCenter();
        }
    }

    private void initialCenters() {
        for (int i = 0; i < k; i++) {
            centers.add(new c(data.get(i)));
        }
    }

    private void cluster() {
        for (double[] point : data) {
            c nearestCenter = null;
            double minDist = Double.MAX_VALUE;
            for (c center : centers) {
                double dist = center.dist(point);
                if (dist < minDist) {
                    nearestCenter = center;
                    minDist = dist;
                }
            }
            nearestCenter.addPoint(point);
        }
    }

    private void updateCenter() {
        for (c center : centers) {
            center.update();
        }
    }

    private static class c {

        private final double[] center;

        private final List<double[]> points;

        public c(double[] center) {
            this.center = center;
            this.points = new ArrayList<>();
        }

        public void addPoint(double[] point) {
            points.add(point);
        }

        public void update() {
            for (int i = 0; i < center.length; i++) {
                double sum = 0.0;
                for (double[] point : points) {
                    sum += point[i];
                }
                if (points.size() > 0) {
                    center[i] = sum / points.size();
                }
            }
        }

        public double dist(double[] point) {
            double dist = 0.0;
            for (int i = 0; i < center.length; i++) {
                dist += (center[i] - point[i]) * (center[i] - point[i]);
            }
            return Math.sqrt(dist);
        }
    }

    public static void main(String[] args) {
        List<double[]> data = new ArrayList<>();
        data.add(new double[]{1.0, 1.0});
        data.add(new double[]{1.5, 2.0});
        data.add(new double[]{3.0, 4.0});
        data.add(new double[]{5.0, 7.0});
        data.add(new double[]{3.5, 5.0});
        data.add(new double[]{4.5, 5.0});
        data.add(new double[]{3.5, 4.5});

        KMeans kMeans = new KMeans(2, 10, data);
        kMeans.run();

        for (int i = 0; i < kMeans.centers.size(); i++) {
            System.out.println("Cluster " + (i + 1) + ": " + kMeans.centers.get(i));
        }
    }
}

代码解析:

在该示例中,我们首先定义了一个KMeans类,其中包含了计算两点距离的方法dist,以及代表中心点的类c。在main方法中我们设置数据点数目和簇的数目,然后调用KMeans类进行聚类操作。在聚类结束后,我们将每个簇的中心坐标打印出来。

3. 总结

综上所述,K均值聚类算法的Java版实现并不复杂,而且在Java中也有很多现成的工具库可以供我们使用,例如Apache Mahout、Weka等。但是为了更好地理解该算法的原理和实现思路,我们还是需要亲自动手写一下。

通过本文的讲解,我相信你已经对K均值聚类算法的Java版实现有了更深入的了解,希望对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:K均值聚类算法的Java版实现代码示例 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • spring/springboot整合curator遇到的坑及解决

    下面是“spring/springboot整合curator遇到的坑及解决”的完整攻略: 环境准备 首先,需要在本地或服务器上安装一个ZooKeeper集群,并开启相关端口。其次,根据具体的开发需求,在Spring或Spring Boot项目中集成Curator。 Spring/Spring Boot整合Curator 1. 添加Curator依赖 在Mav…

    Java 2023年5月20日
    00
  • Hibernate实现批量添加数据的方法

    下面是关于“Hibernate实现批量添加数据的方法”的完整攻略: 什么是Hibernate? Hibernate是一个开源的ORM(对象关系映射)框架,用于Java语言编写的应用程序。使用Hibernate可以将Java对象与关系数据库中的表进行映射,它提供了简单的CRUD(增、删、改、查)和高级查询功能,避免了手动编写复杂的SQL语句。 Hibernat…

    Java 2023年5月20日
    00
  • JAVA读取文本文件内容实例代码

    下面是关于”JAVA读取文本文件内容的实例代码”的完整攻略: 一、准备工作 首先需要创建一个文本文件(test.txt)并保存在计算机中,文件中可以存放一些需要读取的文本内容。 二、使用JAVA读取文本文件内容 Java 读取文本文件内容可以分为以下几个步骤: 创建File对象,指定需要读取的文本文件路径。 创建BufferedReader对象,使用 Fil…

    Java 2023年5月20日
    00
  • 解读java try catch 异常后还会继续执行吗

    当 Java 代码中出现异常时,程序默认会中止执行,如果希望程序继续执行下去,可以使用 try-catch 语句来捕捉异常并对其进行处理。 Java 中的 try-catch 语句的作用是:当某些代码可能会生成异常时,可以通过捕获异常并做出相应的处理,来避免程序因为异常中止。其中 try 语句块中包含可能会引起异常的代码,catch 语句块中对异常进行处理。…

    Java 2023年5月27日
    00
  • Java基础之面向对象机制(多态、继承)底层实现

    Java基础之面向对象机制(多态、继承)底层实现 Java作为一种面向对象的语言,通过多态和继承两种机制来实现面向对象的特性。本文将从底层角度分别探究多态和继承的实现方式。 多态的底层实现 多态通过方法重写和方法重载来实现,方法重写是指子类重写父类的方法,而方法重载是指在同一个类中,两个或多个方法具有相同的名称,但具有不同的参数列表。 下面是一个多态的例子:…

    Java 2023年5月19日
    00
  • JPA配置详解之jpaProperties用法

    JPA配置详解之jpaProperties用法 为了更好地管理JPA配置,Spring Boot提供了许多配置属性,其中一个是jpaProperties属性。在这篇攻略中,我们将学习如何在Spring Boot应用程序中使用jpaProperties属性,并且将通过示例代码演示其用法。 使用示例 假设我们有一个简单的Spring Boot应用程序,并且需要使…

    Java 2023年5月20日
    00
  • 通过JSP的预编译消除性能瓶颈

    通过JSP的预编译可以有效地消除JSP页面的性能瓶颈。下面将介绍完整的攻略。 1. 基本概念 JSP的预编译,是将JSP页面转换成Servlet类,并把需要在运行时依赖解析引擎的部分存储在JavaBean或Java Class中的过程。预编译后的Servlet类可以存储在本地文件中,以执行效率更高的Java类文件方式执行。 2. 实现步骤 进行JSP预编译的…

    Java 2023年6月15日
    00
  • Java中String判断值为null或空及地址是否相等的问题

    下面我来详细讲解一下Java中String判断值为null或空及地址是否相等的问题的攻略。 判断字符串是否为空 在Java中,判断字符串是否为空可以用以下三种方式。 1.使用length()方法 String str = ""; if (str.length() == 0) { System.out.println("字符串为空…

    Java 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部