高效的knn算法

时间:2016-04-11 19:07:59

标签: algorithm knn

我试图实现knn算法,该算法对R中的一维向量进行操作,但是一个与标准向量略有不同,因为它在一个平局的情况下需要较小的元素(所以距离只是属性之间差异的绝对值)。更准确地说,我试图找到最接近给定数字的k数字,如果有关系,我希望选择较小的数字。

听起来很简单,但是我的算法需要几秒钟才能完成,而类包中的那个(knn)会立即输出一个答案(尽管它在一个平局或随机元素的情况下需要所有元素)。我的以下是:

  1. 我对一个训练样本进行抽样并逐渐订购。
  2. 我拿一个元素(一个数字) 2.5。并在训练样本中搜索第一个小于某个数字的地方。
  3. 我从训练样本中取2k + 1个数字 - 在2.5中找到的数字左边是k,右边是k(如果这些数字少于k,我尽可能多地拿走)。 / LI>
  4. 最后,我计算了所选元素与我所选择的元素之间的距离,并逐渐将它们与相应的元素一起排序(以便逐渐对元素及其距离进行排序)
  5. 然后我从4中创建的列表中取k个第一个元素(所以没有两个具有相同的距离)
  6. 但男孩,完成需要6到7秒......你对改进有什么想法吗? (这不是R特定的问题,它恰好发生在R中。)

    编辑。代码:

    dec <- function(u, x, k) {
    ## u is the training sample sorted increasingly
    ## x is an object for classification
    ## k is a knn parameter
    knn <- list()
    i <- 1
    div <- 0
    for (j in u) {
        if (x < j) {
            div <- 0
            break
    }
        i <- i+1
    }
    if (div == 0) {
        distances <- array(0,dim=c(2,k))
        z <- 1
        for (j in 1:k) {
            distances[1,z] <- u[10000-j]
            distances[2,z] <- abs(u[10000-j]-x)
        }
    } else {
        end1 <- div+k
        end2 <- div-k
        if (div<k) {
            distances <- array(0,dim=c(2,(div+k)))
            a <- 1
            for (j in u[1:end1]) {
                distances[1,a] <- j
                distances[2,a] <- abs(j-x)
                a <- a+1
            }
        } else if (10000-div<k) {
            distances <- array(0,dim=c(2,(1000-div+k)))
            a <- 1
            for (j in u[end2:10000]) {
                distances[1,a] <- j
                distances[2,a] <- abs(j-x)
                a <- a+1
            }
        } else {
            a <- 1
            distances <- array(0,dim=c(2,(2*k+1)))
            for (j in u[end1:end2]) {
                distances[1,a] <- j
                distances[2,a] <- abs(j-x)
                a <- a+1
            }
        }
        distances <- t(distances)
        distances <- distances[ order( distances[,2], distances[,1]), ]
        distances <- t(distances)
    }
    for (i in 1:k) {    
        if (i>1 && distances[1,i-1] != distances[1,i])
            knn[i] <- distances[1,i]
    }
     ## and sth later...
    }
    

1 个答案:

答案 0 :(得分:1)

1D中的kNN很简单。

越来越多地对值进行排序。要执行查询,请通过二分法搜索找到排序序列中的值。然后通过踩到最近的两侧(更小或更大)k次来找到k个最接近的值。