lib/statsample/factor.rb in statsample-0.14.0 vs lib/statsample/factor.rb in statsample-0.14.1
- old
+ new
@@ -13,7 +13,81 @@
# * Statsample::Factor::Varimax
# * Statsample::Factor::Equimax
# * Statsample::Factor::Quartimax
# See documentation of each class to use it
module Factor
+ # Anti-image covariance matrix.
+ # Useful for inspection of desireability of data for factor analysis.
+ # According to Dziuban & Shirkey (1974, p.359):
+ # "If this matrix does not exhibit many zero off-diagonal elements,
+ # the investigator has evidence that the correlation
+ # matrix is not appropriate for factor analysis."
+ #
+ def self.anti_image_covariance_matrix(matrix)
+ s2=Matrix.diag(*(matrix.inverse.diagonal)).inverse
+ aicm=(s2)*matrix.inverse*(s2)
+ aicm.extend(Statsample::CovariateMatrix)
+ aicm.fields=matrix.fields if matrix.respond_to? :fields
+ aicm
+ end
+ def self.anti_image_correlation_matrix(matrix)
+ s=Matrix.diag(*(matrix.inverse.diagonal)).sqrt.inverse
+ aicm=s*matrix.inverse*s
+ aicm.extend(Statsample::CovariateMatrix)
+ aicm.fields=matrix.fields if matrix.respond_to? :fields
+ aicm
+
+ end
+
+ # Kaiser-Meyer-Olkin measure of sampling adequacy for correlation matrix.
+ #
+ # Kaiser's (1974, cited on Dziuban & Shirkey, 1974) present calibration of the index is as follows :
+ # * .90s—marvelous
+ # * .80s— meritorious
+ # * .70s—middling
+ # * .60s—mediocre
+ # * .50s—miserable
+ # * .50 •—unacceptable
+ def self.kmo(matrix)
+ q=anti_image_correlation_matrix(matrix)
+ n=matrix.row_size
+ sum_r,sum_q=0,0
+ n.times do |j|
+ n.times do |k|
+ if j!=k
+ sum_r+=matrix[j,k]**2
+ sum_q+=q[j,k]**2
+ end
+ end
+ end
+ sum_r.quo(sum_r+sum_q)
+ end
+ # Kaiser-Meyer-Olkin measure of sampling adequacy for one variable.
+ #
+ def self.kmo_univariate(matrix, var)
+ if var.is_a? String
+ if matrix.respond_to? :fields
+ j=matrix.fields.index(var)
+ raise "Matrix doesn't have field #{var}" if j.nil?
+ else
+ raise "Matrix doesn't respond to fields"
+ end
+ else
+ j=var
+ end
+
+ q=anti_image_correlation_matrix(matrix)
+ n=matrix.row_size
+
+ sum_r,sum_q=0,0
+
+ n.times do |k|
+ if j!=k
+ sum_r+=matrix[j,k]**2
+ sum_q+=q[j,k]**2
+ end
+ end
+ sum_r.quo(sum_r+sum_q)
+ end
+
end
end