Кластерный анализ в наборе целых чисел - PullRequest
0 голосов
/ 28 мая 2018

Извините за широкое название, я просто не знаю, как назвать это.

У меня есть список целых чисел, скажем:

X = [20, 30, 40, 50, 60, 70, 80, 100]

И второй список кортежейразмером от 2 до 6 сделаны из следующих целых чисел:

Y = [(20, 30), (40, 50, 80, 100), (100, 100, 100), ...]

Некоторые числа возвращаются довольно часто в Y, и я бы хотел определить группу целых чисел, возвращающихся часто.

Прямо сейчас я считаю количество появлений каждого целого числа.Он дает мне некоторую информацию, но ничего о группах.

Пример:

Y = [(20, 40, 80), (30, 60, 80), (60, 80, 100), (60, 80, 100, 20), (40, 60, 80, 20, 100), ...]

В этом примере (60, 80) и (60, 80, 100) - это комбинации, которые часто возвращаются.

Я мог бы использовать itertools.combinations_with_replacement() для генерации каждой комбинации, а затем подсчитать количество появлений, но есть ли другой лучший способ сделать это?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

Подход, который вы ищете, называется

Работа с частыми наборами предметов

Он находит частые подмножества, учитывая список наборов.

0 голосов
/ 28 мая 2018

Не знаю, является ли это строго лучшим способом сделать это или, скорее, похожим, но вы могли бы попытаться проверить долю внешнего вида подмножеств.Ниже описан грубый метод сохранения результатов в словаре.Вполне возможно, было бы лучше построить дерево, в котором вы не выполняете поиск по ветви, если скорость появления ее элементов уже не срезана.(то есть, если (20,80) не появляется вместе достаточно часто, то зачем искать (20,80,100)?)

N=len(Y)
dicter = {}
for i in range(2,7):
    for comb in itertools.combinations(X,i):
        c3 = set(comb)
        d3 = sum([c3.issubset(set(val)) for val in Y])/N
        dicter['{}'.format(c3)] =  d3

Как редактировать: вас, вероятно, не интересуют все неявки, поэтомуЯ добавлю кусок кода, чтобы сократить окончательный размер словаря. Сначала мы определим функцию, которая возвращает поверхностную копию нашего словаря с удаленным 1 значением.Это необходимо, чтобы избежать RunTimeError при циклическом выполнении dict.

def removekey(d, key):
    r = dict(d)
    del r[key]
    return r

Затем мы удаляем незначительные «кластеры»

for d, v in dicter.items():
    if v < 0.1:
        dicter = removekey(dicter, d)

Это все равно будет не отсортировано, так какнаборы не сортируются сами по себе.Надеюсь, это поможет вам в дальнейшем.

...