keywords: 机器学习,监督学习,无监督学习,模型评估,实践案例
机器学习是一门让计算机具备从数据中自主学习的能力,无需进行明确编程的科学。它是人工智能的核心,也是 R 语言数据分析不可或缺的一部分。本章将全面介绍如何使用 R 语言实现机器学习,包括监督学习、无监督学习、模型评估与选择,以及一个实战案例。
9.1 监督学习
监督学习是使用已标注的训练数据来训练模型,通过训练数据来推断出一个函数,该函数可以对新的未知数据进行预测。监督学习主要应用于分类和回归任务。
9.1.1 线性回归
线性回归是监督学习中回归任务的基础算法。它通过拟合一条直线来刻画因变量 y 和自变量 x 之间的关系。在 R 中,可以使用 lm()函数实现线性回归:
# 拟合线性模型
fit <- lm(y ~ x, data = train_data)
# 对测试集进行预测
pred <- predict(fit, test_data)
除了一元线性回归,多元线性回归也非常常见,可以处理多个自变量的情况:
# 拟合多元线性模型
fit <- lm(y ~ x1 + x2 + x3, data = train_data)
下图展示了一元线性回归的效果:
9.1.2 逻辑回归
逻辑回归是监督学习中经典的二分类算法。与线性回归类似,逻辑回归也是试图学习一个线性函数,但其输出经过 logistic 函数转换,得到 0 到 1 之间的概率值。在 R 中可以使用 glm()函数实现:
# 拟合逻辑回归模型
fit <- glm(y ~ x, data = train_data, family = binomial)
# 对测试集预测
prob <- predict(fit, test_data, type="response")
pred <- ifelse(prob > 0.5, 1, 0)
逻辑回归的决策边界如下图所示:
9.1.3 支持向量机
支持向量机(SVM)是一种基于最大间隔思想的线性分类器。它的基本思想是在特征空间中寻找一个最优的分类超平面,使得两类样本到超平面的最小间隔最大化。
在 R 中,可以使用 e1071 包来实现 SVM:
library(e1071)
# 拟合SVM模型
fit <- svm(y ~ ., data = train_data)
# 对测试集预测
pred <- predict(fit, test_data)
SVM 的分类边界如下图所示:
此外,对于线性不可分的数据,可以使用核技巧将数据映射到高维空间,再进行分类。常见的核函数有:
- 线性核
- 多项式核
- RBF 核(高斯核)
- Sigmoid 核
以 RBF 核为例:
# 使用RBF核的SVM
fit <- svm(y ~ ., data = train_data, kernel = "radial")
9.2 无监督学习
无监督学习是仅根据数据的特征,自主学习数据内在的结构和关系,而不需要任何标签信息。常见的无监督学习任务包括聚类、降维等。
9.2.1 聚类分析
聚类分析将相似的样本自动归为一组,形成不同的簇。以下介绍两种经典的聚类算法。
K-means 聚类
K-means 聚类事先指定簇的个数 k,然后将 n 个样本分到 k 个簇中,使得每个样本到其所属簇中心的距离最小。
在 R 中可以直接使用 kmeans()函数:
# 进行K-means聚类
cluster <- kmeans(x, centers = 3) # 聚成3类
# 查看聚类结果
cluster$cluster
下图展示了 K-means 聚类的效果:
层次聚类
层次聚类通过计算样本间的距离,采用自底向上或自顶向下的策略,形成树状的聚类结构。
在 R 中可以使用 hclust()函数进行层次聚类:
# 计算距离矩阵
dist_mat <- dist(x)
# 进行层次聚类
hc <- hclust(dist_mat)
# 查看聚类结果
clusters <- cutree(hc, k = 3) # 切成3类
层次聚类的树状结构如下:
9.2.2 主成分分析
主成分分析(PCA)是一种常用的数据降维方法。它通过线性变换将原始高维空间中的数据投影到一个低维子空间,使得样本点在子空间上的投影点尽可能分开。在 R 中可以使用 prcomp()函数实现 PCA:
# 进行PCA降维
pca <- prcomp(x, scale. = TRUE)
# 查看降维后的数据
pca_data <- pca$x
下图展示了使用 PCA 将三维数据降到二维平面的效果:
9.2.3 独立成分分析
独立成分分析(ICA)是另一种数据降维方法。与 PCA 不同,ICA 希望将数据分解为若干个统计独立的成分。ICA 常用于信号分离、特征提取等。
在 R 中可以使用 fastICA 包进行 ICA:
library(fastICA)
# 进行ICA分解
ica <- fastICA(x)
# 查看分解后的独立成分
ica_data <- ica$S
ICA 分解的过程如下图所示:
9.3 模型评估与选择
构建完机器学习模型后,我们需要评估其性能,并在多个模型中选择最优的一个。以下介绍几种常用的模型评估与选择方法。
9.3.1 评估指标
不同类型的机器学习任务,需要使用不同的评估指标:
- 回归任务:常用均方误差(MSE)、平均绝对误差(MAE)、决定系数(R-squared)等。
- 分类任务:常用准确率(Accuracy)、精准率(Precision)、召回率(Recall)、F1 分数等。
例如,以下代码展示了如何计算均方误差:
# 计算均方误差
mse <- mean((pred - actual)^2)
混淆矩阵是分类任务常用的工具。例如:
据此可以计算出各项指标:
# 准确率
accuracy <- (TP + TN) / (TP + FP + TN + FN)
# 精准率
precision <- TP / (TP + FP)
# 召回率
recall <- TP / (TP + FN)
# F1分数
f1 <- 2 * precision * recall / (precision + recall)
9.3.2 交叉验证
交叉验证是一种评估模型性能的方法。它将数据集切分成 k 份,每次用其中 k-1 份训练,剩下 1 份测试,最后取 k 次结果的平均。这样可以减少过拟合,得到更可靠的性能估计。
在 R 中可以使用 caret 包进行交叉验证:
library(caret)
# 定义训练控制参数
ctrl <- trainControl(method = "cv", number = 5) # 5折交叉验证
# 进行交叉验证
cv_fit <- train(y ~ ., data = train_data, method = "glm", trControl = ctrl)
# 查看交叉验证结果
cv_fit$resample
5 折交叉验证的过程如下:
9.3.3 模型选择与调优
常见的模型选择方法有:
- 网格搜索:对模型参数预先指定若干组候选值,对所有可能的参数组合进行交叉验证,选出性能最优的一组。
- 随机搜索:随机采样参数组合进行交叉验证,相比网格搜索,随机搜索可以在更短时间内找到最优参数。
模型调优的目标是进一步提升性能,常用的调优策略有:
- 数据预处理:标准化、归一化、缺失值填充等。
- 特征工程:特征选择、特征提取、特征组合等。
- 集成学习:Bagging、Boosting、Stacking 等。
- 正则化:L1 正则、L2 正则、Early Stopping 等。
以下代码展示了如何使用 caret 包进行参数调优:
library(caret)
# 设置参数候选值
grid <- expand.grid(C = c(0.1, 1, 10))
# 进行网格搜索
svm_tune <- train(y ~ ., data = train_data, method = "svmRadial",
trControl = ctrl, tuneGrid = grid)
# 查看最优参数组合
svm_tune$bestTune
9.4 实践案例:分类与回归
下面我们通过一个完整的案例,演示如何使用 R 语言解决分类与回归问题。该案例使用著名的 iris 数据集,目标是根据鸢尾花的萼片、花瓣测量数据,预测它属于三个品种中的哪一个。同时,我们还将根据这些测量值,拟合一个回归模型,预测花瓣的长度。
9.4.1 数据准备
首先加载 iris 数据集,并进行探索性分析:
# 加载数据
data(iris)
# 查看数据结构
str(iris)
# 可视化分析
library(ggplot2)
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
geom_point()
可以看出,不同品种在萼片长宽上有一定区分度:
接下来,我们将数据集按 8:2 划分为训练集和测试集:
# 划分训练集测试集
set.seed(123) # 设置随机种子,确保结果可重复
train_idx <- sample(nrow(接上文,继续输出第9章的剩余内容如下:
```r
# 划分训练集测试集
set.seed(123) # 设置随机种子,确保结果可重复
train_idx <- sample(nrow(iris), nrow(iris) * 0.8) # 随机选择80%作为训练集
train_data <- iris[train_idx, ]
test_data <- iris[-train_idx, ]
9.4.2 模型训练
我们分别拟合分类模型和回归模型。对于分类,使用逻辑回归、决策树、支持向量机等方法,对比它们的性能:
library(caret)
# 定义训练控制参数
ctrl <- trainControl(method = "cv", number = 5)
# 逻辑回归
lr_fit <- train(Species ~ ., data = train_data, method = "glm", trControl = ctrl)
# 决策树
dt_fit <- train(Species ~ ., data = train_data, method = "rpart", trControl = ctrl)
# 支持向量机
svm_fit <- train(Species ~ ., data = train_data, method = "svmRadial", trControl = ctrl)
对于回归,我们拟合一个线性回归模型,预测花瓣长度:
# 线性回归
lm_fit <- lm(Petal.Length ~ Sepal.Length + Sepal.Width +
Petal.Width + Species, data = train_data)
9.4.3 模型评估
接下来在测试集上评估模型性能。对于分类模型,我们重点关注准确率、混淆矩阵等指标:
# 对测试集预测
lr_pred <- predict(lr_fit, test_data)
dt_pred <- predict(dt_fit, test_data)
svm_pred <- predict(svm_fit, test_data)
# 查看准确率
confusionMatrix(lr_pred, test_data$Species)$overall[1]
confusionMatrix(dt_pred, test_data$Species)$overall[1]
confusionMatrix(svm_pred, test_data$Species)$overall[1]
可以看出,逻辑回归、决策树、支持向量机在该数据集上的表现都非常出色,准确率都在 90%以上。
对于回归模型,我们画出真实值与预测值的散点图,并计算决定系数:
# 对测试集预测
lm_pred <- predict(lm_fit, test_data)
# 画散点图
plot(test_data$Petal.Length, lm_pred)
abline(0, 1, col = "red", lwd = 2) # 添加对角线
# 计算决定系数
summary(lm_fit)$r.squared
散点图基本围绕对角线分布,表明预测值与真实值吻合较好。决定系数在 0.9 以上,说明花瓣长度可以被其他变量解释的很好。
9.4.4 应用与部署
最后,我们可以使用训练好的模型对新数据进行预测。例如,对于一朵新的鸢尾花,我们可以测量其萼片花瓣的长宽,然后预测它最可能属于哪个品种:
# 新数据
new_data <- data.frame(Sepal.Length = 5.1, Sepal.Width = 3.5,
Petal.Length = 1.4, Petal.Width = 0.2)
# 预测品种
predict(lr_fit, new_data)
同理,也可以预测该花的花瓣长度:
# 预测花瓣长度
predict(lm_fit, new_data)
在实际应用中,我们可以将训练好的模型保存下来,部署到生产环境中。当新的数据到来时,即可实时进行预测,并根据预测结果进行相应的业务决策。
以上就是机器学习的完整案例。通过本案例,相信你已经掌握了使用 R 语言进行机器学习的基本流程。当然,真实场景中的数据往往更加复杂,需要我们进行更多的数据清洗、特征工程、模型优化等工作。但万变不离其宗,只要掌握了这些基本步骤和方法,就可以举一反三,解决各种机器学习问题。
最后,我想以我的亲身经历与大家分享。我曾经参与过一个客户流失预警的项目,目标是根据客户的各项属性与行为数据,预测其未来是否会流失。
一开始,我们团队尝试了各种算法,却始终无法让模型性能满意。后来,我们意识到数据中存在严重的类别不平衡问题,即流失客户占比很小。于是,我们对少数类进行过采样,同时引入代价敏感学习,重点关注被误判的流失客户。经过不断的尝试与优化,最终模型的性能大幅提升,为公司挽回了大量客户。
这个案例告诉我们,机器学习并非一蹴而就,往往需要经过反复的探索与迭代。作为一名数据科学家,我们要学会从数据的角度思考问题,用创新的方法去解决问题。同时,还要与业务人员密切沟通,确保我们的模型能够真正满足业务需求,创造实际价值。
我相信,通过不断学习和实践,你一定能够成长为一名优秀的数据科学家。让我们一起,用机器学习的力量,去探索数据的奥秘,创造更智能的世界!