Commit 6a1346ba authored by hoffmann's avatar hoffmann
Browse files

small changes for grammatical and aesthetical purposes

parent 24885a58
Loading
Loading
Loading
Loading
+53 −52
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ Example:
    
        $ python3 absinth.py
        
    The function can be called with a list of modifiers.
    absinth.py can be called with a list of modifiers.
    
Modifiers:
    '-t': Runs absinth.py on the trial path given in the config.py instead of the
@@ -79,7 +79,7 @@ def read_dataset(data_path: str) -> (dict, dict):
            if id1 not in results:
                results[id1]=list()
                
            results[id1].append(" ".join(l[2:]).strip()) # here I join title and snippet, the URL is ignored
            results[id1].append(" ".join(l[2:]).strip()) # here title and snippet are joined, the URL is ignored
            
    
    # topics.txt is a list of target words
@@ -106,6 +106,8 @@ def induce(topic_name: str, result_list: list) -> (nx.Graph, list, dict):
    Counts frequencies from corpus and search result list, builds graph from
    these counts (with some filters). Root hubs (senses) are collected from
    this graph.
    The frequencies are saved in json-files (from where they are loaded, if found)
    to improve runtime in the later use of absinth.py

    Args:
        topic_name: Target string.
@@ -138,13 +140,13 @@ def induce(topic_name: str, result_list: list) -> (nx.Graph, list, dict):
    edge_dict_name = topic_name+'_edge.json'

    graph_in_existence = False
    for graph_name in os.listdir(config.graph):
    for graph_name in os.listdir(config.graph_path):
        
        if topic_name in graph_name:

            graph_in_existence = True

            with open(config.graph+node_dict_name, 'r') as node_file, open(config.graph+edge_dict_name, 'r') as edge_file:
            with open(config.graph_path+node_dict_name, 'r') as node_file, open(config.graph_path+edge_dict_name, 'r') as edge_file:
        
                node_freq_dict = json.load(node_file)
                edge_freq_dict = json.load(edge_file)
@@ -159,7 +161,7 @@ def induce(topic_name: str, result_list: list) -> (nx.Graph, list, dict):

        node_freq_dict, edge_freq_dict = frequencies(target_string, result_list)
        
        with open(config.graph+node_dict_name, 'w') as node_file, open(config.graph+edge_dict_name, 'w') as edge_file:
        with open(config.graph_path+node_dict_name, 'w') as node_file, open(config.graph_path+edge_dict_name, 'w') as edge_file:
            
            json.dump(node_freq_dict, node_file)

@@ -187,7 +189,7 @@ def induce(topic_name: str, result_list: list) -> (nx.Graph, list, dict):
    print('[a]', 'Collecting root hubs.\t('+topic_name+')')
    root_hub_list = root_hubs(graph, edge_freq_dict)
    
    #adds sense inventory to buffer with some common neighbors for context
    #adds sense inventory to buffer with some common neighbours for context
    stat_dict['hubs'] = dict()
    
    for root_hub in root_hub_list:
@@ -196,10 +198,10 @@ def induce(topic_name: str, result_list: list) -> (nx.Graph, list, dict):
                                        if root_hub < node \
                                        else edge_freq_dict[node, root_hub]
                                    
        most_frequent_neighbor_list = sorted(graph.adj[root_hub],
        most_frequent_neighbour_list = sorted(graph.adj[root_hub],
                                                key=by_frequency, reverse=True) 
        
        stat_dict['hubs'][root_hub] = most_frequent_neighbor_list[:6]
        stat_dict['hubs'][root_hub] = most_frequent_neighbour_list[:6]

    return graph, root_hub_list, stat_dict

@@ -209,7 +211,7 @@ def frequencies(target_string: str, search_result_list: list) -> (dict, dict):
    
    Iterates over the corpus (and snippets provided with the task) line by line 
    and counts every token and tuple of tokens within a line (context). These 
    tokens is filtered by stop words, pos tags and context length.
    tokens are filtered by stop words, pos tags and context length.
    
    Args:
        target_string: contexts are selected if they contain this string. For
@@ -218,8 +220,9 @@ def frequencies(target_string: str, search_result_list: list) -> (dict, dict):
        
    Returns:
        Dictionary of occurrences of every eligible token within every context
            the target occurs in, dictionary of occurrences of every eligible
            tuple of tokens within every context the target occurs in.
            the target occurs in, 
        Dictionary of occurrences of every eligible tuple of tokens within every 
            context the target occurs in.
    
    """

@@ -400,7 +403,7 @@ def build_graph(node_freq_dict: dict, edge_freq_dict: dict) -> nx.Graph:
            tokens within every context the target occurs in.
    
    Returns:
        Filtered undirected dice weighted small word cooccurrence graph for a 
        Filtered undirected weighted small word cooccurrence graph for a 
            given target entity.
    """
    
@@ -469,13 +472,13 @@ def root_hubs(graph: nx.Graph, edge_freq_dict: dict) -> list:
    """Identifies senses (root hubs) by choosing nodes with high degrees
    
    Selects root hubs according to the algorithm in Véronis (2004). Nodes with
    high degree and neighbors with low weights (high cooccurrence) are chosen
    high degree and neighbours with low weights (high cooccurrence) are chosen
    until there are no more viable candidates. A root hub candidate is every
    node that is not already a hub and is not a neighbor of one.
    node that is not already a hub and is not a neighbour of one.
    
    Args:
        graph: Weighted undirected graph.
        edge_freq_dict: Dictionary of weights for every tuple in our graph.
        edge_freq_dict: Dictionary of weights for every tuple in the graph.
        
    Returns:
        List of root hubs, i.e. strings that are selected using the algorithm
@@ -484,17 +487,17 @@ def root_hubs(graph: nx.Graph, edge_freq_dict: dict) -> list:
    
    mean_degree = np.mean(list(dict(graph.degree).values()))
    
    if config.min_neighbors == 'log' and mean_degree > 0:
        min_neighbors = int(np.log(mean_degree) * mean_degree)
    if config.min_neighbours == 'log' and mean_degree > 0:
        min_neighbours = int(np.log(mean_degree) * mean_degree)
    else:
        min_neighbors = config.min_neighbors
        min_neighbours = config.min_neighbours
    
    threshold = config.threshold
    
    # Allow operations on graph without altering original one.
    graph_copy = deepcopy(graph)
    
    # Sort according to degree (number of neighbors).
    # Sort according to degree (number of neighbours).
    candidate_list = sorted(graph_copy.nodes,
                            key=lambda node: graph_copy.degree[node],
                            reverse=True)
@@ -506,27 +509,27 @@ def root_hubs(graph: nx.Graph, edge_freq_dict: dict) -> list:
        
        candidate = candidate_list[0] #best hub candidate
        
        if graph_copy.degree[candidate] >= min_neighbors:
        if graph_copy.degree[candidate] >= min_neighbours:
        
            by_frequency = lambda node: edge_freq_dict[candidate,node] \
                                         if candidate < node \
                                         else edge_freq_dict[node,candidate]
                              
            most_frequent_neighbor_list = sorted(graph_copy.adj[candidate],
            most_frequent_neighbour_list = sorted(graph_copy.adj[candidate],
                                                 key=by_frequency,
                                                 reverse=True) [:min_neighbors] 
                                                 reverse=True) [:min_neighbours] 
            
            # If the mean weight of the most frequent neighbors cooccur
            # If the mean weight of the most frequent neighbours cooccur
            # frequently enough with candidate, the candidate is approved.
            if np.mean([graph_copy.edges[candidate,node]['weight'] 
                        for node in most_frequent_neighbor_list])  < threshold: 
                        for node in most_frequent_neighbour_list])  < threshold: 
                
                # Add candidate as root hub.
                hub_list.append(candidate)
            
                # Remove neighbors of new hub as hub candidates.
                for neighbor in deepcopy(graph_copy).adj[candidate]:
                    graph_copy.remove_node(neighbor)
                # Remove neighbours of new hub as hub candidates.
                for neighbour in deepcopy(graph_copy).adj[candidate]:
                    graph_copy.remove_node(neighbour)
                
            # Remove hub candidate.
            graph_copy.remove_node(candidate)
@@ -550,9 +553,9 @@ def root_hubs(graph: nx.Graph, edge_freq_dict: dict) -> list:


def label_graph(graph: nx.Graph, root_hub_list: list) -> nx.Graph:
    """propagations graph accoring to root hubs.
    """Propagations graph according to root hubs.
    
    Evolving network that propagations neighboring nodes iterative. See sentiment
    Evolving network that propagations neighbouring nodes iterative. See sentiment
    propagation.
    
    Args:
@@ -560,7 +563,7 @@ def label_graph(graph: nx.Graph, root_hub_list: list) -> nx.Graph:
        root_hub_list: List of senses.
        
    Returns:
        labelled graph.
        Labelled graph.
    """
    
    
@@ -592,20 +595,20 @@ def label_graph(graph: nx.Graph, root_hub_list: list) -> nx.Graph:
        
        for node in graph.nodes:
            
            neighbor_weight_list = [0] * len(root_hub_list)
            neighbour_weight_list = [0] * len(root_hub_list)
            
            for neighbor in graph_copy[node]:
            for neighbour in graph_copy[node]:
                
                if graph_copy.node[neighbor]['sense'] == None:
                if graph_copy.node[neighbour]['sense'] == None:
                    pass
                else:
                    neighbor_weight_list[graph_copy.node[neighbor]['sense']] \
                        += 1 - graph_copy[node][neighbor]['weight']
                    neighbour_weight_list[graph_copy.node[neighbour]['sense']] \
                        += 1 - graph_copy[node][neighbour]['weight']
            
            
            if any(neighbor_weight_list):
            if any(neighbour_weight_list):
                
                graph.node[node]['dist'].append(neighbor_weight_list)
                graph.node[node]['dist'].append(neighbour_weight_list)
                
                old_propagation = graph_copy.node[node]['sense']
                new_propagation = np.argmax(np.mean(graph.node[node]['dist'], axis=0))
@@ -625,8 +628,6 @@ def label_graph(graph: nx.Graph, root_hub_list: list) -> nx.Graph:
        
        graph.node[node]['dist'] = np.mean(graph.node[node]['dist'], axis=0)

    draw_propagation(graph,root_hub_list)

    return graph


@@ -719,7 +720,7 @@ def disambiguate_propagation(graph: nx.Graph, root_hub_list: list, context_list:
    return mapping_dict


def draw_propagation(graph: nx.Graph, root_hub_list: list) -> None:
"""def draw_propagation(graph: nx.Graph, root_hub_list: list) -> None:
    
    pass

@@ -758,7 +759,7 @@ def draw_propagation(graph: nx.Graph, root_hub_list: list) -> None:
    plt.savefig('../figures/'+graph.graph['target']+'.png')

    plt.clf()

"""

##############################
#     MST Disambiguation     #
@@ -768,7 +769,7 @@ def draw_propagation(graph: nx.Graph, root_hub_list: list) -> None:
def components(graph: nx.Graph, root_hub_list: list, target_string: str) -> nx.Graph:
    """Builds minimum spanning tree from graph and removes singletons.
    
    Applies components algorithm from Véronis (2004) and removes singletons.
    Applies components algorithm from Véronis (2004)
    
    Args:
        graph: Undirected weighted graph.
@@ -938,7 +939,7 @@ def local_clustering_coefficient(graph: nx.Graph, node: str) -> float:
    """Calculates local clustering coefficient from node.
    
    Local Clustering Coefficient is defined as number of edges between
    neighbors of a node, divided by the number of possible nodes.
    neighbours of a node, divided by the number of possible nodes.
    
    Args:
        graph: Undirected graph.
@@ -948,23 +949,23 @@ def local_clustering_coefficient(graph: nx.Graph, node: str) -> float:
        Local coefficient.
    """
    
    neighbor_list = graph.adj[node]
    neighbour_list = graph.adj[node]
    
    neighbor_edge_list = [(x,y) for x in neighbor_list 
                          for y in neighbor_list if x<y]
    neighbour_edge_list = [(x,y) for x in neighbour_list 
                          for y in neighbour_list if x<y]
    
    if len(neighbor_edge_list) == 0:
    if len(neighbour_edge_list) == 0:
        
        return 0
    
    else:
        
        edge_count = 0
        for x,y in neighbor_edge_list:
        for x,y in neighbour_edge_list:
            if graph.has_edge(x,y):
                edge_count += 1
        
        return edge_count/len(neighbor_edge_list)
        return edge_count/len(neighbour_edge_list)



@@ -1112,7 +1113,7 @@ def main(topic_id: int, topic_name: str, result_dict: dict) -> None:
            stat_dict['L_rand'] = None
            stat_dict['C_rand'] = 0
        
        propagation_rank = config.colour_rank
        propagation_rank = config.propagation_rank
        mst_rank = config.mst_rank
        
        #Merges Mappings according to pipeline
@@ -1209,9 +1210,9 @@ if __name__ == '__main__':
    
    # If absinth.py is run in test environment.
    if '-t' in sys.argv:
        data_path = config.test
        data_path = config.testset
    else:
        data_path = config.dataset
        data_path = config.trialset
        
    result_dict, topic_dict = read_dataset(data_path)
    
+34 −26
Original line number Diff line number Diff line
@@ -102,8 +102,9 @@ def frequencies(target_string: str, search_result_list: list) -> (dict, dict):
        
    Returns:
        Dictionary of occurrences of every eligible token within every context
            the target occurs in, dictionary of occurrences of every eligible
            tuple of tokens within every context the target occurs in.
            the target occurs in, 
        Dictionary of occurrences of every eligible tuple of tokens within every 
            context the target occurs in.
    
    """

@@ -340,8 +341,20 @@ def build_graph(node_freq_dict: dict, edge_freq_dict: dict) -> nx.Graph:


def induce(topic_name: str, result_list: list) -> (nx.Graph, list, dict):
    """
    """ Induces word senses for a given topic from corpus.

    Use n random nodes as root hubs.
    The frequencies are saved in json-files (from where they are loaded, if found)
    to improve runtime in the later use of abstinent.py

    Args:
        topic_name: Target string.
        result_list: List of search result (context) strings.
        
    Returns:
        A cooccurrence graph,
        a list of root hub strings (senses) 
        and dictionary of various statistics.
    """
    
    stat_dict = dict()
@@ -356,13 +369,13 @@ def induce(topic_name: str, result_list: list) -> (nx.Graph, list, dict):
    edge_dict_name = topic_name+'_edge.json'

    graph_in_existence = False
    for graph_name in os.listdir(config.graph):
    for graph_name in os.listdir(config.graph_path):
        
        if topic_name in graph_name:

            graph_in_existence = True

            with open(config.graph+node_dict_name, 'r') as node_file, open(config.graph+edge_dict_name, 'r') as edge_file:
            with open(config.graph_path+node_dict_name, 'r') as node_file, open(config.graph_path+edge_dict_name, 'r') as edge_file:
        
                node_freq_dict = json.load(node_file)
                edge_freq_dict = json.load(edge_file)
@@ -377,7 +390,7 @@ def induce(topic_name: str, result_list: list) -> (nx.Graph, list, dict):

        node_freq_dict, edge_freq_dict = frequencies(topic_name, result_list)
        
        with open(config.graph+node_dict_name, 'w') as node_file, open(config.graph+edge_dict_name, 'w') as edge_file:
        with open(config.graph_path+node_dict_name, 'w') as node_file, open(config.graph_path+edge_dict_name, 'w') as edge_file:
            
            json.dump(node_freq_dict, node_file)

@@ -411,7 +424,7 @@ def induce(topic_name: str, result_list: list) -> (nx.Graph, list, dict):
                           reverse=True)[:sense_count]
    root_hub_list = [hub[1] for hub in root_hub_list]
    
    #adds sense inventory to buffer with some common neighbors for context
    #adds sense inventory to buffer with some common neighbours for context
    stat_dict['hubs'] = dict()
    
    for root_hub in root_hub_list:
@@ -420,17 +433,16 @@ def induce(topic_name: str, result_list: list) -> (nx.Graph, list, dict):
                                        if root_hub < node \
                                        else edge_freq_dict[node, root_hub]
                                    
        most_frequent_neighbor_list = sorted(graph.adj[root_hub],
        most_frequent_neighbour_list = sorted(graph.adj[root_hub],
                                                key=by_frequency, reverse=True) 
        
        stat_dict['hubs'][root_hub] = most_frequent_neighbor_list[:6]
        stat_dict['hubs'][root_hub] = most_frequent_neighbour_list[:6]

    return graph, root_hub_list, stat_dict


def bag_of_senses(graph: nx.Graph, root_hub_list:list) -> dict:
    """
    Matches each node to the root hub it is closest to.
    """Matches each node to the root hub it is closest to.
    """
    
    root_hub_count = len(root_hub_list)
@@ -456,7 +468,7 @@ def bag_of_senses(graph: nx.Graph, root_hub_list:list) -> dict:

def disambiguate(bag_of_senses: dict, context_list: list) -> dict:
    """
    Lesk.
    A simple Lesk disambiguation Algorithm.
    """
    
    context_idx = 0
@@ -534,10 +546,6 @@ def print_stats(stat_dict: dict) -> None:
        stat_file.write('\t'.join([str(stat_dict[key]) for key in key_list])+'\n')
        

        
            
        

def global_clustering_coefficient(graph: nx.Graph) -> float:
    """Calculates global clustering coefficient from graph.
    
@@ -555,23 +563,23 @@ def global_clustering_coefficient(graph: nx.Graph) -> float:
    
    for node in graph.nodes:
        
        neighbor_list = graph.adj[node]
        neighbour_list = graph.adj[node]
        
        neighbor_edge_list = [(x,y) for x in neighbor_list 
                              for y in neighbor_list if x<y]
        neighbour_edge_list = [(x,y) for x in neighbour_list 
                              for y in neighbour_list if x<y]
        
        if len(neighbor_edge_list) == 0:
        if len(neighbour_edge_list) == 0:
            
            local_coefficient_list.append(0)
        
        else:
            
            edge_count = 0
            for x,y in neighbor_edge_list:
            for x,y in neighbour_edge_list:
                if graph.has_edge(x,y):
                    edge_count += 1
            
            local_coefficient_list.append(edge_count/len(neighbor_edge_list))
            local_coefficient_list.append(edge_count/len(neighbour_edge_list))
        
    return np.mean(local_coefficient_list)

@@ -695,16 +703,16 @@ def main(topic_id: int, topic_name: str, result_dict: dict) -> None:
if __name__ == '__main__':
    """Check for modifiers and call main().
    
    Only called when absinth.py is started manually. Checks for various
    Only called when abstinent.py is started manually. Checks for various
    modifiers, i.e. test environment and number of processes to run 
    simultaneously.
    """
    
    # If absinth.py is run in test environment.
    # If abstinent.py is run in test environment.
    if '-t' in sys.argv:
        data_path = config.test
        data_path = config.testset
    else:
        data_path = config.dataset
        data_path = config.trialset
        
    result_dict, topic_dict = read_dataset(data_path)
    
+9 −2
Original line number Diff line number Diff line
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""All-In-One Baseline for ABSINTH

This tool works as a All-In-One Clustering Baseline

.. _Association Based Semantic Induction Tools from Heidelberg
    https://gitlab.cl.uni-heidelberg.de/zimmermann/absinth

"""
import config
import time
import sys
@@ -10,9 +17,9 @@ final_path = 'final/{}.absinth'.format(hex(time_int)[2:])
results = open(final_path, 'w')

if '-t' in sys.argv:
    data_path = config.test
    data_path = config.testset
else:
    data_path = config.dataset
    data_path = config.trialset

with open(data_path+'results.txt', 'r') as f:
    
+9 −8
Original line number Diff line number Diff line
@@ -6,10 +6,10 @@ Configuration file
Choose paths for corpus, dataset and output.
- The output directory should be empty when starting absinth.
'''
graph = "./.graphs/"
graph_path = "./.graphs/"
corpus = "/proj/absinth/wikipedia_shuffled2/"
dataset = "../WSI-Evaluator/datasets/trial/"
test = "../WSI-Evaluator/datasets/test/"
tialset = "../WSI-Evaluator/datasets/trial/"
testset = "../WSI-Evaluator/datasets/test/"
base_out = "../baseline/output/"
output = "../output/"

@@ -20,7 +20,7 @@ which they should be merged.
The first method with a positive result is used and methods labeled with 0 are ignored.
At least one method must be given a value != 0.
'''
colour_rank = 1
propagation_rank = 1
mst_rank = 2

'''
@@ -45,9 +45,10 @@ max_context_size = 20

'''
Choose filters for building the graph.
- Use dynamic filters for nodes and edges (mean frequencies of occurences)

- Use dynamic filters for nodes and edges (mean frequencies of occurences) (ABSINTH uses this as a standard) 
or
- Only consider occurrences/cooccurrences for nodes/edges, that occur more often than these values.
- Only consider occurrences/cooccurrences for nodes/edges, that occur more often than these values. (Hyperlex uses these (nodes: 10, edges: 5)))

- Only consider edges with a weight beneath the maximum weight
'''
@@ -59,9 +60,9 @@ max_weight = 0.9

'''
Choose minimum number of neighbours and maximum median weight of the most frequent neighbours of a node for root hubs. 
- the threshold is calculated using the media of the same number of neighbors declared in min_neighbors.
- (the threshold is calculated using the median of the same number of neighbours declared in min_neighbours)
'''
min_neighbors = 6
min_neighbours = 5
threshold = 0.8

'''
+9 −2
Original line number Diff line number Diff line
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Singleton Baseline for ABSINTH

This tool works as a Singleton Clustering Baseline

.. _Association Based Semantic Induction Tools from Heidelberg
    https://gitlab.cl.uni-heidelberg.de/zimmermann/absinth

"""
import config
import time
import sys
@@ -10,9 +17,9 @@ final_path = 'final/{}.absinth'.format(hex(time_int)[2:])
results = open(final_path, 'w')

if '-t' in sys.argv:
    data_path = config.test
    data_path = config.testset
else:
    data_path = config.dataset
    data_path = config.trialset

with open(data_path+'results.txt', 'r') as f: