遗传算法——Kmeans聚类

1. K-means算法的核心思想

  • 将样本之间的距离作为分类标准,实现设定好聚类值k,再通过聚类中心的合理选择,使的同类别中的样本距离尽可能小。属于无监督学习。
  • 无监督学习:在进行分析前,不知道真实的结果,通过聚类将结果进行划分。
  • K-means原理演示网址

Blog - Naftali Harris: Statistician, Hacker and Climbericon-default.png?t=N7T8https://www.naftaliharris.com/blog/

2. 优化设计的关键

  • 聚类数的确定:将种群分为几类
  • 初始聚类点的确定(会影响最终的结果)
  • 聚类结果的可视化(多为数据可视化)
  • 聚类效果评价(评价标准)

3. 聚类实例

3.1 生成一个数据集

% 设置随机数生成器的种子以便结果可复现
rng(0);

% 定义三个聚类中心
means = [1 2 3 4; 5 6 7 8; 9 10 11 12];

% 定义三个聚类的协方差矩阵,这里假设特征间相关性不大,使用对角矩阵
covariances = repmat(eye(4), [1, 1, 3]) * 0.5; % 较小的协方差值意味着数据点更紧密

% 定义每个聚类的样本数
clusterSizes = [50, 50, 50];

% 初始化数据矩阵
data = [];

% 使用循环为每个聚类生成数据
for i=1:size(means, 1)
    % 为每个聚类生成随机数据
    clusterData = mvnrnd(means(i, :), covariances(:, :, i), clusterSizes(i));
    % 将生成的数据加入到数据矩阵中
    data = [data; clusterData];
end


3.2 聚类值K的设定

3.2.1 手动设定聚类数(也可以用轻代码)

% 使用指定的簇个数执行 K 均值聚类(K 值)
K = 3;
[clusterIndices,centroids] = kmeans(data,K);
clear K

% 显示结果

% 显示二维散点图(PCA)
figure
[~,score] = pca(data);
clusterMeans = grpstats(score,clusterIndices,"mean");
h = gscatter(score(:,1),score(:,2),clusterIndices,colormap("lines"));
for i2 = 1:numel(h)
    h(i2).DisplayName = strcat("Cluster",h(i2).DisplayName);
end
clear h i2 score
hold on
h = scatter(clusterMeans(:,1),clusterMeans(:,2),50,"kx","LineWidth",2);
hold off
h.DisplayName = "ClusterMeans";
clear h clusterMeans
legend;
title("First 2 PCA Components of Clustered Data");
xlabel("First principal component");
ylabel("Second principal component");

 下图分别为k=3,2,4的结果

3.2.2 最佳

3.2.2.1 计算标准
  • Calinski-Harabasz准则(方差比准则VRC:用于确定最佳K值,对应具有较大的簇间方差(簇与簇之间较为分散)和较小的簇内方差(每一簇较为聚拢),最佳聚类数对应于有较好的Calinski-Harabasz指数值的解。(越大越好)
    % 使用指定范围选择最佳簇个数(K 值)
    fh = @(X,K)(kmeans(X,K));
    eva = evalclusters(data,fh,"CalinskiHarabasz","KList",2:5);
    clear fh
    K = eva.OptimalK;
    clusterIndices = eva.OptimalY;
    
    % 显示簇计算标准值
    figure
    bar(eva.InspectedK,eva.CriterionValues);
    xticks(eva.InspectedK);
    xlabel("Number of clusters");
    ylabel("Criterion values - Calinski-Harabasz");
    legend("Optimal number of clusters is " + num2str(K))
    title("Evaluation of Optimal Number of Clusters")
    disp("Optimal number of clusters is " + num2str(K));
    clear K eva
    
    % 计算质心
    centroids = grpstats(data,clusterIndices,"mean");
    
    % 显示结果
    
    % 显示二维散点图(PCA)
  • Davies-Bouldin准则:与VRC相反,最佳聚类数对应具有最小的Davies-Bouldin指数值(DBI)。
    % 使用指定范围选择最佳簇个数(K 值)
    fh = @(X,K)(kmeans(X,K));
    eva = evalclusters(data,fh,"DaviesBouldin","KList",2:5);
    clear fh
    K = eva.OptimalK;
    clusterIndices = eva.OptimalY;
    
    % 显示簇计算标准值
    
    
    % 计算质心
    
  • 轮廓准则(SilhouetteEvaluation):每个点的轮廓值是衡量与同一集群相似度的度量。如果大多数点的轮廓值都很高,则解决方案是合适的。如果许多点轮廓值较低或者为负,那么K可能过大或者过小。(越大越好)
  • 间距准则(GapEvaluation):间距标准对应于(ExceptedLogW-LogW),其中W是簇内离散度,ExceptedLogW是由蒙特卡洛抽样的标准分布,LogW是由样本书记计算得出。最佳聚类数对应于在容差范围内具有最大局部的间距值(gap value)。(越大越好)

4. 优化阶段 

优化目标

function o = ob_GA_kmeans(x,data,K,n)

m=reshape(x,[K,n]); %将x重组为K行n列的矩阵
d=pdist2(data,m); % 到质心的欧式距离
[dmin,~]=min(d,[],2);
o=sum(dmin);
end

优化

%% 初始化


clc;clear;
load("data.mat");
n=size(data,2); %变量数,特征值
K=3; %给一个默认K值
N=n*K; %计算自变量数,每个质心对应几行几列,
% 行对应分类数,列对应变量数

%% 优化

% 将固定参数传递给 objfun
objfun = @(x)ob_GA_kmeans(x,data,K,n);

% 设置非默认求解器选项
options = optimoptions("ga","PlotFcn","gaplotbestf");

% 求解
[solution,objectiveValue] = ga(objfun,N,[],[],[],[],[],[],[],[],options);

% 清除变量
clearvars objfun options

%% 绘制

m=reshape(solution,[K,n]); %将x重组为K行n列的矩阵
d=pdist2(data,m); % 到质心的欧式距离
[dmin,post]=min(d,[],2);
% 显示二维散点图(PCA)
figure
[~,score] = pca(data);
clusterMeans = grpstats(score,post,"mean");
h = gscatter(score(:,1),score(:,2),post,colormap("lines"));
for i2 = 1:numel(h)
    h(i2).DisplayName = strcat("Cluster",h(i2).DisplayName);
end
clear h i2 score
hold on
h = scatter(clusterMeans(:,1),clusterMeans(:,2),50,"kx","LineWidth",2);
hold off
h.DisplayName = "ClusterMeans";
clear h clusterMeans
legend;
title("First 2 PCA Components of Clustered Data");
xlabel("First principal component");
ylabel("Second principal component");

结果

  • 15
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Kmeans聚类算法是一种无监督学习算法,用于将数据集划分为不同的簇。它是一个迭代算法,通过计算每个数据点与簇中心的距离,将数据点分配到最近的簇中心。然后,根据分配的数据点更新簇中心。重复这个过程,直到簇中心不再变化或达到预设的迭代次数。 下面是一个使用Python实现Kmeans聚类算法的示例: ``` python import numpy as np import matplotlib.pyplot as plt # 生成随机数据 np.random.seed(0) X = np.random.randn(100, 2) # 初始化K个簇中心 K = 3 centers = X[np.random.choice(len(X), K, replace=False)] # 迭代聚类 for i in range(10): # 计算每个数据点最近的簇中心 distances = np.linalg.norm(X[:, np.newaxis, :] - centers, axis=2) labels = np.argmin(distances, axis=1) # 更新簇中心 for k in range(K): centers[k] = np.mean(X[labels == k], axis=0) # 可视化聚类结果 colors = ['r', 'g', 'b'] for k in range(K): plt.scatter(X[labels == k, 0], X[labels == k, 1], c=colors[k]) plt.scatter(centers[:, 0], centers[:, 1], marker='*', s=200, c='#050505') plt.show() ``` 在这个例子中,我们生成了一个随机数据集,然后初始化了3个簇中心。然后,我们执行10次迭代,计算每个数据点最近的簇中心,并根据分配的数据点更新簇中心。最后,我们可视化聚类结果,其中每个簇用不同的颜色表示,簇中心用星号表示。 Kmeans聚类算法是一种简单有效的聚类算法,但它有一些缺点。例如,它需要预先指定簇的数量K,这可能不是很容易确定。此外,它对初始簇中心的选择很敏感,可能会导致陷入局部最优解。因此,在实际应用中,需要对它进行改进,例如Kmeans++算法和层次聚类算法等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值