Advertisement

k-means算法

阅读量:

该算法[()是一种经典的无监督学习方法

复制代码
 import java.util.*;

    
  
    
 public class KMeans {
    
     private int k;
    
     private double[][] points;
    
     private int[] labels;
    
     private double[][] centroids;
    
  
    
     public KMeans(int k, double[][] points) {
    
         this.k = k;
    
         this.points = points;
    
         this.labels = new int[points.length];
    
         this.centroids = new double[k][points[0].length];
    
  
    
         // 随机初始化质心
    
         Random rand = new Random();
    
         for (int i = 0; i < k; i++) {
    
             int randomIndex = rand.nextInt(points.length);
    
             centroids[i] = points[randomIndex];
    
         }
    
     }
    
  
    
     public void run(int maxIterations) {
    
         for (int iteration = 0; iteration < maxIterations; iteration++) {
    
             // 分配点到最近的质心
    
             assignPointsToClusters();
    
  
    
             // 更新质心
    
             updateCentroids();
    
  
    
             // 检查是否收敛
    
             if (hasConverged()) {
    
                 break;
    
             }
    
         }
    
     }
    
  
    
     private void assignPointsToClusters() {
    
         for (int i = 0; i < points.length; i++) {
    
             double minDistance = Double.MAX_VALUE;
    
             int clusterIndex = -1;
    
  
    
             for (int j = 0; j < k; j++) {
    
                 double distance = calculateDistance(points[i], centroids[j]);
    
                 if (distance < minDistance) {
    
                     minDistance = distance;
    
                     clusterIndex = j;
    
                 }
    
             }
    
  
    
             labels[i] = clusterIndex;
    
         }
    
     }
    
  
    
     private void updateCentroids() {
    
         for (int i = 0; i < k; i++) {
    
             List<double[]> clusterPoints = new ArrayList<>();
    
             for (int j = 0; j < points.length; j++) {
    
                 if (labels[j] == i) {
    
                     clusterPoints.add(points[j]);
    
                 }
    
             }
    
  
    
             double[] newCentroid = new double[points[0].length];
    
             for (double[] point : clusterPoints) {
    
                 for (int dim = 0; dim < point.length; dim++) {
    
                     newCentroid[dim] += point[dim];
    
                 }
    
             }
    
  
    
             for (int dim = 0; dim < newCentroid.length; dim++) {
    
                 newCentroid[dim] /= clusterPoints.size();
    
             }
    
  
    
             centroids[i] = newCentroid;
    
         }
    
     }
    
  
    
     private boolean hasConverged() {
    
         double[][] newCentroids = new double[k][points[0].length];
    
         for (int i = 0; i < k; i++) {
    
             newCentroids[i] = centroids[i].clone();
    
         }
    
  
    
         updateCentroids();
    
  
    
         for (int i = 0; i < k; i++) {
    
             if (!Arrays.deepEquals(newCentroids[i], centroids[i])) {
    
                 return false;
    
             }
    
         }
    
  
    
         return true;
    
     }
    
  
    
     private double calculateDistance(double[] point1, double[] point2) {
    
         double sum = 0;
    
         for (int i = 0; i < point1.length; i++) {
    
             sum += Math.pow(point1[i] - point2[i], 2);
    
         }
    
         return Math.sqrt(sum);
    
     }
    
  
    
     public void printClusters() {
    
         for (int i = 0; i < k; i++) {
    
             System.out.println("Cluster " + i + ":");
    
             for (int j = 0; j < points.length; j++) {
    
                 if (labels[j] == i) {
    
                     System.out.println(Arrays.toString(points[j]));
    
                 }
    
             }
    
             System.out.println("Centroid: " + Arrays.toString(centroids[i]));
    
             System.out.println();
    
         }
    
     }

全部评论 (0)

还没有任何评论哟~