Как я могу использовать scala методы сбора, чтобы создать метод для коэффициента корреляции? - PullRequest
1 голос
/ 19 марта 2020

Итак, я использую формулу коэффициента корреляции с этого сайта: https://en.wikipedia.org/wiki/Pearson_correlation_coefficient

Формула: [https://i.stack.imgur.com/Jzkm8.png]

Как я могу суммировать каждое значение x и y из списка в отдельности? Это все, что у меня есть:

  def correlation[T](elements: List[T], property1: T => Double, property2: T => Double): Double = {
    val xValues = elements.map(property1)
    val yValues = elements.map(property2)
    val Sx = standardDeviation(xValues, property1)
    val Sy = standardDeviation(yValues, property2)
    val xSize = xValues.size.toDouble
    val ySize = yValues.size.toDouble
    val xMean = xValues.sum / xSize
    val yMean = yValues.sum / ySize
    (1/xSize-1) * (xValues.map(x => x - xMean) * yValues.map(y => y - yMean)).sum
 }

Так, например, у нас есть набор данных List ((2,7), (8,12), (11,17))

x̅ будет 7 ((2 + 8 + 11) / 3 = 7). y̅ будет 12 ((7 + 12 + 17) / 3 = 12).

Я пытаюсь взять каждое значение x и минус x̅ от каждого из них. Это дает нам, (2-7) = -5; (8-7) = 1; (11-7) = 4. То же самое для значений у, (7-12) = -5; (12-12) = 0; (17-12) = 5.

И умножить каждое из значений x и y дает нам, (-5 * -5) = 25; (1 * 0) = 0; (4 * 5) = 20.

Суммирование каждого из них дает нам, (25 + 20) = 45

Но я не могу получить часть умножения каждого х и значения y перед суммированием. Нужна ли мне для этого рекурсия?

Редактировать: у меня есть отдельный метод для расчета стандартного отклонения

Ответы [ 2 ]

3 голосов
/ 19 марта 2020

Вы можете сделать это с помощью функции zip:

xValues.zip(yValues).map((x, y) => (x - xMean) * (y - yMean)).sum

(извините, если синтаксис неправильный, не программировал в scala годами)

1 голос
/ 20 марта 2020

Последняя строка должна быть

xValues.zip(yValues).map { case (x, y) => (x - xMean) * (y - yMean) }.sum

Это очень близко к другому ответу, с добавленной деталью, что при пинге map нам нужно использовать case, чтобы разобрать кортеж, созданный zip. Это должно быть сделано, потому что map принимает только один параметр, а (x, y) => ... - это функция с двумя параметрами.

Другой допустимый подход был бы:

xValues.zip(yValues).map(pair => (pair._1 - xMean) * (pair._2 - yMean)).sum

Где _1 и _2 доступ к элементу в кортеже.

Обратите внимание, что это относится к Scala 2.x, Scala 3 будет поддерживать параметр unptupling .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...