Beispiel #1
0
static int
do_search(struct saucy *s)
{
	int min;

	unprepare_permutation(s);

	/* Backtrack to the ancestor with zeta */
	if (s->lev > s->anc) s->lev = s->anc + 1;

	/* Perform additional backtracking */
	min = backtrack(s);

	/* Keep going while there are tree nodes to expand */
	while (s->lev) {

		/* Descend to a new leaf node */	
		if (descend(s, &s->right, s->start[s->lev], min)
				&& descend_left(s)) {

			/* Prepare permutation */
			prepare_permutation(s);

			/* If we found an automorphism, return it */
			if (s->is_automorphism(s)) {
				++s->stats->gens;
				s->stats->support += s->ndiffs;
				update_theta(s);
				return s->consumer(s->n, s->gamma,
					s->ndiffs, s->unsupp, s->arg);
			}
			else {
				unprepare_permutation(s);
			}
		}

		/* If we get here, something went wrong; backtrack */
		++s->stats->bads;
		min = backtrack_bad(s);
	}

	/* Normalize group size */
	while (s->stats->grpsize_base >= 10.0) {
		s->stats->grpsize_base /= 10;
		++s->stats->grpsize_exp;
	}
	return 0;
}
Beispiel #2
0
void SPF::learn() {
    double old_likelihood, delta_likelihood, likelihood = -1e10;
    int likelihood_decreasing_count = 0;
    time_t start_time, end_time;

    int iteration = 0;
    char iter_as_str[4];
    bool converged = false;
    bool on_final_pass = false;

    while (!converged) {
        time(&start_time);
        iteration++;
        printf("iteration %d\n", iteration);

        reset_helper_params();

        // update rate for user preferences
        b_theta.each_col() += sum(beta, 1);

        set<int> items;
        int user = -1, item, rating;
        for (int i = 0; i < settings->sample_size; i++) {
            if (on_final_pass && settings->final_pass_test) {
                user++;
                while (data->test_users.count(user)==0) {
                    user++;
                }
            } else if (settings->svi) {
                user = gsl_rng_uniform_int(rand_gen, data->user_count());
            } else {
                user = i;
            }

            bool user_converged = false;
            int user_iters = 0;
            while (!user_converged) {
                user_iters++;
                a_beta_user.zeros();
                a_delta_user.zeros();

                // look at all the user's items
                for (int j = 0; j < data->item_count(user); j++) {
                    item = data->get_item(user, j);
                    items.insert(item);
                    rating = 1;
                    //TODO: rating = data->get_train_rating(i);
                    update_shape(user, item, rating);
                }

                // update per-user parameters
                double user_change = 0;
                if (!settings->factor_only && !settings->fix_influence)
                    user_change += update_tau(user);
                if (!settings->social_only)
                    user_change += update_theta(user);
                if (!settings->social_only && !settings->factor_only && !settings->fix_influence) {
                    user_change /= 2;

                    // if the updates are less than 1% change, the local params have converged
                    if (user_change < 0.01)
                        user_converged = true;

                } else {
                    // if we're only looking at social or factor (not combined)
                    // then the user parameters will always have converged with
                    // a single pass (since there's nothing to balance against)
                    user_converged = true;
                }
            }
            if (settings->verbose)
                printf("%d\tuser %d took %d iters to converge\n", iteration, user, user_iters);
            a_beta += a_beta_user;
            a_delta += a_delta_user;
        }

        if (!settings->social_only) {
            // update rate for item attributes
            b_beta.each_col() += sum(theta, 1);

            // update per-item parameters
            set<int>::iterator it;
            for (it = items.begin(); it != items.end(); it++) {
                item = *it;
                if (iter_count[item] == 0)
                    iter_count[item] = 0;
                iter_count[item]++;
                update_beta(item);
                if (settings->item_bias)
                    update_delta(item);
            }
        } else if (settings->item_bias) {
            set<int>::iterator it;
            for (it = items.begin(); it != items.end(); it++) {
                item = *it;
                if (iter_count[item] == 0)
                    iter_count[item] = 0;
                iter_count[item]++;
                if (settings->item_bias)
                    update_delta(item);
            }
        }


        // check for convergence
        if (on_final_pass) {
            printf("Final pass complete\n");
            converged = true;

            old_likelihood = likelihood;
            likelihood = get_ave_log_likelihood();
            delta_likelihood = abs((old_likelihood - likelihood) /
                                   old_likelihood);
            log_convergence(iteration, likelihood, delta_likelihood);
        } else if (iteration >= settings->max_iter) {
            printf("Reached maximum number of iterations.\n");
            converged = true;

            old_likelihood = likelihood;
            likelihood = get_ave_log_likelihood();
            delta_likelihood = abs((old_likelihood - likelihood) /
                                   old_likelihood);
            log_convergence(iteration, likelihood, delta_likelihood);
        } else if (iteration % settings->conv_freq == 0) {
            old_likelihood = likelihood;
            likelihood = get_ave_log_likelihood();

            if (likelihood < old_likelihood)
                likelihood_decreasing_count += 1;
            else
                likelihood_decreasing_count = 0;
            delta_likelihood = abs((old_likelihood - likelihood) /
                                   old_likelihood);
            log_convergence(iteration, likelihood, delta_likelihood);
            if (settings->verbose) {
                printf("delta: %f\n", delta_likelihood);
                printf("old:   %f\n", old_likelihood);
                printf("new:   %f\n", likelihood);
            }
            if (iteration >= settings->min_iter &&
                    delta_likelihood < settings->likelihood_delta) {
                printf("Model converged.\n");
                converged = true;
            } else if (iteration >= settings->min_iter &&
                       likelihood_decreasing_count >= 2) {
                printf("Likelihood decreasing.\n");
                converged = true;
            }
        }

        // save intermediate results
        if (!converged && settings->save_freq > 0 &&
                iteration % settings->save_freq == 0) {
            printf(" saving\n");
            sprintf(iter_as_str, "%04d", iteration);
            save_parameters(iter_as_str);
        }

        // intermediate evaluation
        if (!converged && settings->eval_freq > 0 &&
                iteration % settings->eval_freq == 0) {
            sprintf(iter_as_str, "%04d", iteration);
            evaluate(iter_as_str);
        }

        time(&end_time);
        log_time(iteration, difftime(end_time, start_time));

        if (converged && !on_final_pass &&
                (settings->final_pass || settings->final_pass_test)) {
            printf("final pass on all users.\n");
            on_final_pass = true;
            converged = false;

            // we need to modify some settings for the final pass
            // things should look exactly like batch for all users
            if (settings->final_pass) {
                settings->set_stochastic_inference(false);
                settings->set_sample_size(data->user_count());
                scale = 1;
            } else {
                settings->set_sample_size(data->test_users.size());
                scale = data->user_count() / settings->sample_size;
            }
        }
    }

    save_parameters("final");
}
Beispiel #3
0
int *
saucy_search(void)
{
	int i;

	/* Do initialization steps if necessary */
	if (!init) {
		init = 1;

		/* Initialize stats */
		stats->grpsize_base = 1.0;
		stats->grpsize_exp = stats->nodes = stats->bads = stats->gens = 0;

		/* Preprocessing after initial coloring */
		refine();
	}

	/* Keep going while there are tree nodes to expand */
	while (lev) {
		if (desc) { desc = 0; descend(); }

		/* Find a target cell */
		++stats->nodes; target_cell();
		if (target != n+1) { descend_left(); continue; }

		/* We don't have a target, so we're discrete */
		if (!have_zeta) {
			have_zeta = 1;
			for (i = 0; i < n; ++i) zeta[lab[i]] = i;
			if (canon != NULL) memcpy(canon, lab, n * sizeof(int));
		}
		else {
			/* Prepare permutation and check */
			for (i = 0; i < n; ++i) gamma[i] = lab[zeta[i]];
			is_automorphism();

			/* Do some stuff if we actually got an automorphism */
			if (flag) {
				++stats->gens;
				update_theta();
			}
			/* Keep track of leaf nodes that are not automorphisms */
			else {
				++stats->bads;
			}
		}

		/* Since we're discrete, we need to backtrack */
		backtrack(stats); desc = 1;
		if (flag) return gamma;
	}

	/* Normalize group size */
	while (stats->grpsize_base >= 10.0) {
		stats->grpsize_base /= 10;
		++stats->grpsize_exp;
	}

	/* All done */
	return NULL;
}