C++实现K均值聚类算法
时间: 2023-07-17 07:07:58 浏览: 125
C++实现k均值聚类算法
5星 · 资源好评率100%
K均值聚类算法是一种常用的无监督学习算法,用于将数据集划分为K个不同的类别。下面是一个简单的C++实现示例:
```cpp
#include <iostream>
#include <vector>
#include <cmath>
// 计算两个向量之间的欧氏距离
double euclideanDistance(const std::vector<double>& v1, const std::vector<double>& v2) {
double distance = 0.0;
for (int i = 0; i < v1.size(); ++i) {
distance += pow(v1[i] - v2[i], 2);
}
return sqrt(distance);
}
// 将每个数据点分配给最近的聚类中心
void assignToClusters(const std::vector<std::vector<double>>& data, const std::vector<std::vector<double>>& centroids,
std::vector<int>& clusterAssignments) {
for (int i = 0; i < data.size(); ++i) {
double minDistance = INFINITY;
int clusterIndex = -1;
for (int j = 0; j < centroids.size(); ++j) {
double distance = euclideanDistance(data[i], centroids[j]);
if (distance < minDistance) {
minDistance = distance;
clusterIndex = j;
}
}
clusterAssignments[i] = clusterIndex;
}
}
// 更新聚类中心为每个簇的平均值
void updateCentroids(const std::vector<std::vector<double>>& data, const std::vector<int>& clusterAssignments,
std::vector<std::vector<double>>& centroids) {
std::vector<int> clusterCounts(centroids.size(), 0);
std::vector<std::vector<double>> sums(centroids.size(), std::vector<double>(data[0].size(), 0.0));
for (int i = 0; i < data.size(); ++i) {
int clusterIndex = clusterAssignments[i];
for (int j = 0; j < data[i].size(); ++j) {
sums[clusterIndex][j] += data[i][j];
}
clusterCounts[clusterIndex]++;
}
for (int i = 0; i < centroids.size(); ++i) {
for (int j = 0; j < centroids[i].size(); ++j) {
if (clusterCounts[i] > 0) {
centroids[i][j] = sums[i][j] / clusterCounts[i];
}
}
}
}
// K均值聚类算法
std::vector<int> kMeans(const std::vector<std::vector<double>>& data, int k) {
std::vector<int> clusterAssignments(data.size(), 0);
std::vector<std::vector<double>> centroids(k, std::vector<double>(data[0].size(), 0.0));
// 初始化聚类中心为随机的数据点
for (int i = 0; i < k; ++i) {
centroids[i] = data[rand() % data.size()];
}
bool centroidsChanged = true;
while (centroidsChanged) {
// 将数据点分配给最近的聚类中心
assignToClusters(data, centroids, clusterAssignments);
// 更新聚类中心
std::vector<std::vector<double>> oldCentroids = centroids;
updateCentroids(data, clusterAssignments, centroids);
// 判断聚类中心是否发生变化
centroidsChanged = false;
for (int i = 0; i < centroids.size(); ++i) {
if (centroids[i] != oldCentroids[i]) {
centroidsChanged = true;
break;
}
}
}
return clusterAssignments;
}
int main() {
// 示例数据集
std::vector<std::vector<double>> data = {
{2.0, 3.0}, {2.5, 5.0}, {1.5, 2.5}, {4.0, 2.0}, {3.5, 4.5}, {3.0, 2.5}
};
int k = 2; // 聚类数量
std::vector<int> clusterAssignments = kMeans(data, k);
// 输出每个数据点所属的聚类
for (int i = 0; i < clusterAssignments.size(); ++i) {
std::cout << "Data point " << i + 1 << " belongs to cluster " << clusterAssignments[i] + 1 << std::endl;
}
return 0;
}
```
上述代码是一个简单的K均值聚类算法的实现,可以根据自己的数据集和需要进行适当的修改。在示例代码中,我们使用了一个二维数据集并将其分为两个聚类。输出中显示了每个数据点所属的聚类。
阅读全文