第100+19步 ChatGPT学习:R实现朴素贝叶斯分类

基于R 4.2.2版本演示

一、写在前面

有不少大佬问做机器学习分类能不能用R语言,不想学Python咯。

答曰:可!用GPT或者Kimi转一下就得了呗。

加上最近也没啥内容写了,就帮各位搬运一下吧。

二、R代码实现朴素贝叶斯分类

(1) 导入数据

我习惯用RStudio自带的导入功能:

(2) 建立朴素贝叶斯模型(默认参数)

R 复制代码
# 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 (拉普拉斯平滑):

思路:防止模型计算出的概率为零,特别是在面对未在训练集中见过的特征组合时。增加拉普拉斯平滑参数有助于处理这种数据稀疏性。

可选项:

  1. 0(无平滑,是默认值)
  2. 1(通常的起始平滑值)
  3. 任何大于0的数值,根据数据稀疏程度逐步增加

2. usekernel (使用核密度估计):

思路:为非正态分布的连续数据提供更准确的概率估计。核密度估计通过平滑处理帮助适应各种连续数据分布。

可选项:

  1. TRUE(启用核密度估计)
  2. FALSE(默认,假设数据遵循正态分布)

3. adjust (带宽调整):

思路:控制核密度估计的平滑程度。带宽的选择影响核密度估计的紧密性或宽松性,对模型预测连续变量的能力至关重要。

可选项:

  1. 默认值通常为 1
  2. 任何正实数,根据数据特性适当增加或减少(通常在0.5到2之间调整)

4. kernel (核函数类型):

思路:选择合适的核函数可以优化对数据分布的拟合,不同的核函数适应不同类型的数据分布。

可选项:

  1. "gaussian"(高斯核,适用于许多情况)
  2. "rectangular"(矩形核)
  3. "triangular"(三角形核)
  4. "epanechnikov"(埃帕内契科夫核)
  5. 更多依赖于 naivebayes 包版本的核类型

5. prior (类别的先验概率):

思路:在类别分布极不均衡的情况下,调整先验概率可以帮助模型更好地预测少数类,防止模型偏向多数类。

可选项:

  1. 自动计算(基于训练数据中的类分布)
  2. 手动指定,如 c(0.7, 0.3) 对于二分类问题,表示类别1和类别2的先验概率

大家自个调吧,我不调了,举个栗子:

R 复制代码
# 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

相关推荐
6.9424 分钟前
Scala——身份证号码查询籍贯
学习·scala
爱吃西瓜的小菜鸡34 分钟前
【C语言】矩阵乘法
c语言·学习·算法
初学者7.1 小时前
Webpack学习笔记(2)
笔记·学习·webpack
机器学习之心2 小时前
BiTCN-BiGRU基于双向时间卷积网络结合双向门控循环单元的数据多特征分类预测(多输入单输出)
深度学习·分类·gru
qingyunliushuiyu3 小时前
企业为何需要可视化数据分析系统
数据挖掘·数据分析·数据采集·数据可视化·数据分析系统
创意锦囊4 小时前
随时随地编码,高效算法学习工具—E时代IDE
ide·学习·算法
尘觉4 小时前
算法的学习笔记—扑克牌顺子(牛客JZ61)
数据结构·笔记·学习·算法
1 9 J4 小时前
Java 上机实践11(组件及事件处理)
java·开发语言·学习·算法
Blankspace学4 小时前
Wireshark软件下载安装及基础
网络·学习·测试工具·网络安全·wireshark
机器学习之心4 小时前
Bayes-GRU-Attention的数据多特征分类预测Matlab实现
matlab·分类·gru