R语言文本分析与模型验证
1. 模型预测与支持向量机分类
在进行文本分析时,我们可以使用已创建的模型对测试集的值进行预测。以下是具体的操作步骤:
# 使用模型预测测试集的值
TestDF$classif = predict(model2, TestDF, type = "response")
TestDF$classif[TestDF$classif>0.5] = 1
TestDF$classif[TestDF$classif<=0.5] = 0
confusionMatrix(TestDF$quality, TestDF$classif)
从屏幕输出可以看出,测试数据集的预测效果比训练数据集差。不过,准确率仍有0.72,还算不错,但kappa值降至0.45。我们可以尝试使用支持向量机(SVM)算法来获得更好的结果。
支持向量机试图在两类之间找到尽可能宽的分隔。根据样本在分隔中的位置进行分类。与逻辑回归不同,SVM不限于线性关系,通过核技巧可以发现任何类型的关系。以下是使用SVM拟合模型并检查预测可靠性的步骤:
# 加载e1071包
library(e1071)
# 使用SVM拟合模型
modelSVM = svm (quality ~ ., data = TrainDF)
# 预测训练集
probSVMtrain = predict(modelSVM, TrainDF[,-1])
classifSVMtrain = probSVMtrain
classifSVMtrain[classifSVMtrain>0.5] = 1
classifSVMtrain[classifSVMtrain<=0.5] = 0
confusionMatrix(TrainDF$quality, classifSVMtrain)
在训练数据集上,SVM的分类效果非常好,准确率为0.93,kappa值为0.85,比逻辑回归更好。那在测试集上的分类性能如何呢?我们来看看:
# 预测测试集
probSVMtest = predict(modelSVM, TestDF[,-1])
classifSVMtest = probSVMtest
classifSVMtest[classifSVMtest>0.5] = 1
classifSVMtest[classifSVMtest<=0.5] = 0
confusionMatrix(TestDF$quality, classifSVMtest)
遗憾的是,测试集的分类效果不如逻辑回归,甚至稍差一些。不过,根据具体情况,该算法的性能(这里71%的数据被正确分类,kappa = 0.42)可能是足够的。
2. 新闻挖掘与文档分类
接下来,我们将探讨如何使用R进行新闻挖掘。首先是一个成功的文档分类案例。我们有一个包含2071篇标题中包含“flu”的新闻文章的数据集,这些文章来自《纽约时报》和《卫报》。以下是具体的操作步骤:
# 加载数据集
Strands = read.csv("StrandsPackt.csv", header = T)
# 查看关于季节性流感的文章数量
colSums(Strands[1])
输出结果显示有777篇关于季节性流感的文章。我们的任务是预测文章中讨论的流感是季节性流感还是其他类型。在进行预测之前,我们可以检查与每个类别相关的最频繁的术语:
# 提取季节性流感文章
Seasonal = subset(Strands, SEASONAL.FLU == 1)
# 计算季节性流感文章中术语的频率
FreqSeasonal = colSums(Seasonal)[-1]
# 查看前20个最频繁的术语
head(FreqSeasonal[order(FreqSeasonal, decreasing=T)], 20)
输出结果显示了讨论季节性流感的文章中文档频率最高的前20个术语,如“year”、“peopl”、“vaccin”等。同样,我们可以检查其他类型流感文章的最频繁术语:
# 提取其他类型流感文章
Other = subset(Strands, SEASONAL.FLU == 0)
# 计算其他类型流感文章中术语的频率
FreqOther = colSums(Strands[Strands[,1] == 0])[-1]
# 查看前20个最频繁的术语
head(FreqOther[order(FreqOther, decreasing=T)], 20)
可以看到,两类文章中最频繁的术语有所不同,但也有一些共同的术语,如“influenza”、“vaccine”和“viru”。由于最频繁术语的重叠度较低,我们有希望对文章进行分类。
由于术语 - 文档矩阵中有数千个术语,逻辑回归无法处理特征数量超过样本数量的情况。我们可以使用集成学习的方法,即重复进行100次逻辑回归分析,每次使用不同的300个随机预测变量,然后汇总结果概率来确定文章的类别。以下是具体的操作步骤:
# 设置随机种子
set.seed(1234)
# 确定训练实例
TrainCases = sample(1:nrow(Strands),1086)
# 创建矩阵存储训练集和测试集的预测结果
TrainPredictions = matrix(ncol=1086,nrow=100)
TestPredictions = matrix(ncol=1085,nrow=100)
# 运行100次逻辑回归分析
for (i in 1:100) {
UNUSED = sample(2:ncol(Strands), ncol(Strands)-300)
Strands2 = Strands[,-UNUSED]
StrandsTrain = Strands2[TrainCases,]
StrandsTest = Strands2[-TrainCases,]
model = glm(StrandsTrain$SEASONAL.FLU~., data = StrandsTrain, family="binomial")
TrainPredictions[i,] = t(predict(model,StrandsTrain, type="response"))
TestPredictions[i,] = t(predict(model,StrandsTest, type="response"))
}
# 计算训练集和测试集的平均概率预测并进行分类
PredsTrain = colMeans(TrainPredictions)
PredsTrain[PredsTrain< .5] = 0
PredsTrain[PredsTrain>= .5] = 1
PredsTest = colMeans(TestPredictions)
PredsTest[PredsTest< .5] = 0
PredsTest[PredsTest>= .5] = 1
# 检查训练集的分类可靠性
confusionMatrix(PredsTrain,StrandsTrain$SEASONAL.FLU)
# 检查测试集的分类可靠性
confusionMatrix(PredsTest,StrandsTest$SEASONAL.FLU)
训练集的分类几乎完美,准确率超过99%,kappa值约为0.98;测试集的分类效果也不错,超过86%的案例被正确分类,kappa值为0.69。
3. 文章主题提取
我们已经能够可靠地分类文章是否讨论季节性流感,接下来可以提取文章的主题。首先,我们将两类文章分开,并去除区分它们的属性:
# 提取季节性流感文章
Seasonal = subset(Strands,SEASONAL.FLU ==1)[,-1]
# 提取非季节性流感文章
Non.Seasonal = subset(Strands,SEASONAL.FLU ==0)[,-1]
# 安装并加载qdap包
install.packages("qdap"); library(qdap)
# 将数据框转换为tm文档 - 词项矩阵
seasonal.tm <- as.dtm(as.wfm(t(Seasonal)))
non.seasonal.tm <- as.dtm(as.wfm(t(Non.Seasonal)))
# 安装并加载topicmodels包
install.packages("topicmodels"); library(topicmodels)
# 为每个文档 - 词项矩阵生成两个主题
Topics.seasonal = LDA(seasonal.tm, 2)
Topics.non.seasonal = LDA(non.seasonal.tm, 2)
# 查看每个主题关联的前10个术语
Terms.seasonal = terms(Topics.seasonal, 20)
Terms.non.seasonal = terms(Topics.non.seasonal, 20)
Terms.seasonal
Terms.non.seasonal
对于季节性流感文章,主题1与季节性、具体的预防措施和流感病例数相关;主题2与季节性以及更抽象的预防措施相关。对于非季节性流感文章,两个主题都与病毒传播有关,但主题1侧重于病毒报告,主题2侧重于病毒的传播。
4. 从纽约时报API收集新闻文章
搜索新闻和比较信息可能会花费大量时间。我们可以使用R简化这个过程。以下是具体的操作步骤:
# 安装并加载tm.plugin.webmining包
install.packages("tm.plugin.webmining")
library(tm.plugin.webmining)
我们需要从http://developer.nytimes.com/获取开发者密钥。获取密钥后,我们可以下载与欧元相关的新闻文章:
# 设置开发者密钥
nytimes_appid = "YOUR_KEY_HERE"
# 下载新闻文章
NYtimesNews <- WebCorpus(NYTimesSource("Euro", appid = nytimes_appid))
NYtimesNews
默认情况下,会下载100篇文章。我们可以保存文章内容,添加新文章,预处理文本并构建词项 - 文档矩阵:
# 保存文章内容
writeCorpus(NYtimesNews, path = "M:/")
# 添加新文章
updated = corpus.update(NYtimesNews)
# 预处理文本
preprocessedNews = preprocess(NYtimesNews)
# 构建词项 - 文档矩阵
tdmNews = TermDocumentMatrix(preprocessedNews)
# 加载保存的词项 - 文档矩阵
loaded_tdm = dget("tdmNews")
# 查看最频繁的术语
findFreqTerms(loaded_tdm, low = 100)
输出结果显示了出现次数超过100次的术语,如“bank”、“euro”、“germani”等。我们还可以检查词项之间的关联:
# 检查词项关联
Assocs = findAssocs(loaded_tdm, terms = c("bank", "greek"), corlim = c(0.5, 0.45))
# 显示关联
Assocs
# 可视化“bank”的关联
barplot(Assocs[[1]], ylim = c(0,1))
5. 模型的交叉验证与自助法
在评估模型的可靠性时,我们可以使用交叉验证。常见的交叉验证方法有十折交叉验证和留一法交叉验证。以下是使用caret包在R中进行交叉验证的步骤:
# 安装并加载caret包
install.packages("caret"); library (caret)
# 设置十折交叉验证
CtrlCV = trainControl(method = "cv", number = 10)
# 设置留一法交叉验证
CtrlLOO = trainControl(method = "LOOCV")
我们以鸢尾花数据集为例,使用不同的算法进行十折交叉验证:
# Naive Bayes
install.packages("klaR")
modelNB = train(Species ~ ., data = iris, trControl = CtrlCV, method = "nb")
# C4.5
library(RWeka)
modelC45 = train(Species ~ ., data = iris, trControl = CtrlCV, method = "J48")
# C5.0
modelC50 = train(Species ~ ., data = iris, trControl =CtrlCV, method = "C5.0")
# CART
modelCART = train(Species ~ ., data = iris, trControl =CtrlCV, method = "rpart")
# 随机森林
modelRF = train(Species ~ ., data = iris, trControl = CtrlCV, method = "rf")
我们可以查看模型的准确率,以Naive Bayes分类为例:
# 查看Naive Bayes模型的准确率
modelNB
输出结果显示了样本、类别、预测变量的信息,以及不同调优参数下的平均准确率、kappa值及其标准差。可以看到,平均准确率和kappa值都很优秀,标准差较小。
总结
本文介绍了如何使用R进行文本分析,包括模型预测、支持向量机分类、新闻挖掘、文档分类、文章主题提取、新闻文章收集以及模型的交叉验证。通过这些方法,我们可以更好地处理文本数据,提取有价值的信息。在实际应用中,我们可以根据具体情况选择合适的算法和方法,以获得更好的结果。
以下是一个简单的流程图,展示了从数据加载到模型评估的主要步骤:
graph LR
A[数据加载] --> B[数据预处理]
B --> C[模型训练]
C --> D[模型预测]
D --> E[模型评估]
E --> F[结果分析]
同时,为了更清晰地对比不同算法的性能,我们可以列出一个表格:
| 算法 | 训练集准确率 | 测试集准确率 | kappa值 |
| ---- | ---- | ---- | ---- |
| 逻辑回归 | | 0.72 | 0.45 |
| 支持向量机 | 0.93 | 0.71 | 0.42 |
| 集成逻辑回归(训练集) | 0.9945 | | 0.9881 |
| 集成逻辑回归(测试集) | | 0.8645 | 0.6936 |
| Naive Bayes(交叉验证) | 0.9533333 | | 0.93 |
R语言文本分析与模型验证
6. 交叉验证方法详解
交叉验证是评估模型可靠性的重要方法,它可以帮助我们避免过拟合,使模型在未知数据上也能有较好的表现。下面详细介绍两种常见的交叉验证方法:十折交叉验证和留一法交叉验证。
6.1 十折交叉验证
十折交叉验证将数据集随机分成10个大小相近的子集。具体操作流程如下:
1. 把数据集分成10个组,编号为1 - 10。
2. 进行10次分析:
- 第一次,使用组1 - 9训练模型,用组10进行测试。
- 第二次,使用组1 - 8和组10训练模型,用组9进行测试。
- 以此类推,直到完成10次分析。
这样做的好处是每次迭代都使用了9/10的数据进行训练,并且所有数据都参与了测试和训练。通过多次分析,可以得到更准确的模型可靠性估计。
6.2 留一法交叉验证
留一法交叉验证与十折交叉验证类似,但它不将数据分组。具体操作是:
- 分析的次数与数据集中的样本数量相同。
- 每次选择一个样本进行测试,其余样本用于训练。
这种方法的优点是充分利用了所有数据进行训练和测试,但计算成本较高。
以下是使用caret包设置这两种交叉验证的代码:
# 安装并加载caret包
install.packages("caret"); library (caret)
# 设置十折交叉验证
CtrlCV = trainControl(method = "cv", number = 10)
# 设置留一法交叉验证
CtrlLOO = trainControl(method = "LOOCV")
7. 不同算法的交叉验证实践
我们以鸢尾花数据集为例,使用不同的算法进行十折交叉验证。以下是具体的操作步骤和代码:
7.1 Naive Bayes
# 安装必要的包
install.packages("klaR")
# 进行Naive Bayes模型训练
modelNB = train(Species ~ ., data = iris, trControl = CtrlCV, method = "nb")
7.2 C4.5
# 加载RWeka包
library(RWeka)
# 进行C4.5模型训练
modelC45 = train(Species ~ ., data = iris, trControl = CtrlCV, method = "J48")
7.3 C5.0
# 进行C5.0模型训练
modelC50 = train(Species ~ ., data = iris, trControl = CtrlCV, method = "C5.0")
7.4 CART
# 进行CART模型训练
modelCART = train(Species ~ ., data = iris, trControl = CtrlCV, method = "rpart")
7.5 随机森林
# 进行随机森林模型训练
modelRF = train(Species ~ ., data = iris, trControl = CtrlCV, method = "rf")
我们可以查看模型的准确率,以Naive Bayes分类为例:
# 查看Naive Bayes模型的准确率
modelNB
8. 交叉验证结果分析
以Naive Bayes模型为例,查看其交叉验证结果。输出结果包含了样本、类别、预测变量的信息,以及不同调优参数下的平均准确率、kappa值及其标准差。
Naive Bayes
150 samples
4 predictor
3 classes: 'setosa', 'versicolor', 'virginica'
No pre-processing
Resampling: Cross-Validated (10 fold)
Summary of sample sizes: 135, 135, 135, 135, 135, 135, ...
Resampling results across tuning parameters:
usekernel Accuracy Kappa Accuracy SD Kappa SD
FALSE 0.9533333 0.93 0.05488484 0.08232726
TRUE 0.9533333 0.93 0.05488484 0.08232726
Tuning parameter fL was held constant at a value of 0.
Accuracy was used to select the optimal model using the largest value.
The final values used for the model were fL = 0 and usekernel = FALSE.
从输出可以看出,平均准确率和kappa值都很优秀,标准差较小,说明模型在不同的子集上表现稳定。
9. 总结与展望
本文全面介绍了使用R进行文本分析的一系列方法,包括模型预测、支持向量机分类、新闻挖掘、文档分类、文章主题提取、新闻文章收集以及模型的交叉验证。通过这些方法,我们能够更好地处理文本数据,提取有价值的信息。
在实际应用中,我们可以根据具体情况选择合适的算法和方法。例如,当数据特征较多时,可以考虑使用集成学习方法;在评估模型可靠性时,交叉验证是一种有效的手段。
未来,我们可以进一步探索更复杂的模型和算法,如深度学习模型,以提高文本分析的准确性和效率。同时,结合更多的数据源和特征,挖掘更多有价值的信息。
以下是一个流程图,展示了交叉验证的主要步骤:
graph LR
A[数据集] --> B[设置交叉验证方式]
B --> C{选择算法}
C -->|Naive Bayes| D[训练模型]
C -->|C4.5| D
C -->|C5.0| D
C -->|CART| D
C -->|随机森林| D
D --> E[评估模型]
E --> F[分析结果]
为了更清晰地对比不同算法在交叉验证中的性能,我们列出以下表格:
| 算法 | 平均准确率 | kappa值 | 准确率标准差 | kappa值标准差 |
| ---- | ---- | ---- | ---- | ---- |
| Naive Bayes | 0.9533333 | 0.93 | 0.05488484 | 0.08232726 |
| C4.5 | | | | |
| C5.0 | | | | |
| CART | | | | |
| 随机森林 | | | | |
在实际应用中,我们可以根据这些指标选择最适合的算法。
超级会员免费看

被折叠的 条评论
为什么被折叠?



