java语言实现K-means聚类算法
时间: 2023-11-01 18:01:51 浏览: 94
K-means是一种聚类算法,可以将相似的数据点分组。Java语言可以很容易地实现K-means算法。下面是一个简单的Java实现示例:
```java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
public class KMeans {
private List<Point> points;
private List<Cluster> clusters;
private int k;
public KMeans(List<Point> points, int k) {
this.points = points;
this.k = k;
}
public void run() {
initializeClusters();
boolean isChanged = true;
while (isChanged) {
isChanged = false;
for (Point point : points) {
double minDistance = Double.MAX_VALUE;
Cluster nearestCluster = null;
for (Cluster cluster : clusters) {
double distance = cluster.getDistance(point);
if (distance < minDistance) {
minDistance = distance;
nearestCluster = cluster;
}
}
if (!point.getCluster().equals(nearestCluster)) {
if (point.getCluster() != null) {
point.getCluster().removePoint(point);
}
nearestCluster.addPoint(point);
point.setCluster(nearestCluster);
isChanged = true;
}
}
}
}
public List<Cluster> getClusters() {
return clusters;
}
private void initializeClusters() {
clusters = new ArrayList<>();
for (int i = 0; i < k; i++) {
Point centroid = getRandomPoint();
Cluster cluster = new Cluster(centroid);
clusters.add(cluster);
}
}
private Point getRandomPoint() {
Random random = new Random();
return points.get(random.nextInt(points.size()));
}
public static void main(String[] args) {
List<Point> points = Arrays.asList(
new Point(1, 1), new Point(1, 2), new Point(2, 1),
new Point(8, 8), new Point(8, 9), new Point(9, 8)
);
KMeans kMeans = new KMeans(points, 2);
kMeans.run();
List<Cluster> clusters = kMeans.getClusters();
for (int i = 0; i < clusters.size(); i++) {
System.out.println("Cluster " + (i + 1) + ": " + clusters.get(i).getPoints());
}
}
}
class Point {
private double x;
private double y;
private Cluster cluster;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public Cluster getCluster() {
return cluster;
}
public void setCluster(Cluster cluster) {
this.cluster = cluster;
}
@Override
public String toString() {
return "(" + x + ", " + y + ")";
}
}
class Cluster {
private Point centroid;
private List<Point> points;
public Cluster(Point centroid) {
this.centroid = centroid;
this.points = new ArrayList<>();
}
public Point getCentroid() {
return centroid;
}
public void setCentroid(Point centroid) {
this.centroid = centroid;
}
public List<Point> getPoints() {
return points;
}
public void addPoint(Point point) {
points.add(point);
}
public void removePoint(Point point) {
points.remove(point);
}
public double getDistance(Point point) {
double dx = centroid.getX() - point.getX();
double dy = centroid.getY() - point.getY();
return Math.sqrt(dx * dx + dy * dy);
}
@Override
public String toString() {
return "Cluster{" +
"centroid=" + centroid +
", points=" + points +
'}';
}
}
```
在这个示例中,我们定义了一个`KMeans`类,该类接受数据点列表和要创建的簇数。我们使用`initializeClusters()`方法初始化了簇,并使用`run()`方法运行K-means算法。最后,我们可以使用`getClusters()`方法获取聚类结果。
我们还定义了`Point`类和`Cluster`类。`Point`类表示数据点,包含x和y坐标以及它属于的簇。`Cluster`类表示簇,包含簇的质心和数据点列表。`Cluster`类还包含了一些操作簇的方法,例如添加和删除点以及计算点到簇质心的距离。
在`main()`方法中,我们创建了一个简单的数据点列表,并使用`KMeans`类运行K-means算法。最后,我们打印了每个簇的数据点列表。
这是一个简单的Java实现K-means算法的示例。需要注意的是,这只是一个简单的示例,实际使用时还需要考虑更多的细节,例如如何选择初始簇和如何选择合适的k值等。
阅读全文