Как получить Top N самых похожих элементов на основе косинусного сходства результатов в кадре данных? - PullRequest
0 голосов
/ 24 апреля 2019

У меня есть набор данных изображений (идентификатор, URL, функции), для которых я выполнил косинусное сходство между всеми изображениями.Результатом является фрейм данных pyspark со следующей структурой:

>>> cos_df.printSchema()
root
 |-- id: integer (nullable = true)
 |-- url: string (nullable = true)
 |-- vec: vector (nullable = true)

vec - это столбец, который содержит результаты сходства косинусов (DenseVector).Я пытаюсь создать столбец «Similar_urls» ИЛИ обновить «vec» и ввести для каждой строки верхние N наиболее похожих элементов на основе значений столбца vec.

Например, еслиЯ беру id = 26, я хочу посмотреть в «vec» и найти индексы верхних N элементов (id и индексы одинаковы) и заменить значения vec списком URL-адресов верхних N элементов.

Что я пытался сделать, это:

  1. заменить "vec" списком / массивом из верхних N индексов наиболее похожих элементов (udf)
  2. заменить этосписок / массив со списком / массивом URL (udf)

Я застрял на первом шаге, потому что я не могу преобразовать свои значения "vec" в массив / список, чтобы найтиверхние 10 значений.

from pyspark.sql.functions import udf

def convert_to_array(vec):
    return type(vec)

test_udf = udf(convert_to_array, StringType())

cos_df = cos_df.withColumn("vec", test_udf("vec"))

Когда я пытаюсь посмотреть тип значений VEC, он возвращает

net.razorvine.pickle.objects.ClassDictConstructor@2db673eb

Есть ли у вас какие-либо представления о том, что это за тип и как можноЯ манипулирую им так, чтобы я мог преобразовать vec?

PS: Я также открыт для любого другого решения, которое было бы лучше для дачи.n проблема!

1 Ответ

0 голосов
/ 24 апреля 2019

Придумал это решение для 1. Кажется, оно работает.

from pyspark.sql.functions import udf

def convert_to_array(vec):
    vec_list = vec.tolist()
    sorted_top = sorted(range(len(vec_list)), key=lambda i: vec_list[i], reverse=True)[1:16]
    return sorted_top

test_udf = udf(convert_to_array, ArrayType(IntegerType()))

cos_df = cos_df.withColumn("similar_url", test_udf("vec"))
...