Kmode addresses your problem
Kmeans algorithms are best suited for clustering large datasets, however it limits its usage to numerical value
Kmodes on other hand, extends kmeans paradigm to categorical domains and is also able to cluster mixed data as mentioned in this paper, A Fast Clustering Algorithm to Cluster Very Large Categorical Data Sets in Data Mining
k-modes is used for clustering categorical variables. It defines clusters based on the number of matching categories between data points. (This is in contrast to the more well-known k-means algorithm, which clusters numerical data based on Euclidean distance.) The k-prototypes algorithm combines k-modes and k-means and is able to cluster mixed numerical / categorical data.
The kmodes algorithm have three major modifications to the k-means algorithm,
i.e.,
- using different dissimilarity measures,
- replacing k means with k modes, and
- using a frequency based method to update modes.
USAGE :
import numpy as np
from kmodes.kmodes import KModes
# random categorical data
data = np.random.choice(20, (100, 10))
km = KModes(n_clusters=4, init='Huang', n_init=5, verbose=1)
clusters = km.fit_predict(data)
# Print the cluster centroids
print(km.cluster_centroids_)
References
- Example 1: applied directly on categorical
x = ["Dog", "Blue", "Female", "Sad"]
y = ["Cat", "Yellow", "Male", "Happy"]
z = ["Sheep", "Yellow", "Male", "Happy"]
a = ["Sheep", "Yellow", "Female", "Happy"]
df2 = pd.DataFrame([x,y,z,a], columns= ["Pet", "Sky", "Gender", "Feeling"])
km_2 = KModes(n_clusters=2, init="Huang")
km_2.fit_predict(df2)
km_2.cluster_centroids_
- Example for numerical
x = [0,1,0]
y = [0,1,1]
z = [1,0,1]
a = [1,0,1]
b = [1,0,0]
df = pd.DataFrame([x,y,z, a, b], columns= ["Pet", "Sky", "Gender"])
km = KModes(n_clusters=2, init='Huang')
result = km.fit_predict(df)
km.cluster_centroids_
Out[14]:
array([[1, 0, 1],
[0, 1, 0]])
In [15]:
km.labels_
- Example 3 with categorical and numerical data
iris_df = pd.read_csv("../input_data/iris.csv")
iris_df.head()
from kmodes.kprototypes import KPrototypes
kP = KPrototypes(n_clusters=3, init='Huang', n_init=1, verbose=True)
kP.fit_predict(iris_df, categorical=[5])
kP.cluster_centroids_
Out[28]:
[array([[125.5 , 6.588, 2.974, 5.552, 2.026],
[ 25.5 , 5.006, 3.428, 1.462, 0.246],
[ 75.5 , 5.936, 2.77 , 4.26 , 1.326]]), array([['virginica'],
['setosa'],
['versicolor']], dtype='<U10')]
iris_df["cluster_id"] = kP.labels_
# testing to confirm
iris_df[iris_df.Species == 'versicolor']