Exemplo n.º 1
0
    def fit(self, bags, y):
        """
        @param bags : a sequence of n bags; each bag is an m-by-k array-like
                      object containing m instances with k features
        @param y : an array-like object of length n containing -1/+1 labels
        """
        def transform(mx):
            """
            Transform into np.matrix if array/list
            ignore scipy.sparse matrix
            """
            if issparse(mx):
                return mx.todense()
            return np.asmatrix(mx)

        self._bags = [transform(bag) for bag in bags]
        y = np.asmatrix(y).reshape((-1, 1))

        bs = BagSplitter(self._bags, y)
        best_obj = float('inf')
        best_svm = None
        for rr in range(self.restarts + 1):
            if rr == 0:
                if self.verbose:
                    print('Non-random start...')
                pos_bag_avgs = np.vstack([np.average(bag, axis=0) for bag in bs.pos_bags])
            else:
                if self.verbose:
                    print('Random restart %d of %d...' % (rr, self.restarts))
                pos_bag_avgs = np.vstack([rand_convex(len(bag)) * bag for bag in bs.pos_bags])

            intial_instances = np.vstack([bs.neg_instances, pos_bag_avgs])
            classes = np.vstack([-np.ones((bs.L_n, 1)),
                                 np.ones((bs.X_p, 1))])

            # Setup SVM and QP
            if self.scale_C:
                C = self.C / float(len(intial_instances))
            else:
                C = self.C
            setup = self._setup_svm(intial_instances, classes, C)
            K = setup[0]
            qp = IterativeQP(*setup[1:])

            # Fix Gx <= h
            neg_cons = spzeros(bs.X_n, bs.L_n)
            for b, (l, u) in enumerate(slices(bs.neg_groups)):
                neg_cons[b, l:u] = 1.0
            pos_cons = speye(bs.X_p)
            bot_left = spzeros(bs.X_p, bs.L_n)
            top_right = spzeros(bs.X_n, bs.X_p)
            half_cons = sparse([[neg_cons, bot_left],
                                [top_right, pos_cons]])
            qp.G = sparse([-speye(bs.X_p + bs.L_n), half_cons])
            qp.h = cvxmat(np.vstack([np.zeros((bs.X_p + bs.L_n, 1)),
                                     C * np.ones((bs.X_p + bs.X_n, 1))]))

            # Precompute kernel for all positive instances
            kernel = kernel_by_name(self.kernel, gamma=self.gamma, p=self.p)
            K_all = kernel(bs.instances, bs.instances)

            neg_selectors = np.array(range(bs.L_n))

            class MISVMCCCP(CCCP):

                def bailout(cself, svm, selectors, instances, K):
                    return svm

                def iterate(cself, svm, selectors, instances, K):
                    cself.mention('Training SVM...')
                    alphas, obj = qp.solve(cself.verbose)

                    # Construct SVM from solution
                    svm = SVM(kernel=self.kernel, gamma=self.gamma, p=self.p,
                              verbose=self.verbose, sv_cutoff=self.sv_cutoff)
                    svm._X = instances
                    svm._y = classes
                    svm._alphas = alphas
                    svm._objective = obj
                    svm._compute_separator(K)
                    svm._K = K

                    cself.mention('Recomputing classes...')
                    p_confs = svm.predict(bs.pos_instances)
                    pos_selectors = bs.L_n + np.array([l + np.argmax(p_confs[l:u])
                                                       for l, u in slices(bs.pos_groups)])
                    new_selectors = np.hstack([neg_selectors, pos_selectors])

                    if selectors is None:
                        sel_diff = len(new_selectors)
                    else:
                        sel_diff = np.nonzero(new_selectors - selectors)[0].size

                    cself.mention('Selector differences: %d' % sel_diff)
                    if sel_diff == 0:
                        return None, svm
                    elif sel_diff > 5:
                        # Clear results to avoid a
                        # bad starting point in
                        # the next iteration
                        qp.clear_results()

                    cself.mention('Updating QP...')
                    indices = (new_selectors,)
                    K = K_all[indices].T[indices].T
                    D = spdiag(classes)
                    qp.update_H(D * K * D)
                    return {'svm': svm, 'selectors': new_selectors,
                            'instances': bs.instances[indices], 'K': K}, None

            cccp = MISVMCCCP(verbose=self.verbose, svm=None, selectors=None,
                             instances=intial_instances, K=K, max_iters=self.max_iters)
            svm = cccp.solve()
            if svm is not None:
                obj = float(svm._objective)
                if obj < best_obj:
                    best_svm = svm
                    best_obj = obj

        if best_svm is not None:
            self._X = best_svm._X
            self._y = best_svm._y
            self._alphas = best_svm._alphas
            self._objective = best_svm._objective
            self._compute_separator(best_svm._K)
Exemplo n.º 2
0
Arquivo: misvm.py Projeto: DiNAi/misvm
    def fit(self, bags, y):
        """
        @param bags : a sequence of n bags; each bag is an m-by-k array-like
                      object containing m instances with k features
        @param y : an array-like object of length n containing -1/+1 labels
        """
        def transform(mx):
            """
            Transform into np.matrix if array/list
            ignore scipy.sparse matrix
            """
            if issparse(mx):
                return mx.todense()
            return np.asmatrix(mx)

        self._bags = [transform(bag) for bag in bags]
        y = np.asmatrix(y).reshape((-1, 1))

        bs = BagSplitter(self._bags, y)
        best_obj = float('inf')
        best_svm = None
        for rr in range(self.restarts + 1):
            if rr == 0:
                if self.verbose:
                    print 'Non-random start...'
                pos_bag_avgs = np.vstack([np.average(bag, axis=0) for bag in bs.pos_bags])
            else:
                if self.verbose:
                    print 'Random restart %d of %d...' % (rr, self.restarts)
                pos_bag_avgs = np.vstack([rand_convex(len(bag)) * bag for bag in bs.pos_bags])

            intial_instances = np.vstack([bs.neg_instances, pos_bag_avgs])
            classes = np.vstack([-np.ones((bs.L_n, 1)),
                                 np.ones((bs.X_p, 1))])

            # Setup SVM and QP
            if self.scale_C:
                C = self.C / float(len(intial_instances))
            else:
                C = self.C
            setup = self._setup_svm(intial_instances, classes, C)
            K = setup[0]
            qp = IterativeQP(*setup[1:])

            # Fix Gx <= h
            neg_cons = spzeros(bs.X_n, bs.L_n)
            for b, (l, u) in enumerate(slices(bs.neg_groups)):
                neg_cons[b, l:u] = 1.0
            pos_cons = speye(bs.X_p)
            bot_left = spzeros(bs.X_p, bs.L_n)
            top_right = spzeros(bs.X_n, bs.X_p)
            half_cons = sparse([[neg_cons, bot_left],
                                [top_right, pos_cons]])
            qp.G = sparse([-speye(bs.X_p + bs.L_n), half_cons])
            qp.h = cvxmat(np.vstack([np.zeros((bs.X_p + bs.L_n, 1)),
                                     C * np.ones((bs.X_p + bs.X_n, 1))]))

            # Precompute kernel for all positive instances
            kernel = kernel_by_name(self.kernel, gamma=self.gamma, p=self.p)
            K_all = kernel(bs.instances, bs.instances)

            neg_selectors = np.array(range(bs.L_n))

            class MISVMCCCP(CCCP):

                def bailout(cself, svm, selectors, instances, K):
                    return svm

                def iterate(cself, svm, selectors, instances, K):
                    cself.mention('Training SVM...')
                    alphas, obj = qp.solve(cself.verbose)

                    # Construct SVM from solution
                    svm = SVM(kernel=self.kernel, gamma=self.gamma, p=self.p,
                              verbose=self.verbose, sv_cutoff=self.sv_cutoff)
                    svm._X = instances
                    svm._y = classes
                    svm._alphas = alphas
                    svm._objective = obj
                    svm._compute_separator(K)
                    svm._K = K

                    cself.mention('Recomputing classes...')
                    p_confs = svm.predict(bs.pos_instances)
                    pos_selectors = bs.L_n + np.array([l + np.argmax(p_confs[l:u])
                                                       for l, u in slices(bs.pos_groups)])
                    new_selectors = np.hstack([neg_selectors, pos_selectors])

                    if selectors is None:
                        sel_diff = len(new_selectors)
                    else:
                        sel_diff = np.nonzero(new_selectors - selectors)[0].size

                    cself.mention('Selector differences: %d' % sel_diff)
                    if sel_diff == 0:
                        return None, svm
                    elif sel_diff > 5:
                        # Clear results to avoid a
                        # bad starting point in
                        # the next iteration
                        qp.clear_results()

                    cself.mention('Updating QP...')
                    indices = (new_selectors,)
                    K = K_all[indices].T[indices].T
                    D = spdiag(classes)
                    qp.update_H(D * K * D)
                    return {'svm': svm, 'selectors': new_selectors,
                            'instances': bs.instances[indices], 'K': K}, None

            cccp = MISVMCCCP(verbose=self.verbose, svm=None, selectors=None,
                             instances=intial_instances, K=K, max_iters=self.max_iters)
            svm = cccp.solve()
            if svm is not None:
                obj = float(svm._objective)
                if obj < best_obj:
                    best_svm = svm
                    best_obj = obj

        if best_svm is not None:
            self._X = best_svm._X
            self._y = best_svm._y
            self._alphas = best_svm._alphas
            self._objective = best_svm._objective
            self._compute_separator(best_svm._K)