In the specific situation where we estimate an intercept-free regression model, our current estimate of the variance of the residuals (np.std(res, axis=0, ddof=X.shape[1])) is biased and will yield slightly lower standard errors and slightly higher t-statistics (not true for models that contain an intercept). For this reason we should change our estimate of sigma to sigma = np.sqrt(res.T.dot(res) / (X.shape[0] - X.shape[1])), which doesn't have this issue.