<s> import pyfora . pure_modules . pure_pandas as PurePandas <EOL> import Base <EOL> class RegressionTree : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , rules , numDimensions = None , columnNames = None ) : <EOL> self . rules = rules <EOL> self . numDimensions = numDimensions <EOL> self . columnNames = columnNames <EOL> def featureImportances ( self ) : <EOL> raise NotImplementedError ( ) <EOL> def rawFeatureImportances ( self ) : <EOL> raise NotImplementedError ( ) <EOL> def predict ( self , x , depth = None ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( x , PurePandas . PurePythonDataFrame ) : <EOL> return x . apply ( <EOL> lambda row : self . _predictionFunction ( row , depth ) , <EOL> <NUM_LIT:1> <EOL> ) <EOL> else : <EOL> return self . _predictionFunction ( x , depth ) <EOL> def _predictionFunction ( self , row , depth = None ) : <EOL> if depth is None : <EOL> depth = <NUM_LIT> <EOL> ix = <NUM_LIT:0> <EOL> currentDepth = <NUM_LIT:0> <EOL> while True : <EOL> rule = self . rules [ ix ] <EOL> if isinstance ( rule , Base . SplitRule ) : <EOL> if currentDepth == depth : <EOL> return rule . leafValue <EOL> if rule . rule . isLess ( row ) : <EOL> ix = ix + rule . jumpIfLess <EOL> else : <EOL> ix = ix + rule . jumpIfHigher <EOL> else : <EOL> return rule . leafValue <EOL> def score ( self , x , yTrue ) : <EOL> """<STR_LIT>""" <EOL> sz = len ( x ) <EOL> assert sz == len ( yTrue ) <EOL> if isinstance ( yTrue , PurePandas . PurePythonDataFrame ) : <EOL> yTrue = yTrue . iloc [ : , <NUM_LIT:0> ] <EOL> yPredicted = self . predict ( x ) <EOL> u = sum ( <EOL> ( yTrue [ ix ] - yPredicted [ ix ] ) ** <NUM_LIT> for ix in xrange ( sz ) <EOL> ) <EOL> mean = sum ( yTrue ) / sz <EOL> v = sum ( <EOL> ( yTrue [ ix ] - mean ) ** <NUM_LIT> for ix in xrange ( sz ) <EOL> ) <EOL> return <NUM_LIT:1.0> - u / v <EOL> class RegressionLeafRule : <EOL> def __init__ ( self , leafValue ) : <EOL> self . leafValue = leafValue <EOL> def __str__ ( self ) : <EOL> return "<STR_LIT>" + str ( self . leafValue ) + "<STR_LIT:)>" <EOL> def predict ( self , _ ) : <EOL> return self . leafValue <EOL> class RegressionTreeBuilder : <EOL> """<STR_LIT>""" <EOL> def __init__ ( <EOL> self , <EOL> maxDepth , <EOL> minSamplesSplit = <NUM_LIT:2> , <EOL> numBuckets = <NUM_LIT> , <EOL> minSplitThresh = <NUM_LIT> <EOL> ) : <EOL> self . maxDepth = maxDepth <EOL> self . impurityMeasure = Base . SampleSummary <EOL> self . minSamplesSplit = minSamplesSplit <EOL> self . minSplitThresh = minSplitThresh <EOL> self . numBuckets = numBuckets <EOL> @ staticmethod <EOL> def samplesummary ( xVec ) : <EOL> return sum ( <EOL> ( Base . SampleSummary ( xVec [ ix ] ) for ix in xrange ( len ( xVec ) ) ) , <EOL> Base . SampleSummary ( ) <EOL> ) <EOL> def bestRule ( self , df , yDim , xDimensions , activeIndices ) : <EOL> bestRuleByDimension = [ <EOL> self . bestRuleForXDimension ( df , yDim , ix , activeIndices ) for ix in xDimensions <EOL> ] <EOL> bestRuleIx = argmax ( <EOL> [ rule . impurityImprovement for rule in bestRuleByDimension ] <EOL> ) <EOL> return bestRuleByDimension [ bestRuleIx ] <EOL> @ staticmethod <EOL> def sampleSummary ( xVec ) : <EOL> return sum ( <EOL> ( Base . SampleSummary ( xVec [ ix ] ) for ix in xrange ( len ( xVec ) ) ) , <EOL> Base . SampleSummary ( ) <EOL> ) <EOL> def bestRuleForXDimension ( self , df , yDim , xDim , activeIndices ) : <EOL> xColumn = OnDemandSelectedVector ( df . iloc [ : , xDim ] , activeIndices ) <EOL> yColumn = OnDemandSelectedVector ( df . iloc [ : , yDim ] , activeIndices ) <EOL> xColumnSampleSummary = RegressionTreeBuilder . sampleSummary ( xColumn ) <EOL> bucketedSampleSummaries = self . computeBucketedSampleSummaries ( <EOL> xColumn , <EOL> yColumn , <EOL> xColumnSampleSummary . mean - xColumnSampleSummary . stdev * <NUM_LIT> , <EOL> xColumnSampleSummary . mean + xColumnSampleSummary . stdev * <NUM_LIT> , <EOL> self . numBuckets <EOL> ) <EOL> splitPoint , impurityImprovement = bucketedSampleSummaries . bestSplitPointAndImpurityImprovement ( ) <EOL> return Base . Rule ( <EOL> xDim , <EOL> splitPoint , <EOL> impurityImprovement , <EOL> len ( activeIndices ) <EOL> ) <EOL> def computeBucketedSampleSummaries ( <EOL> self , xCol , yCol , x0 , x1 , count , low = <NUM_LIT:0> , high = None ) : <EOL> if high is None : <EOL> high = len ( xCol ) <EOL> if high - low < self . minSplitThresh : <EOL> hist = Base . SampleSummaryHistogram ( x0 , x1 , count , False ) <EOL> for ix in xrange ( low , high ) : <EOL> hist . observe ( xCol [ ix ] , Base . SampleSummary ( yCol [ ix ] ) ) <EOL> return hist . freeze ( ) <EOL> mid = ( low + high ) / <NUM_LIT:2> <EOL> return self . computeBucketedSampleSummaries ( <EOL> xCol , yCol , x0 , x1 , count , low , mid ) + self . computeBucketedSampleSummaries ( <EOL> xCol , yCol , x0 , x1 , count , mid , high ) <EOL> def fit ( self , x , y ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( y , PurePandas . PurePythonDataFrame ) : <EOL> assert y . shape [ <NUM_LIT:1> ] == <NUM_LIT:1> <EOL> y = y . iloc [ : , <NUM_LIT:0> ] <EOL> return self . fit_ ( <EOL> x . pyfora_addColumn ( "<STR_LIT>" , y ) , <EOL> x . shape [ <NUM_LIT:1> ] , <EOL> self . maxDepth , <EOL> range ( x . shape [ <NUM_LIT:1> ] ) <EOL> ) <EOL> def fit_ ( self , <EOL> df , <EOL> yDim , <EOL> maxDepth = None , <EOL> xDimensions = None , <EOL> leafValueFun = None , <EOL> activeIndices = None ) : <EOL> if maxDepth is None : <EOL> maxDepth = self . maxDepth <EOL> if xDimensions is None : <EOL> xDimensions = [ ix for ix in xrange ( df . shape [ <NUM_LIT:1> ] ) if ix != yDim ] <EOL> if leafValueFun is None : <EOL> leafValueFun = RegressionTreeBuilder . defaultLeafValueFun ( yDim ) <EOL> if activeIndices is None : <EOL> activeIndices = range ( len ( df ) ) <EOL> if len ( activeIndices ) < self . minSamplesSplit or maxDepth == <NUM_LIT:0> : <EOL> leafValue = leafValueFun ( df , activeIndices ) <EOL> return RegressionTree ( <EOL> [ RegressionLeafRule ( <EOL> leafValue <EOL> ) ] , <EOL> len ( xDimensions ) <EOL> ) <EOL> bestRule = self . bestRule ( df , yDim , xDimensions , activeIndices ) <EOL> leftIndices , rightIndices = bestRule . splitDataframe ( df , activeIndices ) <EOL> if len ( leftIndices ) == <NUM_LIT:0> or len ( rightIndices ) == <NUM_LIT:0> : <EOL> return RegressionTree ( <EOL> [ RegressionLeafRule ( <EOL> leafValueFun ( df , activeIndices ) <EOL> ) ] , <EOL> len ( xDimensions ) <EOL> ) <EOL> nextDepth = maxDepth - <NUM_LIT:1> <EOL> treeLeft = self . fit_ ( <EOL> df , yDim , nextDepth , <EOL> xDimensions , <EOL> leafValueFun , <EOL> leftIndices <EOL> ) <EOL> treeRight = self . fit_ ( <EOL> df , yDim , nextDepth , <EOL> xDimensions , <EOL> leafValueFun , <EOL> rightIndices <EOL> ) <EOL> treeLeft = treeLeft . rules <EOL> treeRight = treeRight . rules <EOL> leafValue = ( len ( leftIndices ) * treeLeft [ <NUM_LIT:0> ] . leafValue + len ( rightIndices ) * treeRight [ <NUM_LIT:0> ] . leafValue ) / ( len ( leftIndices ) + len ( rightIndices ) ) <EOL> return RegressionTree ( <EOL> [ Base . SplitRule ( <EOL> bestRule , <EOL> <NUM_LIT:1> , <EOL> <NUM_LIT:1> + len ( treeLeft ) , <EOL> leafValue <EOL> ) ] + treeLeft + treeRight , <EOL> len ( xDimensions ) <EOL> ) <EOL> @ staticmethod <EOL> def defaultLeafValueFun ( yDim ) : <EOL> def tr ( values , activeIndices ) : <EOL> selectedValues = OnDemandSelectedVector ( values . iloc [ : , yDim ] , activeIndices ) <EOL> sz = len ( selectedValues ) <EOL> if sz == <NUM_LIT:0> : <EOL> return float ( "<STR_LIT>" ) <EOL> return sum ( selectedValues ) / float ( sz ) <EOL> return tr <EOL> @ staticmethod <EOL> def buildTree ( x , y , minSamplesSplit , maxDepth ) : <EOL> """<STR_LIT>""" <EOL> return RegressionTreeBuilder ( <EOL> maxDepth , <EOL> Base . SampleSummary , <EOL> minSamplesSplit , <EOL> ) . fit ( x , y ) <EOL> class OnDemandSelectedVector : <EOL> def __init__ ( self , vectorToSelectFrom , selectingIndices ) : <EOL> self . vectorToSelectFrom = vectorToSelectFrom <EOL> self . selectingIndices = selectingIndices <EOL> def __getitem__ ( self , ix ) : <EOL> return self . vectorToSelectFrom [ self . selectingIndices [ ix ] ] <EOL> def __len__ ( self ) : <EOL> return len ( self . selectingIndices ) <EOL> def __iter__ ( self ) : <EOL> for ix in xrange ( len ( self ) ) : <EOL> yield self [ ix ] <EOL> def argmax ( vec ) : <EOL> curMax = vec [ <NUM_LIT:0> ] <EOL> curMaxIx = <NUM_LIT:0> <EOL> for ix in xrange ( len ( vec ) ) : <EOL> val = vec [ ix ] <EOL> if vec [ ix ] > curMax : <EOL> curMax = val <EOL> curMaxIx = ix <EOL> return curMaxIx </s>
