0

У меня есть 1000 объектов, каждый объект имеет 4 списка атрибутов: список слов, изображений, аудиофайлов и видеофайлов.Алгоритм для сопоставления объектов

Я хочу, чтобы сравнить каждый объект против:

  1. одного объекта, Быка, из 1000.
  2. каждый другой объект.

Сравнение будет примерно таким: sum (общие слова/общие изображения + ...).

Я хочу, чтобы алгоритм, который поможет мне найти ближайший 5, скажем, объекты для Быка и (другой?) Алгоритм, чтобы найти ближайший 5 пар объектов

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

+0

Когда есть два изображения? –

+0

Когда у них одинаковые надежные хэши с использованием расстояния Хэмминга. – schoon

ответ

1

Я сделал пример программы для решения вашего первого вопроса. Но вы должны реализовать ho, вы хотите сравнить изображения, аудио и видео. И я предполагаю, что каждый объект имеет одинаковую длину для всех списков. Чтобы ответить на ваш вопрос номер два, это было бы нечто похожее, но с двойной петлей.

import numpy as np 
from random import randint 

class Thing: 

    def __init__(self, words, images, audios, videos): 
     self.words = words 
     self.images = images 
     self.audios = audios 
     self.videos = videos 

    def compare(self, other): 
     score = 0 
     # Assuming the attribute lists have the same length for both objects 
     # and that they are sorted in the same manner: 
     for i in range(len(self.words)): 
      if self.words[i] == other.words[i]: 
       score += 1 
     for i in range(len(self.images)): 
      if self.images[i] == other.images[i]: 
       score += 1 
     # And so one for audio and video. You have to make sure you know 
     # what method to use for determining when an image/audio/video are 
     # equal. 
     return score 


N = 1000 
things = [] 
words = np.random.randint(5, size=(N,5)) 
images = np.random.randint(5, size=(N,5)) 
audios = np.random.randint(5, size=(N,5)) 
videos = np.random.randint(5, size=(N,5)) 
# For testing purposes I assign each attribute to a list (array) containing 
# five random integers. I don't know how you actually intend to do it. 
for i in xrange(N): 
    things.append(Thing(words[i], images[i], audios[i], videos[i])) 

# I will assume that object number 999 (i=999) is the Ox: 
ox = 999 
scores = np.zeros(N - 1) 
for i in xrange(N - 1): 
    scores[i] = (things[ox].compare(things[i])) 

best = np.argmax(scores) 
print "The most similar thing is thing number %d." % best 
print 
print "Ox attributes:" 
print things[ox].words 
print things[ox].images 
print things[ox].audios 
print things[ox].videos 
print 
print "Best match attributes:" 
print things[ox].words 
print things[ox].images 
print things[ox].audios 
print things[ox].videos 

EDIT:

Теперь здесь та же программа модифицирована sligthly, чтобы ответить на ваш второй вопрос. Это оказалось очень простым. Мне просто нужно было добавить 4 строки:

  1. Изменение scores в (N, N) массив вместо просто (N).
  2. Добавление for j in xrange(N): и, таким образом, создание двойной петли.
  3. if i == j:
  4. break

где 3. и 4. просто чтобы убедиться, что я только сравнивать каждую пару вещей раз и не дважды и не compary какие-то вещи с собой.

Затем есть еще несколько строк кода, необходимых для извлечения индексов из 5 самых больших значений в scores. Я также переформатировал печать, поэтому будет легко подтвердить, что напечатанные пары на самом деле очень похожи.

Здесь приходит новый код:

import numpy as np 

class Thing: 

    def __init__(self, words, images, audios, videos): 
     self.words = words 
     self.images = images 
     self.audios = audios 
     self.videos = videos 

    def compare(self, other): 
     score = 0 
     # Assuming the attribute lists have the same length for both objects 
     # and that they are sorted in the same manner: 
     for i in range(len(self.words)): 
      if self.words[i] == other.words[i]: 
       score += 1 
     for i in range(len(self.images)): 
      if self.images[i] == other.images[i]: 
       score += 1 
     for i in range(len(self.audios)): 
      if self.audios[i] == other.audios[i]: 
       score += 1 
     for i in range(len(self.videos)): 
      if self.videos[i] == other.videos[i]: 
       score += 1 
     # You have to make sure you know what method to use for determining 
     # when an image/audio/video are equal. 
     return score 


N = 1000 
things = [] 
words = np.random.randint(5, size=(N,5)) 
images = np.random.randint(5, size=(N,5)) 
audios = np.random.randint(5, size=(N,5)) 
videos = np.random.randint(5, size=(N,5)) 
# For testing purposes I assign each attribute to a list (array) containing 
# five random integers. I don't know how you actually intend to do it. 
for i in xrange(N): 
    things.append(Thing(words[i], images[i], audios[i], videos[i])) 


################################################################################ 
############################# This is the new part: ############################ 
################################################################################ 
scores = np.zeros((N, N)) 
# Scores will become a triangular matrix where scores[i, j]=value means that 
# value is the number of attrributes thing[i] and thing[j] have in common. 
for i in xrange(N): 
    for j in xrange(N): 
     if i == j: 
      break 
      # Break the loop here because: 
      # * When i==j we would compare thing[i] with itself, and we don't 
      # want that. 
      # * For every combination where j>i we would repeat all the 
      # comparisons for j<i and create duplicates. We don't want that. 
     scores[i, j] = (things[i].compare(things[j])) 

# I want the 5 most similar pairs: 
n = 5 
# This list will contain a tuple for each of the n most similar pairs: 
best_list = [] 
for k in xrange(n): 
    ij = np.argmax(scores) # Returns a single integer: ij = i*n + j 
    i = ij/N 
    j = ij % N 
    best_list.append((i, j)) 
    # Erease this score so that on next iteration the second largest score 
    # is found: 
    scores[i, j] = 0 

for k, (i, j) in enumerate(best_list): 
    # The number 1 most similar pair is the BEST match of all. 
    # The number N most similar pair is the WORST match of all. 
    print "The number %d most similar pair is thing number %d and %d." \ 
      % (k+1, i, j) 
    print "Thing%4d:" % i, \ 
      things[i].words, things[i].images, things[i].audios, things[i].videos 
    print "Thing%4d:" % j, \ 
      things[j].words, things[j].images, things[j].audios, things[j].videos 
    print 
+0

Если этот ответ является тем, что вы имели в виду, я могу изменить его, чтобы найти ближайшие 5 пар объекта. – PaulMag

+0

Спасибо! Большая помощь. – schoon

+0

@schoon Нет проблем. Достаточно ли этого для вас или я должен его расширить, чтобы полностью ответить на второй вопрос? – PaulMag

1

Если сравнение работы с «создать сумму всех функций и найти те, которые ближе всего сумма», есть простой трюк, чтобы получить близкие объекты:

  1. Поместите все объекты в массив
  2. Вычислить все суммы
  3. Сортировка массива по сумме.

Если вы берете какой-либо индекс, объекты, близкие к нему, теперь будут иметь и индекс закрытия. Итак, чтобы найти 5 ближайших объектов, вам просто нужно посмотреть index+5 на index-5 в отсортированном массиве.

Смежные вопросы