“应用多输出KNN回归解决2023美赛C题第二小问:一种简单有效的模型预测方法”

       受到一篇O奖论文启发,对于2023美赛C题第2小问采用多输出KNN回归解决,此方法的好处是:1.可解释性好。2.保证最后加起来百分比还是100%。3.算法实施简单,便于理解。
第二小问题目如下:
● 对于未来日期的给定未来解决方案词,开发一个模型,允许您预测报告结果的分布。换句话说,来预测未来一个日期的(1、2、3、4、5、6、X)的相关百分比。你的模型和预测有哪些不确定性?
2023美赛C题原文请查阅https://zhuanlan.zhihu.com/p/615471028
       接下来,讲述使用KNN算法解决第2小问的步骤:
       KNN(K-Nearest Neighbor)算法是机器学习算法中一种有监督算法,它既能用于分类,也能用于回归。KNN通过计算某一事物特征值之间的距离来进行分类或回归,它通常的使用形式是多输入-单输出。但在此问题中,单词的特征是多维度,而其输出,尝试次数(1,2,3,4,5,6,7)是多维度的。为了使其适应多重输出多重输出(MIMO)的预测问题,将其改造为MIMO-KNN算法。
首先介绍普通的KNN回归算法:
1.KNN算法用于回归预测时,由于指标的单位或者⼤⼩相差较⼤,或者某特征的⽅差相⽐其他的特征要⼤出⼏个数量级,容易影响(⽀配)⽬标结果,使得算法⽆法学习到其它的特征。,我们需对指标进行z-score标准化,使不同规格的数据转换到同⼀规格。
z = x − μ σ \mathrm{z=\frac{x-\mu}\sigma} z=σxμ
2.计算各个目标之间的距离来寻找新来的预测实例的 k 近邻,此处选用欧几里得距离。
d 12 = ∑ k = 1 n ( x 1 k − x 2 k ) 2 d_{12}=\sqrt{\sum_{k=1}^{n}(x_{1k}-x_{2k})^{2}} d12=k=1n(x1kx2k)2

3.然后对这 k 个样本的目标值取 均值 即可作为新样本的预测值:
y ^ = 1 K ∑ i = 1 K y i \hat{y}=\frac{1}{K}\sum_{i=1}^K{y_i} y^=K1i=1Kyi
上述算法只能应对单输出预测情况,为了使其适应多输出的情况,需要将其进行修改,使其适应多输出预测情况,上述预测公式需要改成如下
y ^ j = 1 K ∑ i = 1 K y j i   ,   j = 1 , 2 , . . . , 7 ← \hat{y}_j=\frac{1}{K}\sum_{i=1}^K{y_{ji}}\ ,\ j=1,2,...,7\gets y^j=K1i=1Kyji , j=1,2,...,7
       上述式子只有一个参数未知,为了得到最佳的参数值,上述问题可以转化为以下优化问题,采用均方误差(MSE)最小原则.
min ⁡  MSE = 1 n ∑ j = 1 n ( y j − y ^ j ) 2 = 1 7 ∑ j = 1 7 ( y j − y ^ j ) 2 s . t . y ^ j = 1 K ∑ i = 1 K y j i   ,   j = 1 , 2 , . . . , 7 ← \begin{aligned}\min\text{ MSE}&=\frac1n\sum_{j=1}^n\left(y_j-\hat{y}_j\right)^2=\frac17\sum_{j=1}^7\left(y_j-\hat{y}_j\right)^2\\\\s.t.&\hat{y}_j=\frac1K\sum_{i=1}^Ky_{ji}~,~j=1,2,...,7\leftarrow\end{aligned} min MSEs.t.=n1j=1n(yjy^j)2=71j=17(yjy^j)2y^j=K1i=1Kyji , j=1,2,...,7
       参数K的取值一般不超过20,因此对参数在1到20范围内遍历搜索,训练集和测试集按80%,20%的比例划分,计算相应的MSE,最小的MSE对应的K值,即为最优K值,从而可以进行随后的预测。

整体matlab代码如下:

clc
clear all
close all
data_zhen=readmatrix('Problem_C_Data_Wordle.xlsx','range','g2:m359');
data_bian=readmatrix('Problem_C_Data_Wordle.xlsx','range','n2:q359');
%Z-score标准化
%data_bian_new = zscore(data_bian);
%data_bian=data_bian_new';
% %min-max标准化
% data_bian_new = mapminmax(data_bian',0,1);
% data_bian=data_bian_new';
data=readmatrix('Problem_C_Data_Wordle.xlsx','range','f2:f359');
sample_number=length(data_bian);
train_number=floor(0.8*sample_number);
test_number=sample_number-train_number;

%%%%%%%%训练集80测试集20
y_zhen=data_zhen(1:train_number,:);
x_zhun=data_bian(1:train_number,:);


y_zhen_test=data_zhen(train_number+1:end,:);
x_zhun_test=data_bian(train_number+1:end,:);

cishu=length(y_zhen);
%y_yuce=0;
distance=zeros(cishu,1);

y_yuce=zeros(cishu,size(data_zhen,2));
%k=3;%%%%%%%%%%%%%邻居数量

k_zuijia=1;
eps=inf;
temp=0;
for k=1:1:20
for i=1:1:cishu
    distance(i)=inf;
    for j=1:1:cishu
        if(i~=j)
        distance(j)=norm(x_zhun(i,:)-x_zhun(j,:));
        end
    end
    %将dist从小到大进行排序
    [Y,I]=sort(distance,1);   
    I=I(1:k);
    y_yuce(i,1:size(data_zhen,2))=mean(y_zhen(I,1:size(data_zhen,2)));

end
temp=norm(y_yuce-y_zhen);
if(temp<eps)
    eps=temp;
    k_zuijia=k;
end
end
%%%%%%%%%%%%%%训练集 评估
k=k_zuijia;
for i=1:1:cishu
    distance(i)=inf;
    for j=1:1:cishu
        if(i~=j)
        distance(j)=norm(x_zhun(i,:)-x_zhun(j,:));
        end
    end
    %将dist从小到大进行排序
    [Y,I]=sort(distance,1);   
    I=I(1:k);
    y_yuce(i,1:size(data_zhen,2))=mean(y_zhen(I,1:size(data_zhen,2)));
end

figure

for i=1:1:size(data_zhen,2)
subplot(3,3,i)
plot(y_zhen(:,i),'r-');
hold on
plot(y_yuce(:,i),'bo-');
legend('Actual data','Prediction');
title(strcat('Training Set: try',num2str(i)));
end

grid on

x_ceshu=[7.5,4,3,420];
y_test=zeros(1,size(data_zhen,2));
for i=1:1:cishu

    distance(i)=norm(x_ceshu-x_zhun(i,:));
    %将dist从小到大进行排序
end

    [Y,I]=sort(distance,1);   
    I=I(1:k);
    y_test(i,1:size(data_zhen,2))=mean(y_zhen(I,1:size(data_zhen,2)));
R2=zeros(1,7);
MSE=zeros(1,7);
RMSE=zeros(1,7);
MAE=zeros(1,7);
for i=1:1:7
[mse,rmse,mae,r2,text,n]=model_evaluation(y_zhen(:,i),y_yuce(:,i));
R2(i)=r2;
MSE(i)=mse;
RMSE(i)=rmse;
MAE(i)=mae;

end

ave=mean(R2);
disp(strcat('训练集的拟合优度R2=',num2str(ave)));
%%%%%%%%%%%%%%测试集评估

%y_zhen_test=data_zhen(train_number+1:end,:);
%x_zhun_test=data_bian(train_number+1:end,:);
distance=zeros(length(x_zhun_test),1);
y_yuce_test=zeros(1,size(data_zhen,2))
k=k_zuijia;
for i=1:1:length(x_zhun_test)
    distance(i)=inf;
    for j=1:1:length(x_zhun_test)
        if(i~=j)
        distance(j)=norm(x_zhun_test(i,:)-x_zhun_test(j,:));
        end
    end
    %将dist从小到大进行排序
    [Y,I]=sort(distance,1);   
    I=I(1:k);
    y_yuce_test(i,1:size(data_zhen,2))=mean(y_zhen_test(I,1:size(data_zhen,2)));
end


TEST_R2=zeros(1,7);
TEST_MSE=zeros(1,7);
TEST_RMSE=zeros(1,7);
TEST_MAE=zeros(1,7);
for i=1:1:7
[mse,rmse,mae,r2,text,n]=model_evaluation(y_zhen_test(:,i),y_yuce_test(:,i));
TEST_R2(i)=r2;
TEST_MSE(i)=mse;
TEST_RMSE(i)=rmse;
TEST_MAE(i)=mae;

end
ave1=mean(TEST_R2);
disp(strcat('测试集的拟合优度R2=',num2str(ave1)));

figure
for i=1:1:size(data_zhen,2)
subplot(3,3,i)
plot(y_zhen_test(:,i),'r-');
hold on
plot(y_yuce_test(:,i),'bo-');
legend('Actual data','Prediction');
title(strcat('Testing Set: try',num2str(i)));
grid on
end

训练集上测试效果:
训练集
训练集的拟合优度R2=0.65337
在这里插入图片描述

测试集:

测试集
测试集的拟合优度R2=0.54502
在这里插入图片描述
测试集的拟合优度较低,主要是数据中存在一些突变值,此算法对于突变值的拟合效果不是很好。

本文完整代码文件及数据集请在下面的百度云网盘连接下载:
链接: https://pan.baidu.com/s/11LAJ_bRDAMCwLhO2bikfEw?pwd=uz3u 提取码: uz3u

  • 20
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值