symbolic-regression 0.1.0.2 → 0.2.0.0
raw patch · 3 files changed
+41/−27 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Symbolic.Regression: [numFolds] :: RegressionConfig -> Int
+ Symbolic.Regression: [validationConfig] :: RegressionConfig -> Maybe ValidationConfig
- Symbolic.Regression: RegressionConfig :: Int -> Int -> Int -> Bool -> Distribution -> Int -> Int -> Int -> Int -> Double -> Double -> [Expr Double -> Expr Double] -> [Expr Double -> Expr Double -> Expr Double] -> Int -> Bool -> Bool -> Int -> String -> String -> RegressionConfig
+ Symbolic.Regression: RegressionConfig :: Int -> Int -> Maybe ValidationConfig -> Bool -> Distribution -> Int -> Int -> Int -> Int -> Double -> Double -> [Expr Double -> Expr Double] -> [Expr Double -> Expr Double -> Expr Double] -> Int -> Bool -> Bool -> Int -> String -> String -> RegressionConfig
Files
- CHANGELOG.md +4/−0
- src/Symbolic/Regression.hs +36/−26
- symbolic-regression.cabal +1/−1
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for symbolic-regression +## 0.2.0.0+* Fix variable name mapping when translating back to dataframe.+* Add validation config that specifies seed and validation percentage.+ ## 0.1.0.2 * Add some unary functions
src/Symbolic/Regression.hs view
@@ -130,8 +130,8 @@ -- ^ Number of evolutionary generations to run (default: 100) , maxExpressionSize :: Int -- ^ Maximum tree depth\/complexity for generated expressions (default: 5)- , numFolds :: Int- -- ^ Number of cross-validation folds (default: 3)+ , validationConfig :: Maybe ValidationConfig+ -- ^ The configuration for cross validation. , showTrace :: Bool -- ^ Whether to print progress during evolution (default: 'True') , lossFunction :: Distribution@@ -168,6 +168,11 @@ -- ^ File path to load e-graph state from a previous run (default: @\"\"@) } +data ValidationConfig = ValidationConfig+ { validationPercent :: Double+ , validationSeed :: Int+ }+ {- | Default configuration for symbolic regression. Provides sensible defaults for most use cases:@@ -185,7 +190,7 @@ RegressionConfig { generations = 100 , maxExpressionSize = 5- , numFolds = 3+ , validationConfig = Nothing , showTrace = True , lossFunction = MSE , numOptimisationIterations = 30@@ -243,13 +248,18 @@ fit cfg targetColumn df = do g <- getStdGen let- df' =- D.exclude- [F.name targetColumn]- (D.selectBy [D.byProperty (D.hasElemType @Double)] df)- matrix = either throw id (D.toDoubleMatrix df')- features = fromLists' Seq (V.toList (V.map VU.toList matrix)) :: Array S Ix2 Double- target' = fromLists' Seq (D.columnAsList targetColumn df) :: Array S Ix1 Double+ (train, validation) = case (validationConfig cfg) of+ Nothing -> (df, df)+ Just vcfg -> D.randomSplit (mkStdGen (validationSeed vcfg)) (1 - (validationPercent vcfg)) df+ cols = D.columnNames (D.exclude [F.name targetColumn] (D.selectBy [D.byProperty (D.hasElemType @Double)] train))+ toFeatureMatrix d =+ either throw id $+ D.toDoubleMatrix $+ D.exclude+ [F.name targetColumn]+ (D.selectBy [D.byProperty (D.hasElemType @Double)] d)+ toFeatures d = fromLists' Seq (V.toList (V.map VU.toList (toFeatureMatrix d))) :: Array S Ix2 Double+ toTarget d = fromLists' Seq (D.columnAsList targetColumn d) :: Array S Ix1 Double nonterminals = intercalate ","@@ -262,7 +272,7 @@ "," ( Prelude.map T.unpack- (Prelude.filter (/= F.name targetColumn) (D.columnNames df))+ cols ) alg = evalStateT@@ -270,26 +280,26 @@ cfg nonterminals varnames- [((features, target', Nothing), (features, target', Nothing))]- [(features, target', Nothing)]+ [((toFeatures train, toTarget train, Nothing), (toFeatures validation, toTarget validation, Nothing))]+ [(toFeatures df, toTarget df, Nothing)] ) emptyGraph- fmap (Prelude.map (toExpr df')) (evalStateT alg g)+ fmap (Prelude.map (toExpr cols)) (evalStateT alg g) -toExpr :: D.DataFrame -> Fix SRTree -> Expr Double+toExpr :: [T.Text] -> Fix SRTree -> Expr Double toExpr _ (Fix (Const value)) = Lit value-toExpr df (Fix (Var ix)) = Col (D.columnNames df !! ix)-toExpr df (Fix (Uni f value)) = case f of- SI.Square -> F.pow (toExpr df value) 2- SI.Cube -> F.pow (toExpr df value) 3- SI.Log -> log (toExpr df value)- SI.Recip -> F.lit 1 / toExpr df value+toExpr cols (Fix (Var ix)) = Col (cols !! ix)+toExpr cols (Fix (Uni f value)) = case f of+ SI.Square -> F.pow (toExpr cols value) 2+ SI.Cube -> F.pow (toExpr cols value) 3+ SI.Log -> log (toExpr cols value)+ SI.Recip -> F.lit 1 / toExpr cols value treeOp -> error ("UNIMPLEMENTED OPERATION: " ++ show treeOp)-toExpr df (Fix (Bin op left right)) = case op of- SI.Add -> toExpr df left + toExpr df right- SI.Sub -> toExpr df left - toExpr df right- SI.Mul -> toExpr df left * toExpr df right- SI.Div -> toExpr df left / toExpr df right+toExpr cols (Fix (Bin op left right)) = case op of+ SI.Add -> toExpr cols left + toExpr cols right+ SI.Sub -> toExpr cols left - toExpr cols right+ SI.Mul -> toExpr cols left * toExpr cols right+ SI.Div -> toExpr cols left / toExpr cols right treeOp -> error ("UNIMPLEMENTED OPERATION: " ++ show treeOp) toExpr _ _ = error "UNIMPLEMENTED"
symbolic-regression.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: symbolic-regression-version: 0.1.0.2+version: 0.2.0.0 synopsis: Symbolic Regression in Haskell description: Automatically discover mathematical expressions that best fit your data using genetic programming with e-graph optimization. license: MIT