KNN是有监督的学习算法,其特点有:
机器学习算法R实现-KNN
# 选择iris数据集为例,iris共有150条数据,内容如下head(iris)
## Sepal.Length\Sepal.Width\Petal.Length\Petal.Width为分类的四个维度,Species为分类结果
# 1、对iris进行归一化处理,scale归一化的公式为(x-mean(x))/sqrt(var(x))
iris_s <- data.frame(scale(iris[, 1:4]))
iris_s <- cbind(iris_s, iris[, 5])names(iris_s)[5] = "Species"
# 1、对iris数据集随机选择其中的100条记录作为已知分类的样本集
sample.list <- sample(1:150, size = 100)
iris.known <- iris_s[sample.list, ]
# 2、剩余50条记录作为未知分类的样本集(测试集)
iris.unknown <- iris_s[-sample.list, ]
## 3、对测试集中的每一个样本,计算其与已知样本的距离,因为已经归一化,此处直接使用欧氏距离
length.known <- nrow(iris.known)length.unknown <- nrow(iris.unknown)
for (i in 1:length.unknown) {
# dis 记录与每个已知分类样本的距离及改样本的分类
dis_to_known <- data.frame(dis = rep(0, length.known))
for (j in 1:length.known) {
# 计算距离
dis_to_known[j, 1] <- dist(rbind(iris.unknown[i, 1:4], iris.known[j,1:4]), method = "euclidean")
# 保存已知样本的分类
dis_to_known[j, 2] <- iris.known[j, 5] names(dis_to_known)[2] = "Species"
}
# 按距离从小到大排序
dis_to_known <- dis_to_known[order(dis_to_known$dis), ]
# Knn中的K,定义了具体最近的K个已知分类的样本
k <- 5
# 按因子进行计数
type_freq <- as.data.frame(table(dis_to_known[1:k, ]$Species))
# 按计数值进行排序
type_freq <- type_freq[order(-type_freq$Freq), ]
# 记录频数最大的类型
iris.unknown[i, 6] <- type_freq[1, 1]上面结果中,Species为样本实际分类,Species.pre为Knn算法的分类。经过多次实验,50个样本中,有5个左右样本的分类判断错误,正确率在90%。可见Knn算法效果较好,原理容易理解。
Knn算法存在的问题:
1、k值的确定是个难题。
2、如果距离最近的k个已知分类样本中,频数最高的类型有多个(频数相同),如何选择对未知样本的分类?目前看是随机的。
3、如果有n个未知类型样本,m个已知类型样本,则需要计算n*m个距离,计算量较大,且需存储全部数据集合,空间复杂度也较大。 4、能否把预测的样本分类加入到已知类别集合中,对剩余的未知类型样本进行分类? 5、归一化放在所有处理的最前面,这样需要知道全部的样本集合(已知分类+未知分类)来构建分类器,而实际上未知分类的样本并不一定能事先获得,这样如何进行归一化处理?
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:『原创』机器学习算法的R语言实现(一):KNN - Python技术站