• Saltar al contenido principal
  • Skip to secondary menu
  • Saltar a la barra lateral principal
  • Saltar al pie de página
  • Inicio
  • Secciones
    • Ciencia de datos
    • Criptografía
    • Herramientas
    • Machine Learning
    • Noticias
    • Opinión
    • Productividad
    • Programación
      • JavaScript
      • Julia
      • Matlab
      • Python
      • R
  • Programación
    • JavaScript
    • Julia
    • Matlab
    • Python
    • R
  • Laboratorio
    • Encuestas: Tamaño de Muestra
    • Lotería: Probabilidad de Ganar
    • Reparto de Escaños (D’Hondt)
    • Tres en Raya con IA
  • Noticias
  • Boletín
  • Contacto
  • Tienda
    • Libros
    • Equipamiento de oficina
    • Equipamiento en movilidad
    • Tiendas afiliadas
      • AliExpress
      • Amazon
      • Banggood
      • GeekBuying
      • Lenovo

Analytics Lane

Ciencia e ingeniería de datos aplicada

  • Ciencia de datos
  • Machine Learning
  • IA Generativa
  • Python
  • Pandas
  • NumPy
  • R
  • Excel

Cómo funciona k-modes e implementación en Python

octubre 14, 2022 Por Daniel Rodríguez Deja un comentario
Tiempo de lectura: 6 minutos

La semana pasada publiqué un artículo donde explicaba el funcionamiento del algoritmo de k-means o k-medias junto a una implementación básica en Python. Este algoritmo es uno de los más utilizados para análisis de clúster. Aunque cuenta con un problema importante, al estar basado en la métrica euclídea solamente se puede utilizar cuando todas las características del conjunto de datos son numéricas, no siendo posible emplearlos cuando hay datos categóricos. Para solucionar este problema se puede recurrir al algoritmo de k-modes o k-medias, una modificación de k-means en el que se cambia la distancia euclídea por las diferencias (dissimilarities) y la media para definir los centroides por la moda. Veamos cómo se puede modificar el código visto la semana pasada para implementar el algoritmo de k-modes en Python.

El algoritmo de k-modes

Comprendiendo el algoritmo de k-means es fácil entender k-modes. Debido a que este último es una modificación del primero cambiando el uso de la media por la moda para obtener la posición de los centroides en cada iteración y empleando el número de diferencias (dissimilarities) entre dos registros como medida de la distancia en lugar de la métrica euclídea.

Al igual que en el caso de k-means, los resultados que se obtienen con k-modes son fácilmente interpretables. El centroide es el valor típico, en este caso moda, de cada uno de los clusteres en los que se divide el conjunto de datos.

Balance de 2025 en Analytics Lane
En Analytics Lane
Balance de 2025 en Analytics Lane

Así, el algoritmo de k-modes se puede resumir en los siguientes pasos:

  1. Generar aleatoriamente k centroides en espacios del conjunto de datos.
  2. Obtener las diferencias (dissimilarities) de cada uno de los datos a todos los centroides y asignar al grupo cuya distancia sea menor.
  3. Estimar la moda en cada uno de los grupos para actualizar los centroides.
  4. Comprobar si los centroides se han desplazado por debajo de un valor límite, si es así esta es la solución, en caso contrario volver al punto 2.

Como se puede apreciar los pasos en este caso son prácticamente idénticos a los de k-means.

Publicidad


Entendiendo la medida de las diferencias (dissimilarities)

Al trabajar con datos categóricos no existe una medida de distancia. Por ejemplo, al trabajar con colores, no se puede definir una distancia entre rojo y azul o entre rojo y verde, en ambos casos los valores son diferentes. Así una manera de medir la distancia entre dos vectores de variables categóricas es la cantidad de valores que son diferentes, de tal manera que la distancia entre rojo y azul es uno, entre rojo y verde también es uno, siendo solemnemente cero entre rojo y rojo.

Esto se puede ver por ejemplo en la siguiente tabla de camisas:

CuelloTejidoColor
ItalianoAlgodónBlanca
InglésAlgodónAzul
InglésLinoAzul

Así la separación que existe usando las diferencias entre la primera fila y la segunda se obtiene un valor de 2, ya que ni el cuello ni el color coinciden. Mientras que la distancia entre la primera y la tercera es de 3, ninguno de los valores coincide. Finalmente, la distancia entre la primera y la tercera es 1, solamente cambia el color.

Implementación de Python de k-modes

Una implmentación de k-modes se puede llevar a cabo con el siguiente código.

import numpy as np

def next_step(centroids, previous, iteration, max_iter=10, stop_limit=0):
    """Comprueba si se debe calcular la siguiente iteración.
    
    Parameters
    ----------
    centroids : ndarray
        La posición actual de los centroides.
        
    previous : ndarray
        La posición previa de los centroides.
        
    iterations : integer
        La iteración actual.
        
    max_iter : integer
        El número máximo de iteraciones permitidas.
        
    stop_limit : real
        La diferencia entre a partir de la cual se considera que el
        algoritmo ha convergido.
        
    Returns
    -------
    mode : boolean
        Verdadero si el algoritmo debe continuar, falso en el resto de
        los casos.
    """ 
    if previous is None:
        return True
    elif iteration > max_iter:
        return False
    elif np.sum(centroids == previous) <= stop_limit:
        return False
    else:
        return True
    

def mode(data):
    """Estima la moda de cada uno de las columnas de la matriz
    
    Parameters
    ----------
    data : ndarray
        El conjunto de datos sobre el que se desea obtener la moda
    
    Returns
    -------
    mode : ndarray
        Un vector con la moda de cada una de las columnas
    """
    result = np.zeros(data.shape[1])
    
    for col in range(data.shape[1]):
        vals, counts = np.unique(data[:, col], return_counts=True)
        result[col] = vals[counts == np.max(counts)][0]
        
    return result


def dissimilarities(data, centroids):
    """Mide la disimilitudes (dissimilarities)
    
    Estima disimilitudes (dissimilarities) que existe entre las filas de
    una matriz y cada uno de los centroides.
    
    Parameters
    ----------
    data : ndarray
        La matriz con los datos sobre los que se desea medir las
        disimilitudes

    centroids : ndarray
        Los centroides de referencia sobre los que se desea medir las
        disimilitudes
        
    Returns
    -------
    dissimilarities : ndarray
        Matriz con las disimilitudes 
    """
    n_clusters = centroids.shape[0]
    result = np.zeros([data.shape[0], n_clusters])
    
    for num in range(n_clusters):
        result[:, num] = data.shape[1] - np.sum(np.equal(data, centroids[num, :]), axis=1)
    
    return result


def k_modes(data, n_clusters, max_iter=10, stop_limit=0, random_state=None):    
    """Implementación básica del algoritmo de Kmodes.
    
    Nota: esta función es solamente una implementación básica con fines
    pedagógicos, no usar en producción.
    
    Parameters
    ----------
    data : ndarray
        El conjunto de datos sobre el que se desea aplicar el algoritmo
        de Kmodes.
        
    n_clusters : integer
        El número de clústeres.
        
    max_iter : integer
        El número máximo de iteraciones permitidas.
        
    stop_limit : real
        La diferencia entre a partir de la cual se considera que el
        algoritmo ha convergido.
    
    random_state : number or None
        La semilla con la que se generan los números aleatorios.
        
    Returns
    -------
    centroids : ndarray
        Los centroides obtenidos.
    """ 
    if random_state is not None:
        np.random.seed(random_state)
        
    centroids = np.random.choice(data.shape[0], n_clusters, replace=False)
    centroids = data[centroids, :]
    
    iteration = 0
    previous = None
    
    while next_step(centroids, previous, iteration, max_iter, stop_limit):
        iteration += 1
        previous = np.empty_like(centroids)
        
        distance = dissimilarities(data, centroids)
        clusters = np.argmin(distance, axis=1)
        
        for num in range(n_clusters):
            if np.any(clusters == num):
                centroids[num, :] = mode(data[clusters == num, :])
            
    return centroids

La primera función que se ha escrito es next_step() mediante la cual se decide si se debe continuar o no. Para lo que la función devuelve verdejo siempre que no se alcance el máximo de iteraciones o el número de diferencias entre los centroides sea inferior o igual a un límite.

A continuación se encuentra la función mode() con la que se obtiene la moda. Función que es necesaria escribir dado que no existe una implementación del estadístico en NumPy.

La función dissimilarities() mide la cantidad de registros que son diferentes entre dos vectores, implementado de este modo la medida de las diferencias.

Finalmente en la función k_modes() se ha implementado el algoritmo en sí. En el que, una vez fijada la semilla, se selecciona aleatoriamente los registros que serán los centroides inciales. Posteriormente, al igual que el algoritmo de k-means se refina iterativamente los censores hasta que los valores convergen a la solución.

Publicidad


Validación con la libreria KModes

Existe una implementación dentro del paquete kmodes. Un paquete que se puede instalar lanzando el comando pip install kmodes en la terminal. Una vez instado, la creación de un modelo es exactamente igual a cualquier clasificado de Scikit-learn, se crea la clase y se ajusta con el método fit().

Así se puede comprobar que la implantación realizada en este caso obtiene el mismo resultado que la de este paquete.

from kmodes.kmodes import KModes

data = np.array([[0, 0, 0, 0, 0],
                 [1, 1, 1, 1, 1],
                 [2, 2, 1, 0, 3],
                 [1, 0, 2, 1, 1],
                 [0, 3, 2, 2, 4],
                 [0, 1, 1, 2, 4],
                 [1, 1, 2, 3, 0],
                 [0, 4, 3, 2, 4],
                 [1, 3, 2, 0, 0],
                 [2, 1, 4, 0, 4]])

centroids = k_modes(data, 2, random_state=0)

kmodes = KModes(n_clusters=2).fit(data)
kmodes.cluster_centroids_

print('Implementación')
print(centroids)
print('Scikit-learn')
print(kmodes.cluster_centroids_)
Implementación
[[0 1 1 2 4]
 [1 0 2 0 0]]
Scikit-learn
[[0 1 1 2 4]
 [1 0 2 0 0]]

Conclusiones

Hoy se han visto las bases del algoritmo de k-modes y como se puede realizar una implementación básica en Python. Obteniendo resultados similares a la clase del paquete kmodes en conjunto de datos básico.

Al igual que comente en el caso de k-menas, no recomiendo el uso de esta implementación ya que es básica. Si se necesita crear un modelo con k-modes en Python recomiendo usar las clases del paquete kmodes.

Imagen de WikiImages en Pixabay

¿Te ha parecido de utilidad el contenido?

¡Puntúalo entre una y cinco estrellas!

Puntuación promedio 5 / 5. Votos emitidos: 1

Ya que has encontrado útil este contenido...

¡Síguenos en redes sociales!

¡Siento que este contenido no te haya sido útil!

¡Déjame mejorar este contenido!

Dime, ¿cómo puedo mejorar este contenido?

Publicidad


Publicaciones relacionadas

  • Balance de 2025 en Analytics Lane
  • El promedio engañoso: cuando la media no cuenta toda la historia
  • Comprender las pruebas de hipótesis para no especialistas
  • Ordenadores para Machine Learning e Inteligencia Artificial en 2026: Guía completa para elegir el equipo adecuado según tu perfil y presupuesto
  • ¿Qué significa realmente un porcentaje? Por qué no es lo mismo subir un 20% que bajar un 20%
  • null y undefined en JavaScript y TypeScript: ¿son realmente lo mismo?
  • Riesgo relativo vs riesgo absoluto: la trampa de los titulares alarmistas
  • Guía práctica de categorías para changelogs en inglés y castellano
  • El valor esperado: la mejor herramienta que casi nadie usa

Publicado en: Ciencia de datos, Python Etiquetado como: Análisis de clúster, Aprendizaje no supervisado, Machine learning, NumPy

Interacciones con los lectores

Deja una respuesta Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

I accept the Terms and Conditions and the Privacy Policy

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Barra lateral principal

Suscríbete a nuestro boletín

Suscríbete al boletín semanal para estar al día de todas las publicaciones.

Política de Privacidad

Analytics Lane en redes sociales

  • Amazon
  • Bluesky
  • Facebook
  • GitHub
  • Instagram
  • Mastodon
  • Pinterest
  • RSS
  • Telegram
  • Tumblr
  • Twitter
  • YouTube

Publicidad

Entradas recientes

El valor esperado: la mejor herramienta que casi nadie usa

febrero 5, 2026 Por Daniel Rodríguez

Guía práctica de categorías para changelogs en inglés y castellano

febrero 3, 2026 Por Daniel Rodríguez

Riesgo relativo vs riesgo absoluto: la trampa de los titulares alarmistas

enero 29, 2026 Por Daniel Rodríguez

Publicidad

Es tendencia

  • ¿Qué es la estadística y por qué todos deberíamos comprenderla? publicado el noviembre 22, 2024 | en Opinión
  • Correlación y causalidad: no es lo mismo publicado el junio 13, 2025 | en Ciencia de datos
  • Gráfica con los datos y las anomalías detectadas con OneClass SVM One-Class SVM: Detección de anomalías con máquinas de vector soporte publicado el marzo 15, 2024 | en Ciencia de datos
  • Cómo encontrar la posición de elementos en una lista de Python publicado el abril 12, 2021 | en Python
  • pandas Optimización con Chunks en archivos grandes: Uso de pd.read_csv() con el Parámetro chunksize publicado el febrero 17, 2025 | en Python

Publicidad

Lo mejor valorado

4.9 (24)

Seleccionar filas y columnas en Pandas con iloc y loc

4.6 (16)

Archivos JSON con Python: lectura y escritura

4.4 (14)

Ordenación de diccionarios en Python mediante clave o valor

4.7 (13)

Operaciones de filtrado de DataFrame con Pandas en base a los valores de las columnas

4.5 (10)

Diferencias entre var y let en JavaScript

Publicidad

Comentarios recientes

  • M. Pilar en Cómo eliminar las noticias en Windows 11 y recuperar tu concentración
  • Daniel Rodríguez en Probabilidad básica: cómo entender el azar en nuestra vida diaria
  • Pepe en Probabilidad básica: cómo entender el azar en nuestra vida diaria
  • CARLOS ARETURO BELLO CACERES en Justicio: La herramienta gratuita de IA para consultas legales
  • Piera en Ecuaciones multilínea en Markdown

Publicidad


Footer

Analytics Lane

  • Acerca de Analytics Lane
  • Boletín de noticias
  • Contacto
  • Libros
  • Lo más popular
  • Noticias
  • Tienda
  • Tiendas afiliadas

Secciones

  • Ciencia de datos
  • Criptografía
  • Herramientas
  • Machine Learning
  • Opinión
  • Productividad
  • Programación
  • Reseñas

Sobre de Analytics Lane

En Analytics Lane tratamos de explicar los principales conceptos de la ciencia e ingeniería de datos con un enfoque práctico. Los principales temas tratados son ciencia de datos, ingeniería de datos, inteligencia artificial, machine learning, deep learning y criptografía. Además, también se habla de los principales lenguajes de programación y herramientas utilizadas por los científicos e ingenieros de datos.

Copyright © 2018-2026 Analytics Lane ·Términos y condiciones ·Política de Cookies ·Política de Privacidad ·Herramientas de privacidad ·Contacto