第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

相关推荐
@小博的博客8 分钟前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
南宫生1 小时前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法
懒惰才能让科技进步1 小时前
从零学习大模型(十二)-----基于梯度的重要性剪枝(Gradient-based Pruning)
人工智能·深度学习·学习·算法·chatgpt·transformer·剪枝
love_and_hope2 小时前
Pytorch学习--神经网络--搭建小实战(手撕CIFAR 10 model structure)和 Sequential 的使用
人工智能·pytorch·python·深度学习·学习
Chef_Chen2 小时前
从0开始学习机器学习--Day14--如何优化神经网络的代价函数
神经网络·学习·机器学习
芊寻(嵌入式)2 小时前
C转C++学习笔记--基础知识摘录总结
开发语言·c++·笔记·学习
hong1616883 小时前
跨模态对齐与跨领域学习
学习
阿伟来咯~3 小时前
记录学习react的一些内容
javascript·学习·react.js
Suckerbin4 小时前
Hms?: 1渗透测试
学习·安全·网络安全
水豚AI课代表4 小时前
分析报告、调研报告、工作方案等的提示词
大数据·人工智能·学习·chatgpt·aigc