API
Rotation criteria
FactorRotations.Absolmin
— TypeAbsolmin(epsilon)
The Absolmin component loss factor rotation criterion. It has the loss function
\[h(\lambda) = |\lambda|\]
FactorRotations.Biquartimax
— FunctionBiquartimax()
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
FactorRotations.Biquartimin
— TypeBiquartimin
The Biquartimin rotation criterion.
Keyword arguments
orthogonal
: orthogonal: If orthogonal = true an orthogonal rotation is performed, an oblique rotation otherwise. (default:false
)
FactorRotations.ComponentLoss
— TypeComponentLoss(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
: Iforthogonal = 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
FactorRotations.Concave
— TypeConcave(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.
FactorRotations.CrawfordFerguson
— TypeCrawfordFerguson(; 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:
- κ = γ/p:
Oblimin(gamma = γ, orthogonal = true)
- κ = 0:
Quartimax
- κ = 1/p:
Varimax
- κ = k/2p:
Equamax
- κ = (k - 1)/(p + k - 2):
Parsimax
- κ = 1: Factor parsimony
Examples
julia> CrawfordFerguson(kappa = 0, orthogonal = true)
CrawfordFerguson{Orthogonal, Int64}(0)
julia> CrawfordFerguson(kappa = 1/2, orthogonal = false)
CrawfordFerguson{Oblique, Float64}(0.5)
FactorRotations.Equamax
— TypeEquamax()
Equamax is an orthogonal rotation method, which is equivalent to Oblimin
rotation of p × k loadings matrix Λ with $\gamma = \frac{k}{2}$.
FactorRotations.Geomin
— TypeGeomin(epsilon = 0.01)
The Geomin rotation method.
Keyword arguments
epsilon
: A small constant to deal with zero loadings.
FactorRotations.Infomax
— TypeInfomax(; orthogonal = false)
The Infomax rotation method.
Keyword arguments
orthogonal
: Iforthogonal = true
an orthogonal rotation is performed, an oblique rotation otherwise. (default:false
)
FactorRotations.KatzRohlf
— TypeKatzRohlf(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.
FactorRotations.LinearRightConstant
— TypeLinearRightConstant(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.
FactorRotations.MinimumEntropy
— TypeMinimumEntropy()
The Minimum Entropy rotation method.
FactorRotations.MinimumEntropyRatio
— TypeMinimumEntropyRatio()
The Minimum Entropy Ratio rotation method.
FactorRotations.Oblimax
— TypeOblimax(; orthogonal = false)
The Oblimax rotation method.
Keyword arguments
orthogonal
: Iforthogonal = 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
FactorRotations.Oblimin
— TypeOblimin(; gamma, orthogonal = false)
The family of Oblimin rotation methods.
Keyword arguments
gamma
: The shape parameter determining the rotation criterion (see Details).orthogonal
: Iforthogonal = 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
:
- γ = p×κ:
CrawfordFerguson(kappa = κ, orthogonal = true)
- γ = 0:
Quartimax
- γ = 1/2:
Biquartimax
- γ = 1:
Varimax
- γ = k/2:
Equamax
- γ = p×(k - 1)/(p + k - 2):
Parsimax
For oblique rotation Oblimin is equivalent to the following rotation methods:
- γ = 0: Quartimin
- γ = 1/2:
Biquartimin
Examples
julia> Oblimin(gamma = 0.5)
Oblimin{Oblique, Float64}(0.5)
julia> Oblimin(gamma = 1, orthogonal = true)
Oblimin{Orthogonal, Int64}(1)
FactorRotations.Parsimax
— TypeParsimax()
Parsimax is an orthogonal rotation method, which is equivalent to CrawfordFerguson
rotation of p × k loadings matrix Λ with $\kappa = \frac{k - 1}{p + k - 2}$.
FactorRotations.PatternSimplicity
— TypePatternSimplicity(; orthogonal = false)
The Pattern Simplicity factor rotation criterion.
Keyword arguments
orthogonal
: Iforthogonal = true
an orthogonal rotation is performed, an oblique rotation otherwise. (default:false
)
FactorRotations.Quartimax
— TypeQuartimax()
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
FactorRotations.Simplimax
— TypeSimplimax(; m::Int)
The Simplimax rotation method.
FactorRotations.TandemCriteria
— TypeTandemCriteria(; keep)
The tandem criteria rotation method.
Keyword arguments
keep
: The number of factors to keep for the second tandem criterion.
FactorRotations.TandemCriterionI
— TypeTandemCriterionI()
The first criterion of the tandem criteria factor rotation method.
FactorRotations.TandemCriterionII
— TypeTandemCriterionI()
The second criterion of the tandem criteria factor rotation method.
FactorRotations.TargetRotation
— TypeTargetRotation(target::AbstractMatrix; orthogonal = false)
The (partial) target rotation criterion.
Keyword arguments
orthogonal
: Iforthogonal = 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
FactorRotations.Varimax
— TypeVarimax()
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
User Interface
FactorRotations.factor_correlation
— Functionfactor_correlation(r::FactorRotation)
Return the factor correlation matrix from r
.
FactorRotations.isoblique
— Functionisoblique(::RotationMethod)
Checks if the supplied rotation method is oblique.
Examples
julia> isoblique(Varimax())
false
julia> isoblique(Oblimax(orthogonal = false))
true
FactorRotations.isorthogonal
— Functionisorthogonal(::RotationMethod)
Checks if the supplied rotation method is orthogonal.
Examples
julia> isorthogonal(Varimax())
true
julia> isorthogonal(Oblimax(orthogonal = false))
false
FactorRotations.kaiser_denormalize
— Functionkaiser_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
FactorRotations.kaiser_denormalize!
— Functionkaiser_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
FactorRotations.kaiser_normalize
— Functionkaiser_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
FactorRotations.kaiser_normalize!
— Functionkaiser_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
FactorRotations.loadings
— Functionloadings(r::FactorRotation)
Return the rotated factor loading matrix from r
.
FactorRotations.reflect
— Functionreflect(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
LinearAlgebra.reflect!
— Functionreflect!(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
FactorRotations.rotate
— Functionrotate(Λ, 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. Ifinit = 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. Ifrandomstarts = false
(the default), the algorithm is calculated once for the initial values provided byinit
. Ifrandomstarts = true
, the algorithm is started 100 times from random starting matrices. Ifrandomstarts = x::Int
, the algorithm is startedx
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
LinearAlgebra.rotate!
— Functionrotate!(Λ, 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
FactorRotations.rotation
— Functionrotation(r::FactorRotation)
Return the factor rotation matrix from r
.
FactorRotations.rotation_type
— Functionrotation_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
FactorRotations.setverbosity!
— Functionsetverbosity!(::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.
FactorRotations.set_autodiff_backend
— Functionset_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
)
Internals
FactorRotations.FactorRotation
— TypeFactorRotation{T <: Real}
A type holding results of a factor rotation.
Fields
L
: The rotated factor loading matrixT
: The factor rotation matrixphi
: The factor correlation matrixweights
: Normalization weights
FactorRotations.Oblique
— TypeOblique
A type representing an oblique rotation type.
FactorRotations.Orthogonal
— TypeOrthogonal
A type representing an orthogonal rotation type.
FactorRotations.RotationMethod
— TypeRotationMethod{T<:RotationType}
An abstract type representing a factor rotation method.
Each implementation of M <: RotationMethod
must provide criterion_and_gradient!
method.
FactorRotations.criterion
— Functioncriterion(method::RotationMethod, Λ::Abstractmatrix{<:Real})
Calculate the criterion of a given method
with respect to the factor loading matrix Λ
.
The method is just a wrapper for a criterion_and_gradient!(nothing, method, Λ)
call.
FactorRotations.criterion_and_gradient!
— Functioncriterion_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.