1. datasample
initial_centroids = datasample(data, k, 'Replace', false);
是MATLAB中的命令,用于从数据集data中随机抽取k个样本作为初始聚类汇总新,并且抽取时不放回。
- datasample:是MATLAB中的函数,用于从数组中随机抽取样本
- data:是你想要进行聚类分析的数据集,通常是包含了所有待分类样本特征的矩阵
- k:表示希望创建的聚类数量。在K-means算法中,这是个关键参数,需要实现确定。
- 'Replace', false:这个参数指定了抽样的方式。当设置为false时,意味着每个样本在一次抽样中只能被选中一次,即不放回抽样。这对于确保初始聚类中心之间的独立性是有益的。
function [centroids, idx] = runKMeans(X, initial_centroids, max_iters)
% 获取样本数和特征数
[m, n] = size(X);
% 获取聚类中心数
k = size(initial_centroids, 1);
% 初始化变量
centroids = initial_centroids;
previous_centroids = centroids;
idx = zeros(m, 1);
% 运行 K-means
for i = 1:max_iters
% 聚类分配步骤
idx = findClosestCentroids(X, centroids);
% 更新聚类中心
centroids = computeCentroids(X, idx, k);
% 如果聚类中心变化很小,则停止迭代
if isequal(previous_centroids, centroids)
break;
end
previous_centroids = centroids;
end
end
以上定义了一个名为runKMeans的函数,它接受三个输入参数:样本数据矩阵X、初始聚类中信initial_centroids和最大迭代次数max_iters。该函数输出两个变量:最终的聚类中心centroids和每个样本所属的聚类索引idx。
2.size()
[m, n] = size(X);
k = size(initial_centroids, 1);
- 获取尺寸:计算输入样本矩阵X的行数(样本数)和列数(特征数)n
- 确定聚类数:通过计算initial_centroids的行数来得到聚类中心的数量k
size()函数用于获取数组(包括但不限于矩阵、向量、多维数组等)的尺寸信息,它可以给返回数组的行数、列数、或是更高维度的大小。size函数的基本语法:
size(A)
size(A, dim)
- size(A):当不带第二个参数调用时,size()函数返回一个行向量,其中包含了数组A的各个维度的大小。对于最常见的二维数组(矩阵),它会返回一个包含两元素的行向量,第一个元素是行数,第二个元素是列数。对于一维数组(向量),它将返回一个单元素行向量,表示该向量的长度。
- size(A, dim):如果指定了第二个参数dim,则size函数只返回数组A在指定维度dim上的大小。在MATLAB中,维度编号从1开始。例如,size(A, 1)返回数组的行数,size(A, 2)返回列数。对于更高维度的数组,dim可以是1到数组维数的最大值
1.一维向量
B = [1 2 3 4];
len = size(B); % 返回 [4],表示长度为4
2.二维矩阵
A = [1 2; 3 4; 5 6];
sz = size(A); %返回 [2 2],表示2行2列
rows = size(A, 1); % 返回 2,表示行数
cols = size(A, 2); % 返回 3,表示列数
3.三维数组
C = zeros(3, 4, 2); % 创建一个3x4x2的三维数组
dims = size(C); % 返回[3 4 2],表示三维数组的尺寸
depth = size(C, 3); % 返回2,表示第三维的大小
3.zeros()
centroids = initial_centroids;
previous_centroids = centroids;
idx = zeros(m, 1);
- centroids:将初始聚类中心赋值给centroids,这是要迭代更新的变量
- previous_centroids:用于存储上一次迭代的聚类中心,用于比较是否需要继续迭代
- idx:初始化一个全为0的向量,用于记录每个样本点归属的聚类索引,长度等于样本数m。
在MATLAB中,zeros是一个用于创建全零数组(矩阵) 的函数,基本语法:
Z = zeros(size)
Z = zeros(sz1, ..., szN)
Z = zeros(sz, dim)
- Z = zeros(size):这是最简单的形式,其中size可以是一个标量、向量或者元胞数组(类似于结构体、对象、字典),用来指定输出数组的尺寸。如果size是一个标量,则创建一个 size x size的方阵;如果是一个向量,向量的元素分别代表数组的行数和列数,或更高维度大小。如果是元胞数组,根据元胞数组的内容生成对应尺寸的数组
- Z = zeros(sz1, ..., szN):这种形式允许直接指定数组的各维大小,例如zeros(3, 4)会创建一个3行4列的全零矩阵
- Z = zeros(sz, dim):这种形式中,sz定义了数组在除了维度dim以外的所有其他维度的大小,而dim指定的维度大小则是1.
4.findClosestCentroids()
idx = findClosestCentroids(X, centroids);
聚类分配:调用findClosestCentroids函数,该函数计算每个样本点距离所有聚类中心的距离,并为每个样本分配最近的聚类中心的索引,将结果存入idx。
function idx = findClosestCentroids(X, centroids)
K = size(centroids, 1);
idx = zeros(size(X,1), 1);
% 计算每个样本点到各个聚类中心的距离
for i = 1:size(X,1)
distances = zeros(K, 1);
for j = 1:K
distances(j) = sum((X(i,:) - centroids(j,:)).^2);
end
% 找到最近的聚类中心
[~, idx(i)] = min(distances);
end
end
-
传入参数
- X:是一个二维数组(矩阵),其中的每一行代表一个数据点,每一列代表一个特征。
- centroids:也是一个二维数组,每一行代表一个聚类中心,每一列对应一个特征维度。行数等于聚类的数量。
-
工作流程
- 初始化:为每个数据点初始化一个索引变量,准备记录它所归属的最近质心的索引。
- 计算距离:遍历数据集中的每一个数据点,计算该点与每一个聚类中心之间的距离。
- 找到最近得质心:对于每个数据点,找出距离最小得那个聚类中心,并记录下这个质心的索引
- 返回索引向量:最后,函数返回一个向量(或数组),其中的每个元素对应X中的一个数据点,值为该点分配的聚类索引。
distances(j) = sum((X(i,:) - centroids(j,:)).^2);
这行代码用来计算一个数据点到某个聚类中心得欧几里得距离得平方和
- distances(j):这是用于存储第i个数据点到第j个聚类中心得距离平方和变量。distances是一个向量,每个元素对应一个聚类中心,最终会用来找到距离最近得聚类中心。
- sum():是一个累加函数,用于计算括号内所有元素得总和
- (X(i, :) - centroids(j, :):这部分是减法操作,它计算了数据X的第i行(代表第i个数据点的所有特征值)与聚类中信centroids的第j行(代表第j个聚类中心的的所有特征值)之间的差值。结果是一个向量,每个元素表示对应特征上的差值。
- (...) .^ 2:这是对上述差值向量中的每个元素进行平方操作,即计算差值的平方。
综上所述,这行代码的完整意义是:对于数据点X中的第i个点,计算它与聚类中心centroids中第j个中心的每个特征值的差值,然后将这些差值各自平方,最后将这些平方差值相加起来可以得到距离的平方和,存储在distances(j)中。这样,通过遍历所有聚类中心,可以找到距离第i个数据点最近的聚类中心,并记录下该中心的索引。
[~, idx(i)] = min(distances);
这行代码用来找到数组中的最小值并同时获取其索引。
- min(distances):这部分的作用是计算向量distances中的最小值。distances是一个向量,其中包含了数据点到各个聚类中心的距离。min()函数会遍历这个向量,找到其中的最小值。
- [~, idx(i)]:这里使用了MATLAB的输出参数列表特性,允许你从一个函数中同时获取多个输出。波浪线
~
是一个特殊的占位符,表示你对该函数的某个输出不感兴趣,不需要保存。在本例中,min()函数默认会返回两个输出:最小值和对应的索引位置,但因为我们只需要索引,所以用~
忽略了最小值。
综上所述,这行代码的完整意义是计算distances向量中的最小值,并将这个最小值对应的索引位置赋给向量的第i个元素。这意味着,对于每个数据点,它会找到距离最近的聚类中心的索引,并记录下来,以便后续分配该数据点到相应的聚类中。
5.computeCentroids(X, idx, K)
function centroids = computeCentroids(X, idx, K)
[m, n] = size(X);
centroids = zeros(K,n);
% 对每个聚类计算新的聚类中心
for i = 1:K
centroids(i,:) = mean(X(idx == i,:));
end
end
这个函数用于计算K-means聚类算法中的新聚类中心。
function centroids = computeCentroids(X, idx, K)
- centroids:输出参数,表示计算后的聚类中心矩阵,每一行对应一个聚类中心
- X:输入参数,是一个二维矩阵,其中的每一行代表一个数据点,每一列代表一个特征。
- idx:输入参数,是一个向量,长度与X的行数相同,表示每个数据点分配到的聚类索引
- K:输入参数,表示聚类的数量
[m, n] = size(X);
centroids = zeros(K,n);
- [m, n] = size(X):获取X的行数(样本数)m和列数(特征数)n
- centroids = zeros(K, n):初始化一个K行n列的零矩阵,用于存放新的聚类中心
for i = 1:K
centroids(i,:) = mean(X(idx == i, :));
end
- for i = 1:K:循环遍历每一个聚类(从1到K)
- mean(X(idx == i, :):这里是关键步骤,idx == i 生成一个与X同形状的布尔矩阵,其中与第i类对应的数据点位置为真(非0),其余为假(零)。然后用这个布尔矩阵索引X,仅选取第i类的所有数据点。mean()计算这些数据点再每一列的平均值,即计算再第i类的质心在每个特征维度上的平均值
- centroids(i, :) = ...:将计算得到的第i类的质心值赋给centroids矩阵的第i行,完成一个聚类中心的更新
综上所述,函数的主要作用是根据当前数据点到聚类的分配情况(由idx给出),重新计算每个聚类的中心(均值)。这是K-means算法中“更新聚类中心”步骤的实现,通过不断迭代这个过程,聚类中心会逐渐趋于稳定,直到满足停止条件(如质心移动距离小于阈值或达到迭代上限)。
1.mean(X(idx == i, :))生成布尔矩阵
在MATLAB中,像 idx == i 这样的表达式,它实际上是在执行一个元素的比较操作。这里的idx 和 i都是向量或者数组。表达式的运算结果会是一个与idx 和 i 形状相同的逻辑数组(也常被称为布尔矩阵),其中的每个元素是true或者false。例如:
idx = [1, 2, 3, 2, 1];
i = 2;
boolMatrix = idx == i;
执行上述代码后,boolMatrix 将会是[false, true, false, true, false];
mean(X(idx == i, :))工作流程:
-
生成布尔矩阵:首先,通过 idx == i 比较操作生成一个逻辑数组,该数组指示 X 中哪些行的索引匹配 i。
-
索引操作:然后,这个逻辑数组被用作 X 的行索引来选取数据。在 MATLAB 中,当你用一个布尔数组作为索引时,它会选择那些对应位置为 true的元素。所以 X(idx == i, :) 实际上选取了 X 中所有索引为 i 的行。
-
计算平均值:最后,mean 函数被应用到这些选中的行上,计算它们的平均值。这意味着你会得到一个标量结果,代表索引为
i
的所有行的平均值。
2.mean()函数
用于计算数组中元素的平均值
1.一维数组
A = [1, 2, 3, 4, 5];
avg = mean(A); % avg将会是3,因为(1+2+3+4+5)/5=3
2.二维数组
按列(默认)沿着行方向操作,计算得到每一列的平均值
B = [1, 2; 3, 4; 5, 6];
colMeans = mean(B); % colMeans将会是[3; 4],即每列的平均值
按行
rowMeans = mean(B, 2); % rowMeans将会是[1.5; 3.5; 5.5],即每行的平均值