Exemplo n.º 1
0
    def ridge_regression(matrix_a, matrix_b, lambda_, intercept=False):
        #log.print_info(logger, "In Ridge regression..", 4)
        #log.print_matrix_info(logger, matrix_a, 5, "Input matrix A:")
        #log.print_matrix_info(logger, matrix_b, 5, "Input matrix B:")
        """
        Performs Ridge Regression.

        This method use the general formula:
            ...
        to solve the problem:
            :math:`X = argmin(||AX - B||_2 + \\lambda||X||_2)`

        Args:
            matrix_a: input matrix A, of type Matrix
            matrix_b: input matrix A, of type Matrix
            lambda_: scalar, lambda parameter
            intercept: bool. If True intercept is used. Optional, default False.

        Returns:
            solution X of type Matrix

        """

        matrix_a._assert_same_type(matrix_b)
        # TODO: check out where to define this assert
        assert_same_shape(matrix_a, matrix_b, 0)

        matrix_type = type(matrix_a)
        dim = matrix_a.shape[1]

        if intercept:
            matrix_a = matrix_a.hstack(
                matrix_type(np.ones((matrix_a.shape[0], 1))))
        lambda_diag = (lambda_) * matrix_type.identity(dim)

        if intercept:
            lambda_diag = padd_matrix(padd_matrix(lambda_diag, 0, 0.0), 1, 0.0)

        matrix_a_t = matrix_a.transpose()
        try:
            tmp_mat = Linalg.pinv(((matrix_a_t * matrix_a) + lambda_diag))
        except np.linalg.LinAlgError:
            print "Warning! LinAlgError"
            tmp_mat = matrix_type.identity(lambda_diag.shape[0])

        tmp_res = tmp_mat * matrix_a_t
        result = tmp_res * matrix_b

        #S: used in generalized cross validation, page 244 7.52 (YZ also used it)
        # S is defined in 7.31, page 232
        # instead of computing the matrix and then its trace, we can compute
        # its trace directly
        # NOTE when lambda = 0 we get out trace(S) = rank(matrix_a)

        dist = (matrix_a * result - matrix_b).norm()
        S_trace = matrix_a_t.multiply(tmp_res).sum()

        return result, S_trace, dist
Exemplo n.º 2
0
    def ridge_regression(matrix_a , matrix_b, lambda_, intercept=False):
        #log.print_info(logger, "In Ridge regression..", 4)
        #log.print_matrix_info(logger, matrix_a, 5, "Input matrix A:")
        #log.print_matrix_info(logger, matrix_b, 5, "Input matrix B:")
        """
        Performs Ridge Regression.

        This method use the general formula:
            ...
        to solve the problem:
            :math:`X = argmin(||AX - B||_2 + \\lambda||X||_2)`

        Args:
            matrix_a: input matrix A, of type Matrix
            matrix_b: input matrix A, of type Matrix
            lambda_: scalar, lambda parameter
            intercept: bool. If True intercept is used. Optional, default False.

        Returns:
            solution X of type Matrix

        """

        matrix_a._assert_same_type(matrix_b)
        # TODO: check out where to define this assert
        assert_same_shape(matrix_a, matrix_b, 0)

        matrix_type = type(matrix_a)
        dim = matrix_a.shape[1]

        if intercept:
            matrix_a = matrix_a.hstack(matrix_type(np.ones((matrix_a.shape[0],
                                                             1))))
        lambda_diag = (lambda_ ) * matrix_type.identity(dim)

        if intercept:
            lambda_diag = padd_matrix(padd_matrix(lambda_diag, 0, 0.0), 1, 0.0)

        matrix_a_t = matrix_a.transpose()
        try:
            tmp_mat = Linalg.pinv(((matrix_a_t * matrix_a) + lambda_diag))
        except np.linalg.LinAlgError:
            print "Warning! LinAlgError"
            tmp_mat = matrix_type.identity(lambda_diag.shape[0])

        tmp_res = tmp_mat * matrix_a_t
        result = tmp_res * matrix_b

        #S: used in generalized cross validation, page 244 7.52 (YZ also used it)
        # S is defined in 7.31, page 232
        # instead of computing the matrix and then its trace, we can compute
        # its trace directly
        # NOTE when lambda = 0 we get out trace(S) = rank(matrix_a)

        dist = (matrix_a * result - matrix_b).norm()
        S_trace = matrix_a_t.multiply(tmp_res).sum()

        return result, S_trace, dist
Exemplo n.º 3
0
 def _compose(self, arg1_mat, arg2_mat):
     #NOTE when we get in this compose arg1 mat and arg2 mat have the same type
     [mat_a_t, mat_b_t, arg1_mat
      ] = resolve_type_conflict([self._mat_a_t, self._mat_b_t, arg1_mat],
                                type(arg1_mat))
     if self._has_intercept:
         return arg1_mat * mat_a_t + padd_matrix(arg2_mat, 1) * mat_b_t
     else:
         return arg1_mat * mat_a_t + arg2_mat * mat_b_t
Exemplo n.º 4
0
 def _compose(self, arg1_mat, arg2_mat):
     #NOTE when we get in this compose arg1 mat and arg2 mat have the same type
     [mat_a_t, mat_b_t, arg1_mat] = resolve_type_conflict([self._mat_a_t,
                                                           self._mat_b_t,
                                                           arg1_mat],
                                                          type(arg1_mat))
     if self._has_intercept:
         return arg1_mat * mat_a_t + padd_matrix(arg2_mat, 1) * mat_b_t
     else:
         return arg1_mat * mat_a_t + arg2_mat * mat_b_t
Exemplo n.º 5
0
    def _compose(self, function_arg_vec, arg_vec, function_arg_element_shape):

        new_shape = (np.prod(function_arg_element_shape[0:-1]), 
                            function_arg_element_shape[-1])

        function_arg_vec.reshape(new_shape)

        if self._has_intercept:
            comp_el = function_arg_vec * padd_matrix(arg_vec.transpose(), 0)
        else:
            comp_el = function_arg_vec * arg_vec.transpose()
            
        return comp_el.transpose()
Exemplo n.º 6
0
    def _compose(self, function_arg_vec, arg_vec, function_arg_element_shape):

        new_shape = (np.prod(function_arg_element_shape[0:-1]),
                     function_arg_element_shape[-1])

        function_arg_vec.reshape(new_shape)

        if self._has_intercept:
            comp_el = function_arg_vec * padd_matrix(arg_vec.transpose(), 0)
        else:
            comp_el = function_arg_vec * arg_vec.transpose()

        return comp_el.transpose()
    def test_crossvalidation(self):

        a = DenseMatrix(np.matrix([[1, 1],[2, 3],[4, 6]]))
        b = DenseMatrix(np.matrix([[12, 15, 18],[21, 27, 33],[35, 46, 57]]))
        res = DenseMatrix(np.matrix([[1, 2, 3],[4, 5, 6],[7, 8, 9]]))

        learner = RidgeRegressionLearner(intercept=True, param_range=[0])
        learner2 = LstsqRegressionLearner(intercept=False)

        res1 = learner2.train(a, b)
        res2 = learner.train(a, b)

        np.testing.assert_array_almost_equal(res2.mat[:-1,:], res[0:2,:].mat, 6)
        np.testing.assert_array_almost_equal(res2.mat[-1,:], res[2:3,:].mat, 6)

        new_a = padd_matrix(a, 1)
        self.assertGreater(((a * res1) - b).norm(), ((new_a * res2) - b).norm())
Exemplo n.º 8
0
    def test_crossvalidation(self):

        a = DenseMatrix(np.matrix([[1, 1], [2, 3], [4, 6]]))
        b = DenseMatrix(np.matrix([[12, 15, 18], [21, 27, 33], [35, 46, 57]]))
        res = DenseMatrix(np.matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))

        learner = RidgeRegressionLearner(intercept=True, param_range=[0])
        learner2 = LstsqRegressionLearner(intercept=False)

        res1 = learner2.train(a, b)
        res2 = learner.train(a, b)

        np.testing.assert_array_almost_equal(res2.mat[:-1, :], res[0:2, :].mat,
                                             6)
        np.testing.assert_array_almost_equal(res2.mat[-1, :], res[2:3, :].mat,
                                             6)

        new_a = padd_matrix(a, 1)
        self.assertGreater(((a * res1) - b).norm(),
                           ((new_a * res2) - b).norm())
    def compute_matreps(self,vecspace,matspace,multiply_matrices=False):
        '''
        This method computes symbolic and numeric matrix representations od a 
        papfunc node, taking as input a vector space, a matrix space. An optional Boolean argument, if set to True, makes matrices to be multiplied rather than summed when both subconstituents have arity greater than 0.
        '''
        # for terminal nodes call insert_terminal_node_representation
        if self.is_terminal():
            matrep,temp_numrep=self.insert_terminal_node_representation(vecspace,matspace)
            self._matrep = matrep
            if temp_numrep[0] == "empty":
                numrep = []
            else:
                numrep = [temp_numrep[0].transpose()]
                dimensionality=(temp_numrep[0].shape[1])
                if len(temp_numrep)>1:
            # all matrices are stored flattened, as long vectors. We need to 
            # reshape them before we use them in computations
                    for x in range(1, (len(temp_numrep))):
                        y = DenseMatrix(temp_numrep[x])
                        y.reshape((dimensionality,(y.shape[1]/dimensionality)))
                        numrep.append(y)
            self._numrep = numrep
        #raise an exception for a non-terminal node without children
        elif len(self._children) == 0:
            raise ValueError("Non-terminal non-branching node!")
        # inherit the value of the single daughter in case of unary branching
        if len(self._children) == 1:
            self._matrep = self.get_child(0)._matrep
            self._numrep = self.get_child(0)._numrep
        #apply composition for binary branching nodes
        if len(self._children) == 2 and self._matrep == []:
            matrep1=self.get_child(0)._matrep
        #ignore 'empty' nodes
            if not matrep1:
                raise ValueError("Empty matrix representation for node %s!" %self.get_child(0))
            matrep2=self.get_child(1)._matrep
            if not matrep2:
                raise ValueError("Empty matrix representation for node %s!" %self.get_child(1))
            arity1=len(matrep1)-1
            arity2=len(matrep2)-1
            # first, compute symbolic matrix representation
            # default to componentwise addition for daughters of equal arity
            if arity1-arity2 == 0:
                for x in range(0, arity1+1):
                    self._matrep.append('(' + matrep1[x] + '+' + matrep2[x] + ')')
            # left function application
            if arity1 < arity2 and not re.search('empty$',matrep2[0]) and not re.search('empty$',matrep1[0]):
                for x in range(0, arity2):
                    if x == 0: #compute the vector
                        self._matrep.append('(' + matrep2[x] + '+' + matrep2[arity2] + '*' + matrep1[x] + ')')
                    # compute a matrix
                    # If both daughters have matrices in the xth position in
                    # their vector-matrix structures, add or multiply those 
                    # matrices according to the multiply_matrices parameter
                    elif x < len(matrep1):
                        if multiply_matrices: self._matrep.append('(' + matrep2[x] + '*' + matrep1[x] + ')')
                        else: self._matrep.append('(' + matrep2[x] + '+' + matrep1[x] + ')')
                    # inherit the function's extra lexical matrix
                    else:
                        self._matrep.append(matrep2[x])
            # right function application
            if arity1 > arity2 and not re.search('empty$',matrep2[0]) and not re.search('empty$',matrep1[0]):
                for x in range(0, arity1):
                    if x == 0:
                        self._matrep.append('(' + matrep1[x] + '+' + matrep1[arity1] + '*' + matrep2[x] + ')')
                    # compute a matrix
                    # If both daughters have matrices in the xth position in
                    # their vector-matrix structures, add or multiply those
                    # matrices according to the multiply_matrices parameter
                    elif x < len(matrep2):
                        if multiply_matrices: self._matrep.append('(' + matrep1[x] + '*' + matrep2[x] + ')')
                        else: self._matrep.append('(' + matrep1[x] + '+' + matrep2[x] + ')')
                    else:
                        self._matrep.append(matrep1[x])
# ignore 'empty' elements
            if re.search('empty$',matrep1[0]):
                self._matrep = matrep2
            if re.search('empty$',matrep2[0]):
                self._matrep = matrep1
            # computing numeric matrix representation of a node from those of its two daughters    
            numrep1=self.get_child(0)._numrep
            numrep2=self.get_child(1)._numrep
            if arity1-arity2 == 0 and numrep1 and numrep2:
                for x in range(0, arity1+1):
                    self._numrep.append(numrep1[x].__add__(numrep2[x]))
            # left function application
            if arity1 < arity2 and not numrep1==[] and not numrep2==[]:
                for x in range(0, arity2):
                    if x == 0: #compute the vector
                        self._numrep.append(numrep2[x].__add__(numrep2[arity2] * padd_matrix(numrep1[x],0)))
                    elif x < len(numrep1):
                        if multiply_matrices:
                            self._numrep.append(numrep2[x] * numrep1[x])
                        else:
                            self._numrep.append(numrep1[x].__add__(numrep2[x]))
                    else:
                        self._numrep.append(numrep2[x])
            # right function application
            if arity1 > arity2 and not numrep1==[] and not numrep2==[]:
                for x in range(0, arity1):
                    if x == 0: # compute the vector
                        self._numrep.append(numrep1[x].__add__(numrep1[arity1] * padd_matrix(numrep2[x],0)))
                    elif x < len(numrep2):
                        if multiply_matrices:
                            self._numrep.append(numrep2[x] * numrep1[x])
                        else:
                            self._numrep.append(numrep1[x].__add__(numrep2[x]))
                    else:
                        self._numrep.append(numrep1[x])
            # ignore 'empty' elements
            if (numrep1 == []):
                self._numrep = numrep2
            if (numrep2 == []):
                self._numrep = numrep1
        # end of numrep computation  
        # Raise an exception for non-binary branching - we don't want to handle those structures
        if len(self._children)>2:
            raise ValueError("Matrix representations are not defined for trees with more than binary branching")