By **Lamarcus Coleman**

Statistical Arbitrage is one of the most recognizable quantitative trading strategies. Though several variations exist, the basic premise is that despite two securities being random walks, their relationship is not random, thus yielding a trading opportunity. A key concern of implementing any version of statistical arbitrage is the process of pair selection.

**Part II: Understanding K-Means**

In this post, we will survey a machine learning for trading model to address the issue of pair selection.

K-Means Clustering For Pair Selection In Python – Part IIClick To Tweet

**What Is K-Means Clustering?**

K-Means Clustering is a type of unsupervised machine learning that groups data on the basis of similarities. Recall that in supervised machine learning we provide the algorithm with features or variables that we would like it to associate with labels or the outcome in which we would like it to predict or classify. In unsupervised machine learning we only provide the model with features and it then “learns” the associations on its own.

K-Means is one technique for finding subgroups within datasets. One difference in K-Means versus that of other clustering methods is that in K-Means, we have a predetermined amount of clusters and some other techniques do not require that we predefine the number of clusters. The algorithm begins by randomly assigning each data point to a specific cluster with no one data point being in any two clusters. It then calculates the centroid, or mean of these points.

The object of the algorithm is to reduce the total within-cluster variation. In other words, we want to place each point into a specific cluster, measure the distances from the centroid of that cluster and then take the squared sum of these to get the total within-cluster variation. Our goal is to reduce this value. The process of assigning data points and calculating the squared distances is continued until there are no more changes in the components of the clusters, or in other words, we have optimally reduced the in cluster variation.

**How K-Means Works**

Let’s take a look at how K-Means works.

We will begin by importing our usual data analysis and manipulation libraries. Sci-kit learn offers built-in datasets that you can play with to get familiar with various algorithms. You can take a look at some of the datasets provided by sklearn here.

To gain an understanding of how K-Means works, we’re going to create our own toy data and visualize the clusters. Then we will use sklearn’s KMeans algorithm to assess it’s ability to identify the clusters that we created. Let’s get started!

#importing necessary libraries #data analysis and manipulation librariesimport numpy as np import pandas as pd#visualization librariesimport matplotlib.pyplot as plt import seaborn as sns#machine learning libraries #the below line is far making fake data far illustration purposesfrom sklearn.datasets import make_blobs

Now that we have imported our data analysis, visualization and the make_blobs method from sklearn, we’re ready to create our toy data to begin our analysis.

#creating fake datadata=make_blobs(n_samples=500, n_features=8,centers=5, cluster_std=1.5, random_state=201)

In the above line of code, we have created a variable named data and have initialized it using our make_blobs object imported from sklearn. The make blobs object allows us to create and specify the parameters associated with the data we’re going to create. We’re able to assign the number of samples, or the number of observations equally divided between clusters, the number of features, clusters, cluster standard deviation, and a random state. Using the centres variable, we can determine the number of clusters that we want to create from our toy data.

Now that we have initialized our method, let’s take a look at our data.

#Let's take a look at our fake datadata[0] #produces an array of our samples

Printing data[0] returns an array of our samples. These are the toy data points we created when initializing the n_samples parameter in our make_blobs object. We can also view the cluster assignments we created.

#viewing the clusters of our datadata[1]

Printing data[1] allows us to view the clusters created. Note that though we specified five clusters in our initialization, our cluster assignments range from 0 to 4. This is because python indexing begins at 0 and not 1. So cluster counting, so to speak, begins at 0 and continues for five steps.

We’ve taken a look at our data and viewed our clusters, but looking at arrays doesn’t give us a lot of information. This is where our visualization libraries come in. Python’s matplotlib is a great library for visualizing data so that we can make inferences about it. Let’s create a scatter plot, or a visual to identify the relationships inherent in our data.

#creating a scatter plot of our data in features 1 and 2plt.scatter(data[0][:,0],data[0][:,1])

The above plot gives us a little more information. Not to mention its easier to read. We have created a scatter plot of our sample data using the first two features we created. We can somewhat see that there are some distinct clusters. The group to the upper right of the chart is the most distinct. There is also a degree of separation in the data to the left of the chart. But, didn’t we assign five clusters to our data? We can’t visually see the five clusters yet, but we know that they’re there.

One way that we can improve our visualization is to colour it by the clusters we created.

#the above plot doesn't give us much information #Let's recreate it using our clustersplt.scatter(data[0][:,0],data[0][:,1],c=data[1])

The above plot is a further improvement. We can now see that the grouping to the lower left of our original plot was actually multiple overlapping clusters. What would make this visualization even better is if we added more distinct colours that would allow us to identify the specific points in each cluster. We can do this by adding another parameter to our scatter plot called cmap. The cmap parameter will allow us to set a colour mapping built into matplotlib to recolour our data based on our clusters. Learn more about matplotlib’s colormapping.

#we can improve the above visualization by adding a color map to our plotplt.scatter(data[0][:,0],data[0][:,1],c=data[1],cmap=‘gist_rainbow')

To review, at this point, we have created some toy data using sklearn’s built-in make_blobs method. We then viewed the rows of the first two features, followed by the actual clusters of our toy data. Next, we plotted our data both with and without colouring based on the clusters.

To display how K-Means is implemented, we can now create the K-Means object and fit it to our toy data and compare the results.

#importing K-Meansfrom sklearn.cluster import KMeans

Each time that we import a model in sklearn, to use it, must create an instance of it. The models are objects and thus we create an instance of the object and specify the parameters for our specific object. Naturally, this allows us to create a variety of different models, each with different specifications for our analysis. In this example, we’ll create a single instance of the K-Means object and specify the number of clusters.

#instantiating kmeansmodel=KMeans(n_clusters=5) #n_clusters represents # of clusters; we know this because we created this dataset KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300, n_clusters=5, n_init=10, n_jobs=1, precompute_distances='auto', random_state=None, tol=0.0001, verbose=0)

In the above line of code, we have now fitted our model to our data. We can see that it confirms the parameters our model applied to our data. Next, now that we have both our toy data and have visualized the clusters we created, we can compare the clusters we created from our toy data to the ones that our K-Means algorithm created based on viewing our data. We’ll code a visualization similar to the one we created earlier, however, instead of a single plot, we will use matplotlibs subplot method to create two plots, our clusters and K-Means clusters, that can be viewed side by side for analysis. If you would like to learn more about matplotlibs subplot functionality, you can visit here.

#now we can compare our clustered data to that of kmeans #creating subplotsplt.figure(figsize=(10,8)) plt.subplot(121) plt.scatter(data[0][:,0],data[0][:,1],c=data[1],cmap='gist_rainbow')#in the above line of code, we are simply replotting our clustered data #based on already knowing the labels(i.e. c=data[1])plt.title('Our Clustering') plt.tight_layout() plt.subplot(122) plt.scatter(data[0][:,0],data[0][:,1],c=model.labels_,cmap='gist_rainbow')#notice that the above line of code differs from the first in that #c=model.labels_ instead of data[1]...this means that we will be plotting #this second plot based on the clusters that our model predictedplt.title('K-Means Clustering') plt.tight_layout() plt.show()

The above plots show that the K-Means algorithm was able to identify the clusters within our data. The colouring has no bearing on the clusters and is merely a way to distinguish clusters. In practice, we won’t have the actual clusters that our data belongs to and thus we wouldn’t be able to compare the clusters of K-Means to prior clusters; But what this walkthrough shows is the ability of K-Means to identify the presence of subgroups within data.

At this point in our journey toward better understanding the application and usefulness of K-Means we’ve created our own clusters from data we created, used the K-Means algorithms to identify the clusters within our toy data and travelled back in time to a Statistical Arbitrage and mean reversion trading world with no K-Means

We’ve learned that K-Means assigns data points to clusters randomly initially and then calculates centroids or mean values. It then calculates the distances within each cluster, squares these, and sums them, to get the sum of squared error. The goals is to reduce this error or distance. The algorithm repeats this process until there is no more in-cluster variation, or put another way, the cluster compositions stop changing.

Ahead, we will enter a Statistical Arbitrage trading world where K-Means is a viable option for solving the problem of pair selection and use the same to implement a Statistical Arbitrage trading strategy.

**Next Step**

In the next part we continue to build on our understanding of how K-Means can improve our Statistical Arbitrage strategies and determining what value we should use for K. Click here to read our next edition.

*Disclaimer: All investments and trading in the stock market involve risk. Any decisions to place trades in the financial markets, including trading in stock or options or other financial instruments is a personal decision that should only be made after thorough research, including a personal risk and financial assessment and the engagement of professional assistance to the extent you believe necessary. The trading strategies or related information mentioned in this article is for informational purposes only.*

**Download Python Code**

- Python Code for K-Means Clustering for Pair Selection