реализация кластеризации k-средств в Python, исчерпывая память

Большой выбор был бы:

gg=G

Это действительно быстро, и все располагается с отступом;-)

6
задан tshepang 9 March 2014 в 00:50
поделиться

2 ответа

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

a. почему ключи в prefs, как показано, длинные? если у вас нет миллиардов пользователей, простые int будут хороши и сэкономят вам немного памяти.

b. ваш код:

centroids = [prefs[random.choice(users)] for i in range(k)]

может дать вам повторы (два идентичных центроида), что, в свою очередь, не сделает алгоритм K-средних. Просто используйте более быстрый и надежный

centroids = [prefs[u] for random.sample(users, k)]

c. в опубликованном коде вы вызываете функцию simple_pearson , которую вы нигде не определяете; Я предполагаю, что вы хотите позвонить sim_func , но очень сложно помочь по разным вопросам, и в то же время нужно угадывать, чем опубликованный вами код отличается от любого кода, который может действительно работать

d. еще одно указание на то, что этот опубликованный код может отличаться от всего, что может действительно работать: вы устанавливаете bestmatch = (0,0) , но затем проверяете с помощью , если d - как тест будет успешным? возвращает ли функция расстояния отрицательные значения?

e. суть defaultdict в том, что простой доступ к row [m] волшебным образом добавляет элемент в row по индексу m (со значением, полученным путем вызова фабрики defaultdict , здесь 0,0). Тогда этот предмет навсегда займет память. Вам абсолютно НЕ нужно такое поведение, и, следовательно, ваш код:

  row = prefs[user_id]                    
  for m in items:
      if row[m] > 0.0: centroids[i][m]+=(row[m]/len_best)

тратит впустую огромное количество памяти, превращая prefs в плотную матрицу (в основном заполненную значениями 0.0) из разреженной матрицы, которую он использовал для быть. Если вы кодируете вместо

  row = prefs[user_id]                    
  for m in row:
      centroids[i][m]+=(row[m]/len_best)

, не будет роста в строке и, следовательно, в prefs , потому что вы перебираете ключи, которые уже есть в строке .

Может быть много других подобных проблем, крупных, подобных предыдущему, или второстепенных - например, последний,

f. не делите миллиард раз на len_best : вычислите обратное значение вне цикла и умножьте на это обратное - также вам не нужно делать это умножение внутри цикла, вы можете сделать это в оканчиваются на отдельные, так как это то же значение, которое умножает каждый элемент - это не экономит память, но позволяет избежать бесполезной траты времени процессора ;-). Хорошо, это две второстепенные проблемы, я полагаю, не одна; -).

Как я уже упоминал, может быть много других,

6
ответ дан 17 December 2019 в 02:32
поделиться

Ваши центроиды не обязательно должны быть реальным списком.

Вы, кажется, никогда не ссылаетесь ни на что, кроме центроидов [i] [m] . Если вам нужны только центроидов [i] , то, возможно, это не обязательно должен быть список; простой словарь, вероятно, подойдет.

    centroids = defaultdict(float)

    #  Move the centroids to the average of their members
    for i in range(k):
        len_best = len(bestmatches[i])

        if len_best > 0:             
            items = set.union(*[set(prefs[u].keys()) for u in bestmatches[i]])

            for user_id in bestmatches[i]:
                row = prefs[user_id]
                for m in items:
                    if row[m] > 0.0: centroids[m]+=(row[m]/len_best)  

Может работать лучше.

0
ответ дан 17 December 2019 в 02:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: