• Ruby简单实现Kmeans聚类算法


    http://fuliang.iteye.com/blog/891991

    K-means是一个简单容易实现的聚类算法,我们以对一个图片的颜色的RGB值进行聚类为例, 
    实现这个算法。 
    K-means算法是一个EM的迭代过程: 
    1.随机选择k个作为聚类中心 
    2.E step: 
    对每一个点,计算它到每一个聚类中心的距离,把这个点分配到最近的聚类中心代表的 
    聚类中。 
    3.M step: 
    重新计算每个聚类的中心:每个聚类中心为该聚类所有点的均值。 

    重复2~3直到达到最大的迭代次数或者聚类不再发生变化。 

    Ruby代码  收藏代码
    1. #!/usr/bin/ruby  
    2. # autor: fuliang http://fuliang.iteye.com/  
    3.   
    4. class RGB  
    5.     attr_accessor :r,:g,:b  
    6.   
    7.     def initialize(r=0,g=0,b=0)  
    8.         @r,@g,@b = r,g,b  
    9.     end  
    10.   
    11.     def +(rgb)  
    12.         @r += rgb.r  
    13.         @g += rgb.g  
    14.         @b += rgb.b  
    15.         self  
    16.     end  
    17.   
    18.     def /(n)  
    19.         @r /= n  
    20.         @g /= n  
    21.         @b /= n  
    22.         self  
    23.     end  
    24. end  
    25.   
    26. def random_k_centers(instances,k)  
    27.     rand_indxes = (0...instances.size).sort_by{rand}[0...k]  
    28.     instances.values_at(*rand_indxes)  
    29. end  
    30.   
    31. def distance(ins1,ins2)#采用余弦值,因为255,255,255和200,200,200颜色基本类似  
    32.     dot_product = ins1.r * ins2.r + ins1.g * ins2.g + ins1.b * ins2.b  
    33.     mod1 = Math.sqrt(ins1.r * ins1.r + ins1.g * ins1.g + ins1.b * ins1.b)  
    34.     mod2 = Math.sqrt(ins2.r * ins2.r + ins2.g * ins2.g + ins2.b * ins2.b)  
    35.     return 1 - dot_product / (mod1 * mod2)  
    36. end  
    37.   
    38. def k_means_cluster(instances,k,max_iter=100)  
    39.     random_centers = random_k_centers(instances,k)  
    40.     p random_centers  
    41.     instance_cluster_map = {}  
    42.     change_count = 0  
    43.     clusters = []  
    44.     0.upto(max_iter) do |iter_num|  
    45.         clusters = []  
    46.         puts "iterate #{iter_num} ..."  
    47.         change_count = 0  
    48.         # E-step  
    49.         instances.each do |instance|  
    50.             min_distance = 1.0/0  
    51.             min_indx = 0  
    52.             random_centers.each_with_index do |center,index|  
    53.                 current_distance = distance(center,instance)  
    54.                 if min_distance > current_distance then  
    55.                     min_indx = index  
    56.                     min_distance = current_distance  
    57.                 end  
    58.             end  
    59.             if instance_cluster_map[instance] != min_indx then#trace the change  
    60.                 change_count += 1  
    61.                 instance_cluster_map[instance] = min_indx  
    62.             end  
    63.             clusters[min_indx] ||= []  
    64.             clusters[min_indx] << instance  
    65.         end  
    66.         puts "change_count=#{change_count}"  
    67.         break if change_count.zero?  
    68.         #M-step  
    69.         clusters.each_with_index do |cluster,index|  
    70.             center = RGB.new  
    71.             cluster.each do |instance|  
    72.                 center += instance  
    73.             end  
    74.             center /= cluster.size  
    75.             random_centers[index] = center # update center  
    76.         end  
    77.     end  
    78.     return clusters  
    79. end  
    80.   
    81. instances = []  
    82. File.open("rgbs.txt").each_line do |line|  
    83.     line.split(/\t/).each do | rgb |  
    84.         r,g,b = rgb.split(/,/).collect{|e| e.to_i}  
    85.         instances << RGB.new(r,g,b)  
    86.     end  
    87. end  
    88.   
    89. clusters = k_means_cluster(instances,5,100)  
    90. k_candidates = []  
    91. clusters.each do |cluster|  
    92.     sum = cluster.inject(RGB.new) {|sum,ins| sum + ins}  
    93.     candidate = sum / cluster.size  
    94.     k_candidates << candidate  
    95. end  
    96.   
    97. p k_candidates  


    可以使用聚类算法对这个图片进行有损压缩。

  • 相关阅读:
    codevs 1160 蛇形矩阵
    进程同步-进程内部也需要锁
    进程间通讯-3(Manager)-实现数据的同时修改
    进程间通讯-2(pipe)
    python 中的queue 与多进程--待继续
    进程间通讯-1-传递函数的方法
    多进程
    queue队列
    python-输出颜色显示
    python深浅copy-转自EVA的博客
  • 原文地址:https://www.cnblogs.com/lexus/p/2265948.html
Copyright © 2020-2023  润新知