Class: Statsample::Factor::PrincipalAxis
- Inherits:
-
Object
- Object
- Statsample::Factor::PrincipalAxis
- Includes:
- GetText
- Defined in:
- lib/statsample/factor/principalaxis.rb
Overview
Principal Axis Analysis for a covariance or correlation matrix.
For PCA, use Statsample::Factor::PCA
Usage:
require 'statsample'
a=[2.5, 0.5, 2.2, 1.9, 3.1, 2.3, 2.0, 1.0, 1.5, 1.1].to_scale
b=[2.4,0.7,2.9,2.2,3.0,2.7,1.6,1.1,1.6,0.9].to_scale
ds={'a'=>a,'b'=>b}.to_dataset
cor_matrix=Statsample::Bivariate.correlation_matrix(ds)
pa=Statsample::Factor::PrincipalAxis.new(cor_matrix)
pa.iterate(1)
pa.m
=> 1
pca.component_matrix
=> GSL::Matrix
[ 9.622e-01
9.622e-01 ]
pca.communalities
=> [0.962964636346122, 0.962964636346122]
References:
-
SPSS manual
-
Smith, L. (2002). A tutorial on Principal Component Analysis. Available on courses.eas.ualberta.ca/eas570/pca_tutorial.pdf
Constant Summary collapse
- DELTA =
Minimum difference between succesive iterations on sum of communalities
1e-3- MAX_ITERATIONS =
Maximum number of iterations
50
Instance Attribute Summary collapse
-
#eigenvalues ⇒ Object
Eigenvalues of factor analysis.
-
#epsilon ⇒ Object
Tolerance for iteratios.
-
#initial_eigenvalues ⇒ Object
readonly
Initial eigenvalues.
-
#iterations ⇒ Object
readonly
Number of iterations required to converge.
-
#m ⇒ Object
Number of factors.
-
#max_iterations ⇒ Object
Maximum number of iterations.
-
#name ⇒ Object
Name of analysis.
-
#smc ⇒ Object
Use SMC(squared multiple correlations) as diagonal.
Class Method Summary collapse
-
.separate_matrices(matrix, y) ⇒ Object
Returns two matrixes from a correlation matrix with regressors correlation matrix and criteria xy matrix.
Instance Method Summary collapse
-
#communalities(m = nil) ⇒ Object
Communality for all variables given m factors.
-
#component_matrix(m = nil) ⇒ Object
Component matrix for m factors.
- #initial_communalities ⇒ Object
-
#initialize(matrix, opts = Hash.new) ⇒ PrincipalAxis
constructor
A new instance of PrincipalAxis.
-
#iterate(m = nil) ⇒ Object
Iterate to find the factors.
- #report_building(generator) ⇒ Object
- #summary ⇒ Object
Constructor Details
#initialize(matrix, opts = Hash.new) ⇒ PrincipalAxis
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/statsample/factor/principalaxis.rb', line 56 def initialize(matrix, opts=Hash.new) @matrix=matrix @name="" @m=nil @initial_eigenvalues=nil @initial_communalities=nil @component_matrix=nil @delta=DELTA @smc=true @max_iterations=MAX_ITERATIONS opts.each{|k,v| self.send("#{k}=",v) if self.respond_to? k } if @m.nil? pca=PCA.new(::Matrix.rows(@matrix.to_a)) @m=pca.m end @clean=true end |
Instance Attribute Details
#eigenvalues ⇒ Object
Eigenvalues of factor analysis
54 55 56 |
# File 'lib/statsample/factor/principalaxis.rb', line 54 def eigenvalues @eigenvalues end |
#epsilon ⇒ Object
Tolerance for iteratios.
48 49 50 |
# File 'lib/statsample/factor/principalaxis.rb', line 48 def epsilon @epsilon end |
#initial_eigenvalues ⇒ Object (readonly)
Initial eigenvalues
46 47 48 |
# File 'lib/statsample/factor/principalaxis.rb', line 46 def initial_eigenvalues @initial_eigenvalues end |
#iterations ⇒ Object (readonly)
Number of iterations required to converge
44 45 46 |
# File 'lib/statsample/factor/principalaxis.rb', line 44 def iterations @iterations end |
#m ⇒ Object
Number of factors. Set by default to the number of factors with eigen values > 1 on PCA over data
38 39 40 |
# File 'lib/statsample/factor/principalaxis.rb', line 38 def m @m end |
#max_iterations ⇒ Object
Maximum number of iterations
52 53 54 |
# File 'lib/statsample/factor/principalaxis.rb', line 52 def max_iterations @max_iterations end |
#name ⇒ Object
Name of analysis
41 42 43 |
# File 'lib/statsample/factor/principalaxis.rb', line 41 def name @name end |
#smc ⇒ Object
Use SMC(squared multiple correlations) as diagonal. If false, use 1
50 51 52 |
# File 'lib/statsample/factor/principalaxis.rb', line 50 def smc @smc end |
Class Method Details
.separate_matrices(matrix, y) ⇒ Object
Returns two matrixes from a correlation matrix with regressors correlation matrix and criteria xy matrix.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/statsample/factor/principalaxis.rb', line 148 def self.separate_matrices(matrix, y) ac=[] matrix.column_size.times do |i| ac.push(matrix[y,i]) if i!=y end rxy=Matrix.columns([ac]) rows=[] matrix.row_size.times do |i| if i!=y row=[] matrix.row_size.times do |j| row.push(matrix[i,j]) if j!=y end rows.push(row) end end rxx=Matrix.rows(rows) [rxx,rxy] end |
Instance Method Details
#communalities(m = nil) ⇒ Object
Communality for all variables given m factors
78 79 80 81 82 83 84 |
# File 'lib/statsample/factor/principalaxis.rb', line 78 def communalities(m=nil) if m!=@m or @clean iterate(m) raise "Can't calculate comunality" if @communalities.nil? end @communalities end |
#component_matrix(m = nil) ⇒ Object
Component matrix for m factors
86 87 88 89 90 91 |
# File 'lib/statsample/factor/principalaxis.rb', line 86 def component_matrix(m=nil) if m!=@m or @clean iterate(m) end @component_matrix end |
#initial_communalities ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/statsample/factor/principalaxis.rb', line 129 def initial_communalities if @initial_communalities.nil? if @smc @initial_communalities=@matrix.column_size.times.collect {|i| rxx , rxy = PrincipalAxis.separate_matrices(@matrix,i) matrix=(rxy.t*rxx.inverse*rxy) matrix[0,0] } else @initial_communalities=[1.0]*@matrix.column_size end end @initial_communalities end |
#iterate(m = nil) ⇒ Object
Iterate to find the factors
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/statsample/factor/principalaxis.rb', line 93 def iterate(m=nil) @clean=false m||=@m @m=m t = @max_iterations work_matrix=@matrix.to_a prev_com=initial_communalities pca=PCA.new(::Matrix.rows(work_matrix)) @initial_eigenvalues=pca.eigenvalues prev_sum=prev_com.inject(0) {|ac,v| ac+v} @iterations=0 t.times do |i| @iterations+=1 prev_com.each_with_index{|v,it| work_matrix[it][it]=v } pca=PCA.new(::Matrix.rows(work_matrix)) @communalities=pca.communalities(m) @eigenvalues=pca.eigenvalues com_sum=@communalities.inject(0) {|ac,v| ac+v} jump=true break if (com_sum-prev_sum).abs<@delta @communalities.each_with_index do |v2,i2| raise "Variable #{i2} with communality > 1" if v2>1.0 end prev_sum=com_sum prev_com=@communalities end @component_matrix=pca.component_matrix(m) end |
#report_building(generator) ⇒ Object
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/statsample/factor/principalaxis.rb', line 172 def report_building(generator) iterate if @clean anchor=generator.toc_entry(_("Factor Analysis: ")+name) generator.html "<div class='pca'>"+_("Factor Analysis")+" #{@name}<a name='#{anchor}'></a>" generator.text "Number of factors: #{m}" generator.text "Iterations: #{@iterations}" t=ReportBuilder::Table.new(:name=>_("Communalities"), :header=>["Variable","Initial","Extraction"]) communalities(m).each_with_index {|com,i| t.row([i, sprintf("%0.4f", initial_communalities[i]), sprintf("%0.3f", com)]) } generator.parse_element(t) t=ReportBuilder::Table.new(:name=>_("Eigenvalues"), :header=>["Variable","Value"]) @initial_eigenvalues.each_with_index {|eigenvalue,i| t.row([i, sprintf("%0.3f",eigenvalue)]) } generator.parse_element(t) t=ReportBuilder::Table.new(:name=>_("Component Matrix"), :header=>["Variable"]+m.times.collect {|c| c+1}) i=0 component_matrix(m).to_a.each do |row| t.row([i]+row.collect {|c| sprintf("%0.3f",c)}) i+=1 end generator.parse_element(t) generator.html("</div>") end |
#summary ⇒ Object
167 168 169 170 171 |
# File 'lib/statsample/factor/principalaxis.rb', line 167 def summary rp=ReportBuilder.new() rp.add(self) rp.to_text end |