title: Clustering observations based first on an attribute and on distance matrix
body: <p>I have a dataset with locations (coordinates) and a scalar attribute of each location (for example, temperature). I need to cluster the locations based on the scalar attribute, but taking into consideration the distance between locations. </p>
  
  <p>The problem is that, using temperature as an example, it is possible for locations that are far from each other to have the same temperature. If I cluster on temperature, these locations will be in the same cluster, when they shouldn't. The opposite is true if two locations that are near each other have different temperatures. In this case, clustering on temperature may result in these observations being in different clusters, while clustering based on a distance matrix would put them in the same one.</p>
  
  <p>So, is there a way in which I could cluster observations giving more importance to one attribute (temperature) and then "refining" based on the distance matrix? </p>
  
  <p>Here is a simple example showing how clustering differs depending on whether an attribute is used as the basis or the distance matrix. My goal is to be able to use both, the attribute and the distance matrix, giving more importance to the attribute.</p>
  
  <pre><code>import numpy as np
  import matplotlib.pyplot as plt
  import haversine
  from scipy.cluster.hierarchy import linkage, fcluster
  from scipy.spatial import distance as ssd
  
  # Create location data
  x = np.random.rand(100, 1)
  y = np.random.rand(100, 1)
  
  t = np.random.randint(0, 20, size=(100,1))
  
  # Compute distance matrix
  D = np.zeros((len(x),len(y)))
  for k in range(len(x)):
      for j in range(len(y)):
          distance_pair= haversine.distance((x[k], y[k]), (x[j], y[j]))
          D[k,j] = distance_pair
  
  # Compare clustering alternatives
  Zt = linkage(t, 'complete')
  Zd = linkage(ssd.squareform(D), method="complete")
  
  # Cluster based on t
  clt = fcluster(Zt, 5, criterion='distance').reshape(100,1)
  plt.figure(figsize=(10, 8))
  plt.scatter(x, y, c=clt)  
  plt.show()
  
  # Cluster based on distance matrix
  cld = fcluster(Zd, 10, criterion='distance').reshape(100,1)
  plt.figure(figsize=(10, 8))
  plt.scatter(x, y, c=cld)  
  plt.show()
  </code></pre>
  
  <p>haversine.py is available here: <a href="https://gist.github.com/rochacbruno/2883505" rel="nofollow noreferrer">https://gist.github.com/rochacbruno/2883505</a></p>
  
  <p>Thanks.</p>