20、数据建模中的交叉验证、自助法与模型导出

数据建模中的交叉验证、自助法与模型导出

1. 自助法(Bootstrapping)

自助法的目标是更精确地评估模型在数据上的可靠性。与将数据划分为训练集和测试集不同,自助法是从原始数据集中有放回地随机抽取 n 个样本,重复 N 次(N 为迭代次数,n 为样本数量)。每次抽取的样本都独立进行分析,从而得到估计值的均值和标准差。

在 R 语言中使用 caret 包进行自助法的操作如下:

CtrlBoot = trainControl(method="boot", number=1000)
# 以下是不同算法的示例
# Naive Bayes
modelNBboot = train(Species ~ ., data = iris, 
   trControl = CtrlBoot, method = "nb")
# C4.5
modelC45boot = train(Species ~ ., data = iris, 
   trControl = CtrlBoot, method = "J48")
# C5.0
modelC50boot = train(Species ~ ., data = iris,
   trControl = CtrlBoot, method = "C5.0")
# CART
modelCARTboot = train(Species ~ ., data = iris, 
   trControl = CtrlBoot, method = "rpart")
# 随机森林
modelRFboot = train(Species ~ ., data = iris, 
   trControl = CtrlBoot, method = "rf")
2. 预测新数据

构建预测模型的目的是对未知数据进行预测。可以通过以下步骤实现:
1. 使用分层抽样将数据划分为两个集合,75% 用于交叉验证的训练和测试,25% 作为未知数据。

forCV = createDataPartition(iris$Species, p=0.75, list=FALSE)
CVset = iris[forCV,]
NEWset = iris[-forCV,]
  1. 创建交叉验证模型(以朴素贝叶斯为例)。
model = train(Species ~ ., data = CVset, trControl = CtrlCV,
   method = "nb")
  1. 使用该模型预测未知数据。
Predictions = predict(model, NEWset)
3. 使用 PMML 导出模型
3.1 什么是 PMML

PMML(Predictive Model Markup Language)是一种跨软件共享预测模型的标准。自 1997 年以来,数据挖掘组一直在开发和改进该标准。使用 PMML,用户可以在一个软件包中构建模型,并在另一个软件包中进行预测。目前,许多软件都支持使用 PMML 进行模型的导出和导入,包括 R、Rapidminer、SAS Enterprise Miner、SPSS Modeler 和 Weka 等。

支持 PMML 的算法如下表所示:
| 算法 | 函数 | 包 |
| — | — | — |
| K - 均值聚类 | kmeans | (stats) |
| 层次聚类 | hclust | (stats) |
| 关联规则挖掘 | apriori | arules |
| 线性回归 | lm | (stats) |
| 朴素贝叶斯分类与回归 | naiveBayes | e1071 |
| 分类与回归树 | rpart | rpart |
| 随机森林分类与回归 | randomForest | randomForest |
| 逻辑回归 | glm | (stats) |
| 支持向量机分类 | svm | e1071 |

3.2 PMML 对象结构简介

PMML 对象使用 XML 生成。以下是一个简单线性回归模型的 PMML 转换示例:

install.packages("pmml"); library(pmml)
model = lm (Sepal.Length ~ Sepal.Width, data = iris)
model
# 生成 PMML 代码
pmml(model)

生成的 PMML 代码结构如下:

<PMML version="4.2" xmlns="http://www.dmg.org/PMML-4_2"  
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
xsi:schemaLocation="http://www.dmg.org/PMML-4_2  
http://www.dmg.org/v4-2/pmml-4-2.xsd">
<Header copyright="Copyright (c) 2015 mayore" description="Linear 
Regression Model">
<Extension name="user" value="mayore" extender="Rattle/PMML"/>
<Application name="Rattle/PMML" version="1.4"/>
<Timestamp>2015-02-18 13:36:46</Timestamp>
</Header>
<DataDictionary numberOfFields="2">
<DataField name="Sepal.Length" optype="continuous" dataType="double"/>
<DataField name="Sepal.Width" optype="continuous" dataType="double"/>
</DataDictionary>
<RegressionModel modelName="Linear_Regression_Model" 
functionName="regression" algorithmName="least squares">
<MiningSchema>
<MiningField name="Sepal.Length" usageType="predicted"/><MiningField 
name="Sepal.Width" usageType="active"/>
</MiningSchema>
<Output>
<OutputField name="Predicted_Sepal.Length" feature="predictedValue"/>
</Output>
<RegressionTable intercept="6.52622255089448">
<NumericPredictor name="Sepal.Width" exponent="1" 
coefficient="-0.2233610611299"/>
</RegressionTable>
</RegressionModel>
</PMML>
3.3 预测模型导出示例
  • 导出 K - 均值对象
iris.kmeans = kmeans(iris[1:4],3)
pmml_kmeans = pmml(iris.kmeans)
saveXML(pmml_kmeans, data=iris, "iris_kmeans.PMML")
  • 层次聚类
DF = cbind(c(rep(1,4),rep(2,4),rep(3,4),rep(4,4)), rep(c(1,2,3,4),4), 
 rep(c(rep(1,2),rep(2,2),rep(3,2),rep(4,2)),2))
DF.hclust = hclust(dist(DF))
plot(DF.hclust)
Cut = cutree(DF.hclust, k = 2)
centroids = aggregate(DF, list(Cut), mean)
pmml_hclust = pmml(DF.hclust, centers = centroids)
saveXML(pmml_hclust, data=DF, "DF_hclust.PMML")
  • 导出关联规则(apriori 对象)
library(arules)
data(Adult,AdultUCI)
Adult.Apriori = apriori(Adult)
saveXML(pmml(Adult.Apriori), "Adult_Apriori.PMML")
  • 导出朴素贝叶斯对象
library(e1071)
iris.NaiveBayes = naiveBayes(Species ~ Sepal.Length + Sepal.Width +  
   Petal.Length + Petal.Width, data = iris)
saveXML(pmml(iris.NaiveBayes,dataset = iris, predictedField =  
   "Species"), "iris_NaiveBayes.pmml")
  • 导出决策树(rpart 对象)
iris.rpart = rpart(Species ~ Sepal.Length + Sepal.Width +  
   Petal.Length + Petal.Width, data = iris)
saveXML(pmml(iris.rpart), data = iris, "iris_rpart.pmml")
  • 导出随机森林对象
library(randomForest)
iris.RandomForest = randomForest(Species ~ Sepal.Length + Sepal.Width 
 + Petal.Length + Petal.Width, data = iris)
saveXML(pmml(iris.RandomForest), data = iris,  
   "iris_randomForest.pmml")
  • 导出逻辑回归对象
set.seed(1234)
y = c(rep(0,50),rep(1,50))
x = rnorm(100)
x[51:100] = x[51:100] + 0.2
glm.model = glm(y ~ x, family = "binomial")
saveXML(pmml(glm.model), "glm_model.PMML")
  • 导出支持向量机对象
iris.svm = svm(Species ~ Sepal.Length + Sepal.Width + Petal.Length +  
   Petal.Width, data = iris)
saveXML(pmml(iris.svm), "iris_svm.PMML")
4. 练习题

以下是一些练习题,帮助巩固所学知识:
1. 数据可视化与操作 :想象一个玩家连续 1000 次押注红色,使用数据框 Data 的 isRed 属性,玩家初始资金为 1000 美元,每次押注 1 美元。绘制游戏过程中资金的变化图,判断玩家最终是赢还是输。
2. 数据可视化(Lattice) :绘制 iris 数据集中 Petal.Length 和 Petal.Width 的关系图,并包含回归直线。
3. 聚类分析 :使用不同的距离度量(欧几里得距离、最大距离、曼哈顿距离),确定 iris 数据集(不包括 Species 属性)的最佳聚类数。
4. 层次聚类 :使用 hclust() 对 iris 数据集(不包括 Species 属性)进行聚类,使用不同的距离计算方法和链接选项。
5. 主成分分析 :对 bfi 数据集中的 25 个项目进行分析,包括检查缺失值、进行诊断、运行 PCA、确定保留的成分数、重新运行分析并保存得分、计算累积方差比例、命名成分以及分析成分与年龄的相关性。
6. 关联规则挖掘 :使用 ICU 数据集(不包括 race 属性),获取支持度为 0.1、置信度为 0.8、最小长度为 2 且前件为 pco=<=45 的关联规则,将规则对象转换为数据框,添加 Fisher 精确检验的显著性值,并可视化提升度与显著性的关系。
7. 概率分布、协方差和相关性 :计算欧洲轮盘赌中出现 40 - 49 次和 51 - 60 次红色数字的概率,计算 iris 数据集中花瓣长度和宽度的相关性。
8. 线性回归 :使用 nurses 数据集,分析工作 - 家庭冲突(WFC)对工作满意度(WorkSat)的影响,包括创建不同的模型、检查关系变化、进行 Sobel 检验。
9. K - 近邻和朴素贝叶斯分类 :使用 knn() 对 Ozone 数据集进行分类,确定最佳邻居数,并评估分类的可靠性。
10. 分类树 :使用 C4.5 和 CART 对 iris 数据集进行分类,比较测试集上的准确率,并创建评估准确率的函数。
11. 多层次分析 :使用 NursesML 数据集,可视化不同医院中疲惫感、去个性化与工作满意度的关系,确定预测值增加 1 时工作满意度的差异以及模型的截距。
12. 文本分析 :找出 tm 包中 50 篇新闻文章语料库在预处理前后出现次数超过 100 次的术语,并绘制预处理后词频大于 10 的排序词频图。

5. 练习题解决方案
  • 数据可视化与操作
money = rep(0,1001)
money[1] = 1000
wins = Data$isRed
for (i in 1:nrow(Data)) {
    if (wins[i] == 1) money[i+1] = money[i] + 1
    else money[i+1] = money[i] - 1
}
par (mfrow = c(1,1), pin=c(5,2))
plot(money, type = "l", xlab = "Trial number")
  • 数据可视化(Lattice)
library(lattice)
xyplot(Petal.Length ~ Petal.Width | Species, data = iris,
   panel = function(x, y, ...) {
      panel.xyplot(x,y)
      panel.abline(lm(y~x))
   }
)
  • 聚类分析
library(NbClust)
NbClust(iris[1:4],distance="euclidean", method= "kmeans")
NbClust(iris[1:4],distance="manhattan", method= "kmeans")
NbClust(iris[1:4],distance="maximum", method= "kmeans")
  • 层次聚类
dist.types = c("euclidean", "maximum", "manhattan", "canberra", 
   "binary", "minkowski")
d = list(dist(iris[1:4], method = dist.types[1]))
for (i in 2:length(dist.types)) d = c(d,list(dist(iris[1:4], 
   method = dist.types[i])))
agglo.types = c("ward.D", "ward.D2", "single", "complete", 
   "average", "mcquitty", "median", "centroid")
M = array(list(), 8)
for (i in 1:length(agglo.types)) {
    OneDList = list(hclust(d[[1]], method = agglo.types[i]))
    for (j in 2:length(dist.types)) OneDList = 
       c(OneDList, list(hclust(d[[j]], method = agglo.types[i])))
    M[[i]] = OneDList
}
plot(M[[4]][[1]])
  • 主成分分析
library(psych)
summary(bfi[,1:25])
Dat = na.omit(bfi[,1:25])
dim(bfi)[1] - dim(Dat)[1]
cortest.normal(Dat)
KMO(Dat)
pcas = princomp(Dat)
plot(pcas$sd^2)
pcas2 = principal(Dat,nfactors=5, rotate="varimax", scores=T)
Dat = cbind(Dat, pcas2$scores)
pcas2
  • 关联规则挖掘
library(vcdExtra)
ICU_norace = ICU[-4]
library(arules)
ICU_norace$age = cut(ICU_norace$age, breaks = 4)
ICU_norace$systolic = cut(ICU_norace$systolic, breaks = 4)
ICU_norace$hrtrate = cut(ICU_norace$hrtrate, breaks = 4)
ICU_norace_tr = as(ICU_norace, "transactions")
rulesLowpco = apriori(ICU_norace_tr, parameter = 
   list(confidence = 0.8, support=.1, minlen = 2), 
   appearance = list(lhs = c("pco=<=45"), default="rhs")) 
rulesLowpco.df = as(rulesLowpco,"data.frame")
IM = interestMeasure(rulesLowpco, "fishersExactTest",  
   ICU_norace_tr)
rulesLowpco.df$IM= round(IM, digits = 2)
plot (rulesLowpco.df$lift, rulesLowpco.df$IM, xlab = "lift", 
   ylab = "Significance")
  • 概率分布、协方差和相关性
p = 18/37
N = 100
n = 1
v40_49 = rep(1,10)
v51_60 = v40_49
i=1
for (n in 40:49) {
    v40_49[i] = choose(N, n) * (p^n) * (1 - p)^(N-n)
    i = i + 1
}
i=1
for (n in 51:60) {
    v51_60[i] = choose(N, n) * (p^n) * (1 - p)^(N-n)
    i = i + 1
}
sum(v40_49)
sum(v51_60)
cor.test(iris$Petal.Width,iris$Petal.Length)
  • 线性回归
model01 = lm(WorkSat ~ WFC, data = nurses)
model02 = lm(WorkSat ~ WFC + Exhaus, data = nurses)
summary(model01)
summary(model02)
model03 = lm(Exhaus ~ WFC, data = nurses)
summary(model03)
library(bda)
mediation.test(nurses$Exhaus, nurses$WFC, nurses$WorkSat)
  • K - 近邻和朴素贝叶斯分类
library(psych); library(class)
kappas = rep(0,9)
for (i in 1:9) {
    set.seed(2222)
    pred.train = knn(train = TRAIN[,2:13], test = TRAIN[,2:13],
       cl = TRAIN$season, k = i+1)
    tab = table(pred.train,TRAIN[,14])
    kappas[i] = cohen.kappa(tab)[1]
}
which.max(kappas)
pred.test = knn(train = TRAIN[,2:13], test = TEST[,2:13],
   cl = TRAIN$season, k = 2)
cohen.kappa(table(pred.test,TEST[,14]))[1]
  • 分类树
library(RWeka)
IRIS.C45 = J48(Species~ . , data= IRIStrain, 
   control= Weka_control(U=FALSE))
C45.preds = predict(IRIS.C45, IRIStest)
library(rpart)
IRIS.CART = rpart(Species ~. , data= IRIStrain)
CART.probs = as.data.frame(predict(IRIS.CART, IRIStest))
CART.preds = apply(CART.probs, 1, which.max)
for (i in 1:length(CART.preds)) {
    col= as.numeric(CART.preds[i]) 
    CART.preds[i] = names(CART.probs[col])
}
CONF.C45 = table(IRIStest$Species, C45.preds)
CONF.CART = table(IRIStest$Species, CART.preds)
acc = function(table) {
    sum(diag(dim(table)[1])*table) / sum(CONF.C45)
}
acc(CONF.C45)
acc(CONF.CART)
  • 多层次分析
library(lattice)
attach(NursesML)
xyplot(WorkSat~Exhaust | as.factor(hosp), panel = function(x,y) { 
    panel.xyplot(x,y) 
    panel.lmline(x,y)
})
xyplot(WorkSat~Depers | as.factor(hosp), panel = function(x,y) { 
     panel.xyplot(x,y) 
     panel.lmline(x,y)
})
coeffs(modelPred)
  • 文本分析
DTM = as.matrix(DocumentTermMatrix(acq))
FR = colSums(DTM)
FR[FR>100]
acq2 = preprocess(acq)
DTM2 = as.matrix(DocumentTermMatrix(acq2))
FR2 = colSums(DTM2)
FR2[FR2>100]
barplot(sort(FR2[FR2>30]), names.arg = rownames(sort(FR2[FR2>30])))

通过以上内容,我们学习了自助法、交叉验证、使用 PMML 导出模型的方法,并通过练习题和解决方案巩固了相关知识。这些技术和方法在数据建模和分析中具有重要的应用价值。

数据建模中的交叉验证、自助法与模型导出

6. 方法总结与对比

在前面的内容中,我们介绍了自助法、交叉验证以及使用 PMML 导出模型等多种方法。下面对这些方法进行总结和对比,以便更好地理解它们的特点和适用场景。

方法 目的 操作步骤 适用场景
自助法 更精确地评估模型在数据上的可靠性 从原始数据集中有放回地随机抽取 n 个样本,重复 N 次,每次抽取的样本独立进行分析 当需要对模型的可靠性进行更精确的估计时使用
交叉验证 评估模型的泛化能力 将数据划分为训练集和测试集,多次重复划分和训练测试过程,取平均结果 用于评估模型在不同数据集上的表现,选择最优模型
PMML 导出模型 跨软件共享预测模型 将模型作为参数传递给 pmml() 函数生成 PMML 代码,保存为 XML 文件 需要在不同软件之间共享模型时使用
7. 流程梳理

为了更清晰地展示这些方法的使用流程,下面使用 mermaid 格式的流程图进行梳理。

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;

    A([开始]):::startend --> B{选择方法}:::decision
    B -->|自助法| C(设置参数,进行抽样和分析):::process
    B -->|交叉验证| D(划分数据集,训练和测试模型):::process
    B -->|PMML 导出模型| E(生成 PMML 代码,保存为 XML 文件):::process
    C --> F(评估模型可靠性):::process
    D --> G(评估模型泛化能力):::process
    E --> H(在其他软件中使用模型):::process
    F --> I([结束]):::startend
    G --> I
    H --> I
8. 深入理解与拓展
8.1 自助法的原理和优势

自助法的核心思想是通过有放回的抽样来模拟从总体中多次抽样的过程。这种方法可以在不增加数据量的情况下,通过多次抽样得到多个样本,从而更全面地评估模型的可靠性。自助法的优势在于它可以处理各种类型的数据,并且不需要对数据的分布做出假设。

8.2 交叉验证的不同方式

交叉验证有多种方式,如 k - 折交叉验证、留一交叉验证等。k - 折交叉验证将数据划分为 k 个子集,每次选择一个子集作为测试集,其余子集作为训练集,重复 k 次。留一交叉验证则是每次只留下一个样本作为测试集,其余样本作为训练集,重复 n 次(n 为样本数量)。不同的交叉验证方式适用于不同的数据集和问题,需要根据具体情况进行选择。

8.3 PMML 的应用场景和发展趋势

PMML 作为一种跨软件共享预测模型的标准,具有广泛的应用场景。它可以方便地在不同的软件之间共享模型,提高模型的复用性和可移植性。随着数据挖掘和机器学习的发展,PMML 的应用也越来越广泛,未来可能会在更多的领域得到应用。

9. 注意事项和常见问题

在使用这些方法时,需要注意以下几点:
1. 数据预处理 :在进行自助法、交叉验证或模型导出之前,需要对数据进行预处理,包括缺失值处理、异常值处理、特征选择等。
2. 参数选择 :不同的方法有不同的参数需要选择,如自助法的抽样次数、交叉验证的折数等。参数的选择会影响方法的效果,需要根据具体情况进行调整。
3. 模型评估指标 :在评估模型时,需要选择合适的评估指标,如准确率、召回率、F1 值等。不同的评估指标适用于不同的问题,需要根据具体情况进行选择。

常见问题及解决方法如下:
| 问题 | 解决方法 |
| — | — |
| 自助法抽样结果不稳定 | 增加抽样次数,或者使用更稳定的抽样方法 |
| 交叉验证结果差异较大 | 检查数据的分布情况,调整折数或使用其他交叉验证方式 |
| PMML 导出的模型在其他软件中无法使用 | 检查 PMML 代码的格式是否正确,确保其他软件支持 PMML 标准 |

10. 总结与展望

通过本文的介绍,我们学习了自助法、交叉验证和使用 PMML 导出模型的方法,了解了它们的原理、操作步骤、适用场景以及注意事项。这些方法在数据建模和分析中具有重要的应用价值,可以帮助我们更准确地评估模型的性能,提高模型的泛化能力,实现模型的跨软件共享。

未来,随着数据挖掘和机器学习技术的不断发展,这些方法也将不断完善和创新。例如,自助法可能会与深度学习相结合,提高模型的训练效率和可靠性;交叉验证可能会采用更智能的方式进行数据集的划分,提高评估的准确性;PMML 可能会支持更多的算法和模型类型,进一步拓展其应用范围。

希望本文能够帮助读者更好地理解和应用这些方法,在实际的数据建模和分析中取得更好的效果。

【四旋翼无人机】具备螺旋桨倾斜机构的全驱动四旋翼无人机:建模控制研究(Matlab代码、Simulink仿真实现)内容概要:本文围绕具备螺旋桨倾斜机构的全驱动四旋翼无人机展开研究,重点探讨其系统建模控制策略,结合Matlab代码Simulink仿真实现。文章详细分析了无人机的动力学模型,特别是引入螺旋桨倾斜机构后带来的全驱动特性,使其在姿态位置控制上具备更强的机动性自由度。研究涵盖了非线性系统建模、控制器设计(如PID、MPC、非线性控制等)、仿真验证及动态响应分析,旨在提升无人机在复杂环境下的稳定性和控制精度。同时,文中提供的Matlab/Simulink资源便于读者复现实验并进一步优化控制算。; 适合人群:具备一定控制理论基础和Matlab/Simulink仿真经验的研究生、科研人员及无人机控制系统开发工程师,尤其适合从事飞行器建模先进控制算研究的专业人员。; 使用场景及目标:①用于全驱动四旋翼无人机的动力学建模仿真平台搭建;②研究先进控制算(如模型预测控制、非线性控制)在无人机系统中的应用;③支持科研论文复现、课程设计或毕业课题开发,推动无人机高机动控制技术的研究进展。; 阅读建议:建议读者结合文档提供的Matlab代码Simulink模型,逐步实现建模控制算,重点关注坐标系定义、力矩分配逻辑及控制闭环的设计细节,同时可通过修改参数和添加扰动来验证系统的鲁棒性适应性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值