2
$\begingroup$

I use python, and I have a list of numbers that contains 19 elements and I would like to divide this list into 6 groups or fewer.

The list could have numbers between 0 and 1. and it mustn't be ordered, I need to keep it on its form and getting cut-off

list:

Numbers :  [[ 0.867   - 0.808   - 0.740    - 0.746    - 0.674   - 0.669   -
              0.648   - 0.722   - 0.781    - 0.612    - 0.575   - 0.566   -
              0.500   - 0.555   - 0.818    - 0.800    - 0.500   - 0.500   - 0.666 ]]   

I would like to get clusters like :

A: [[ 0.867   - 0.808   - 0.740    - 0.746 ]]

B: [[ 0.674   - 0.669   - 0.648 ]]

C: [[ 0.722   - 0.781 ]]

D: [[ 0.612   - 0.575   - 0.566    - 0.500    - 0.555  ]]

E: [[ 0.818   - 0.800 ]]

F: [[ 0.500   - 0.500    - 0.666 ]]

I make splitting by eyes and for that, I ask for a scientific method for getting my objective.

  • Concerning how I defined these clusters :

I have a value that is getting from an extra function, it is equal to 0.80. I need to compare each value on the list with 0.80 for knowing the difference.

After making a comparison I get the following table

Numbers      Difference_0.80
0.867            +0.06 
0.808             0.0
0.740            -0.06
0.746            -0.06

0.674            -0.13
0.669            -0.14
0.648            -0.16

0.722            -0.08
0.781            -0.02

0.612            -0.19
0.575            -0.23
0.566            -0.24
0.500            -0.3
0.555            -0.25

0.818            +0.01
0.800             0.0

0.500            -0.3
0.500            -0.3
0.666            -0.14

when I tried clustering method (with n_clusters=2) I ve got :

0   category_Kk-mean
0.867   0
0.808   0
0.740   0
0.746   0
0.674   1
0.669   1
0.648   1
0.722   0
0.781   0
0.612   1
0.575   1
0.566   1
0.500   1
0.555   1
0.818   0
0.800   0
0.500   1
0.500   1
0.666   1

But I want to know also that this category (D) have a big decrease than a category (B):

category D
0.612   1
0.575   1
0.566   1
0.500   1
0.555   1
Category B

0.674   1
0.669   1
0.648   1

I tried with n_clusters=3 but I got a totaly bad result

Is there any method in the statistic or mathematic that can help me for getting that

$\endgroup$
  • $\begingroup$ I don‘t understand your question. Do you want to group „closest numbers“ based on a predefined number of groups. In this case you can simply build groups based on the distribution of numbers. So, say two groups, means split by median. $\endgroup$ – Peter Jun 1 '19 at 21:44
  • $\begingroup$ I have a list of numbers that contains an increase and decrease percentages. The original value is 0.80. I want to keep the table without making any order. and I want to know when to start the next decrease and when it is finished and the same thing for increases categories. $\endgroup$ – rima Jun 1 '19 at 22:38
  • $\begingroup$ but if there is a category that contains a small decrease percentage and that is placed between 2 categories which contain both a big decrease like category C It should be considerate as increase $\endgroup$ – rima Jun 1 '19 at 22:38
  • $\begingroup$ I will check your suggestion If it could help me $\endgroup$ – rima Jun 1 '19 at 22:40
  • $\begingroup$ Have a look at time series segmentation/jump algorithms. $\endgroup$ – Edmund Jun 8 '19 at 16:46
0
$\begingroup$

Because you care about the ordering you can represent your points in two dimensions (where the x coordinate is just rescaled sequence number) and apply K-means.


import numpy as np

numbers = np.array([0.867, 0.808, 0.740, 0.746, 0.674, 
                    0.669, 0.648, 0.722, 0.781, 0.612, 
                    0.575, 0.566, 0.500, 0.555, 0.818, 
                    0.800, 0.500, 0.500, 0.666])

#you can experiment with other step sizes
step_size = (numbers.max() - numbers.min())/len(numbers)
numbers2d = np.array([(step_size * i,x) for (i,x) in enumerate(numbers - 0.8)])

from sklearn.cluster import KMeans

kmeans = KMeans(n_clusters=6)
kmeans.fit(numbers2d) #random init - possibly different result each time

print(kmeans.labels_)

import matplotlib.pyplot as plt

for cluster in set(kmeans.labels_):
    x = np.where(kmeans.labels_==cluster)[0]
    y = numbers[x]
    x = numbers2d[:,0][x]
    plt.scatter(x,y)

plt.show()

Output:

[3 3 3 3 1 1 1 1 1 4 4 4 4 4 5 5 2 2 0]

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.