Реализация попарно линейного расстояния в Scala - PullRequest
0 голосов
/ 15 февраля 2019

Предположим, у меня есть следующий DataFrame в Scala Spark, где год year значение является категориальным представлением String, но в данных есть порядок.

+-----+
|years|
+-----+
|  0-1|
|  1-2|
|  2-5|
| 5-10|
+-----+

Я хотел бы создать результирующийпопарная матрица, представляющая «расстояние» для каждой пары значений.Одни и те же значения получают оценку 1, значения на крайнем конце - 0, например.«0-1» и «5-10».Остальные значения заполнены линейной моделью .:

Я хотел бы получить следующие ожидаемые результаты (в DataFrame или аналогичной структуре для запроса пары)

x/y, 0-1,   1-2,  2-5,  5-10,
0-1,  1   , 0.33, 0.67, 0,
1-2,  0.33, 1 ,   0.33, 0.67,
2-5,  0.67, 0.33, 1 ,   0.33,
5-10, 0   , 0.67, 0.33, 1

В конце дляданная пара years Я бы хотел получить значения distance.Я хотел бы избежать жесткого кодирования этого решения, есть ли лучший способ сделать это?

1 Ответ

0 голосов
/ 15 февраля 2019

Просто сопоставьте ваши метки с точками 0 = 0/g, 1/g, 2/g, ... , g/g = 1, где g - это число промежутков между двумя смежными метками, то есть количество меток минус один:

def similarityMatrix[A](xs: List[A]): Map[A, Map[A, Double]] = {
  val numGaps = xs.size - 1
  val positions = xs.zip((0 to numGaps).map(i => i.toDouble / numGaps)).toMap
  def similarity(x: A, y: A) = 1.0 - math.abs(positions(x) - positions(y))
  xs.map(x => (x, xs.map(y => (y, similarity(x, y))).toMap)).toMap
}

Ваш пример:

val ranges = List("0-1", "1-2", "2-5", "5-10")
val matrix = similarityMatrix(ranges)

for (x <- ranges) {
  for (y <- ranges) {
    printf("%4.2f ", matrix(x)(y))
  }
  println()
}

Дает следующую вложенную карту:

1.00 0.67 0.33 0.00 
0.67 1.00 0.67 0.33 
0.33 0.67 1.00 0.67 
0.00 0.33 0.67 1.00 

Работает для любого измерения, конечно:

1.00 0.94 0.88 0.81 0.75 0.69 0.63 0.56 0.50 0.44 0.38 0.31 0.25 0.19 0.13 0.06 0.00 
0.94 1.00 0.94 0.88 0.81 0.75 0.69 0.63 0.56 0.50 0.44 0.38 0.31 0.25 0.19 0.13 0.06 
0.88 0.94 1.00 0.94 0.88 0.81 0.75 0.69 0.63 0.56 0.50 0.44 0.38 0.31 0.25 0.19 0.13 
0.81 0.88 0.94 1.00 0.94 0.88 0.81 0.75 0.69 0.63 0.56 0.50 0.44 0.38 0.31 0.25 0.19 
0.75 0.81 0.88 0.94 1.00 0.94 0.88 0.81 0.75 0.69 0.63 0.56 0.50 0.44 0.38 0.31 0.25 
0.69 0.75 0.81 0.88 0.94 1.00 0.94 0.88 0.81 0.75 0.69 0.63 0.56 0.50 0.44 0.38 0.31 
0.63 0.69 0.75 0.81 0.88 0.94 1.00 0.94 0.88 0.81 0.75 0.69 0.63 0.56 0.50 0.44 0.38 
0.56 0.63 0.69 0.75 0.81 0.88 0.94 1.00 0.94 0.88 0.81 0.75 0.69 0.63 0.56 0.50 0.44 
0.50 0.56 0.63 0.69 0.75 0.81 0.88 0.94 1.00 0.94 0.88 0.81 0.75 0.69 0.63 0.56 0.50 
0.44 0.50 0.56 0.63 0.69 0.75 0.81 0.88 0.94 1.00 0.94 0.88 0.81 0.75 0.69 0.63 0.56 
0.38 0.44 0.50 0.56 0.63 0.69 0.75 0.81 0.88 0.94 1.00 0.94 0.88 0.81 0.75 0.69 0.63 
0.31 0.38 0.44 0.50 0.56 0.63 0.69 0.75 0.81 0.88 0.94 1.00 0.94 0.88 0.81 0.75 0.69 
0.25 0.31 0.38 0.44 0.50 0.56 0.63 0.69 0.75 0.81 0.88 0.94 1.00 0.94 0.88 0.81 0.75 
0.19 0.25 0.31 0.38 0.44 0.50 0.56 0.63 0.69 0.75 0.81 0.88 0.94 1.00 0.94 0.88 0.81 
0.13 0.19 0.25 0.31 0.38 0.44 0.50 0.56 0.63 0.69 0.75 0.81 0.88 0.94 1.00 0.94 0.88 
0.06 0.13 0.19 0.25 0.31 0.38 0.44 0.50 0.56 0.63 0.69 0.75 0.81 0.88 0.94 1.00 0.94 
0.00 0.06 0.13 0.19 0.25 0.31 0.38 0.44 0.50 0.56 0.63 0.69 0.75 0.81 0.88 0.94 1.00 
...