-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathKmeans.py
More file actions
74 lines (66 loc) · 3.09 KB
/
Copy pathKmeans.py
File metadata and controls
74 lines (66 loc) · 3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import numpy as np
import distance
import random
class K_MEANS:
"""
K-Means Clustering Algorithm.
Parameters:
- k (int): Number of clusters.
- methode_d (str): Method to calculate distance between instances.
- methode_c (str): Method to select initial centroids ('Random' or 'Better picking').
- max_iterations (int): Maximum number of iterations for the algorithm.
- dataset (numpy.ndarray): Dataset to be clustered.
Methods:
- fit(xt): Fits the model to the input data.
- centroid_selection(methode): Selects the initial centroids.
- _cluster(): Performs clustering on the dataset.
- _prediction(instance): Predicts the cluster for a given instance.
"""
def __init__(self,k,methode_d,methode_c,max_iterations, dataset) -> None:
self.k = k
self.centroid=[]
self.dataset_letiqu = np.hstack((dataset[:,:].copy(), -1*np.ones((dataset[:,:].shape[0], 1))))
self.methode_c=methode_c
self.methode_d=methode_d
self.max_iterations=max_iterations
def fit(self,xt):
self.Xtrain=xt
def centroid_selection(self,methode):
if methode=="Random":#random sans prendre le meme
self.centroid.extend(self.Xtrain[random.sample(range(self.Xtrain.shape[0]), self.k),:])
elif methode=="Better picking":#better picking
self.centroid.append(list(self.Xtrain[np.random.choice(self.Xtrain.shape[0]),:]))
dist = np.apply_along_axis(lambda x: distance.distance(x, self.centroid[0], self.methode_d), axis=1, arr=self.Xtrain)
ind = np.argsort(dist)
for i in range(self.k,0,-1):
self.centroid.append(list(self.Xtrain[ind[int((len(ind)/self.k)*i )-1],:]))
def _cluster(self):#instance
#choose centroid
self.centroid_selection(self.methode_c)
#boucle
change=True
nbr_iteration=0
while(change):
#distance
for j in range(self.Xtrain.shape[0]):
distances=[]
for i in range(self.k):
distances.append(distance.distance(instance1= self.centroid[i], instance2= self.Xtrain[j,:] ,methode=self.methode_d))
#affectation
c =np.argmin(distances)
self.dataset_letiqu[j,-1]=c
#maj centroid
oldcentroid=self.centroid.copy()
for i in range(self.k):
cluster=np.array([row[:-1] for row in self.dataset_letiqu if row[-1]==i])
self.centroid[i]=np.array([np.average(cluster[:,j]) for j in range(cluster.shape[1])] )
if np.linalg.norm(np.array(self.centroid) - np.array(oldcentroid)) < 0.0001 or nbr_iteration>self.max_iterations:
change=False
nbr_iteration+=1
return self.dataset_letiqu
#bonus
def _prediction(self,instance):
distances=[]
for i in range(self.k):
distances.append(distance.distance(self.centroid[i],instance,self.methode_d))
return np.argmin(distances),np.array([row[:-1] for row in self.dataset_letiqu if row[-1]==np.argmin(distances)])