我在R中生成了数据,并对这些点应用了贝叶斯分类器。它们都被分类为“橙色”或“蓝色”。我在使用knn
函数时遇到了获取准确结果的困难,我认为这是因为类别(“蓝色”、“橙色”)没有正确地与knn
函数关联起来。
我的训练数据在一个数据框(x, y)
中,我的类别在一个单独的数组中。我对贝叶斯分类器使用了这种方法——这样绘图更容易。然而,现在我不知道如何将我的类别“插入”到knn
中。使用以下代码结果非常不准确。我已经将k
值调整为许多不同的值进行测试,但都同样不准确。
library(class)x <- round(runif(100, 1, 100))y <- round(runif(100, 1, 100))train.df <- data.frame(x, y)x.test <- round(runif(100, 1, 100))y.test <- round(runif(100, 1, 100))test.df <- data.frame(x.test, y.test)cl <- factor(c(rep("blue", 50), rep("orange", 50)))k <- knn(train.df, test.df, cl, k=100)
再次说明,我的排序类别在一个数组classes
中,位于代码的更前面位置。这里是我的完整文档。上述代码位于文档的底部。
library(class)n <- 100x <- round(runif(n, 1, n))y <- round(runif(n, 1, n))# ============================================================# 贝叶斯分类器 + 决策边界代码# ============================================================classes <- "null"colours <- "null"for (i in 1:n){ # P(C = j | X = x, Y = y) = prob # “当X为某个x,Y为某个y时,类别(C)为橙色(j)的概率” # 两个影响分类的预测变量:x, y # 如果x和y都小于50,则有90%的概率为橙色(分组) # 如果x和y都大于50,或者其中一个大于50,则分组为蓝色 # 算法倾向于选择成功概率更高的分组,然后使用该颜色绘图 # 当上述概率(prob)为50%时,绘制边界 percentChance <- 0 if (x[i] < 50 && y[i] < 50) { # 橙色的概率为95%,蓝色的概率为5% # 因此贝叶斯决策边界在x < 50和y < 50时分配给橙色 # “colours”是决策边界分组,不是绘图分组 percentChance <- 95 colours[i] <- "orange" } else { percentChance <- 10 colours[i] <- "blue" } if (round(runif(1, 1, 100)) > percentChance) { classes[i] <- "blue" } else { classes[i] <- "orange" }}boundary.x <- seq(0, 100, by=1)boundary.y <- 0for (i in 1:101){ if (i > 49) { boundary.y[i] <- -10 # 仅为了视觉一致性,真实值为0 } else { boundary.y[i] <- 50 }}df <- data.frame(boundary.x, boundary.y)plot(x, y, col=classes)lines(df, type="l", lty=2, lwd=2, col="red")# ============================================================# K最近邻代码# ============================================================#library(class)#x <- round(runif(100, 1, 100))#y <- round(runif(100, 1, 100))train.df <- data.frame(x, y)x.test <- round(runif(n, 1, n))y.test <- round(runif(n, 1, n))test.df <- data.frame(x.test, y.test)cl <- factor(c(rep("blue", 50), rep("orange", 50)))k <- knn(train.df, test.df, cl, k=(round(sqrt(n))))
感谢您的帮助
回答:
首先,为了重现性,在生成一组随机数(如runif
所做的那样)或运行任何随机的模拟/机器学习算法之前,您应该设置一个种子。请注意,在下面的代码中,我们为生成x
的所有实例设置了相同的种子,为生成y
的所有实例设置了不同的种子。这样,伪随机生成的x
总是相同的(但与y
不同),y
也是如此。
library(class)n <- 100set.seed(1)x <- round(runif(n, 1, n))set.seed(2)y <- round(runif(n, 1, n))# ============================================================# 贝叶斯分类器 + 决策边界代码# ============================================================classes <- "null"colours <- "null"for (i in 1:n){ # P(C = j | X = x, Y = y) = prob # “当X为某个x,Y为某个y时,类别(C)为橙色(j)的概率” # 两个影响分类的预测变量:x, y # 如果x和y都小于50,则有90%的概率为橙色(分组) # 如果x和y都大于50,或者其中一个大于50,则分组为蓝色 # 算法倾向于选择成功概率更高的分组,然后使用该颜色绘图 # 当上述概率(prob)为50%时,绘制边界 percentChance <- 0 if (x[i] < 50 && y[i] < 50) { # 橙色的概率为95%,蓝色的概率为5% # 因此贝叶斯决策边界在x < 50和y < 50时分配给橙色 # “colours”是决策边界分组,不是绘图分组 percentChance <- 95 colours[i] <- "orange" } else { percentChance <- 10 colours[i] <- "blue" } if (round(runif(1, 1, 100)) > percentChance) { classes[i] <- "blue" } else { classes[i] <- "orange" }}boundary.x <- seq(0, 100, by=1)boundary.y <- 0for (i in 1:101){ if (i > 49) { boundary.y[i] <- -10 # 仅为了视觉一致性,真实值为0 } else { boundary.y[i] <- 50 }}df <- data.frame(boundary.x, boundary.y)plot(x, y, col=classes)lines(df, type="l", lty=2, lwd=2, col="red")# ============================================================# K最近邻代码# ============================================================#library(class)set.seed(1)x <- round(runif(n, 1, n))set.seed(2)y <- round(runif(n, 1, n))train.df <- data.frame(x, y)set.seed(1)x.test <- round(runif(n, 1, n))set.seed(2)y.test <- round(runif(n, 1, n))test.df <- data.frame(x.test, y.test)
我认为主要问题出在这里。我认为您想传递给knn
的类别标签是从贝叶斯分类器中获得的,即classes
向量。相反,您传递的是cl
,它只是test.df
中案例的顺序标签,即没有意义。
#cl <- factor(c(rep("blue", 50), rep("orange", 50)))k <- knn(train.df, test.df, classes, k=25)plot(test.df$x.test, test.df$y.test, col=k)