Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 用scala表示欧几里德距离的最简单方法_Arrays_Scala - Fatal编程技术网

Arrays 用scala表示欧几里德距离的最简单方法

Arrays 用scala表示欧几里德距离的最简单方法,arrays,scala,Arrays,Scala,我正在用Scala编写一个数据挖掘算法,我想为给定的测试和几个训练实例编写欧几里德距离函数。我有一个带有测试和训练实例的数组[Array[Double]]。我有一个方法,它针对所有训练实例循环遍历每个测试实例,并计算两者之间的距离(每次迭代选择一个测试和训练实例),然后返回一个双精度 例如,我有以下数据点: testInstance = Array(Array(3.2, 2.1, 4.3, 2.8)) trainPoints = Array(Array(3.9, 4.1, 6.2, 7.3),

我正在用Scala编写一个数据挖掘算法,我想为给定的测试和几个训练实例编写欧几里德距离函数。我有一个带有测试和训练实例的
数组[Array[Double]]
。我有一个方法,它针对所有训练实例循环遍历每个测试实例,并计算两者之间的距离(每次迭代选择一个测试和训练实例),然后返回一个
双精度

例如,我有以下数据点:

testInstance = Array(Array(3.2, 2.1, 4.3, 2.8))
trainPoints = Array(Array(3.9, 4.1, 6.2, 7.3), Array(4.5, 6.1, 8.3, 3.8), Array(5.2, 4.6, 7.4, 9.8), Array(5.1, 7.1, 4.4, 6.9))
我有一个方法存根(突出显示距离函数),它返回给定测试实例周围的邻居:

def predictClass(testPoints: Array[Array[Double]], trainPoints: Array[Array[Double]], k: Int): Array[Double] = {

    for(testInstance <- testPoints)
    {
        for(trainInstance <- trainPoints) 
        {
            for(i <- 0 to k) 
            {
                distance = euclideanDistanceBetween(testInstance, trainInstance) //need help in defining this function
            }
        }
    }    
    return distance
}
关于我希望该方法如何处理函数的基本定义,我有一些伪步骤:

def distanceBetween(testInstance: Array[Double], trainInstance: Array[Double]): Double = {
  // subtract each element of trainInstance with testInstance
  // for example, 
  // iteration 1 will do [Array(3.9, 4.1, 6.2, 7.3) - Array(3.2, 2.1, 4.3, 2.8)]
  // i.e. sqrt(3.9-3.2)^2+(4.1-2.1)^2+(6.2-4.3)^2+(7.3-2.8)^2
  // return result
  // iteration 2 will do [Array(4.5, 6.1, 8.3, 3.8) - Array(3.2, 2.1, 4.3, 2.8)]
  // i.e. sqrt(4.5-3.2)^2+(6.1-2.1)^2+(8.3-4.3)^2+(3.8-2.8)^2
  // return result, and so on......
  }

我怎样才能用代码来写呢?

所以你的公式只适用于二维向量。你有四个维度,但是你可能应该在这个维度上灵活地编写你的函数。所以,看看吧

所以你真正想说的是:

for each position i:
  subtract the ith element of Y from the ith element of X
  square it
add all of those up
square root the whole thing
为了使这种编程风格更具功能性,它将更像:

square root the:
  sum of:
    zip X and Y into pairs
    for each pair, square the difference
所以这看起来像:

import math._

def distance(xs: Array[Double], ys: Array[Double]) = {
  sqrt((xs zip ys).map { case (x,y) => pow(y - x, 2) }.sum)
}

val testInstances = Array(Array(5.0, 4.8, 7.5, 10.0), Array(3.2, 2.1, 4.3, 2.8))
val trainPoints = Array(Array(3.9, 4.1, 6.2, 7.3), Array(4.5, 6.1, 8.3, 3.8), Array(5.2, 4.6, 7.4, 9.8), Array(5.1, 7.1, 4.4, 6.9))

distance(testInstances.head, trainPoints.head)
// 3.2680269276736382
至于预测类,你也可以让它更实用,但不清楚你打算返回的双重目的是什么。您似乎想要预测每个测试实例的类?可能选择与最近训练点对应的类
c

def findNearestClasses(testPoints: Array[Array[Double]], trainPoints: Array[Array[Double]]): Array[Int] = {
  testPoints.map { testInstance =>
    trainPoints.zipWithIndex.map { case (trainInstance, c) =>
      c -> distance(testInstance, trainInstance)
    }.minBy(_._2)._1
  }
}    

findNearestClasses(testInstances, trainPoints)
// Array(2, 0)
或者您可能需要
k
-最近邻:

def findKNearestClasses(testPoints: Array[Array[Double]], trainPoints: Array[Array[Double]], k: Int): Array[Int] = {
  testPoints.map { testInstance =>
    val distances = 
      trainPoints.zipWithIndex.map { case (trainInstance, c) =>
        c -> distance(testInstance, trainInstance)
      }
    val classes = distances.sortBy(_._2).take(k).map(_._1)
    val classCounts = classes.groupBy(identity).mapValues(_.size)
    classCounts.maxBy(_._2)._1
  }
}    

findKNearestClasses(testInstances, trainPoints)
// Array(2, 1)

欧几里德距离的通用公式如下:

math.sqrt(math.pow((x1 - x2), 2) + math.pow((y1 - y2), 2))

您只能比较x坐标和x坐标,y坐标和y坐标。

非常感谢您的回答。这很有帮助。我有几点要澄清。首先,线路
距离(testInstances.head、trainPoints.head)
有助于实现什么?它是否只减去head元素而不减去以下元素?其次,在第三个代码块中查找
kNearestNeighbours
,输出返回什么?我想返回
测试实例的索引和与该索引关联的类(例如,
数组((0,ClassA),(1,ClassB),(2,ClassA),…)
),每个测试实例的类使用k个最近邻(从
训练点中选择)的多数类投票来计算。我将使用预测与实际测试数据集进行比较,并比较其准确性。我该怎么做?
距离(testInstances.head,trainPoints.head)
只是为了演示它是如何工作的。它返回一个类数组,每个数组位置对应于测试实例;如果您想将索引作为元组附加,那么使用
.map
将非常简单。
math.sqrt(math.pow((x1 - x2), 2) + math.pow((y1 - y2), 2))