k近鄰法:R實現(一)
阿新 • • 發佈:2019-01-07
KNN是有監督的學習演算法,其特點有:
1、精度高,對異常值不敏感
2、只能處理數值型屬性
3、計算複雜度高(如已知分類的樣本數為n,那麼對每個未知分類點要計算n個距離)
KNN演算法步驟:
需對所有樣本點(已知分類+未知分類)進行歸一化處理。
然後,對未知分類的資料集中的每個樣本點依次執行以下操作:
1、計算已知類別資料集中的點與當前點(未知分類)的距離。
2、按照距離遞增排序
3、選取與當前距離最小的k個點
4、確定前k個點所在類別的出現頻率
5、返回前k個點出現頻率最高的類別作為當前點的預測類別
<span style="font-family:Times New Roman;font-size:14px;"># 選擇iris資料集為例,iris共有150條資料 #先大致看一下資料 head(iris) #對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" #隨機選出100條記錄作為已知分類的樣本集 sample_list <- sample(1:150, size = 100) iris_know <- iris_s[sample_list, ] #剩餘的50條記錄作為未知分類的樣本 iris_unknow <- iris_s[-sample_list, ] #對測試集中的每一個樣本,計算其與已知樣本的距離,因為已經歸一化,此處直接使用歐氏距離 length_know <- nrow(iris_know) length_unknow <- nrow(iris_unknow) for (i in 1:length_unknow){ dis_know <- data.frame(dis = rep(0, length_know)) for (j in 1:length_know){ #計算已知點和未知點的距離 dis_know[j, 1] <- dist(rbind(iris_unknow[i, 1:4], iris_know[j, 1:4]), method = "euclidean") names(dis_know)[1] = "dis" # 儲存已知樣本分類 dis_know[j, 2] <- iris_know[j, 5] names(dis_know)[2] = "Species" } #按距離從小到大排序 dis_know <- dis_know[order(dis_know$dis), ] #定義K的大小 k <-5 #按因子(也就是分類)進行排序 type_freq <- as.data.frame(table(dis_know[1:k, ]$Species)) #按計數值進行排序 type_freq <- type_freq[order(-type_freq$Freq), ] # 記錄頻數最大的型別 iris_unknow[i, 6] <- type_freq[1,1] names(iris_unknow)[6] = "Species.pre" } #輸出分類結果 iris_unknow[, 5:6] </span>