基于R 4.2.2版本演示
一、写在前面
有不少大佬问做机器学习分类能不能用R语言,不想学Python咯。
答曰:可!用GPT或者Kimi转一下就得了呗。
加上最近也没啥内容写了,就帮各位搬运一下吧。
二、R代码实现朴素贝叶斯分类
(1)导入数据
我习惯用RStudio自带的导入功能:
(2)建立朴素贝叶斯模型(默认参数)
# Load necessary libraries
library(caret)
library(naivebayes)
library(pROC)
library(ggplot2)
# Assume 'data' is your dataframe containing the data
data$X <- as.factor(data$X)
# Set seed to ensure reproducibility
set.seed(123)
# Split data into training and validation sets (80% training, 20% validation)
trainIndex <- createDataPartition(data$X, p = 0.8, list = FALSE)
trainData <- data[trainIndex, ]
validData <- data[-trainIndex, ]
# Train the Naive Bayes model
nbModel <- naive_bayes(X ~ ., data = trainData)
# Predict on the training and validation sets
trainPredict <- predict(nbModel, trainData, type = "prob")[,1]
validPredict <- predict(nbModel, validData, type = "prob")[,1]
# Convert predictions to binary using 0.5 as threshold
trainPredictBinary <- ifelse(trainPredict > 0.5, 1, 0)
validPredictBinary <- ifelse(validPredict > 0.5, 1, 0)
# Compute ROC objects
trainRoc <- roc(response = as.numeric(trainData$X) - 1, predictor = trainPredict)
validRoc <- roc(response = as.numeric(validData$X) - 1, predictor = validPredict)
# Plot ROC curves using ggplot2
trainRocPlot <- ggplot(data = data.frame(fpr = 1 - trainRoc$specificities, tpr = trainRoc$sensitivities), aes(x = fpr, y = tpr)) +
geom_line(color = "blue") +
geom_area(aes(ifelse(fpr <= 1, fpr, NA)), fill = "blue", alpha = 0.2) +
geom_abline(slope = 1, intercept = 0, linetype = "dashed", color = "black") +
ggtitle("Training ROC Curve") +
xlab("False Positive Rate") +
ylab("True Positive Rate") +
annotate("text", x = 0.5, y = 0.1, label = paste("Training AUC =", round(auc(trainRoc), 2)), hjust = 0.5, color = "blue")
validRocPlot <- ggplot(data = data.frame(fpr = 1 - validRoc$specificities, tpr = validRoc$sensitivities), aes(x = fpr, y = tpr)) +
geom_line(color = "red") +
geom_area(aes(ifelse(fpr <= 1, fpr, NA)), fill = "red", alpha = 0.2) +
geom_abline(slope = 1, intercept = 0, linetype = "dashed", color = "black") +
ggtitle("Validation ROC Curve") +
xlab("False Positive Rate") +
ylab("True Positive Rate") +
annotate("text", x = 0.5, y = 0.2, label = paste("Validation AUC =", round(auc(validRoc), 2)), hjust = 0.5, color = "red")
# Display plots
print(trainRocPlot)
print(validRocPlot)
# Calculate confusion matrices based on 0.5 cutoff for probability
confMatTrain <- table(trainData$X, trainPredict >= 0.5)
confMatValid <- table(validData$X, validPredict >= 0.5)
# Function to plot confusion matrix using ggplot2
plot_confusion_matrix <- function(conf_mat, dataset_name) {
conf_mat_df <- as.data.frame(as.table(conf_mat))
colnames(conf_mat_df) <- c("Actual", "Predicted", "Freq")
p <- ggplot(data = conf_mat_df, aes(x = Predicted, y = Actual, fill = Freq)) +
geom_tile(color = "white") +
geom_text(aes(label = Freq), vjust = 1.5, color = "black", size = 5) +
scale_fill_gradient(low = "white", high = "steelblue") +
labs(title = paste("Confusion Matrix -", dataset_name, "Set"), x = "Predicted Class", y = "Actual Class") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1), plot.title = element_text(hjust = 0.5))
print(p)
}
# Now call the function to plot and display the confusion matrices
plot_confusion_matrix(confMatTrain, "Training")
plot_confusion_matrix(confMatValid, "Validation")
# 提取混淆矩阵的值,确保它们的命名与你的混淆矩阵布局一致
fp_train <- confMatTrain[1, 1]
tn_train <- confMatTrain[1, 2]
tp_train <- confMatTrain[2, 1]
fn_train <- confMatTrain[2, 2]
fp_valid <- confMatValid[1, 1]
tn_valid <- confMatValid[1, 2]
tp_valid <- confMatValid[2, 1]
fn_valid <- confMatValid[2, 2]
# 训练集指标
acc_train <- (tp_train + tn_train) / sum(confMatTrain)
error_rate_train <- 1 - acc_train
sen_train <- tp_train / (tp_train + fn_train) # 灵敏度
sep_train <- tn_train / (tn_train + fp_train) # 特异度
precision_train <- tp_train / (tp_train + fp_train) # 精确度
F1_train <- 2 * (precision_train * sen_train) / (precision_train + sen_train)
MCC_train <- (tp_train * tn_train - fp_train * fn_train) / sqrt((tp_train + fp_train) * (tp_train + fn_train) * (tn_train + fp_train) * (tn_train + fn_train))
auc_train <- roc(response = trainData$X, predictor = trainPredict)$auc
# 验证集指标
acc_valid <- (tp_valid + tn_valid) / sum(confMatValid)
error_rate_valid <- 1 - acc_valid
sen_valid <- tp_valid / (tp_valid + fn_valid) # 灵敏度
sep_valid <- tn_valid / (tn_valid + fp_valid) # 特异度
precision_valid <- tp_valid / (tp_valid + fp_valid) # 精确度
F1_valid <- 2 * (precision_valid * sen_valid) / (precision_valid + sen_valid)
MCC_valid <- (tp_valid * tn_valid - fp_valid * fn_valid) / sqrt((tp_valid + fp_valid) * (tp_valid + fn_valid) * (tn_valid + fp_valid) * (tn_valid + fn_valid))
auc_valid <- roc(response = validData$X, predictor = validPredict)$auc
# Print Metrics
cat("Training Metrics\n")
cat("Accuracy:", acc_train, "\n")
cat("Error Rate:", error_rate_train, "\n")
cat("Sensitivity:", sen_train, "\n")
cat("Specificity:", sep_train, "\n")
cat("Precision:", precision_train, "\n")
cat("F1 Score:", F1_train, "\n")
cat("MCC:", MCC_train, "\n")
cat("AUC:", auc_train, "\n\n")
cat("Validation Metrics\n")
cat("Accuracy:", acc_valid, "\n")
cat("Error Rate:", error_rate_valid, "\n")
cat("Sensitivity:", sen_valid, "\n")
cat("Specificity:", sep_valid, "\n")
cat("Precision:", precision_valid, "\n")
cat("F1 Score:", F1_valid, "\n")
cat("MCC:", MCC_valid, "\n")
cat("AUC:", auc_valid, "\n")
结果输出(随便挑的):
效果还行。
三、朴素贝叶斯调参
朴素贝叶斯模型的参数调整的思路旨在优化模型对特定数据集的性能,确保模型能够有效地处理数据的分布特性,同时避免因数据稀疏或类别不平衡带来的问题。下面详细解释默认参数的调整思路以及可选项:
1. Laplace (拉普拉斯平滑):
思路:防止模型计算出的概率为零,特别是在面对未在训练集中见过的特征组合时。增加拉普拉斯平滑参数有助于处理这种数据稀疏性。
可选项:
- 0(无平滑,是默认值)
- 1(通常的起始平滑值)
- 任何大于0的数值,根据数据稀疏程度逐步增加
2. usekernel (使用核密度估计):
思路:为非正态分布的连续数据提供更准确的概率估计。核密度估计通过平滑处理帮助适应各种连续数据分布。
可选项:
- TRUE(启用核密度估计)
- FALSE(默认,假设数据遵循正态分布)
3. adjust (带宽调整):
思路:控制核密度估计的平滑程度。带宽的选择影响核密度估计的紧密性或宽松性,对模型预测连续变量的能力至关重要。
可选项:
- 默认值通常为 1
- 任何正实数,根据数据特性适当增加或减少(通常在0.5到2之间调整)
4. kernel (核函数类型):
思路:选择合适的核函数可以优化对数据分布的拟合,不同的核函数适应不同类型的数据分布。
可选项:
- "gaussian"(高斯核,适用于许多情况)
- "rectangular"(矩形核)
- "triangular"(三角形核)
- "epanechnikov"(埃帕内契科夫核)
- 更多依赖于 naivebayes 包版本的核类型
5. prior (类别的先验概率):
思路:在类别分布极不均衡的情况下,调整先验概率可以帮助模型更好地预测少数类,防止模型偏向多数类。
可选项:
- 自动计算(基于训练数据中的类分布)
- 手动指定,如 c(0.7, 0.3) 对于二分类问题,表示类别1和类别2的先验概率
大家自个调吧,我不调了,举个栗子:
# Train the Naive Bayes model with custom parameters
nbModel <- naive_bayes(
X ~ .,
data = trainData,
laplace = 1, # 添加拉普拉斯平滑,处理零频率问题
usekernel = TRUE, # 对连续变量使用核密度估计
adjust = 1.5, # 调整核密度估计的带宽,使得估计更平滑
kernel = "epanechnikov", # 选择核类型为埃帕内契科夫核,通常对偏态数据较好
prior = c(0.6, 0.4) # 假设数据集中类别的先验概率为 60% 和 40%
)
五、最后
至于怎么安装,自学了哈。
数据嘛:
链接:https://pan.baidu.com/s/1rEf6JZyzA1ia5exoq5OF7g?pwd=x8xm
提取码:x8xm