C++实现多维向量聚类FCM算法

本文提供了一个用C++编写的FCM算法实现,用于对多维向量进行聚类。该实现包含了欧氏距离计算、隶属度矩阵初始化、聚类中心计算、隶属度矩阵更新等核心功能,并提供了完整的代码示例。

#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

// 计算两个向量之间的欧氏距离
double euclideanDistance(const vector<double>& vec1, const vector<double>& vec2) {
    double distance = 0.0;
    for (int i = 0; i < vec1.size(); ++i) {
        distance += pow(vec1[i] - vec2[i], 2);
    }
    return sqrt(distance);
}

// 初始化隶属度矩阵
void initMembershipMatrix(vector<vector<double>>& U, int numClusters, int numPoints) {
    U.resize(numClusters, vector<double>(numPoints));
    for (int i = 0; i < numClusters; ++i) {
        for (int j = 0; j < numPoints; ++j) {
            U[i][j] = (double)rand() / RAND_MAX;
        }
    }
}

// 计算聚类中心
void calculateClusterCenter(const vector<vector<double>>& points, const vector<vector<double>>& U, int numClusters, vector<vector<double>>& centers) {
    int numDimensions = points[0].size();
    centers.resize(numClusters, vector<double>(numDimensions));
    for (int i = 0; i < numClusters; ++i) {
        for (int j = 0; j < numDimensions; ++j) {
            double numerator = 0.0;
            double denominator = 0.0;
            for (int k = 0; k < points.size(); ++k) {
                numerator += pow(U[i][k], 2) * points[k][j];
                denominator += pow(U[i][k], 2);
            }
            centers[i][j] = numerator / denominator;
        }
    }
}

// 更新隶属度矩阵
double updateMembershipMatrix(const vector<vector<double>>& points, const vector<vector<double>>& centers, int numClusters, double fuzziness, vector<vector<double>>& U) {
    double maxDiff = 0.0;
    for (int i = 0; i < numClusters; ++i) {
        for (int j = 0; j < points.size(); ++j) {
            double denominator = 0.0;
            for (int k = 0; k < numClusters; ++k) {
                double distanceIJ = euclideanDistance(points[j], centers[i]);
                double distanceKJ = euclideanDistance(points[j], centers[k]);
                denominator += pow(distanceIJ / distanceKJ, 2 / (fuzziness - 1));
            }
            double newMembership = 1.0 / denominator;
            maxDiff = max(maxDiff, abs(newMembership - U[i][j]));
            U[i][j] = newMembership;
        }
    }
    return maxDiff;
}

// FCM算法
void fuzzyCMeans(const vector<vector<double>>& points, int numClusters, double fuzziness, double epsilon, vector<vector<double>>& U, vector<vector<double>>& centers) {
    initMembershipMatrix(U, numClusters, points.size());
    int maxIterations = 100;
    int iteration = 0;
    double diff = epsilon + 1.0;
    while (iteration < maxIterations && diff > epsilon) {
        calculateClusterCenter(points, U, numClusters, centers);
        diff = updateMembershipMatrix(points, centers, numClusters, fuzziness, U);
        ++iteration;
    }
}

int main() {
    vector<vector<double>> points = {{1.0, 2.0, 3.0}, {2.0, 3.0, 4.0}, {3.0, 4.0, 5.0}, {4.0, 5.0, 6.0}, {5.0, 6.0, 7.0}};
    int numClusters = 2;
    double fuzziness = 2.0;
    double epsilon = 1e-6;
    vector<vector<double>> U;
    vector<vector<double>> centers;
    fuzzyCMeans(points, numClusters, fuzziness, epsilon, U, centers);
    for (int i = 0; i < numClusters; ++i) {
        cout << "Cluster " << i << ": ";
        for (int j = 0; j < centers[i].size(); ++j) {
            cout << centers[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

代码说明:

  • euclideanDistance函数计算两个向量之间的欧氏距离。
  • initMembershipMatrix函数初始化隶属度矩阵U,随机生成0到1之间的值。
  • calculateClusterCenter函数计算聚类中心。
  • updateMembershipMatrix函数更新隶属度矩阵U,返回最大的隶属度变化量。
  • fuzzyCMeans函数实现FCM算法,接收数据点、聚类数、模糊度、收敛精度、隶属度矩阵U和聚类中心数组作为参数。函数循环计算聚类中心和隶属度矩阵U,直到达到最大迭代次数或隶属度变化量小于收敛精度。
  • main函数中定义了一个样本点集,聚类数为2,模糊度为2.0,收敛精度为1e-6。调用fuzzyCMeans函数进行聚类,并输出聚类中心。

参考文献:

[1] Bezdek, J. C. (1981). Pattern recognition with fuzzy objective function algorithms. Springer-Verlag.

C++实现多维向量聚类FCM算法

原文地址: https://www.cveoy.top/t/topic/mRn5 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录