API

Rotation criteria

FactorRotations.AbsolminType
Absolmin(epsilon)

The Absolmin component loss factor rotation criterion. It has the loss function

\[h(\lambda) = |\lambda|\]

source
FactorRotations.BiquartimaxFunction
Biquartimax()

The Biquartimax rotation method.

Details

The Biquartimax rotation method is a special case of the Oblimin rotation with parameters gamma = 0.5 and orthogonal = true.

Examples

julia> L = [
           0.830 -0.396
           0.818 -0.469
           0.777 -0.470
           0.798 -0.401
           0.786  0.500
           0.672  0.458
           0.594  0.444
           0.647  0.333
       ];

julia> L_biquartimax = rotate(L, Biquartimax());

julia> L_oblimin = rotate(L, Oblimin(gamma = 0.5, orthogonal = true));

julia> loadings(L_biquartimax) ≈ loadings(L_oblimin)
true
source
FactorRotations.BiquartiminType
Biquartimin

The Biquartimin rotation criterion.

Keyword arguments

  • orthogonal: orthogonal: If orthogonal = true an orthogonal rotation is performed, an oblique rotation otherwise. (default: false)
source
FactorRotations.ComponentLossType
ComponentLoss(loss::Function; orthogonal = false)

A generic implementation of the component loss factor rotation method. loss defines the loss function that is applied to the components of the loading matrix.

Keyword arguments

  • orthogonal: If orthogonal = true an orthogonal rotation is performed, an oblique rotation otherwise. (default: false)

Details

The component loss factor rotation applies a loss function to each element of the factor loading matrix. Then the following criterion is minimized:

\[Q(\Lambda) = \sum_i \sum_j h(\lambda_{ij})\]

Examples

Quartimax as a component loss

julia> L = [
           0.830 -0.396
           0.818 -0.469
           0.777 -0.470
           0.798 -0.401
           0.786  0.500
           0.672  0.458
           0.594  0.444
           0.647  0.333
       ];

julia> quartimax_loss = ComponentLoss(x -> x^4, orthogonal = true);

julia> L_component_loss = rotate(L, quartimax_loss)
FactorRotation{Float64} with loading matrix:
8×2 Matrix{Float64}:
 0.898755  0.194824
 0.933943  0.129749
 0.902131  0.103864
 0.876508  0.171284
 0.315572  0.876476
 0.251123  0.773489
 0.198007  0.714678
 0.307857  0.659334

julia> L_quartimax = rotate(L, Quartimax())
FactorRotation{Float64} with loading matrix:
8×2 Matrix{Float64}:
 0.898755  0.194823
 0.933943  0.129748
 0.902132  0.103864
 0.876508  0.171284
 0.315572  0.876476
 0.251124  0.773489
 0.198008  0.714678
 0.307858  0.659334

julia> isapprox(loadings(L_component_loss), loadings(L_quartimax), atol = 1e-5)
true
source
FactorRotations.ConcaveType
Concave(bandwidth = 1)

The simple concave component loss factor rotation criterion. It has the loss function

\[h(\lambda) = 1 - \exp(-\frac{|\lambda|}{b})\]

where $b$ is the bandwidth parameter.

source
FactorRotations.CrawfordFergusonType
CrawfordFerguson(; kappa, orthogonal = false)

The family of Crawford-Ferguson rotation methods.

Keyword arguments

  • kappa: The parameter determining the rotation criterion (see Details).
  • orthogonal: orthogonal: If orthogonal = true an orthogonal rotation is performed, an oblique rotation otherwise. (default: false)

Details

The Crawford-Ferguson family allows both orthogonal and oblique rotation of the p×k factor loading matrix. If orthogonal rotation is performed, Crawford-Ferguson with a specific value for kappa is equivalent to the following rotation methods:

Examples

julia> CrawfordFerguson(kappa = 0, orthogonal = true)
CrawfordFerguson{Orthogonal, Int64}(0)

julia> CrawfordFerguson(kappa = 1/2, orthogonal = false)
CrawfordFerguson{Oblique, Float64}(0.5)
source
FactorRotations.EquamaxType
Equamax()

Equamax is an orthogonal rotation method, which is equivalent to Oblimin rotation of p × k loadings matrix Λ with $\gamma = \frac{k}{2}$.

source
FactorRotations.GeominType
Geomin(epsilon = 0.01)

The Geomin rotation method.

Keyword arguments

  • epsilon: A small constant to deal with zero loadings.
source
FactorRotations.InfomaxType
Infomax(; orthogonal = false)

The Infomax rotation method.

Keyword arguments

  • orthogonal: If orthogonal = true an orthogonal rotation is performed, an oblique rotation otherwise. (default: false)
source
FactorRotations.KatzRohlfType
KatzRohlf(bandwidth)

A component loss criterion with loss function

\[h(\lambda) = 1 - \exp\left(-\left(\frac{\lambda}{b}\right)^2\right)\]

where $b$ is the bandwidth parameter.

source
FactorRotations.LinearRightConstantType
LinearRightConstant(bandwidth)

The linear right constant component loss factor rotation criterion. It has the loss function

\[h(\lambda) = \begin{cases} (\frac{\lambda}{b})^2&\text{if } |\lambda| \leq b \\ 1 &\text{if } \lambda > b \end{cases}\]

where $b$ is the bandwidth parameter.

source
FactorRotations.OblimaxType
Oblimax(; orthogonal = false)

The Oblimax rotation method.

Keyword arguments

  • orthogonal: If orthogonal = true an orthogonal rotation is performed, an oblique rotation otherwise. (default: false)

Details

The Oblimax rotation method is equivalent to Quartimax for orthogonal rotation.

Examples

julia> L = [
           0.830 -0.396
           0.818 -0.469
           0.777 -0.470
           0.798 -0.401
           0.786  0.500
           0.672  0.458
           0.594  0.444
           0.647  0.333
       ];

julia> L_oblimax = rotate(L, Oblimax(orthogonal = true));

julia> L_quartimax = rotate(L, Quartimax());

julia> isapprox(loadings(L_oblimax), loadings(L_quartimax), atol = 1e-6)
true
source
FactorRotations.ObliminType
Oblimin(; gamma, orthogonal = false)

The family of Oblimin rotation methods.

Keyword arguments

  • gamma: The shape parameter determining the rotation criterion (see Details).
  • orthogonal: If orthogonal = true an orthogonal rotation is performed, an oblique rotation otherwise. (default: false)

Details

The Oblimin rotation family allows orthogonal as well as oblique rotation of the p×k factor loading matrix. If orthogonal rotation is performed, Oblimin is equivalent to the following rotation methods given a value for gamma:

For oblique rotation Oblimin is equivalent to the following rotation methods:

Examples

julia> Oblimin(gamma = 0.5)
Oblimin{Oblique, Float64}(0.5)

julia> Oblimin(gamma = 1, orthogonal = true)
Oblimin{Orthogonal, Int64}(1)
source
FactorRotations.PatternSimplicityType
PatternSimplicity(; orthogonal = false)

The Pattern Simplicity factor rotation criterion.

Keyword arguments

  • orthogonal: If orthogonal = true an orthogonal rotation is performed, an oblique rotation otherwise. (default: false)
source
FactorRotations.QuartimaxType
Quartimax()

The Quartimax rotation criterion.

Details

The Quartimax criterion is a special case of the Oblimin rotation criterion with parameter gamma = 0.

Examples

Setting up the criterion

julia> Quartimax()
Quartimax()

Testing equivalence of Quartimax and Oblimin

julia> L = [
           0.830 -0.396
           0.818 -0.469
           0.777 -0.470
           0.798 -0.401
           0.786  0.500
           0.672  0.458
           0.594  0.444
           0.647  0.333
       ];

julia> L_quartimax = rotate(L, Quartimax());

julia> L_oblimin = rotate(L, Oblimin(gamma = 0, orthogonal = true));

julia> loadings(L_quartimax) ≈ loadings(L_oblimin)
true
source
FactorRotations.TandemCriteriaType
TandemCriteria(; keep)

The tandem criteria rotation method.

Keyword arguments

  • keep: The number of factors to keep for the second tandem criterion.
source
FactorRotations.TargetRotationType
TargetRotation(target::AbstractMatrix; orthogonal = false)

The (partial) target rotation criterion.

Keyword arguments

  • orthogonal: If orthogonal = true an orthogonal rotation is performed, an oblique rotation otherwise. (default: false)

Details

Target rotation rotates a factor loading matrix towards the target matrix, target. For a fully specified target matrix (e.g. all entries in the matrix are numbers), full target rotation is performed.

Partially specified target rotation can be achieved setting the unspecified entries in the target matrix to missing.

Examples

Full target rotation

julia> L = [
           0.830 -0.396
           0.818 -0.469
           0.777 -0.470
           0.798 -0.401
           0.786  0.500
           0.672  0.458
           0.594  0.444
           0.647  0.333
       ];

julia> target = [1 0; 1 0; 1 0; 1 0; 0 1; 0 1; 0 1; 0 1];

julia> rotate(L, TargetRotation(target, orthogonal = true))
FactorRotation{Float64} with loading matrix:
8×2 Matrix{Float64}:
 0.882633  0.258215
 0.922358  0.195806
 0.892467  0.167726
 0.862116  0.233154
 0.252473  0.89669
 0.195508  0.789382
 0.146707  0.726945
 0.260213  0.679549

Partially specified target rotation

julia> L = [
           0.830 -0.396
           0.818 -0.469
           0.777 -0.470
           0.798 -0.401
           0.786  0.500
           0.672  0.458
           0.594  0.444
           0.647  0.333
       ];

julia> target = [1 0; missing missing; 1 0; 1 0; 0 1; 0 1; 0 1; 0 1];

julia> rotate(L, TargetRotation(target, orthogonal = true))
FactorRotation{Float64} with loading matrix:
8×2 Matrix{Float64}:
 0.873299  0.288209
 0.915133  0.227193
 0.886218  0.198109
 0.85365   0.262462
 0.221701  0.90479
 0.168434  0.795599
 0.121793  0.731532
 0.236852  0.68804
source
FactorRotations.VarimaxType
Varimax()

The Varimax rotation criterion.

Details

The Varimax is an orthogonal rotation method that maximizes the column variances of the loading matrix. It is a special case of the Oblimin rotation criterion with parameter gamma = 1.

Examples

Setting up the criterion

julia> Varimax()
Varimax()

Testing equivalence of Varimax and Oblimin

julia> L = [
           0.830 -0.396
           0.818 -0.469
           0.777 -0.470
           0.798 -0.401
           0.786  0.500
           0.672  0.458
           0.594  0.444
           0.647  0.333
       ];

julia> L_varimax = rotate(L, Varimax());

julia> L_oblimin = rotate(L, Oblimin(gamma = 1, orthogonal = true));

julia> loadings(L_varimax) ≈ loadings(L_oblimin)
true
source

User Interface

FactorRotations.isobliqueFunction
isoblique(::RotationMethod)

Checks if the supplied rotation method is oblique.

Examples

julia> isoblique(Varimax())
false

julia> isoblique(Oblimax(orthogonal = false))
true
source
FactorRotations.isorthogonalFunction
isorthogonal(::RotationMethod)

Checks if the supplied rotation method is orthogonal.

Examples

julia> isorthogonal(Varimax())
true

julia> isorthogonal(Oblimax(orthogonal = false))
false
source
FactorRotations.kaiser_denormalizeFunction
kaiser_denormalize(Λ, weights)

Undo a Kaiser normalization of normalized loading matrix Λ given weights.

Examples

julia> L = [
           0.830 -0.396
           0.818 -0.469
           0.777 -0.470
           0.798 -0.401
           0.786  0.500
           0.672  0.458
           0.594  0.444
           0.647  0.333
       ];

julia> L_norm, weights = kaiser_normalize(L);

julia> L_denorm = kaiser_denormalize(L_norm, weights)
8×2 Matrix{Float64}:
 0.83   -0.396
 0.818  -0.469
 0.777  -0.47
 0.798  -0.401
 0.786   0.5
 0.672   0.458
 0.594   0.444
 0.647   0.333

julia> L ≈ L_denorm
true
source
FactorRotations.kaiser_denormalize!Function
kaiser_denormalize!(Λ, weights)

Undo a Kaiser normalization of normalized Λ in-place given weights.

Examples

julia> L = [
           0.830 -0.396
           0.818 -0.469
           0.777 -0.470
           0.798 -0.401
           0.786  0.500
           0.672  0.458
           0.594  0.444
           0.647  0.333
       ];

julia> L_orig = copy(L);

julia> _, weights = kaiser_normalize!(L);

julia> kaiser_denormalize!(L, weights)
8×2 Matrix{Float64}:
 0.83   -0.396
 0.818  -0.469
 0.777  -0.47
 0.798  -0.401
 0.786   0.5
 0.672   0.458
 0.594   0.444
 0.647   0.333

julia> L ≈ L_orig
true
source
FactorRotations.kaiser_normalizeFunction
kaiser_normalize(Λ)

Perform a Kaiser normalization of loading matrix Λ.

Returns a tuple of a normalized loading matrix and associated weights.

Examples

julia> L = [
           0.830 -0.396
           0.818 -0.469
           0.777 -0.470
           0.798 -0.401
           0.786  0.500
           0.672  0.458
           0.594  0.444
           0.647  0.333
       ];

julia> L_norm, weights = kaiser_normalize(L);

julia> L_norm
8×2 Matrix{Float64}:
 0.902539  -0.430609
 0.867524  -0.497395
 0.855641  -0.517569
 0.89353   -0.449004
 0.84375    0.536737
 0.826331   0.563184
 0.80097    0.598705
 0.889144   0.457627

julia> weights
8-element Vector{Float64}:
 0.9196281857359527
 0.9429130394686458
 0.9080908544853868
 0.8930873417533137
 0.9315556880831118
 0.8132330539273475
 0.7416009708731509
 0.7276661322337326
source
FactorRotations.kaiser_normalize!Function
kaiser_normalize!(Λ)

Perform an in-place Kaiser normalization of loading matrix Λ.

Returns a tuple of a normalized loading matrix and associated weights.

Examples

julia> L = [
           0.830 -0.396
           0.818 -0.469
           0.777 -0.470
           0.798 -0.401
           0.786  0.500
           0.672  0.458
           0.594  0.444
           0.647  0.333
       ];

julia> L_norm, weights = kaiser_normalize!(L);

julia> L_norm
8×2 Matrix{Float64}:
 0.902539  -0.430609
 0.867524  -0.497395
 0.855641  -0.517569
 0.89353   -0.449004
 0.84375    0.536737
 0.826331   0.563184
 0.80097    0.598705
 0.889144   0.457627

julia> weights
8-element Vector{Float64}:
 0.9196281857359527
 0.9429130394686458
 0.9080908544853868
 0.8930873417533137
 0.9315556880831118
 0.8132330539273475
 0.7416009708731509
 0.7276661322337326

julia> L_norm ≈ L
true
source
FactorRotations.reflectFunction
reflect(r::FactorRotation)

Return a new FactorRotation with a modified loading matrix such that the sum of each column is positive. The rotation matrix and factor correlation matrix are updated accordingly.

Examples

julia> L = [
           0.830 -0.396
           0.818 -0.469
           0.777 -0.470
           0.798 -0.401
           0.786  0.500
           0.672  0.458
           0.594  0.444
           0.647  0.333
       ];


julia> r = rotate(L, Varimax());

julia> reflect(r)
FactorRotation{Float64} with loading matrix:
8×2 Matrix{Float64}:
 0.886061  0.246196
 0.924934  0.183253
 0.894664  0.155581
 0.865205  0.221416
 0.264636  0.893176
 0.206218  0.786653
 0.156572  0.724884
 0.269424  0.67595
source
LinearAlgebra.reflect!Function
reflect!(r::FactorRotation)

Modify r in-place by swapping signs of the loading matrix r.L such that the sum of each column is positive. The rotation matrix r.T and factor correlation matrix r.phi are updated accordingly.

Examples

julia> L = [
           0.830 -0.396
           0.818 -0.469
           0.777 -0.470
           0.798 -0.401
           0.786  0.500
           0.672  0.458
           0.594  0.444
           0.647  0.333
       ];


julia> r = rotate(L, Varimax());

julia> r_reflected = reflect!(r)
FactorRotation{Float64} with loading matrix:
8×2 Matrix{Float64}:
 0.886061  0.246196
 0.924934  0.183253
 0.894664  0.155581
 0.865205  0.221416
 0.264636  0.893176
 0.206218  0.786653
 0.156572  0.724884
 0.269424  0.67595

julia> r == r_reflected
true
source
FactorRotations.rotateFunction
rotate(Λ, method::RotationMethod; kwargs...)

Perform a rotation of the factor loading matrix Λ using a rotation method.

Keyword arguments

  • alpha: Sets the inital value for alpha (default: 1).
  • f_atol: Sets the absolute tolerance for the comparison of minimum criterion values when with random starts (default: 1e-6).
  • g_atol: Sets the absolute tolerance for convergence of the algorithm (default: 1e-6).
  • init: A k-by-k matrix of starting values for the algorithm. If init = nothing (the default), the identity matrix will be used as starting values.
  • maxiter1: Controls the number of maximum iterations in the outer loop of the algorithm (default: 1000).
  • maxiter2: Controls the number of maximum iterations in the inner loop of the algorithm (default: 10).
  • normalize: Perform Kaiser normalization before rotation of the loading matrix (default: false).
  • randomstarts: Determines if the algorithm should be started from random starting values. If randomstarts = false (the default), the algorithm is calculated once for the initial values provided by init. If randomstarts = true, the algorithm is started 100 times from random starting matrices. If randomstarts = x::Int, the algorithm is started x times from random starting matrices.
  • reflect: Switch signs of the columns of the rotated loading matrix such that the sum of loadings is non-negative for all columns (default: true)
  • use_threads: Parallelize random starts using threads (default: false)
  • verbose: Print logging statements (default: true)
  • logperiod: How frequently to report the optimization state (default: 100).

Return type

The rotate function returns a FactorRotation object. If randomstarts were requested, then rotate returns the FactorRotation object with minimum criterion value.

Examples

julia> L = [
           0.830 -0.396
           0.818 -0.469
           0.777 -0.470
           0.798 -0.401
           0.786  0.500
           0.672  0.458
           0.594  0.444
           0.647  0.333
       ];

julia> rotate(L, Varimax())
FactorRotation{Float64} with loading matrix:
8×2 Matrix{Float64}:
 0.886061  0.246196
 0.924934  0.183253
 0.894664  0.155581
 0.865205  0.221416
 0.264636  0.893176
 0.206218  0.786653
 0.156572  0.724884
 0.269424  0.67595
source
LinearAlgebra.rotate!Function
rotate!(Λ, method::RotationMethod; kwargs...)

Perform a rotation of the factor loading matrix Λ and overwrite Λ with the rotated loading matrix.

For a list of available keyword arguments see rotate.

Examples

julia> L = [
           0.830 -0.396
           0.818 -0.469
           0.777 -0.470
           0.798 -0.401
           0.786  0.500
           0.672  0.458
           0.594  0.444
           0.647  0.333
       ];

julia> rotate!(L, Quartimax())
8×2 Matrix{Float64}:
 0.898755  0.194823
 0.933943  0.129748
 0.902132  0.103864
 0.876508  0.171284
 0.315572  0.876476
 0.251124  0.773489
 0.198008  0.714678
 0.307858  0.659334
source
FactorRotations.rotation_typeFunction
rotation_type(::RotationMethod)

Return the rotation type for a given rotation method.

Examples

julia> rotation_type(Varimax())
Orthogonal

julia> rotation_type(Oblimin(gamma = 0.5))
Oblique
source
FactorRotations.setverbosity!Function
setverbosity!(::Bool)

Sets the global verbosity level of the package. If set to false (the default), package functions will not log @info statements. If set to true, package functions will provide @info statements.

source
FactorRotations.set_autodiff_backendFunction
set_autodiff_backend(backend::Symbol)

Sets the automatic differentiation backend.

Automatic differentiation is used by the fallback criterion_and_gradient!() implementation. Currently, only :Enzyme backend is supported.

Note that to actually enable the differentiation, the corresponding autodiff package must be loaded first (e.g. using Enzyme)

source

Internals

FactorRotations.FactorRotationType
FactorRotation{T <: Real}

A type holding results of a factor rotation.

Fields

  • L: The rotated factor loading matrix
  • T: The factor rotation matrix
  • phi: The factor correlation matrix
  • weights: Normalization weights
source
FactorRotations.criterion_and_gradient!Function
criterion_and_gradient!(∇Q::Union{AbstractMatrix{<:Real}, Nothing},
                        method::RotationMethod, Λ::AbstractMatrix{<:Real})

Calculate the quality criterion Q and its gradient for a given method with respect to the factor loading matrix Λ. The gradient is output into ∇Q matrix, which should have the same dimensions as Λ. The ∇Q calculation is skipped if ∇Q ≡ nothing.

Returns the Q criterion value.

source