0
$\begingroup$

I have written a simple python code that opens a csv files and then clusters the values of one column. There around 10k rows

This is my code

import pandas as pd
import numpy as np
import random as rd
import matplotlib.pyplot as plt

data = pd.read_csv('file.csv', encoding='unicode_escape')

data.head()

feature_names = ['numbers_col']
X = np.asarray(data[feature_names])

from sklearn.cluster import KMeans

labels = KMeans(5, random_state=10).fit_predict(X)
plt.scatter(X[:, 0], X[:, 0], c=labels,
            s=50, cmap='rainbow');

This is how the result looks like

enter image description here

The result doesn't look that good it looks all liner and the clusters are shown just like dots.

I am asking for some advice so my output would look more towards what a normal K-Means output looks like: Example

enter image description here

$\endgroup$
3
$\begingroup$

The figure looks exactly how it should.

plt.scatter(X[:, 0], X[:, 0], c=labels, s=50, cmap='rainbow');

You are plotting the a value again itself, in two dimensions it will give you a line of the form y = x
Check what you want to plot, if you have only one feature it doesn't mean that the K-Means wouldn't work, you will have a clustering, but the plot its correct.

| improve this answer | |
$\endgroup$
  • $\begingroup$ marked it answred. I wanted to ask if there is a way to be able to extract the values of the cluster on the right most corner ( first graph blue color cluster) I want to learn $\endgroup$ – be1995 Feb 13 at 14:23
  • $\begingroup$ Yes. The sklearn kmeans returns all lables in the object you created. You name it labels (I will advise you to name cluster or something, labels acn be misleading a bit). Check lables.labels_ attribute, you can map the training sample by the position (first in labels_ is first in you training set and so on). $\endgroup$ – Eduardo Di Santi Grönros Feb 14 at 15:20
1
$\begingroup$

If you are just clustering one column it can only look at the relative distance between the values in that column and will always be linear on any chart as it is only clustering one dimension.

To get a result like the second image you have posted would require to cluster across two columns (in the case above you have scale_age on the x axis and scale_wander on the y axis).

| improve this answer | |
$\endgroup$
1
$\begingroup$

I would say the KMeans algo is doing exactly what it's supposed to do. I would be much more surprised if it DIDN'T do what you told it to do. I was also skeptical the first time I saw plots of my own KMeans calculations. Maybe plotting the data in a 3D chart would be more useful/practical. Here is some sample code that you should be able to adapt to your specific scenario.

import pandas as pd
pd.set_option('display.float_format', lambda x: '%.3f' % x)
import numpy as np
import statsmodels.api as sm
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt
import seaborn as sns
import seaborn as sns; sns.set(color_codes=True)
from sklearn.cluster import KMeans
color = sns.color_palette()
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:100% !important; }</style>"))

df = pd.read_csv("https://raw.githubusercontent.com/noahgift/real_estate_ml/master/data/Zip_Zhvi_SingleFamilyResidence_2018.csv")
df.head()

for col in df.columns: 
    print(col) 


import numpy as np
import pandas as pd
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
newdf = df.select_dtypes(include=numerics)

newdf = newdf.fillna(0)

pca_ = PCA(n_components=3)
X_Demo_fit_pca = pca_.fit_transform(newdf)

kmeans_PCA = KMeans(n_clusters=4, init='k-means++', max_iter= 300, n_init= 10, random_state= 3)

y_kmeans_PCA = kmeans_PCA.fit_predict(X_Demo_fit_pca)
y_kmeans_PCA

fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111, projection='3d')
ax.scatter(X_Demo_fit_pca[:,0],X_Demo_fit_pca[:,1],X_Demo_fit_pca[:,2], 
            c=y_kmeans_PCA, cmap='viridis',
            edgecolor='k', s=40, alpha = 0.5)


ax.set_title("First three PCA directions")
ax.set_xlabel("Educational_Degree")
ax.set_ylabel("Gross_Monthly_Salary")
ax.set_zlabel("Claim_Rate")
ax.dist = 10

enter image description here

In your case, it would be something like:

`X[:,0],X[:,1],X[:,2],c=labels`

Also, don't forget this line:

ax = fig.add_subplot(111, projection='3d')

Try that and see how you get along.

FYI...if I did a generic 2D plot, like yours, with the data from the sample I showed above, I would get this as a result.

plt.scatter(X_Demo_fit_pca[:, 0], X_Demo_fit_pca[:, 0], c=y_kmeans_PCA, s=50, cmap='rainbow');

enter image description here

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.