第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

相关推荐
不染_是非17 分钟前
Django学习实战篇四(适合略有基础的新手小白学习)(从0开发项目)
数据库·后端·学习·django·web
Niu_brave27 分钟前
Python基础知识学习(2)
开发语言·python·学习
deflag1 小时前
第T1周:Tensorflow实现mnist手写数字识别
人工智能·python·机器学习·分类·tensorflow
sixteenyy1 小时前
学习笔记(一)
笔记·学习
不是很强 但是很秃1 小时前
秃姐学AI系列之:实战Kaggle比赛:狗的品种识别(ImageNet Dogs)
图像处理·人工智能·pytorch·深度学习·神经网络·计算机视觉·分类
计算机学姐2 小时前
基于python+django+vue的在线学习资源推送系统
开发语言·vue.js·python·学习·django·pip·web3.py
月夕花晨3742 小时前
C++学习笔记(26)
c++·笔记·学习
向往风的男子2 小时前
【从问题中去学习k8s】k8s中的常见面试题(夯实理论基础)(三十一)
学习·容器·kubernetes
蜡笔小新星3 小时前
切换淘宝最新镜像源npm
vue.js·经验分享·学习·npm·node.js