# How to orthogonalize Fama French factors?

The Fama French factors (e.g. size, value) are not orthogonal to each other, so when e.g. you want to create a diversified portfolio of factor mimmicking portfolios (factor investing), the correlation between factors can lead to unwanted concentration to some of them.

Orthogonalizing the factors would prevent this from happening. Does anyone know how to update the weights to the individual stocks that are underlying the factors, such that the factors are orthogonal to each other?

I already saw this thread: Why aren't the Fama-French 3 factors orthogonal to each other? But it doesn't really answer my question.

The Fama-French factors follow from simple sorting procedures, so they do not explicitly control correlation. But if you have access to the underlying stocks, you could replace this sorting procedure by an optimisation model that looks for a portfolio similar to the traditional Fama-French sort portfolio, but with a constraint on correlation between this portfolio and others (see e.g. this example )

An alternative idea would be take the time-series of the factor portfolios and correct their exposure. For instance, suppose you have two factors value and momentum. Here is a bit of R code to give some intuition. I use random numbers for the factors.

set.seed(56423)
value <- rnorm(50)
momentum <- rnorm(50)
cor(value, momentum)
## [1] 0.1828126


So, the factors are correlated. Regressing one on the other then will give a non-zero slope.

model <- lm(value ~ momentum)
## Coefficients:
## (Intercept)   momentum
##      -0.301      0.153


But then, building a portfolio long value minus this slope times momentum will result in a value portfolio that is not correlated to momentum any more.

round(cor(value - coef(model)["momentum"]*momentum, momentum), 8)
## 0


Whether this helps depends on your application and the degree of correlation. Some plots.

plot(value, value - coef(model)["momentum"]*momentum,
xlab = "value", ylab = "value 'minus' momentum")


plot(value - coef(model)["momentum"]*momentum, momentum,
xlab = "value 'minus' momentum", ylab = "momentum")