我正在使用广义线性模型进行回归分析。在使用crossVal
函数时遇到了困难。以下是我目前的实现方式:
x = '一些包含输入和输出的数据集'X = x(:,1:7);Y = x(:,8);cvpart = cvpartition(Y,'holdout',0.3);Xtrain = X(training(cvpart),:);Ytrain = Y(training(cvpart),:);Xtest = X(test(cvpart),:);Ytest = Y(test(cvpart),:);mdl = GeneralizedLinearModel.fit(Xtrain,Ytrain,'linear','distr','poisson');Ypred = predict(mdl,Xtest);res = (Ypred - Ytest);RMSE_test = sqrt(mean(res.^2));
下面的代码是用于计算多重回归的交叉验证,来自于这个链接。我希望能为广义线性模型找到类似的方法。
c = cvpartition(Y,'k',10);regf=@(Xtrain,Ytrain,Xtest)(Xtest*regress(Ytrain,Xtrain));cvMse = crossval('mse',X,Y,'predfun',regf)
回答:
你可以手动执行交叉验证过程(为每个折叠训练模型,预测结果,计算误差,然后报告所有折叠的平均值),或者你可以使用CROSSVAL函数,它将整个过程包装在一个调用中。
举个例子,我将首先加载并准备一个数据集(统计工具箱附带的汽车数据集的一个子集):
% 加载回归数据集load carsmallX = [Acceleration Cylinders Displacement Horsepower Weight];Y = MPG;% 移除包含缺失值的实例missIdx = isnan(Y) | any(isnan(X),2);X(missIdx,:) = [];Y(missIdx) = [];clearvars -except X Y
选项1
在这里,我们将使用k折交叉验证手动划分数据,使用cvpartition(非分层)。对于每个折叠,我们使用训练数据训练一个GLM模型,然后使用该模型预测测试数据的输出。接下来,我们计算并存储该折叠的回归均方误差。最后,我们报告所有分区的平均RMSE。
% 将数据划分为10个折叠K = 10;cv = cvpartition(numel(Y), 'kfold',K);mse = zeros(K,1);for k=1:K % 当前折叠的训练/测试索引 trainIdx = cv.training(k); testIdx = cv.test(k); % 训练GLM模型 mdl = GeneralizedLinearModel.fit(X(trainIdx,:), Y(trainIdx), ... 'linear', 'Distribution','poisson'); % 预测回归输出 Y_hat = predict(mdl, X(testIdx,:)); % 计算均方误差 mse(k) = mean((Y(testIdx) - Y_hat).^2);end% 计算k折的平均RMSEavrg_rmse = mean(sqrt(mse))
选项2
在这里,我们可以简单地调用CROSSVAL,并传入一个适当的函数句柄,该函数句柄在给定一组训练/测试实例时计算回归输出。请参阅文档页面以了解参数的含义。
% 给定训练/测试实例的预测函数fcn = @(Xtr, Ytr, Xte) predict(... GeneralizedLinearModel.fit(Xtr,Ytr,'linear','distr','poisson'), ... Xte);% 执行交叉验证,并返回所有折叠的平均MSEmse = crossval('mse', X, Y, 'Predfun',fcn, 'kfold',10);% 计算均方根误差avrg_rmse = sqrt(mse)
你应该会得到与之前相似的结果(当然会略有不同,因为交叉验证中涉及到随机性)。