Skip to content

Instantly share code, notes, and snippets.

@gbuesing
Created March 30, 2015 01:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gbuesing/2cca7072efa056c378df to your computer and use it in GitHub Desktop.
Save gbuesing/2cca7072efa056c378df to your computer and use it in GitHub Desktop.
Principal Component Analysis in Ruby
# Ruby implementation of PCA as described in:
#
# A tutorial on Principal Components Analysis
# Lindsay I Smith February 26, 2002
# http://www.cs.otago.ac.nz/cosc453/student_tutorials/principal_components.pdf
#
# Install:
#
# brew install gsl
# brew install gnuplot --with-x11
# gem instal rb-gsl gnuplot
require 'gsl'
require 'gnuplot'
# Step 1: Get some data
m = GSL::Matrix[
[2.5, 2.4],
[0.5, 0.7],
[2.2, 2.9],
[1.9, 2.2],
[3.1, 3.0],
[2.3, 2.7],
[2.0, 1.6],
[1.0, 1.1],
[1.5, 1.6],
[1.1, 0.9]
]
p m
# Step 2: Subtract the mean
m.size2.times do |i|
m.col(i).sub! m.col(i).mean
end
p m
Gnuplot.open do |gp|
Gnuplot::Plot.new(gp) do |plot|
plot.title "Mean adjusted data"
plot.terminal "png"
plot.output "mean.png"
plot.data << Gnuplot::DataSet.new([m.col(0).to_a, m.col(1).to_a]) do |ds|
ds.notitle
end
end
end
`open mean.png`
# Step 3: Calculate the covariance matrix
cov = (m.transpose * m) / (m.size1 - 1)
p cov
# Step 4: Calculate the eigenvectors and eigenvalues of the covariance matrix
eigval, eigvec = cov.eigen_symmv
p eigval, eigvec
# Step 5: Choosing components and forming a feature vector
sorted_vecs = eigval.sort_index.to_a.map {|i| eigvec.col(i) }.reverse
feature_vec = GSL::Matrix[*sorted_vecs].transpose
p feature_vec
# Step 5: Deriving the new data set
final = feature_vec.transpose * m.transpose
transformed = final.transpose
p transformed
Gnuplot.open do |gp|
Gnuplot::Plot.new(gp) do |plot|
plot.title "Transformed data"
plot.terminal "png"
plot.output "transformed.png"
plot.data << Gnuplot::DataSet.new([transformed.col(0).to_a, transformed.col(1).to_a]) do |ds|
ds.notitle
end
end
end
`open transformed.png`
@gbuesing
Copy link
Author

Created a gem for this: https://github.com/gbuesing/pca

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment