isodata 聚类分析 实验报告 IRIS数据

ISODATA 算法汇报文档 , IRIS数据 ,Python实现

实验介绍

实验:使用ISODATA聚类算法在IRIS数据上进行聚类分析
ISODATA(迭代自组织数据分析算法 )来自模糊数学领域 ,是统计模式识别 中非监督动态聚类算法的一种。

算法基本思想

可以通过类的自动合并(两 类合一)与分裂(一类分为二),得到较合理的 类型数目c。
算法步骤及实验过程

预处理IRIS数据
data = shuffle(data)
feature_scaling(data, numeric_attrs)
encode_values = data["Species"].unique()
encode_fill_attrs(data, "Species", encode_values)
data.to_csv(processed_data_path, index=False)

打乱IRIS数据的顺序,标准化,保存处理后的文件为process_data.csv。
从process_data.csv中读取文件

input_data_path = 'processed_data\\process_data.csv'
print("Loading data...")
column = ['Sepal.Length', 'Sepal.Width', 'Petal.Length', 'Petal.Width', 'Species']
data = pd.read_csv(input_data_path, header=None, skiprows=[0, 0], sep=',', names=column)
第一步:初始化参数

初始化参数:预期聚类中心个数k、现聚类中心个数c、最少的样本数theta_n、聚类中心之间的最小距离theta_c、距离分布的标准差(阈值)theta_s、最大迭代次数iterator、分裂时样本特征聚类中心分裂参数split_k。

# 预期聚类中心
        self.k = 3
        # 现聚类中心
        self.category_num = 1
        # 每一类聚类中最少的样本数
        self.theta_n = 23
        # 一个聚类域中样本距离分布的标准差(阈值)
        self.theta_s = 0.12
        # 两个聚类中心之间的最小距离,如果小于次数,则合并
        self.theta_c = 1.2
        # 每次迭代允许合并的最大聚类对数目
        self.L = 1
        # 允许的最大迭代次数
        self.max_iterator = 100
        # 迭代次数
        self.iterator = 1
        # 分裂参数
        self.split_k = 0.5
第二步:计算每个样本与聚合中心距离

计算每个样本与聚合中心距离,并把所有样本划分到category_num个聚合中去。

for j in range(len(self.centre_data[i])):
    _, index = compute_min_distance(self.centre_data[i].iloc[j, :4], self.centre_pot)
    if i != index:
        self.centre_data[index] = self.centre_data[index].append(self.centre_data[i].iloc[j])
    else:
        temp_df = temp_df.append(self.centre_data[i].iloc[j])
self.centre_data[i] = temp_df

第三步:舍去小聚类中心

舍去样本数少于theta_n的聚类,并且把样本重新分配到其他聚类中去。在Isodata类中的reject方法里。
temp_set = self.centre_data[index]

删除子集

self.centre_data.pop(index)

删除聚合中心
self.centre_pot.pop(index)
self.category_num -= 1
for j in range(len(temp_set)):
    _, index = compute_min_distance(temp_set.iloc[j, :4], self.centre_pot)
    self.centre_data[index] = self.centre_data[index].append(temp_set.iloc[j], ignore_index=True)
第四步计算修改聚合中心

每次更新聚类中心的样本后,都要对聚类中心更新。

def compute_centre(self):
    centre = []
    for j in range(len(self.centre_data)):
        centre.append(self.centre_data[j].iloc[:, :4].mean(axis=0))
    self.centre_pot = centre
第五六步:计算距离

计算类内距离平均值,计算类内总平均距离D(全部样本对其相应聚类中心的总平 均距离)。

第七步:判断是否需要分裂

如迭代运算次数已达I 次,即最后一次迭代,置c  0, 跳到⑾,运算结束,如 2 K c  ,即聚类中心的数目等于或不到规定值的一半, 则转⑻,将已有的聚类分裂,如迭代运算的次数是偶数,或c  2K ,则不进行分裂,跳 到⑾,若不符合上述两个条件,则进入⑻,进行分裂处理。

第八步:计算最大标准偏差向量

通过第七步的条件,判断是否进入分裂步骤。计算标准偏差向量,其中包括每个特征的标准偏差分量。

第九步:最大标准偏差分量

Isodata类中的compute_max_sigma()来计算最大标准偏差分量。再进行分裂操作

第十步,根据条件进行分裂操作

计算标准偏差向量并且求出每个聚合的最大标准偏差分量后,考察最大标准偏差分量如果其大于theta_s并且满足类内距离平均值大于总平均距离且样本数目超过规定值一倍以上或聚类中心小于k/2的任意一个条件,就可以进行分裂。
分裂要根据计算出的最大标准偏差分量进行。最大标准偏差分量对应的特征聚类中心值通过加减self.split_k * temp_sigma[j]来分裂出两个聚类中心。

temp_centre_1 = self.centre_pot[temp_cat[j]].copy()
temp_centre_1[temp_dim[j]] += self.split_k * temp_sigma[j]
temp_centre_2 = self.centre_pot[temp_cat[j]].copy()
temp_centre_2[temp_dim[j]] -= self.split_k * temp_sigma[j]
temp_centre = [temp_centre_1, temp_centre_2]
temp_df = [pd.DataFrame(), pd.DataFrame()]
第十一步:计算两两聚合中心间的距离

dis = distance(self.centre_pot[j], self.centre_pot[i])

第十二步:比较两两聚合中心间的距离与theta_c

并把小于theta_c的距离按递增次序排队。theta_c 代表聚类中心之间的最小距离,去L个最小的距离(其中L 代表一次迭代中最多允许合并的聚类对数)

第十三步:合并聚类

根据第十二步求出来的所有聚类对数,进行合并操作。

self.centre_data[temp[0]] = pd.concat([self.centre_data[temp[0]], self.centre_data[temp[1]]])
self.centre_data.pop(temp[1])
第十四步 迭代

如果迭代次数没有达到最大值且修改了参数则回到第一步重新开始,如果没有修改参数值,回第二步重新开始。
实验结果分析

结果

程序执行后,生成三个聚类,其中各个聚类的精确度和总精确度各自为
1, accuracy:1.0,
2,accuracy:0.7317073170731707
3,accuracy:0.75
总:accuracy: 0.8296296296296296

在第11次迭代后聚类不变
p———q
11
b———d
舍去小聚类后:聚类数 3 ,各聚类元素数 [46, 41, 48]
最大标准差分量: 0.5866619304969822
距离最小 1.7943908620209774
聚类数 3 ,各聚类元素数 [46, 41, 48]

分析

1.聚类迭代陷入僵局,如果增加最小距离来引导聚类合并,则导致聚类中心减少,达不到预期效果。
cluster 0:1,distance3.9123794593474686
cluster 0:2,distance2.9855463595372598
cluster 1:2,distance1.7943908620209774
根据原始IRIS数据的 标签,计算两两聚类之间的最小距离为1.67,小于本文实现的ISODATA算法聚类后计算的最小距离。所以通过增大theta_c 使其大于1.794来引导聚类合并,再分裂,方法失效。
2.根据实验,选择分裂的k值时条件为0<k<=1,选择0.1至1的10个值进行测试。发现几乎对聚类结果几乎没有影响。方法失效

#代码还有待改进

outbound link: https://blog.csdn.net/canyanruxue/article/details/90600303

1 thought on “isodata 聚类分析 实验报告 IRIS数据”

  1. z_ioei说道:

    got it

发表评论

电子邮件地址不会被公开。 必填项已用*标注