screwlisp proposes kittens

Lisp Principal Component Analysis (PCA) (eigendecomposition)

One way. Related to my gnuplot example, since my kitten is a mere kitten, I am aggregating stuff I can refer to back to here, with the added power of emacs eev mode working with slime. In this case, we will use one way of doing PCA in lisp. PCA is computationally expensive, prohibitively so. It is at the core of the survival of fortran, the only practically important language other than lisp. In contrast to lisp fortran’s version of cachet is that it is designed to compile linear algebra better than any other language in practice. Its version of beauty is its monomania for compilation of linear algebra in contrast to lisp’s habitability. Fortran was the language the BLAS - basic linear algebra system - was defined in. So when the iconic (well, 15 year old to be fair) Japanese telco did machine learning it was via common lisp FFIing into the BLAS for its efficiency and the body of canonical algebraic work built around it. The lisp package itself was actively maintained outside of the telco after the Japanese telco changed hands up to about five years ago. Not needing to constantly change is a facet of package maturity often found in lisp. CLML is fine. Okay, one princomp! By the way, Japanese residents - if you have any leads about CLML in Japan 15 years ago, I am all Mastodon ears.

Common Lisp PCA In One Fell Swoop

Let’s do this! Remembering that in emacs eev-mode, I am just tapping <F8> over and over again.

 (eev-shell)
mkdir -p ~/gits
cd ~/gits
git clone https://github.com/mmaul/clml
cd ~/quicklisp/local-projects # quicklisp.org?
ln -s ~/gits/clml .
cd
 (setq inferior-lisp-program "sbcl --dynamic-space 2560")
 (slime)
 (setq eepitch-buffer-name "*slime-repl sbcl*")

(ql:quickload :clml)
(defparameter *input-vectors* #(#(0 0 1) #(1 2 3) #(4 5 5)))
(defparameter *dimension-names* '("a" "b" "c"))
;; Ā«.this linkĀ»	(to "this link")
*dimension-names*
*input-vector*
(CLML.HJS.READ-DATA:MAKE-UNSPECIALIZED-DATASET ** *)
(CLML.HJS.READ-DATA:PICK-AND-SPECIALIZE-DATA * :data-types '(:numeric :numeric :numeric))
(CLML.PCA:PRINCOMP *)
(CLML.PCA:PRINCOMP-PROJECTION ** (cadr /))
(clml.pca:loading-factors (car ///))

Phee-eww. I guess you got it. Remember in eev eepitch, a ā€œred starā€ line is an elisp one-liner, and everything else is a whatever-program-eepitch-buffer-name-is one liner, executed on the other half of your screen by pressing <F8>.

Because of the one-liner nature of eepitch, I make extensive use of * ** *** and / // /// from ANSI common lisp, which are respectively the-first-return-of the last, second-last and third-last and all-the-returns-as-a-list-of the last, second-last, and third-last.

I guess if you set *dimension-names* and *input-vector* personally and <F8>ed from

;; Ā«this linkĀ» (to ā€œ.this linkā€)

then you would reasonably have PCAed whatever floats your boat. The high quality BLAS-based implementation from that Japanese telco 15 years ago (and lone wolf lisp scientist 5 years ago) make it a heavy duty choice. The barrier to entry here was that the examples and documentation in clml’s source are in Japanese (and lisp, so also inaccessible to the weak of heart). However we are not abjured by either of these.

I do not biplot the graph (I will adapt my gnuplot example to do it instead of time-series-like datas in the future).

Wait, what did we just do?

A PCA is when you replot multidimensional data (i.e. rows having a lot of columns) on a new good-choice-of-axes. The good choice of axes statistically turn out to be ~eigenvectors with the biggest ~eigenvalues. Princomp-projection gives the data where the new (x1 x2 x3 x4 x5..) are the data projections onto the good-choice-of-axes. The loadings should be graphed as arrows from the origin on the good-choice-of-axes graph. The original input data matrix, our *input-vector* turns out to have its eigenvalues (singular values) being the variance of the associated eigenvector ā€œdirectionā€. Inb4 I got something wrong.

See You Space Cowboy

screwlisp proposes kittens