{"record":{"id":"5af6c94df08745f3","repo":"HKUDS/Vibe-Trading","slug":"design-shape-1-regressors-but-only-design-shap","errorCode":null,"errorMessage":"{design.shape[1]} regressors but only {design.shape[0]} assets; the fit would be exactly determined and meaningless","messagePattern":"(.+?) regressors but only (.+?) assets; the fit would be exactly determined and meaningless","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/factormodel.py","lineNumber":421,"sourceCode":"            the inputs, if the design matrix has more columns than rows, or if\n            the exposures are perfectly collinear.\n    \"\"\"\n    common = returns.dropna().index.intersection(exposures.dropna(how=\"any\").index)\n    if len(common) < MIN_CROSS_SECTION:\n        raise ValueError(\n            f\"cross-sectional regression needs at least {MIN_CROSS_SECTION} assets \"\n            f\"with both a return and full exposures, got {len(common)}\"\n        )\n\n    y = returns.loc[common].to_numpy(dtype=float)\n    factor_names = list(exposures.columns)\n    design = np.column_stack(\n        [np.ones(len(common)), exposures.loc[common].to_numpy(dtype=float)]\n    )\n    names = [MARKET_FACTOR, *factor_names]\n\n    if design.shape[1] > design.shape[0]:\n        raise ValueError(\n            f\"{design.shape[1]} regressors but only {design.shape[0]} assets; \"\n            \"the fit would be exactly determined and meaningless\"\n        )\n\n    if market_caps is None:\n        weights = np.ones(len(common))\n    else:\n        caps = pd.Series(market_caps, dtype=float).reindex(common)\n        if caps.isna().any() or (caps <= 0).any():\n            raise ValueError(\n                \"market_caps must be positive and defined for every asset in the \"\n                \"regression\"\n            )\n        weights = np.sqrt(caps.to_numpy(dtype=float))\n\n    sqrt_w = np.sqrt(weights)\n    design_w = design * sqrt_w[:, None]\n    y_w = y * sqrt_w","sourceCodeStart":403,"sourceCodeEnd":439,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/factormodel.py#L403-L439","documentation":"The Fama-MacBeth design matrix includes an intercept (the market factor) plus one column per exposure; if the number of regressors exceeds the number of assets, the OLS fit would be exactly determined (zero residual degrees of freedom) and the 'factor returns' would be meaningless interpolation, so it is rejected.","triggerScenarios":"More style factors than assets in the cross-section — e.g. 20 factor columns but only 12 stocks passing the completeness filter, common when a broad definition set meets a small pilot universe.","commonSituations":"Running the full style definition set on a narrow universe or a single sector, or after the complete-row filter in error 576 slashes the sample.","solutions":["Reduce the number of factors (subset the exposure columns) or enlarge the universe so assets >= factors + 1.","Check that exposures wasn't accidentally transposed (factors as rows)."],"exampleFix":"# before\nfr = cross_sectional_factor_returns(returns, exposures)  # 20 cols, 12 assets\n# after\nkeep = [\"value\", \"momentum\", \"size\"]\nfr = cross_sectional_factor_returns(returns, exposures[keep])","handlingStrategy":"validation","validationCode":"assert exposures.shape[1] + 1 <= returns.dropna().index.intersection(exposures.dropna(how='any').index).size","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Scale the factor set to the universe size.","Guard against accidentally transposed exposure frames."],"tags":["factormodel","regression","degrees-of-freedom"],"backgroundTag":"regressors-exceed-observations","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}