| 14 | |
| 15 | |
| 16 | class QuantumKMeans: |
| 17 | |
| 18 | def __init__(self,data_csv,num_clusters,features,copies=1000,iters=100): |
| 19 | self.data_csv = data_csv |
| 20 | self.num_clusters = num_clusters |
| 21 | self.features = features |
| 22 | self.copies = copies |
| 23 | self.iters = iters |
| 24 | |
| 25 | |
| 26 | def data_preprocess(self): |
| 27 | df = pd.read_csv(self.data_csv) |
| 28 | print(df.columns) |
| 29 | df['theta'] = df.apply(lambda x: math.atan(x[self.features[1]]/x[self.features[0]]), axis=1) |
| 30 | self.X = df.values[:,:2] |
| 31 | self.row_norms = np.sqrt((self.X**2).sum(axis=1)) |
| 32 | self.X = self.X/self.row_norms[:, np.newaxis] |
| 33 | self.X_q_theta = df.values[:,2] |
| 34 | self.num_datapoints = self.X.shape[0] |
| 35 | |
| 36 | def distance(self,x,y): |
| 37 | st = SwapTest(prepare_input_states=True,input_state_dim=2, measure=True, |
| 38 | copies=self.copies) |
| 39 | st.build_circuit(input_1_transforms=[cirq.ry(x)], |
| 40 | input_2_transforms=[cirq.ry(y)]) |
| 41 | prob_0, _ = st.simulate() |
| 42 | _distance_ = 1 - prob_0 |
| 43 | del st |
| 44 | return _distance_ |
| 45 | |
| 46 | def init_clusters(self): |
| 47 | self.cluster_points = np.random.randint(self.num_datapoints,size=self.num_clusters) |
| 48 | self.cluster_datapoints = self.X[self.cluster_points,:] |
| 49 | self.cluster_theta = self.X_q_theta[self.cluster_points] |
| 50 | self.clusters = np.zeros(len(self.X_q_theta)) |
| 51 | |
| 52 | def assign_clusters(self): |
| 53 | self.distance_matrix = np.zeros((self.num_datapoints, self.num_clusters)) |
| 54 | for i,x in enumerate(list(self.X_q_theta)): |
| 55 | for j,y in enumerate(list(self.cluster_theta)): |
| 56 | self.distance_matrix[i, j] = self.distance(x,y) |
| 57 | self.clusters = np.argmin(self.distance_matrix,axis=1) |
| 58 | |
| 59 | def update_clusters(self): |
| 60 | updated_cluster_datapoints = [] |
| 61 | updated_cluster_theta = [] |
| 62 | for k in range(self.num_clusters): |
| 63 | |
| 64 | centroid = np.mean(self.X[self.clusters == k],axis=0) |
| 65 | centroid_theta = math.atan(centroid[1]/centroid[0]) |
| 66 | updated_cluster_datapoints.append(centroid) |
| 67 | updated_cluster_theta.append(centroid_theta) |
| 68 | |
| 69 | self.cluster_datapoints = np.array(updated_cluster_datapoints) |
| 70 | self.cluster_theta = np.array(updated_cluster_theta) |
| 71 | |
| 72 | def plot(self): |
| 73 | fig = plt.figure(figsize=(8, 8)) |