cvpartition 函数
cvpartition
函数是 MATLAB 中用于生成交叉验证数据集索引的函数。交叉验证是一种常用的机器学习方法,用于评估和选择模型,避免过拟合。
cvpartition
函数的基本语法如下:
c = cvpartition(group,'KFold',k)
其中,group
是一个向量,表示数据集中每个样本所属的类别或分组;'KFold'
表示使用 K 折交叉验证方法;k
表示将数据集分成 K 份。c
是一个 cvpartition
类型的对象,保存了交叉验证数据集的索引,可以用于训练和测试模型。
下面是 cvpartition
函数的一些常用参数和用法:
'HoldOut'
方法:将数据集分成训练集和测试集两部分,可以使用'HoldOut'
方法生成索引。语法如下:matlabc = cvpartition(group,'HoldOut',p)
其中,
p
表示将数据集分成的测试集的比例,通常取值为 0.5 ~ 0.9。'LeaveOut'
方法:将每个样本单独作为测试集,其他样本作为训练集,可以使用'LeaveOut'
方法生成索引。语法如下:matlabc = cvpartition(group,'LeaveOut')
'StratifiedKFold'
方法:在 K 折交叉验证中,保持每个类别的样本比例相同,可以使用'StratifiedKFold'
方法生成索引。语法如下:matlabc = cvpartition(group,'StratifiedKFold',k)
'StratifiedHoldOut'
方法:将数据集分成训练集和测试集两部分,并根据每个类别的样本比例保持训练集和测试集中每个类别的样本比例相同,可以使用'StratifiedHoldOut'
方法生成索引。语法如下:matlabc = cvpartition(group,'StratifiedHoldOut',p)
其中,
p
表示将数据集分成的训练集的比例。'StratifiedLeaveOut'
方法:将每个样本单独作为测试集,其他样本作为训练集,并根据每个类别的样本比例保持训练集和测试集中每个类别的样本比例相同,可以使用'StratifiedLeaveOut'
方法生成索引。语法如下:matlabc = cvpartition(group,'StratifiedLeaveOut')
返回值
使用 cvpartition
函数的 'HoldOut'
方法生成训练集和测试集的索引时,返回一个 cvpartition
类型的对象,该对象包含两个属性:
trainingIndices
:训练集的索引,是一个逻辑向量,其中训练集对应的位置为true
,测试集对应的位置为false
。对应数组为 1 或 0 。testIndices
:测试集的索引,是一个逻辑向量,其中测试集对应的位置为true
,训练集对应的位置为false
。
例如,如果使用以下语句将数据集 data
分成训练集和测试集:
c = cvpartition(n,'HoldOut',p);
trainData = data(c.trainingIndices,:);
testData = data(c.testIndices,:);
则 c.trainingIndices
和 c.testIndices
分别是大小为 n
的逻辑向量,其中 c.trainingIndices(i)
和 c.testIndices(i)
分别表示第 i
个样本是否属于训练集或测试集。
需要注意的是,使用 'HoldOut'
方法生成训练集和测试集的索引时,需要根据具体的应用场景选择合适的训练集比例 p
,通常取值为 0.5 ~ 0.9。选择过小的训练集比例可能导致模型过拟合,而选择过大的训练集比例可能导致模型欠拟合。
加载鸢尾花数据集
首先,加载鸢尾花数据集:
Copy code
load fisheriris
接着,将数据集和类别分开:
Copy codeX = meas;
Y = species;
然后,使用cvpartition
函数将数据集划分为训练集和测试集。在这个例子中,我们将70%的数据用于训练,30%的数据用于测试:
Copy codecv = cvpartition(Y,'HoldOut',0.3);
idx = cv.test;
现在,我们可以将训练集和测试集分开:
Copy codeXtrain = X(~idx,:);
Ytrain = Y(~idx,:);
Xtest = X(idx,:);
Ytest = Y(idx,:);
逗号分隔符
KNN分类器
clear
load fisheriris
X = meas;
Y = species;
cv = cvpartition(Y,'HoldOut',0.3);
idx = cv.test;
Xtrain = X(~idx,:);
Ytrain = Y(~idx,:);
Xtest = X(idx,:);
Ytest = Y(idx,:);
mdl = fitcknn(Xtrain,Ytrain,'NumNeighbors',5);
Ypredict = predict(mdl,Xtest);
accuracy = sum(strcmp(Ytest,Ypredict))/numel(Ytest);
disp(["分类准确率",accuracy])
这段代码使用了鸢尾花数据集(fisheriris
),将数据集划分为训练集和测试集,并训练了一个k-NN
分类器。接下来对测试集进行分类并计算分类的准确率。
代码中 cvpartition
函数使用了“Holdout”方法将数据集分为训练集和测试集。其中,Holdout
的参数 0.3
表示将数据集划分为训练集和测试集的比例为 $7:3$,即测试集占总数据集的 $30%$。函数返回一个 cv
对象,其中 test
属性包含了测试集的索引。
接着,通过索引 idx
将数据集划分为训练集和测试集。训练集包含了 ~idx
所表示的索引,测试集包含了 idx
所表示的索引。
然后,使用 fitcknn
函数训练了一个 k-NN
分类器。NumNeighbors
参数指定了 k
的值为 5。函数返回一个分类器模型 mdl
。
之后,通过 predict
函数对测试集进行分类,得到了分类结果 Ypredict
。通过 strcmp
函数比较测试集真实标签 Ytest
和预测标签 Ypredict
的值是否相等,得到分类的准确率。最后使用 disp
函数输出准确率的值。
k-means 聚类器
clear
% 加载鸢尾花数据集
load fisheriris;
% 提取特征矩阵
X = meas;
% 将特征矩阵标准化
X = zscore(X);
% 设置聚类数目和迭代次数
k = 3;
maxIter = 100;
% 使用 K-means 算法进行聚类
[idx, C] = kmeans(X, k, 'MaxIter', maxIter);
% 聚类结果为 idx 聚类中心为 C
% 绘制聚类结果
gscatter(X(:,1), X(:,2), idx);
hold on;
plot(C(:,1), C(:,2), 'kx', 'MarkerSize', 10, 'LineWidth', 2);
legend('Cluster 1', 'Cluster 2', 'Cluster 3', 'Centroids');
title('K-means Clustering of Iris Data');
xlabel('Sepal Length (cm)');
ylabel('Sepal Width (cm)');
首先,通过 load fisheriris
命令加载鸢尾花数据集。然后,将特征矩阵 meas
提取出来并进行标准化处理,即使用 zscore
命令将每个特征的均值归零、方差归一。这一步是为了使得每个特征对聚类结果的贡献相同。
接下来,通过 k = 3
和 maxIter = 100
命令设置聚类数目和最大迭代次数。在本例中,我们设置聚类数目为 3,即将数据集分为 3 类。同时,我们也设置了最大迭代次数为 100,以确保算法能够在可接受的时间内收敛。
然后,使用 kmeans
命令对标准化后的特征矩阵 X
进行聚类分析,并返回聚类索引 idx
和聚类中心 C
。其中,聚类索引 idx
是一个列向量,包含了每个样本所属的聚类编号;聚类中心 C
是一个矩阵,其中每行对应一个聚类中心,列数等于特征数。
最后,使用 gscatter
命令将聚类结果绘制在二维平面上。gscatter
命令需要三个输入参数:X、Y 和 G,其中 X 和 Y 是两个列向量,分别表示每个样本在二维平面上的横纵坐标;G 是一个列向量,表示每个样本所属的聚类编号。hold on
命令是为了使得后面的 plot
命令能够将聚类中心绘制在同一幅图中。最后,通过 legend
、title
、xlabel
和 ylabel
命令设置图例、标题、横纵坐标轴的标签。