机器学习笔记-FCM算法python实现

FCM算法是一种重叠聚类算法,它计算数据集中每个数据点与分类的匹配度,近日写个python程序重温了一下FCM算法。

一、算法代码

给定同维向量数据集合points,数目为n,将其聚为C类,m为权重值,u为初始匹配度矩阵(n*C),采用闵式距离算法,其参数为p,迭代终止条件为终止值e(取值范围(0,1))及终止轮次。

计算停止时返回计算的轮次和匹配度矩阵,返回值为一个tuple:(最终计算过后的u矩阵,计算轮次(从0开始))

def alg_fcm(points,u,m,p,e, terminateturn=sys.maxint):
    assert(len(points) == len(u));
    assert(len(points) > 0);
    assert(len(u[0]) > 0);
    assert(m > 0);
    assert(p > 0);
    assert(e > 0);

    u1 = u;
    k = 0;
    while(True):
        # calculate one more turn
        u2 = fcm_oneturn(points, u1, m, p);
        # max difference between u1 and u2
        maxu = fcm_maxu(u1,u2);
        
        if (maxu < e):
            break;
        u1 = u2;
        k=k+1;
        if k > terminateturn:
            break;
        
    return (u2, k);
每一轮计算的函数fcm_oneturn代码如下,参数与主函数相同,返回值只有匹配度矩阵

def fcm_oneturn(points, u, m, p):
    assert(len(points) == len(u));
    assert(len(points) > 0);
    assert(len(u[0]) > 0);
    assert(m > 0);
    assert(p > 0);

    n = len(points);
    c = len(u[0]);

    # calculate centroids of clusters
    centroids = fcm_c(points, u, m);
    assert(len(centroids) == c);
    
    # calculate new u matrix
    u2 = fcm_u(points, centroids, m, p);
    assert(len(u2) == n);
    assert(len(u2[0]) == c);
    
    return u2;
计算终止值的函数:

def fcm_maxu(u1,u2):
    assert(len(u1) == len(u2));
    assert(len(u1) > 0);
    assert(len(u1[0]) > 0);

    ret = 0;
    n = len(u1);
    c = len(u1[0]);
    for i in range(n):
        for j in range(c):
            ret = max(np.fabs(u1[i][j] - u2[i][j]), ret);
    
    return ret;


每一个轮次计算匹配度矩阵的函数:

参数centroids表示每个类别的质心集合

def fcm_u(points, centroids, m, p):
    assert(len(points) > 0);
    assert(len(centroids) > 0);
    assert(m > 1);
    assert(p > 0);

    n = len(points);
    c = len(centroids);
    ret = [[0 for j in range(c)] for i in range(n)];
    for i in range(n):
        for j in range(c):
            sum1 = 0;
            d1 = dis_minkowski(points[i],centroids[j],p);
            for k in range(c):
                d2 = dis_minkowski(points[i],centroids[k],p);
                if d2!= 0:
                    sum1 += np.power(d1/d2, float(2)/(float(m)-1));
            if sum1!=0:
                ret[i][j] = 1/sum1;

    return ret;
每一个轮次计算类别质心的函数

def fcm_c(points, u, m):
    assert(len(points) == len(u));
    assert(len(points) > 0);
    assert(len(u[0]) > 0);
    assert(m > 0);

    n = len(points);
    c = len(u[0]);
    ret = [];
    for j in range(c):
        sum1 = 0;
        sum2 = 0;
        for i in range(n):
            sum2 += np.power(u[i][j], m);
            sum1 += np.dot(points[i], np.power(u[i][j], m));
        if sum2!= 0:
            cj = sum1 /sum2;
        else:
            cj = [0 for d in range(len(points[i]))];
        ret.append(cj);

    return ret;
二、效果

使用matplotlib编写壳程序,维度取2(平面),p取2(欧式距离),结果图示如下。

200个点聚为4类,终止值0.001,运行了70轮。




20个点聚为4类效果。

上图的匹配度函数曲线效果(X轴投影)。

  • 8
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值