I am running some PCA analysis on some data using sklearn libraries. I am then doing a scatter plot of my PC1 and PC2 scores and I am adding a 95% confidence ellipse onto the same plot using the answer on this link as my reference PCA Hotelling's 95% Python and then I am plotting it using pyplot as below: PCA plot with confidence ellipse output
As you can see, the code works and plots my data as expected however, since the labels overlap heavily. I was thinking of only labelling my outliers (points outside the ellipse defined by the two parametric equations) as those are the only points I really am interested in.
Is there any way to first identify my outliers and then label them only?
Below is my code sample (inherited from link above):
label_buff = pca_raw.iloc[:,2]
labels = label_buff.tolist()
#Calculate ellipse bounds and plot with scores
theta = np.concatenate((np.linspace(-np.pi, np.pi, 50), np.linspace(np.pi, -np.pi, 50)))
circle = np.array((np.cos(theta), np.sin(theta)))
#Where c and d are PC1 and PC2 training score subset for constructing ellipse
sigma = np.cov(np.array((c, d)))
ed = np.sqrt(scipy.stats.chi2.ppf(0.95, 2))
ell = np.transpose(circle).dot(np.linalg.cholesky(sigma) * ed)
c, d = np.max(ell[: ,0]), np.max(ell[: ,1]) #95% ellipse bounds
t = np.linspace(0, 2 * np.pi, 100)
ellipsecos = c * np.cos(t)
ellipsesin = d * np.sin(t)
# a and b are my PC1 and PC2 raw data scores
plt.scatter(a, b, color = "orange")
for i, txt in enumerate(labels):
plt.annotate(txt, (a[i], b[i]), textcoords ='offset points', ha='right', va='bottom' )
plt.plot(ellipsecos, ellipsesin, color = 'black');
plt.show();
What I tried - if ellipsecos and ellipsesin contained all the points defining the ellipse, then a and b would have to be greater than those points to lie outside the ellipse but I didnt get the expected result (So I dont think I have been able to establish the outlier condition correctly). I am more familiar with cartesian system (with the potential to evaluate the ellipse equation to check if the points were in or outside the ellipse) if anyone have perhaps helps me establish the outlier condition using the two parametric equations that would be appreciated.:
#where a and b are PC1 and PC2 scores calculated using sklearn library
for a, b in zip(a, b):
color = 'red' # non-outlier color
if (a > ellipsecos.all() & (b > ellipsesin.all()) ): # condition for being an outlier
color = 'orange' # outlier color
plt.scatter(a, b, color=color)
plt.show()
Will appreciate any help.
The pca library may be of use as it provides outlier detection using Hotelling T2 and SPE/DmodX approach.
An example is demonstrated over here: https://stackoverflow.com/a/63043840/13730780. If you only want the outlier detection, you can use specific functionalities such as:
import pca
outliers_hot = pca.hotellingsT2(PCs, alpha=0.05)
outliers_spe = pca.spe_dmodx(PCs, n_std=2)