Example #1
0
def get_baseline_scoring_fn(pred_wei, pred_bias, C, ent_vecs):
    """
    Get a scoring function for the relpron dataset
    :param pred_wei: weights of semantic functions
    :param pred_bias: biases of semantic functions
    :param ent_vecs: zero-context mean-field vectors, by pred index
    :return: scoring function
    """
    # Set up semantic functions
    semfuncs = [get_semfunc(pred_wei[i], pred_bias[i]) for i in range(len(pred_wei))]
    
    def score(term, description, **kwargs):
        """
        Calculate how much the triple implies the target
        :param term: noun index
        :param description: (SBJ-or-OBJ, (verb, agent, patient))
        :return: probability
        """
        which, triple = description
        if which == 'SBJ':
            i = 1
        elif which == 'OBJ':
            i = 2
        else:
            raise ValueError(which)
        marg = marginal_approx(ent_vecs[triple[i]], C)
        return semfuncs[term](marg)
    
    return score
Example #2
0
def get_scoring_fn(pred_wei, pred_bias, C, meanfield_vecs):
    """
    Get a scoring function for the relpron dataset
    :param pred_wei: weights of semantic functions
    :param pred_bias: biases of semantic functions
    :param C: total cardinality
    :param meanfield_vecs: mean-field vectors for relpron triples
    :return: scoring function
    """
    # Set up semantic functions
    semfuncs = [get_semfunc(pred_wei[i], pred_bias[i]) for i in range(len(pred_wei))]
    # Get marginal distributions
    marg = [[marginal_approx(prob, C) for prob in triple] for triple in meanfield_vecs]
    
    def scoring_fn(term, description, **kwargs):
        """
        Calculate how much the triple implies the term
        :param term: noun index
        :param description: (index-of-SBJ-or-OBJ, index-of-triple)
        :return: probability
        """
        which, index = description
        return semfuncs[term](marg[index][which])
    
    return scoring_fn
Example #3
0
def add_semfunc_scores(scores,
                       param_subdir='simplevec',
                       meanfield_subdir='meanfield_freq',
                       basic_length=7,
                       full_length=11,
                       C_index=8,
                       pred_list=pred_list,
                       constr=(),
                       test_fn=test_all_implies,
                       **test_fn_kwargs):
    "Add new scores"
    # Process each file
    prev_basic_name = None  # Avoid reloading vectors
    for filename in sorted(os.listdir(os.path.join(AUX_DIR,
                                                   meanfield_subdir))):
        # Process filename
        name = filename.split('.')[0]
        settings = tuple(name.split('-'))
        # Ignore auxiliary files
        if len(settings) != full_length:
            continue
        # Ignore files if we haven't loaded that version of the dataset
        if settings[0] != prefix or int(settings[1]) != thresh:
            continue
        # Ignore files we've already evaluated
        if settings in scores:
            continue
        # Ignore files that don't match the given constraints:
        if any(settings[pos] not in [str(x).replace('.', '') for x in val]
               for pos, val in constr):
            continue
        # Extract information from filename
        basic_name = '-'.join(settings[:basic_length])
        C = int(settings[C_index])
        # Load the parameter vectors
        print(filename)
        if basic_name != prev_basic_name:
            with gzip.open(
                    os.path.join(AUX_DIR, param_subdir,
                                 basic_name + '.pkl.gz'), 'rb') as f:
                param_vec = pickle.load(f)
            prev_basic_name = basic_name
        # Load the biases
        with gzip.open(
                os.path.join(AUX_DIR, meanfield_subdir, name + '-bias.pkl.gz'),
                'rb') as f:
            bias = pickle.load(f)
        # Construct the semantic functions
        semfuncs = {i: get_semfunc(param_vec[i], bias[i]) for i in pred_list}
        # Load the entity vectors
        with gzip.open(os.path.join(AUX_DIR, meanfield_subdir, filename),
                       'rb') as f:
            meanfield_vec = pickle.load(f)
        marginal_vec = {
            i: marginal_approx(meanfield_vec[i], C)
            for i in pred_list
        }
        # Test
        scores[settings] = test_fn(marginal_vec, semfuncs, **test_fn_kwargs)
Example #4
0
def get_meanfield_fn(pred_wei, pred_bias, link_wei, ent_bias, C, init_vecs):
    """
    Get a function mapping vso triples to meanfield vectors
    :param pred_wei: weights of semantic functions
    :param pred_bias: biases of semantic functions
    :param link_wei: link weight matrix
    :param ent_bias: entity bias
    :param C: total cardinality
    :param init_vecs: zero-context mean-field vectors, by pred index
    :return: scoring function
    """
    # Set up semantic functions
    semfuncs = [get_semfunc(pred_wei[i], pred_bias[i]) for i in range(len(pred_wei))]
    # Set up constant function
    D = pred_wei.shape[1]
    constant = get_semfunc(np.zeros(D), 0)
    av_ent = np.ones(D) * (C/D)
    
    def meanfield_fn(triple, **kwargs):
        """
        Calculate meanfield vectors for the triple.
        For OOV items, the semfunc is a constant function.
        :param triple: (verb, agent, patient)
        :return: probability
        """
        sf = []
        vecs = []
        for i in triple:
            if i is None:
                sf.append(constant)
                vecs.append(av_ent)
            else:
                sf.append(semfuncs[i])
                vecs.append(init_vecs[i]) 
        meanfield_vecs = mean_field_vso(sf, link_wei, ent_bias, C=C, vecs=vecs, **kwargs)
        return meanfield_vecs
    
    return meanfield_fn
Example #5
0
def load_scoring_fn(filename, option='implies', **kwargs):
    "Load a scoring function"
    # Load files
    pred_wei, pred_bias, C, meanfield_vecs = load_weights_and_vectors(
        filename, meanfield_dir='meanfield_gs2011', **kwargs)
    # Set up semantic functions
    semfuncs = [
        get_semfunc(pred_wei[i], pred_bias[i]) for i in range(len(pred_wei))
    ]
    # Get marginal distributions
    marg = [marginal_approx(prob, C) for prob, _, _ in meanfield_vecs]

    if option == 'implies':

        def scoring_fn(i, j):
            """
            Calculate how much each verbal predicate is true of the other verb's entity
            :param i: triple index
            :param j: triple index
            :return: product of probabilities
            """
            # Get verb semfuncs and verb entities
            funcs = (semfuncs[verbs[i]], semfuncs[verbs[j]])
            ents = (marg[i], marg[j])
            # Multiply probs
            return funcs[0](ents[1]) * funcs[1](ents[0])

    elif option == 'similarity':

        def scoring_fn(i, j):
            """
            Calculate how similar the entities are
            :param i: triple index
            :param j: triple index
            :return: cosine similarity
            """
            # Get verb entities
            ents = (marg[i], marg[j])
            # Get cosine similarity
            return cosine(*ents)

    else:
        raise ValueError('option not recognised')

    return scoring_fn
Example #6
0
def load_semfunc_model(name, param_subdir, meanfield_subdir, basic_length,
                       full_length, C_index):
    "Load a semfunc model"
    settings = tuple(name.split('-'))
    basic_name = '-'.join(settings[:basic_length])
    C = int(settings[C_index])
    # Load the semantic functions
    with gzip.open(os.path.join(AUX_DIR, param_subdir, basic_name + '.pkl.gz'),
                   'rb') as f:
        param_vec = pickle.load(f)
    with gzip.open(
            os.path.join(AUX_DIR, meanfield_subdir, name + '-bias.pkl.gz'),
            'rb') as f:
        bias = pickle.load(f)
    semfuncs = {i: get_semfunc(param_vec[i], bias[i]) for i in pred_list}
    # Load the entity vectors
    with gzip.open(os.path.join(AUX_DIR, meanfield_subdir, name + '.pkl.gz'),
                   'rb') as f:
        meanfield_vec = pickle.load(f)
    marginal_vec = {i: marginal_approx(meanfield_vec[i], C) for i in pred_list}
    return marginal_vec, semfuncs
Example #7
0
def get_semfuncs_from_vectors(name,
                              bias_method,
                              scale,
                              C,
                              target=None,
                              Z=None,
                              alpha=None,
                              pred_list=None,
                              vectors=None,
                              freq=None,
                              as_dict=False,
                              include_bias=False,
                              directory='simplevec'):
    """
    Get semantic functions from given weights
    :param name: name of parameter file
    :param bias_method: how to initialise biases ('target' or 'frequency')
    :param scale: factor to multiply simple vectors by
    :param C: total cardinality
    :param target: desired energy for an 'untypical' vector (only for bias method 'target')
    :param Z: weighted predicate truth of rest of vocabulary (only for bias method 'frequency')
    :param alpha: smoothing of frequency in generation (only for bias method 'frequency')
    :param pred_list: list of predicates to use
    :param as_dict: return as a dict (default as a list)
    :param include_bias: return all biases as an array
    :return: semantic functions (, bias)
    """
    prefix, thresh, dim, *_ = name.split('-')
    dim = int(dim)
    # Predicates to use
    if pred_list is None:
        preds, _ = get_test_preds(prefix, thresh)
        pred_list = sorted(preds)
    # Load vectors
    if vectors is None:
        with gzip.open(os.path.join(AUX_DIR, directory, name + '.pkl.gz'),
                       'rb') as f:
            all_vectors = pickle.load(f)
        if isinstance(all_vectors, np.ndarray):
            if pred_list is False:
                vectors = all_vectors
            else:
                vectors = all_vectors[pred_list]
                del all_vectors  # Conserve memory
        elif isinstance(all_vectors, dict):
            vectors = np.array([all_vectors[i] for i in pred_list])
        else:
            raise TypeError
    # Multiply by the scale factor
    vec = vectors * scale

    # Don't use negative weights in bias calculation
    vec_for_bias = vec.clip(0)

    # Define bias of predicates

    if bias_method == 'target':
        # Maximum activation of each predicate
        high = np.partition(vec_for_bias, -C, axis=1)[:, -C:].sum(axis=1)
        # Average activation if the top units are not used but still nouny/verby
        other = (vec_for_bias.sum(1) - high) / (dim - C) * C
        # Minimum pred bias makes an average predicate have the target energy
        bias = other + target
        # For preds with a bigger gap between max and other activation,
        # make the bias the average of the two
        gap = high - other
        mask = (gap > 2 * target)
        bias[mask] = other[mask] + gap[mask] / 2

    elif bias_method == 'frequency':
        # freq[i] ~ freq[i]^alpha / (Z + freq[i]^alpha) semfunc[i](ent)
        if freq is None:
            freq = get_verb_noun_freq(prefix, thresh, pred_list)
        ent = np.ones(dim * 2) * C / dim
        bias = np.dot(vec_for_bias, ent) + np.log(1 / freq /
                                                  (1 + Z * freq**-alpha) - 1)

    else:
        raise ValueError('bias method not recognised')

    # Define semantic functions
    if as_dict:
        semfuncs = {
            i: get_semfunc(v, b)
            for i, v, b in zip(pred_list, vec, bias)
        }
    else:
        semfuncs = [get_semfunc(v, b) for v, b in zip(vec, bias)]

    if include_bias:
        return semfuncs, bias
    else:
        return semfuncs