DatStorm

Untitled

Dec 3rd, 2018
594
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.10 KB | None | 0 0
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import imageio
  4. import collections
  5. import os
  6. # Load the Iris data set
  7. import sklearn.datasets
  8. from scipy.stats import multivariate_normal
  9.  
  10.  
  11. def lloyds_algorithm(X, k, T):
  12. """ Clusters the data of X into k clusters using T iterations of Lloyd's algorithm.
  13.  
  14. Parameters
  15. ----------
  16. X : Data matrix of shape (n, d)
  17. k : Number of clusters.
  18. T : Maximum number of iterations to run Lloyd's algorithm.
  19.  
  20. Returns
  21. -------
  22. clustering: A vector of shape (n, ) where the i'th entry holds the cluster of X[i].
  23. centroids: The centroids/average points of each cluster.
  24. cost: The cost of the clustering
  25. """
  26. n, d = X.shape
  27.  
  28. # Initialize clusters random.
  29. clustering = np.random.randint(0, k, (n,))
  30. centroids = np.zeros((k, d))
  31. # print(clustering)
  32. # Used to stop if cost isn't improving (decreasing)
  33. cost = 0
  34. oldcost = 0
  35.  
  36. # Column names
  37. print("lloyds_algorithm\nIterations\tCost")
  38.  
  39. for i in range(T):
  40. # Update centroid
  41. # >> import collections, numpy
  42. # >>> a = numpy.array([0, 3, 0, 1, 0, 1, 2, 1, 0, 0, 0, 0, 1, 3, 4])
  43. # >>> collections.Counter(a)
  44. # Counter({0: 7, 1: 4, 3: 2, 2: 1, 4: 1})
  45. # YOUR CODE HERE
  46. centroids = np.zeros((k, d))
  47. counter = collections.Counter(clustering)
  48.  
  49. # Sum points in each cluster x \in C_i
  50. for point in range(n):
  51. cluster = clustering[point]
  52. centroids[cluster] += X[point]
  53.  
  54. # Get mean point in cluster
  55. for cluster in range(k):
  56. if counter[cluster] == 0: # We did not found any point here. So continue
  57. # print(f"you fucked up mark!!! {counter}")
  58. continue
  59. centroids[cluster] /= counter[cluster]
  60. # END CODE
  61.  
  62. # Update clustering
  63.  
  64. # YOUR CODE HERE
  65. # If the point x_i should be in cluster j we have that clustering[i]=j
  66. # Update clustering: Assign x_i to cluster C_j where
  67. # j=argmin||x−μ_j||^2 for i=1,...,n
  68. for ii in range(n):
  69. j = np.argmin((np.linalg.norm(X[ii, :] - centroids, axis=1) ** 2))
  70. clustering[ii] = j
  71. # END CODE
  72.  
  73. # Compute and print cost
  74. # cost = np.sum((X - centroids[clustering])**2)
  75. cost = 0
  76. for j in range(n):
  77. cost += np.linalg.norm(X[j] - centroids[clustering[j]]) ** 2
  78. print(i + 1, "\t\t", cost)
  79.  
  80. # Stop if cost didn't improve more than epislon (decrease)
  81. if np.isclose(cost, oldcost):
  82. break # TODO: DONT KNOW
  83.  
  84. oldcost = cost
  85.  
  86. return clustering, centroids, cost
  87.  
  88.  
  89. def compute_probs_cx(points, means, covs, probs_c, iter):
  90. '''
  91. Input
  92. - points: (n times d) array containing the dataset
  93. - means: (k times d) array containing the k means
  94. - covs: (k times d times d) array such that cov[j,:,:] is the covariance matrix of the j-th Gaussian.
  95. - priors: (k) array containing priors
  96. Output
  97. - probs: (k times n) array such that the entry (i,j) represents Pr(C_i|x_j)
  98. '''
  99. # Convert to numpy arrays.
  100. points, means, covs, probs_c = np.asarray(points), np.asarray(means), np.asarray(covs), np.asarray(probs_c)
  101.  
  102. # Get sizes
  103. n, d = points.shape
  104. k = means.shape[0]
  105.  
  106. # Compute probabilities
  107. # This will be a (k, n) matrix where the (i,j)'th entry is Pr(C_i)*Pr(x_j|C_i).
  108. probs_cx = np.zeros((k, n))
  109. for i in range(k):
  110. try:
  111. probs_cx[i] = probs_c[i] * multivariate_normal.pdf(mean=means[i], cov=covs[i], x=points)
  112. except Exception as e:
  113. print(f"ERROR!!!=> While iteration {iter}, Cov matrix got singular: ", e)
  114. #print(f"COVS: {covs[i]}\ndet(covs[i])={np.linalg.det(covs[i])}")
  115. #exit(1)
  116.  
  117. # The sum of the j'th column of this matrix is P(x_j); why?
  118. probs_x = np.sum(probs_cx, axis=0, keepdims=True)
  119. assert probs_x.shape == (1, n)
  120.  
  121. # Divide the j'th column by P(x_j). The the (i,j)'th then
  122. # becomes Pr(C_i)*Pr(x_j)|C_i)/Pr(x_j) = Pr(C_i|x_j)
  123. probs_cx = probs_cx / probs_x
  124.  
  125. return probs_cx, probs_x
  126.  
  127.  
  128. def em_algorithm(X, k, T, epsilon=0.001, means=None):
  129. """ Clusters the data X into k clusters using the Expectation Maximization algorithm.
  130.  
  131. Parameters
  132. ----------
  133. X : Data matrix of shape (n, d)
  134. k : Number of clusters.
  135. T : Maximum number of iterations
  136. epsilon : Stopping criteria for the EM algorithm. Stops if the means of
  137. two consequtive iterations are less than epsilon.
  138. means : (k times d) array containing the k initial means (optional)
  139.  
  140. Returns
  141. -------
  142. means: (k, d) array containing the k means
  143. covs: (k, d, d) array such that cov[j,:,:] is the covariance matrix of
  144. the Gaussian of the j-th cluster
  145. probs_c: (k, ) containing the probability Pr[C_i] for i=0,...,k.
  146. llh: The log-likelihood of the clustering (this is the objective we want to maximize)
  147. """
  148. n, d = X.shape
  149.  
  150. # Initialize and validate mean
  151. if means is None:
  152. means = np.random.rand(k, d)
  153.  
  154. # Initialize cov, prior
  155. probs_x = np.zeros(n)
  156. probs_cx = np.zeros((k, n))
  157. probs_c = np.zeros(k) + np.random.rand(k)
  158. covs = np.zeros((k, d, d))
  159.  
  160. # print(covs) a1b2−a2b1
  161. for i in range(k): covs[i] = np.identity(d)
  162.  
  163. probs_c = np.ones(k) / k
  164.  
  165. # Column names
  166. print("em_algorithm\nIterations\tLLH")
  167. close = False
  168. old_means = np.zeros_like(means)
  169. iterations = 0
  170. while not (close) and iterations < T:
  171. old_means[:] = means
  172.  
  173. # Test det(A) = 0 <=> A singular
  174. if np.linalg.det(covs).any() == 0:
  175. print("det(A) == 0 => A singular. exipting!")
  176. print(f"{iterations}=>det(covs): {np.linalg.det(covs)} \n {covs}")
  177. exit(1)
  178.  
  179. # if not np.all(np.linalg.eigvals(covs) > 0):
  180. # print(f"{iterations}=>PSD(covs): np.all({np.linalg.eigvals(covs)})>0 \n {covs}")
  181. # exit(1)
  182.  
  183. # Expectation step
  184. # probs_cx = becomes Pr(C_i)*Pr(x_j)|C_i)/Pr(x_j) = Pr(C_i|x_j)
  185. probs_cx, probs_x = compute_probs_cx(X, means, covs, probs_c, iterations)
  186. assert probs_cx.shape == (k, n)
  187.  
  188. # Maximization step
  189. # YOUR CODE HERE
  190. # prior_c = probs_cx.sum(axis=1) # sum rækkerne
  191. # probs_c = prior_c / n
  192. #
  193. # # print("Means B:, ",means, "\n")
  194. # for i in range(k):
  195. # dividend = np.zeros((d))
  196. # for j in range(n):
  197. # dividend += (X[j, :] * probs_cx[i, j]) #:)
  198. # means[i] = dividend / prior_c[i]
  199. #
  200. # # print("Means A:, ",means, "\n")
  201. # # assert not np.isnan(means).any()
  202. #
  203. # # print(f"{iterations}.B=> covs: {covs}")
  204. #
  205. # for i in range(k):
  206. # upper_sum = np.zeros((d, d))
  207. # for j in range(n):
  208. # xmeans = X[j, :] - means[i, :] # shape (d,1)
  209. # # print(f"{iterations}=> xmeans.shape: {xmeans.shape}")
  210. # # print(f"{iterations}=> xmeansT.shape: {xmeansT.shape}")
  211. # upper_sum += probs_cx[i, j] * np.outer(xmeans, xmeans.T)
  212. #
  213. # covs[i] = upper_sum / prior_c[i] # (k, d, d)
  214. # assert np.linalg.det(covs[i]) != 0.0, f"det(covs[i]) failed.\n{covs[i]}\n" # a_1b_2−a_2b_1
  215. # assert np.allclose(covs[i], covs[i].T), f"allclose(covs[i], covs[i].T) failed.\n{covs}\n"
  216.  
  217. # MARTINS KODE!
  218. probs_c = 1 / n * probs_cx.sum(axis=1)
  219.  
  220. for i in range(k):
  221. wi = np.expand_dims(probs_cx[i], axis=0)
  222. means[i] = wi @ X / probs_cx[i].sum()
  223.  
  224. for i in range(k):
  225. s = np.zeros((d, d))
  226. for j in range(n):
  227. z = np.expand_dims(X[j] - means[i], axis=1)
  228. a = probs_cx[i, j] * z @ z.T
  229.  
  230. s += a
  231. s /= probs_cx[i].sum()
  232. covs[i] = s
  233.  
  234. # END CODE
  235.  
  236. # Compute per-sample average log likelihood (llh) of this iteration
  237. llh = 1 / n * np.sum(np.log(probs_x))
  238. print(iterations + 1, "\t\t", llh)
  239.  
  240. # Stop condition
  241. dist = np.sqrt(((means - old_means) ** 2).sum(axis=1))
  242. close = np.all(dist < epsilon)
  243. iterations += 1
  244.  
  245. # Validate output
  246. assert means.shape == (k, d)
  247. assert covs.shape == (k, d, d)
  248. assert probs_c.shape == (k,)
  249.  
  250. return means, covs, probs_c, llh
  251.  
  252.  
  253. def silhouette(data, clustering):
  254. n, d = data.shape
  255. k = np.unique(clustering)[-1] + 1
  256.  
  257. # YOUR CODE HERE
  258. silh = None
  259. # END CODE
  260.  
  261. return silh
  262.  
  263.  
  264. def testEmVsLlyod(X):
  265. for k in range(2, 10):
  266. em_sc = 0 # silhouette(...)
  267. print(f"EM: testEmVsLlyod: iteration: {k}, em_sc: {em_sc}")
  268. means, covs, probs_c, llh = em_algorithm(X, k, 50)
  269.  
  270. lloyd_sc = 0 # silhouette(...)
  271. print(f"LL: testEmVsLlyod: iteration: {k}, lloyd_sc: {lloyd_sc}")
  272. clustering, centroids, cost = lloyds_algorithm(X, k, 50)
  273.  
  274. # (Optional) try the lloyd's initialized EM algorithm.
  275.  
  276.  
  277. def f1(predicted, labels):
  278. n, = predicted.shape
  279. assert labels.shape == (n,)
  280. r = np.max(predicted) + 1
  281. k = np.max(labels) + 1
  282.  
  283. # Implement the F1 score here
  284. # YOUR CODE HERE
  285. contingency = None
  286. F_individual = None
  287. F_overall = None
  288. # END CODE
  289.  
  290. assert contingency.shape == (r, k)
  291. return F_individual, F_overall, contingency
  292.  
  293.  
  294. def download_image(url):
  295. filename = url[url.rindex('/') + 1:]
  296. try:
  297. with open(filename, 'rb') as fp:
  298. return imageio.imread(fp) / 255
  299. except FileNotFoundError:
  300. import urllib.request
  301. with open(filename, 'w+b') as fp, urllib.request.urlopen(url) as r:
  302. fp.write(r.read())
  303. return imageio.imread(fp) / 255
  304.  
  305.  
  306. def compress_kmeans(im, k, T, name):
  307. height, width, depth = im.shape
  308. data = im.reshape((height * width, depth))
  309. clustering, centroids, score = lloyds_algorithm(data, k, 5) # changes from 5
  310.  
  311. # make each entry of data to the value of it's cluster
  312. data_compressed = data
  313.  
  314. for i in range(k): data_compressed[clustering == i] = centroids[i]
  315.  
  316. im_compressed = data_compressed.reshape((height, width, depth))
  317.  
  318. # The following code should not be changed.
  319. fig = plt.figure(frameon=False)
  320. ax = plt.Axes(fig, [0., 0., 1., 1.])
  321. ax.set_axis_off()
  322. fig.add_axes(ax)
  323. plt.imshow(im_compressed)
  324. plt.savefig("compressed1.jpg")
  325. # plt.show()
  326.  
  327. original_size = os.stat(name).st_size
  328. compressed_size = os.stat('compressed1.jpg').st_size
  329. print("Original Size: \t\t", original_size)
  330. print("Compressed Size: \t", compressed_size)
  331. print("Compression Ratio: \t", round(original_size / compressed_size, 5))
  332.  
  333.  
  334. def compress_facade(k=4, T=100):
  335. img_facade = download_image('https://users-cs.au.dk/rav/ml/handins/h4/nygaard_facade.jpg')
  336. compress_kmeans(img_facade, k, T, 'nygaard_facade.jpg')
  337.  
  338.  
  339. def main():
  340. iris = sklearn.datasets.load_iris()
  341. X = iris['data'][:, 0:2] # reduce to 2d so you can plot if you want
  342.  
  343. ##########################
  344. ##### TESTING ############
  345. testEmVsLlyod(X)
  346. ##########################
  347. clustering, centroids, cost = lloyds_algorithm(X, 3, 100)
  348.  
  349. img_facade = download_image('https://uploads.toptal.io/blog/image/443/toptal-blog-image-1407508081138.png')
  350.  
  351. fig, ax = plt.subplots(1, 1, figsize=(5, 5))
  352. ax.imshow(img_facade)
  353. plt.savefig("blob1.jpg")
  354. # fig.show()
  355. # plt.show() # FIXME: Har rettet fra denne linje til den ovenover.
  356.  
  357. size = os.stat('toptal-blog-image-1407508081138.png').st_size
  358.  
  359. print("The image consumes a total of %i bytes. \n" % size)
  360. print("You should compress your image as much as possible! ")
  361.  
  362. compress_facade()
  363.  
  364.  
  365. if __name__ == '__main__':
  366. main()
Advertisement
Add Comment
Please, Sign In to add comment