2013-04-04 43 views
0

我有了這個程序至極計算K均值爲IA錯誤,當我試圖重複不止一次

#! /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 

當我執行此例如用於麥克斯特= 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__' 

有人可以幫助我嗎?今晚我要發送它:(謝謝2所有!!)

+1

像錯誤狀態;你正試圖在一個沒有得到的float對象上觸發'__getitem__'方法。調試信息非常清晰。你應該試着找出爲什麼我會突然觸碰浮動的循環,而不是字典。 – 2013-04-04 18:42:02

回答

3

它看起來像你有一個字典(dic2)的浮游物和字典的浮游物(dic1),你正在拉一個項目與這條線:

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

然後你想遍歷這個float這裏:

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

要在dic1dic2解決這個樣子,他們是如何定義的。

相關問題