Class: Statsample::SEM::SemJFoxEngine
- Inherits:
-
Object
- Object
- Statsample::SEM::SemJFoxEngine
- Includes:
- DirtyMemoize, Summarizable
- Defined in:
- lib/statsample/sem/semjfoxengine.rb
Overview
SEM using J.Fox ‘sem’ R library. Documentation for methods extracted from [davidakenny.net/cm/fit.htm]
Instance Attribute Summary collapse
-
#name ⇒ Object
Returns the value of attribute name.
-
#r_summary ⇒ Object
readonly
Returns the value of attribute r_summary.
-
#summarizable ⇒ Object
Returns the value of attribute summarizable.
Instance Method Summary collapse
-
#adjusted_goodness_of_fit ⇒ Object
Lisrel measure.
-
#bic ⇒ Object
Bayesian Information Criterion (BIC) and Adjusted BIC.
-
#cfi ⇒ Object
Comparative Fit Index (CFI).
-
#chi_square ⇒ Object
Chi-Square.
-
#chi_square_null ⇒ Object
Chi-Square for null model.
- #coefficients ⇒ Object
- #compute ⇒ Object
-
#df ⇒ Object
Degrees of freedom for Chi-Square.
- #df_null ⇒ Object
-
#goodness_of_fit ⇒ Object
Lisrel measure.
- #graphviz ⇒ Object
-
#initialize(model, opts = Hash.new) ⇒ SemJFoxEngine
constructor
A new instance of SemJFoxEngine.
- #iterations ⇒ Object
-
#nfi ⇒ Object
Bentler-Bonett Index or Normed Fit Index (NFI).
-
#nnfi ⇒ Object
Tucker Lewis Index or Non-normed Fit Index (NNFI).
- #normalized_residual ⇒ Object
- #r ⇒ Object
- #r_query ⇒ Object
- #r_semdata ⇒ Object
- #r_sempaths ⇒ Object
-
#rmsea ⇒ Object
Root Mean Square Error of Approximation (RMSEA).
- #rmsea_alpha ⇒ Object
- #rmsea_confidence_interval ⇒ Object
- #srmr ⇒ Object
Constructor Details
#initialize(model, opts = Hash.new) ⇒ SemJFoxEngine
Returns a new instance of SemJFoxEngine.
14 15 16 17 18 19 20 21 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 14 def initialize(model,opts=Hash.new) @model=model defaults = { :name=>_("SEM analysis using J.Fox sem package") } @opts=defaults.merge defaults @name=@opts[:name] end |
Instance Attribute Details
#name ⇒ Object
Returns the value of attribute name.
12 13 14 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 12 def name @name end |
#r_summary ⇒ Object (readonly)
Returns the value of attribute r_summary.
13 14 15 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 13 def r_summary @r_summary end |
#summarizable ⇒ Object
Returns the value of attribute summarizable.
11 12 13 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 11 def summarizable @summarizable end |
Instance Method Details
#adjusted_goodness_of_fit ⇒ Object
Lisrel measure. Don’t trust!
104 105 106 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 104 def adjusted_goodness_of_fit @r_summary["AGFI"] end |
#bic ⇒ Object
Bayesian Information Criterion (BIC) and Adjusted BIC
the AIC pays a penalty of 2 for each parameter estimated. The BIC and adjusted BIC increases the penalty as sample size increases χ2 + [k(k - 1)/2 - df]ln(N)
where ln(N) is the natural logarithm of the number of cases in the sample. The adjusted BIC replaces ln(N) with ln[(N + 2)/24]. The BIC places a high value on parsimony (perhaps too high). The adjusted BIC, while placing a penalty for adding parameters based on sample, does not place as high a penalty as the BIC. Like the AIC, these measures are not absolute measues and are used to compare the fit of two or more models estimated from the same data set.
171 172 173 174 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 171 def bic @r_summary["BIC"] end |
#cfi ⇒ Object
Comparative Fit Index (CFI).
This measure is directly based on the non-centrality measure. Let d = χ2 - df where df are the degrees of freedom of the model. The Comparative Fit Index equals
[d(Null Model) - d(Proposed Model)]/d(Null Model)
If the index is greater than one, it is set at one and if less than zero, it is set to zero. It is interpreted as the previous indexes. If the CFI is less than one, then the CFI is always greater than the TLI. CFI pays a penalty of one for every parameter estimated. Note that the CFI depends on the average size of the correlations in the data. If the average correlation between variables is not high, then the CFI will not be very high.
156 157 158 159 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 156 def cfi @r_summary["CFI"] end |
#chi_square ⇒ Object
Chi-Square.
For models with about 75 to 200 cases, this is a reasonable measure of fit. But for models with more cases, the chi square is almost always statistically significant. Chi square is also affected by the size of the correlations in the model: the larger the correlations, the poorer the fit.
84 85 86 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 84 def chi_square @r_summary["chisq"] end |
#chi_square_null ⇒ Object
Chi-Square for null model
92 93 94 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 92 def chi_square_null @r_summary["chisqNull"] end |
#coefficients ⇒ Object
181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 181 def coefficients est=Hash.new coeffs=@r_summary['coeff'] coeffs[4].each_with_index do |v,i| v=~/(.+) (<---|<-->) (.+)/ f1=$1 f2=$3 key=[f1,f2].sort est[key]={:estimate=>coeffs[0][i], :se=>coeffs[1][i], :z=>coeffs[2][i], :p=>coeffs[3][i], :label=>@model.get_label(key)} end est end |
#compute ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 55 def compute raise "Insuficient information" unless @model.complete? r.assign 'manifests', @model.manifests r.assign 'data', @model.data_type==:raw ? @model.ds : @model.matrix if @model.matrix r.assign 'vn', @model.variables # We should assing names to fields on matrix r.void_eval('dimnames(data)<-list(vn,vn)') end r.void_eval r_query @r_summary=@r.eval('sem.summary').to_ruby end |
#df ⇒ Object
Degrees of freedom for Chi-Square
88 89 90 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 88 def df @r_summary["df"] end |
#df_null ⇒ Object
95 96 97 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 95 def df_null @r_summary["dfNull"] end |
#goodness_of_fit ⇒ Object
Lisrel measure. Don’t trust!
99 100 101 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 99 def goodness_of_fit @r_summary["GFI"] end |
#graphviz ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 67 def graphviz require 'tmpdir' out="" compute if @r_summary.nil? Dir.mktmpdir {|dir| filename=dir+="/model_#{Time.new.to_s}" r.void_eval("path.diagram(sem.object,output.type='dot',file='#{filename}')") file=File.open(filename+".dot","r") do |fp| out=fp.read end } out end |
#iterations ⇒ Object
178 179 180 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 178 def iterations @r_summary['iterations'] end |
#nfi ⇒ Object
Bentler-Bonett Index or Normed Fit Index (NFI).
Define the null model as a model in which all of the correlations or covariances are zero. The null model is referred to as the “Independence Model” in AMOS. Its formula is:
[χ2(Null Model) - χ2(Proposed Model)]/ [χ2(Null Model)]
A value between .90 and .95 is acceptable, and above .95 is good. A disadvantage of this measure is that it cannot be smaller if more parameters are added to the model. Thus, the more parameters added to the model, the larger the index. It is for this reason that this measure is not recommended, but rather NNFI and CFI is used.
132 133 134 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 132 def nfi @r_summary["NFI"] end |
#nnfi ⇒ Object
Tucker Lewis Index or Non-normed Fit Index (NNFI).
A problem with the Bentler-Bonett NFI index is that there is no penalty for adding parameters. The Tucker-Lewis index does have such a penalty. Let χ2/df be the ratio of chi square to its degrees of freedom
[χ2/df(Null Model) - χ2/df(Proposed Model)]/[χ2/df(Null Model) - 1]
If the index is greater than one, it is set at one. It is interpreted as the Bentler-Bonett index. Note than for a given model, a lower chi square to df ratio (as long as it is not less than one) implies a better fitting model.
143 144 145 146 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 143 def nnfi @r_summary["NNFI"] end |
#normalized_residual ⇒ Object
175 176 177 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 175 def normalized_residual @r_summary["norm.res"] end |
#r ⇒ Object
22 23 24 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 22 def r @r||=Rserve::Connection.new end |
#r_query ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 44 def r_query <<-EOF library(sem); sem.model<-matrix(c( #{r_sempaths} ), ncol=3,byrow=TRUE) sem.object<-sem(sem.model,data, obs.variables=manifests, N=#{@model.cases}); sem.summary<-summary(sem.object) EOF end |
#r_semdata ⇒ Object
34 35 36 37 38 39 40 41 42 43 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 34 def r_semdata type=case @model.data_type when :raw raise "Not implemented" when :covariance 'cov' when :correlation raise "not implemented" end end |
#r_sempaths ⇒ Object
25 26 27 28 29 30 31 32 33 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 25 def r_sempaths @model.paths.values.map {|path| sign=(path[:arrow]==1) ? " ->" : "<->" label= path[:label] ? path[:label] : "NA" label_and_value=(path[:free]) ? "'#{label}', NA" : "NA, #{path[:value]}" "'#{path[:from]} #{sign} #{path[:to]}', #{label_and_value}" }.join(",\n") end |
#rmsea ⇒ Object
Root Mean Square Error of Approximation (RMSEA)
This measure is based on the non-centrality parameter. Its formula can be shown to equal:
√[([χ2/df] - 1)/(N - 1)]
where N the sample size and df the degrees of freedom of the model. (If χ2 is less than df, then RMSEA is set to zero.) Good models have an RMSEA of .05 or less. Models whose RMSEA is .10 or more have poor fit.
116 117 118 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 116 def rmsea @r_summary["RMSEA"][0] end |
#rmsea_alpha ⇒ Object
122 123 124 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 122 def rmsea_alpha @r_summary["RMSEA"][3] end |
#rmsea_confidence_interval ⇒ Object
119 120 121 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 119 def rmsea_confidence_interval @r_summary["RMSEA"][1..2] end |
#srmr ⇒ Object
160 161 162 163 |
# File 'lib/statsample/sem/semjfoxengine.rb', line 160 def srmr @r_summary["SRMR"] end |