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