How to find clusters of geospatial data based on their timestamp rather than position?

Viewed 492

I have a set of geospatial data with me that also has the corresponding timestamps in a separate column.

Something like this:

Timestamp Latitude Longitude
1 1.56 104.57
2 1.57 105.42
4 1.65 103.32
12 1.76 101.15
14 1.78 100.45
16 1.80 99.65

I want to be able to cluster the data based on their timestamps rather than their distances.

So for the above example, I should obtain 2 clusters: 1 from the 1st 3 data points, and 1 from the remaining 3. I would also like to obtain the range of timestamps for each cluster is possible.

From what I've researched so far, I've only gotten either geospatial distance clustering, or time-series clustering, both of which do not sound like what I need. Are there any recommended algorithms for what I am trying to do?

1 Answers

Here density-based spatial clustering of applications with noise or shortly DBSCAN algorithm will be helpful in your case. DBSCAN is a density-based clustering algorithm which groups the points based on the closeness between them.

From what I understood in my quick research, DBSCAN draws a circle around its core. The circle's radius is called epsilon. All the points within the single circle will be counted in the same cluster. Larger the epsilon, the more points you will have in your cluster & vice versa.

enter image description here

There is more to this algorithm which you can find on this & this links.

Why DBSCAN is good for Timeseries Clustering:

  • DBSCAN does not require k (number of clusters) as the input

    In your case, there might be many clusters of time periods. Trying to fit an elbow curve to find the best number of clusters will be time-consuming & inefficient.

Code:

The below code snippet will do your task,

import pandas as pd
from sklearn.cluster import DBSCAN
import numpy as np
import matplotlib.pyplot as plt

# Getting Data
df = pd.DataFrame({
    'Timestamp' : [1,2,4,12,14,16,25,28,29],
    'Latitude' : [1.56,1.57,1.65,1.76,1.78,1.80,1.83,1.845,1.855],
    'Longitude' : [104.57,105.42,103.32,101.15,100.45,99.65,100,100.3,101.2]})

# Initializing the object
db = DBSCAN(eps=3.0, min_samples=3)

# eps = Epsilon value. Larger the epsilon, the more distant points you will catch in a single cluster.
#       Ex.  eps = 1.0 wasn't capturing the '4' value from [1,2,4] cluster. Increasing the epsilon 
#       helped in detecting that.

# min_samples = Minimum number of samples you want in your single cluster.

# Fitting the algorithm onto Timestamp column
df['Cluster'] = db.fit_predict(np.array(df['Timestamp']).reshape(-1,1))

print(f"Found {df['Cluster'].nunique()} clusters \n")
print(df)

# Plotting the Graph
fig = plt.figure(figsize = (5,5))
plt.xlabel('Latitude')
plt.ylabel('Longitude')

for data in df.groupby(df['Cluster']):
    index = data[0]
    df = data[1]
    plt.scatter(df['Latitude'], df['Longitude'], c=np.random.rand(1,len(df)),  label=f"Cluster {index}")
    
plt.legend()
plt.show()

OUTPUT:

enter image description here

Related