简体   繁体   English

我尝试多次迭代时出错

[英]Error when I try to iterate more than once

I've got this program which calculate k-means for IA我有这个程序可以计算 IA 的 k 均值

#! /usr/bin/env python
# -*- coding: utf-8 -*-
    
from random import sample
from itertools import repeat
from math import sqrt

# Parametros
k = 6
maxit = 2
    
def leeValoracionesFiltradas (nomFichero = "valoracionesFiltradas.data"):
    lineas = [(l.strip()).split("\t") for l in (open(nomFichero).readlines())]
    diccio = {}
    for l in lineas:    
        diccio[int(l[0])] = {}
    for l in lineas:
        diccio[int(l[0])][int(l[1])] = (float(l[2]),float(l[3]))
    return diccio
        
def distEuclidea(dic1, dic2):
    # Se calcula la suma de cuadrados de los elementos comunes a los dos diccionarios
    sum2 = sum([pow(dic1[elem]-dic2[elem], 2)
                for elem in dic1 if elem in dic2])
    return sqrt(sum2)
        
def similitudEuclidea(dic1, dic2):
    return 1/(1+distEuclidea(dic1, dic2))
            
def coefPearson(dic1, dic2):
    # Se consiguen los elementos comunes en ambos diccionarios
    comunes = [x for x in dic1 if x in dic2]
    nComunes = float(len(comunes))

    # Si no hay comunes -> cero
    if nComunes==0:
        return 0

    # Calculo de las medias de cada diccionario
    media1 = sum([dic1[x][1] for x in comunes]) / nComunes
    media2 = sum([dic2[x][1] for x in comunes]) / nComunes
    
    # Numerador y denominador
    num = sum([(dic1[x][1] - media1) * (dic2[x][1] - media2) for x in comunes])
    den1 = sqrt(sum([pow(dic1[x][1] - media1, 2) for x in comunes]))
    den2 = sqrt(sum([pow(dic2[x][1] - media2, 2) for x in comunes]))
    den  = den1 * den2

    # Caculo del coeficiente
    if den==0:
        return 0

    return num/den
    
    
# Dado un diccionario {key1 : {key2 : valor}} calcula el agrupamiento k-means
# con k clusters (grupo), ejecutando maxit iteraciones, con la funcion de similitud especificada
# Retorna una tupla
# -{key1:numero de clusters} con las asignaciones de clusters (a que clusters pertenece cada elemento)
# -[{key2:valores}] una lista con los k centroides (media de los valores para cada clusters)
def kmeans (diccionario, k, maxit, similitud = coefPearson):
    
   # K puntos aleatorios son elegidos como centroides incialmente
   # Cada centroide es {key2 : valor}
   centroides = [diccionario[x] for x in sample(diccionario.keys(), k)]

   # Se asigna cada key1 a un numero de cluster
   previo  = None
   asignacion = {}
   
   # En cada iteracion se asignan puntos a los centroides y se calculan nuevos centroides
   for it in range(maxit):
       
       # Se asignan puntos a los centroides mas cercanos
       for key1 in diccionario:
           similitudes = map(similitud,repeat(diccionario[key1],k), centroides)
           asignacion[key1] = similitudes.index(max(similitudes))

       # Si no hay cambios en la asignacion, se termina
       if previo == asignacion: break
       previo = asignacion
       
       # Se recalculan los centroides (se anotan los valores de cada key a cada centroide)
       valores   = {x : {} for x in range(k)}
       contadores = {x : {} for x in range(k)}
       for key1 in diccionario:
           grupo = asignacion[key1]
           for key2 in diccionario[key1]:
               if not valores[grupo].has_key(key2):
                   valores   [grupo][key2] = 0
                   contadores [grupo][key2] = 0
               valores  [grupo][key2] += diccionario[key1][key2][1]
               contadores[grupo][key2] += 1
               
       # Se calculan las medias (nuevos centroides)
       centroides = []
       for grupo in valores:
           centro = {}
           for key2 in valores[grupo]:
               centro[key2] = round((valores[grupo][key2] / contadores[grupo][key2]),2)
           centroides.append(centro)
       
       if None in centroides: break
       
   return (asignacion, centroides)
       
       
# Se obtiene el diccionario de valoraciones (las valoraciones ya han sido filtradas)    
diccionario = leeValoracionesFiltradas()

# Se obtienen las asignaciones y los centroides con la correlacion de Pearson
tupla = kmeans (diccionario, k, maxit)
asignaciones = tupla[0]
centroids = tupla[1]
print asignaciones
print centroids 

And when I execute this for example for maxit = 2, it throws:例如,当我为 maxit = 2 执行此操作时,它会抛出:

  File "kmeans_dictio.py", line 46, in coefPearson
    media2 = sum([dic2[x][1] for x in comunes]) / nComunes
TypeError: 'float' object has no attribute '__getitem__'

How can I fix this?我怎样才能解决这个问题?

It looks like you have a dictionary ( dic2 ) of floats and a dictionary of dictionaries of floats ( dic1 ) that you are pulling an item out of with this line:看起来您有一个浮点数字典( dic2 )和浮点数字典( dic1 ),您正在使用以下行dic1提取项目:

comunes = [x for x in dic1 if x in dic2]

Then you are trying to iterate over this float here:然后你试图在这里迭代这个float

media2 = sum([dic2[x][1] for x in comunes]) / nComunes

To fix this look at dic1 and dic2 and how they are defined.要解决此问题,请查看dic1dic2以及它们的定义方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM