def estimate_SI_continuous(cls, underlying: Network, theta: float, outcome: dict, initials: set, immunes: set = set(),
                    tmax=1000.0):
        time = .0
        my_outcome = outcome.copy()
        susceptible = set(underlying.nodes_ids)
        loglikelyhood = .0
        infected = set()
        infected |= initials
        susceptible -= immunes | infected

        prev_time = .0

        for newinf_id, inf_time in my_outcome.items():
            dt = inf_time - prev_time
            prev_time = inf_time
            neighbors = underlying.get_in_neighbors_for_node(newinf_id)
            n_infected = len(neighbors & infected)
            loglikelyhood += math.log(n_infected * theta)
            for sus_id in susceptible:
                sus_neighbors = underlying.get_in_neighbors_for_node(sus_id)
                sus_n_infected = len(sus_neighbors & infected)
                if sus_n_infected:
                    loglikelyhood += sus_n_infected*theta*dt
            infected.add(newinf_id)
            if newinf_id in susceptible:
                susceptible.remove(newinf_id)
        return loglikelyhood
 def make_cascades_summary(self, cascade_networks, logweight=True):
     new_nodes = {}
     new_links = {}
     self.cascades_network = Network()
     for cascade in cascade_networks:
         for node_id in cascade.network.nodes_ids:
             if new_nodes.get(node_id) is None:
                 new_nodes[node_id] = 0
             new_nodes[node_id] += 1
         for from_id, to_id in cascade.network.links.keys():
             if new_links.get((from_id, to_id)) is None:
                 new_links[(from_id, to_id)] = 0
             new_links[(from_id, to_id)] += 1
     self.cascades_network.nodes_attributes.append({'id': 'w', 'title': 'LogWeight', 'type': 'float'})
     for node_id, quantity in new_nodes.items():
         self.cascades_network.add_node(node_id)
         if logweight:
             w = math.log(quantity) + 1
         else:
             w = quantity
         self.cascades_network.add_meta_for_node(node_id, {'w': w})
     for link, quantity in new_links.items():
         if logweight:
             w = math.log(quantity) + 1
         else:
             w = quantity
         self.cascades_network.add_link(link[0], link[1], mutual=False, weighted=True, weight=w)
 def make_underlying_summary(self, underlyings):
     if len(underlyings) == 1:
         self.underlying = underlyings[0].network
     else:
         self.underlying = Network(optimisation=NetworkOptimisation.id_only)
         for underlying in underlyings:
             for node_id, neighbors in underlying.network.nodes.items():
                 self.underlying.add_node(node_id)
                 self.underlying.nodes[node_id].update(neighbors)
def make_test_network_traingle():
    ntw = Network(optimisation=NetworkOptimisation.id_only)
    for i in range(3):
        ntw.add_node(i + 1)
    ntw.add_link(1, 2)
    ntw.add_link(1, 3)
    ntw.add_link(2, 3)
    return ntw
 def estimate_SI(cls, underlying: Network, theta: float, outcome: dict, initials: set, immunes: set = set(),
                 tmax=1000.0, dt=1):
     time = .0
     my_outcome = outcome.copy()
     susceptible = set(underlying.nodes_ids)
     probability = 1.
     infected = set()
     infected |= initials
     susceptible -= immunes | infected
     while time < tmax:
         time += dt
         new_infected = set()
         for node_id in susceptible:
             neighbors = underlying.get_in_neighbors_for_node(node_id)
             n_infected = len(neighbors & infected)
             if n_infected > 0 or (node_id in my_outcome.keys() and my_outcome[node_id] < time):
                 p_not_infected = (1. - theta * dt) ** n_infected
                 if node_id in my_outcome.keys() and my_outcome[node_id] <= time:
                     probability *= 1.0 - p_not_infected
                     new_infected.add(node_id)
                 else:
                     probability *= p_not_infected
         for node_id in new_infected:
             my_outcome.pop(node_id)
         susceptible -= new_infected
         infected |= new_infected
         # print(str(probability) + ' ' + str(infected))
     return probability
Example #6
0
 def __init__(self, net=Network(), name='', base_dir=''):
     super().__init__(net, name, base_dir)
     self.post_meta = {}
     self.posters = {}
     self.hiddens = set()
     self.likers = set()
     self.timestamp = datetime.datetime.now()
Example #7
0
 def __init__(self,
              net=Network(optimisation=NetworkOptimisation.id_only),
              name='',
              base_dir=''):
     super().__init__(net, name, base_dir)
     self.nodes_meta = {}
     self.crawled_nodes = set()
     self.counters_meta = {}
    def simulate_SIR(cls, underlying: Network, theta: float, infected: set = None, immunes: set = None,
                              immune_p=.0, initial_p=.0, tmax=1000.0, dt=.1, recover_rate=.0, recover_time=.0):
        susceptible = set(underlying.nodes_ids)
        outcome_infected = {}
        outcome_recovered = {}
        time = .0
        rec_const = False
        if recover_time > 0:
            rec_const = True

        if infected is None:
            infected = set()
        if immunes is None:
            immunes = set()
        if len(infected) == 0 and initial_p > 0:
            for node_id in susceptible:
                if node_id not in immunes and random.uniform(0, 1.) < initial_p:
                    infected.add(node_id)
                    outcome_infected[node_id] = time
        if len(immunes) == 0 and immune_p > 0:
            for node_id in susceptible:
                if node_id not in infected and random.uniform(0, 1.) < immune_p:
                    immunes.add(node_id)
        susceptible -= immunes | infected
        while time < tmax:
            time += dt
            new_infected = set()
            new_recover = set()
            for node_id in susceptible:
                neighbors = underlying.get_in_neighbors_for_node(node_id)
                n_infected = len(neighbors & infected)
                if n_infected > 0:
                    if random.uniform(0, 1.) < (1. - (1. - theta*dt) ** n_infected):
                        new_infected.add(node_id)
                        outcome_infected[node_id] = time
            for node_id in infected:
                inf_time = outcome_infected[node_id]
                if rec_const:
                    if time - inf_time >= recover_time:
                        new_recover.add(node_id)
                        outcome_recovered[node_id] = (inf_time, time)
                        outcome_infected.pop(node_id)
                else:
                    if random.uniform(0, 1.) < recover_rate:
                        new_recover.add(node_id)
                        outcome_recovered[node_id] = (inf_time, time)
                        outcome_infected.pop(node_id)
            infected |= new_infected
            susceptible -= new_infected
            infected -= new_recover
        for node_id, inf_time in outcome_infected:
            outcome_recovered[node_id] = (inf_time, -1)
        return outcome_recovered
def make_test_network_chain(n=31):
    ntw = Network(optimisation=NetworkOptimisation.id_only)
    for i in range(n):
        ntw.add_node(i + 1)
    for i in range(n - 1):
        ntw.add_link(i + 1, i + 2)
    return ntw
def make_test_network_star():
    ntw = Network(optimisation=NetworkOptimisation.id_only)
    for i in range(31):
        ntw.add_node(i + 1)
    for i in range(30):
        ntw.add_link(1, i + 2)
    return ntw
    def simulate_SI_halflife(cls, underlying: Network, theta: float, halflife: float, infected: set = None,
                            immunes: set = None, immune_p=.0, initial_p=.0, tmax=1000.0, dt=1):
        susceptible = set(underlying.nodes_ids)
        outcome_infected = {}
        time = .0
        probability = 1.
        my_infected = infected.copy()

        if my_infected is None:
            my_infected = set()
        if immunes is None:
            immunes = set()
        if len(my_infected) == 0 and initial_p > 0:
            for node_id in susceptible:
                if node_id not in immunes and random.uniform(0, 1.) < initial_p:
                    my_infected.add(node_id)
                    outcome_infected[node_id] = time
        if len(immunes) == 0 and immune_p > 0:
            for node_id in susceptible:
                if node_id not in my_infected and random.uniform(0, 1.) < immune_p:
                    immunes.add(node_id)
        susceptible -= immunes | my_infected
        while time < tmax:
            time += dt
            new_infected = set()
            for node_id in susceptible:
                neighbors = underlying.get_in_neighbors_for_node(node_id)
                infected_nbrs = neighbors & my_infected
                if len(infected_nbrs) > 0:
                    p_not_infected = 1.
                    for neighbor_id in infected_nbrs:
                        time_gone = outcome_infected.get(neighbor_id)
                        if time_gone:
                            time_gone = time - time_gone
                        else:  # initialy infected
                            time_gone = time
                        theta_r = theta
                        t = time_gone - halflife
                        while t > 0:
                            theta_r /= 2
                            t -= halflife
                        p_not_infected *= 1. - theta_r * dt
                    if random.uniform(0, 1.) < (1. - p_not_infected):
                        new_infected.add(node_id)
                        outcome_infected[node_id] = time
                        probability *= 1. - p_not_infected
                    else:
                        probability *= p_not_infected
            my_infected |= new_infected
            susceptible -= new_infected
            #print(str(probability) + ' ' + str(my_infected) + ' ' + str(time))
        return {'outcome': outcome_infected, 'p': probability}
def make_test_network_connected():
    ntw = Network(optimisation=NetworkOptimisation.id_only)
    for i in range(31):
        ntw.add_node(i + 1)
    for i in range(30):
        for j in range(i + 1, 31):
            ntw.add_link(i + 1, j + 1)
    return ntw
    def simulate_SI_confirm(cls, underlying: Network, theta: float, confirm: float, infected: set = None,
                          immunes: set = None, immune_p=.0, initial_p=.0, tmax=1000.0, dt=1):
        susceptible = set(underlying.nodes_ids)
        outcome_infected = {}
        time = .0
        probability = 1.
        my_infected = infected.copy()

        if my_infected is None:
            my_infected = set()
        if immunes is None:
            immunes = set()
        if len(my_infected) == 0 and initial_p > 0:
            for node_id in susceptible:
                if node_id not in immunes and random.uniform(0, 1.) < initial_p:
                    my_infected.add(node_id)
                    outcome_infected[node_id] = time
        if len(immunes) == 0 and immune_p > 0:
            for node_id in susceptible:
                if node_id not in my_infected and random.uniform(0, 1.) < immune_p:
                    immunes.add(node_id)
        susceptible -= immunes | my_infected
        while time < tmax:
            time += dt
            new_infected = set()
            for node_id in susceptible:
                neighbors = underlying.get_in_neighbors_for_node(node_id)
                n_infected = len(neighbors & my_infected)
                if n_infected > 0:
                    if confirm >= .0:
                        if n_infected / len(neighbors) >= confirm:
                            p_not_infected = (1. - theta * dt) ** n_infected
                        else:
                            p_not_infected = (1. - theta / 10. * dt) ** n_infected
                    elif confirm < .0:
                        if n_infected / len(neighbors) < -confirm:
                            p_not_infected = (1. - theta * dt) ** n_infected
                        else:
                            p_not_infected = (1. - theta / 10. * dt) ** n_infected
                    # p_not_infected = (1. - theta * dt) ** (n_infected ** (confirm+1))
                    if random.uniform(0, 1.) < (1. - p_not_infected):
                        new_infected.add(node_id)
                        outcome_infected[node_id] = time
                        probability *= 1. - p_not_infected
                    else:
                        probability *= p_not_infected
            my_infected |= new_infected
            susceptible -= new_infected
            # print(str(probability) + ' ' + str(infected))
        return {'outcome': outcome_infected, 'p': probability}
    def simulate_ICM(cls, underlying: Network, theta: float, relic: float = .0,
                     infected: set = None, immunes: set = None,
                     immune_p=.0, initial_p=.0):
        susceptible = set(underlying.nodes_ids)
        outcome_infected = {}
        time = .0
        probability = 1.
        my_infected = infected.copy()

        if my_infected is None:
            my_infected = set()
        if immunes is None:
            immunes = set()
        if len(my_infected) == 0 and initial_p > 0:
            for node_id in susceptible:
                if node_id not in immunes and random.uniform(0, 1.) < initial_p:
                    my_infected.add(node_id)
                    outcome_infected[node_id] = time
        if len(immunes) == 0 and immune_p > 0:
            for node_id in susceptible:
                if node_id not in my_infected and random.uniform(0, 1.) < immune_p:
                    immunes.add(node_id)
        susceptible -= immunes | my_infected

        fresh_infected = my_infected.copy()

        while len(fresh_infected):
            new_infected = set()
            time = time + 1.
            for node_id in susceptible:
                neighbors = underlying.get_in_neighbors_for_node(node_id)
                n_infected = len(neighbors & fresh_infected)
                if n_infected > 0:
                    p_not_infected = (1. - theta) ** n_infected * (1. - relic) ** len(fresh_infected)
                    if random.uniform(0, 1.) < (1. - p_not_infected):
                        new_infected.add(node_id)
                        outcome_infected[node_id] = time
                        probability *= 1. - p_not_infected
                    else:
                        probability *= p_not_infected
            my_infected |= new_infected
            fresh_infected = new_infected
            susceptible -= new_infected
            # print(str(probability) + ' ' + str(infected))
        return {'outcome': outcome_infected, 'p': probability}
 def estimate_SI_halflife(cls, underlying: Network, theta: float, halflife: float, outcome: dict, initials: set,
                         immunes: set = set(), tmax=1000.0, dt=1):
     time = .0
     my_outcome = outcome.copy()
     susceptible = set(underlying.nodes_ids)
     probability = 1.
     infected = set()
     infected |= initials
     susceptible -= immunes | infected
     while time < tmax:
         time += dt
         new_infected = set()
         for node_id in susceptible:
             neighbors = underlying.get_in_neighbors_for_node(node_id)
             infected_nbrs = neighbors & infected
             if len(infected_nbrs) > 0 or (node_id in my_outcome.keys() and my_outcome[node_id] == time):
                 p_not_infected = 1.
                 for neighbor_id in infected_nbrs:
                     time_gone = my_outcome.get(neighbor_id)
                     if time_gone:
                         time_gone = time - time_gone
                     else:  # initialy infected
                         time_gone = time
                     theta_r = theta
                     t = time_gone - halflife
                     while t > 0:
                         theta_r /= 2
                         t -= halflife
                     p_not_infected *= 1. - theta_r * dt
                 if node_id in my_outcome.keys() and my_outcome[node_id] <= time:
                     probability *= 1.0 - p_not_infected
                     new_infected.add(node_id)
                 else:
                     probability *= p_not_infected
         #for node_id in new_infected:
         #    my_outcome.pop(node_id)
         susceptible -= new_infected
         infected |= new_infected
         #print(str(probability) + ' ' + str(infected) + ' ' + str(time))
     return probability
    def simulate_SI_decay_confirm_relicexp_hetero(cls, underlying: Network, theta: float,
                                                  decay: float, confirm: float, relic: float, thetas: dict = None,
                                                  infected: set = None, immunes: set = None, immune_p=.0,
                                                  initial_p=.0, tmax=1000.0, dt=1, echo=False):
        susceptible = set(underlying.nodes_ids)
        outcome_infected = {}
        time = .0
        probability = 1.
        my_infected = infected.copy()

        if my_infected is None:
            my_infected = set()
        if immunes is None:
            immunes = set()
        if len(my_infected) == 0 and initial_p > 0:
            for node_id in susceptible:
                if node_id not in immunes and random.uniform(0, 1.) < initial_p:
                    my_infected.add(node_id)
                    outcome_infected[node_id] = time
        if len(immunes) == 0 and immune_p > 0:
            for node_id in susceptible:
                if node_id not in my_infected and random.uniform(0, 1.) < immune_p:
                    immunes.add(node_id)
        susceptible -= immunes | my_infected
        while time < tmax:
            time += dt
            new_infected = set()
            for node_id in susceptible:
                neighbors = underlying.get_in_neighbors_for_node(node_id)
                infected_nbrs = neighbors & my_infected
                p_not_infected = 1.
                relic_total = .0
                for infected_id in my_infected:
                    if outcome_infected.get(infected_id):
                        relic_total += math.exp(-decay * (time - outcome_infected[infected_id]))
                    else:
                        relic_total += math.exp(-decay * time)
                relic_total *= relic
                if len(infected_nbrs) > 0:
                    for neighbor_id in infected_nbrs:
                        time_gone = outcome_infected.get(neighbor_id)
                        if time_gone:
                            time_gone = time - time_gone
                        else:  # initialy infected
                            time_gone = time
                        if thetas and thetas.get(neighbor_id):
                            p_not_infected *= (1. - thetas[neighbor_id] * dt * (math.exp(-time_gone * decay)))
                        else:
                            p_not_infected *= (1. - theta * dt * (math.exp(-time_gone * decay)))
                p_not_infected *= (1. - relic_total * dt)
                if random.uniform(0, 1.) < (1. - p_not_infected):
                    new_infected.add(node_id)
                    outcome_infected[node_id] = time
                    probability *= 1. - p_not_infected
                else:
                    probability *= p_not_infected
            my_infected |= new_infected
            susceptible -= new_infected
            if echo:
                print(str(time) + ' ' + str(probability) + ' ' + str(my_infected))
        return {'outcome': outcome_infected, 'p': probability}
Example #17
0
 def remake_network(self,
                    possible_links: dict,
                    uselikes=True,
                    usehiddens=True,
                    dynamic=True,
                    logdyn=False,
                    start_from_zero=False):
     # print('This method updates network from post_meta, hiddens, likers etc.')
     self.network = Network()
     if dynamic:
         self.network.nodes_attributes.append({
             'id': 'start',
             'title': 'start',
             'type': 'float'
         })
         self.network.nodes_attributes.append({
             'id': 'n',
             'title': 'Underlying_degree',
             'type': 'integer'
         })
         self.network.nodes_attributes.append({
             'id': 'g',
             'title': 'Is_group',
             'type': 'boolean'
         })
         self.network.links_attributes.append({
             'id': 'start',
             'title': 'start',
             'type': 'float'
         })
         self.network.links_attributes.append({
             'id': 'delay',
             'title': 'delay',
             'type': 'float'
         })
     if usehiddens:
         for node_id in self.hiddens:
             self.network.add_node(node_id)
     if uselikes:
         for node_id in self.likers:
             self.network.add_node(node_id)
     nodes = self.posters.keys()
     min_date = float("inf")
     if start_from_zero:
         for node_id in nodes:
             date = self.posters[node_id]['date']
             if date < min_date:
                 min_date = date
     for node_id in nodes:
         self.network.add_node(node_id)
         if node_id > 0:
             self.network.add_meta_for_node(node_id, {'g': "False"})
         else:
             self.network.add_meta_for_node(node_id, {'g': "True"})
         date = self.posters[node_id]['date']
         neighs_set = possible_links.get(node_id)
         if neighs_set:
             self.network.add_meta_for_node(node_id, {'n': len(neighs_set)})
         else:
             self.network.add_meta_for_node(node_id, {'n': 0})
         if start_from_zero:
             date -= min_date
         if dynamic:
             if logdyn:
                 self.network.add_meta_for_node(
                     node_id, {'start': math.log(date + 1)})
             else:
                 self.network.add_meta_for_node(node_id, {'start': date})
         for node2_id in nodes:
             if node2_id != node_id:
                 date2 = self.posters[node2_id]['date']
                 if start_from_zero:
                     date2 -= min_date
                 if date < date2:
                     if neighs_set and node2_id in neighs_set:
                         self.network.add_link(node_id,
                                               node2_id,
                                               mutual=False)
                         self.network.add_meta_for_link(
                             node_id, node2_id, {'delay': date2 - date})
                         if dynamic:
                             if logdyn:
                                 self.network.add_meta_for_link(
                                     node_id, node2_id,
                                     {'start': math.log(date2 + 1)})
                             else:
                                 self.network.add_meta_for_link(
                                     node_id, node2_id, {'start': date2})
    def estimate_SI_relic_decay_confirm_continuous(cls, underlying: Network, theta: float, relic: float, decay: float,
                                                    confirm: .0, confirm_drop: 0.1,
                                                    outcome: dict, initials: set, immunes: set = set(),
                                                    tmax=1000.0, echo=False, leafs_degrees={}):
        time = .0
        my_outcome = []
        for key, value in outcome.items():
            my_outcome.append((key, value))
        my_outcome.sort(key=lambda x: x[1])

        susceptible = set(underlying.nodes_ids)
        loglikelyhood = .0
        infected = set()
        infected |= initials
        susceptible -= immunes | infected
        leafs_dict = {}
        n_no_inf_neighbors = 0
        virulences = {}
        for inf_id in infected:
            virulences[inf_id] = [0, .0, theta] #[start time, integrated, last point]

        nn = 0
        for node_id in underlying.nodes_ids:  # make separate storage for leafs never infected (>99% of all nodes)
            neighbors = underlying.get_in_neighbors_for_node(node_id)
            if len(neighbors) == 1 and node_id not in outcome.keys():
                for n in neighbors:
                    if n in (outcome.keys() | initials):
                        if n not in leafs_dict.keys():
                            leafs_dict[n] = 0
                        leafs_dict[n] += 1
                    else:
                        n_no_inf_neighbors += 1  # leafs having no infected neighbors (>80% of all nodes)
                    nn += 1
                    if node_id in susceptible:
                        susceptible.remove(node_id)
                    break
        prev_time = .0

        for newinf_id, inf_time in my_outcome:
            if inf_time == 0.0:
                continue
            # calculating integrated infection rates
            for inf_id, value in virulences.items():
                value[1] = theta/decay*(math.exp(decay*(value[0] - prev_time)) - math.exp(decay*(value[0] - inf_time)))
                value[2] = theta*math.exp(decay*(value[0] - inf_time))
            dt = inf_time - prev_time
            prev_time = inf_time

            # calculating multipliers for no infection time
            for sus_id in susceptible:
                sus_neighbors = underlying.get_in_neighbors_for_node(sus_id)
                sus_inf_neighbors = sus_neighbors & infected
                if len(sus_inf_neighbors) > 0:
                    inf_rate = 0
                    cd = 1.
                    n_neighbors = len(sus_neighbors)
                    if sus_id in leafs_degrees.keys():
                        n_neighbors = leafs_degrees[sus_id]
                        if n_neighbors == 0:
                            n_neighbors = 100
                    else:
                        n_neighbors = len(sus_neighbors)
                    if confirm > .0:
                        if len(sus_inf_neighbors)/n_neighbors < confirm:
                            cd = confirm_drop
                    elif confirm < .0:
                        if len(sus_inf_neighbors)/n_neighbors > 1. + confirm:
                            cd = confirm_drop
                    for inf_id in sus_inf_neighbors:  # calculate total infection rate
                        inf_rate += virulences[inf_id][1]
                    loglikelyhood -= cd * inf_rate + relic * dt
                else:
                    loglikelyhood -= relic * dt
            for nonleaf_id, n_leafs in leafs_dict.items():
                if nonleaf_id in infected:
                    #assume that all leafs have enough uninfected friends to not beat the treshold
                    cd = 1.
                    if confirm != 0:
                        cd = confirm_drop
                    loglikelyhood -= n_leafs * (cd * virulences[nonleaf_id][1] + relic * dt)
                else:
                    loglikelyhood -= n_leafs * relic * dt
            loglikelyhood -= n_no_inf_neighbors * relic * dt

            # calculating multiplier for infection
            neighbors = underlying.get_in_neighbors_for_node(newinf_id)
            infected_nbrs = neighbors & infected
            inf_rate = 0
            cd = 1.
            if confirm > .0:
                if len(infected_nbrs) / len(neighbors) < confirm:
                    cd = confirm_drop
            elif confirm < .0:
                if len(infected_nbrs) / len(neighbors) > -confirm:
                    cd = confirm_drop
            for inf_id in infected_nbrs:  # calculate total infection rate
                inf_rate += virulences[inf_id][2]
            loglikelyhood += math.log(cd * inf_rate + relic)

            infected.add(newinf_id)
            virulences[newinf_id] = [inf_time, .0, theta]
            if newinf_id in susceptible:
                susceptible.remove(newinf_id)
            if echo:
                print(str(time) + ' ' + str(loglikelyhood))
        return loglikelyhood
class InformationConductivity(object):
    def __init__(self):
        self.cascades_network = Network()
        self.underlying = Network()
        pass

    def make_cascades_summary(self, cascade_networks, logweight=True):
        new_nodes = {}
        new_links = {}
        self.cascades_network = Network()
        for cascade in cascade_networks:
            for node_id in cascade.network.nodes_ids:
                if new_nodes.get(node_id) is None:
                    new_nodes[node_id] = 0
                new_nodes[node_id] += 1
            for from_id, to_id in cascade.network.links.keys():
                if new_links.get((from_id, to_id)) is None:
                    new_links[(from_id, to_id)] = 0
                new_links[(from_id, to_id)] += 1
        self.cascades_network.nodes_attributes.append({'id': 'w', 'title': 'LogWeight', 'type': 'float'})
        for node_id, quantity in new_nodes.items():
            self.cascades_network.add_node(node_id)
            if logweight:
                w = math.log(quantity) + 1
            else:
                w = quantity
            self.cascades_network.add_meta_for_node(node_id, {'w': w})
        for link, quantity in new_links.items():
            if logweight:
                w = math.log(quantity) + 1
            else:
                w = quantity
            self.cascades_network.add_link(link[0], link[1], mutual=False, weighted=True, weight=w)

    def make_underlying_summary(self, underlyings):
        if len(underlyings) == 1:
            self.underlying = underlyings[0].network
        else:
            self.underlying = Network(optimisation=NetworkOptimisation.id_only)
            for underlying in underlyings:
                for node_id, neighbors in underlying.network.nodes.items():
                    self.underlying.add_node(node_id)
                    self.underlying.nodes[node_id].update(neighbors)

    def nodes_summary(self):
        summary = {'in': [], 'out': [], 'in_w': [], 'out_w': [], 'degree': [], 'w': []}
        for node_id, node_data in self.cascades_network.nodes.items():
            degrees = self.cascades_network.node_degree(node_id)
            weights = self.cascades_network.node_weighted_degree(node_id)
            summary['in'].append(degrees['in'])
            summary['out'].append(degrees['out'])
            summary['in_w'].append(weights['in'])
            summary['out_w'].append(weights['out'])
            summary['degree'].append(self.underlying.node_degree(node_id)['inout'])
            summary['w'].append(self.cascades_network.meta_for_node(node_id, 'w'))
        return summary
    def estimate_SI_relic_halflife_continuous(cls, underlying: Network, theta: float, relic: float, halflife: float,
                                              outcome: dict, initials: set, immunes: set = set(),
                                              tmax=1000.0, echo=False):
        time = .0
        my_outcome = []
        for key, value in outcome.items():
            my_outcome.append((key, value))
        my_outcome.sort(key=lambda x: x[1])

        susceptible = set(underlying.nodes_ids)
        loglikelyhood = .0
        infected = set()
        infected |= initials
        susceptible -= immunes | infected
        leafs_dict = {}
        n_no_inf_neighbors = 0
        virulences = {}
        for inf_id in infected:
            virulences[inf_id] = [halflife, theta, 0.]

        nn = 0
        for node_id in underlying.nodes_ids:  # make separate storage for leafs never infected (>99% of all nodes)
            neighbors = underlying.get_in_neighbors_for_node(node_id)
            if len(neighbors) == 1 and node_id not in outcome.keys():
                for n in neighbors:
                    if n in (outcome.keys() | initials):
                        if n not in leafs_dict.keys():
                            leafs_dict[n] = 0
                        leafs_dict[n] += 1
                    else:
                        n_no_inf_neighbors += 1 #leafs having no infected neighbors (>80% of all nodes)
                    nn += 1
                    if node_id in susceptible:
                        susceptible.remove(node_id)
                    break
        prev_time = .0

        for newinf_id, inf_time in my_outcome:
            if inf_time == 0.0:
                continue
            dt = inf_time - prev_time
            prev_time = inf_time
            #calculating integrated infection rates
            for inf_id, value in virulences.items():
                if dt > value[0]: #dt * theta
                    value[2] = value[0] * value[1]
                else:
                    value[2] = dt * value[1]
                value[0] -= dt
                while value[0] < .0:
                    value[1] /= 2  # halflifing
                    value[0] += halflife
                    if value[0] < .0:
                        value[2] += value[1] * halflife
                    else:
                        value[2] += value[1] * (halflife - value[0])

            #calculating multipliers for no infection time
            for sus_id in susceptible:
                sus_neighbors = underlying.get_in_neighbors_for_node(sus_id)
                sus_inf_neighbors = sus_neighbors & infected
                if len(sus_inf_neighbors) > 0:
                    inf_rate = 0
                    for inf_id in sus_inf_neighbors:  # calculate total infection rate
                        inf_rate += virulences[inf_id][2]
                    loglikelyhood -= inf_rate + relic * dt
                else:
                    loglikelyhood -= relic * dt
            for nonleaf_id, n_leafs in leafs_dict.items():
                if nonleaf_id in infected:
                    loglikelyhood -= n_leafs * (virulences[nonleaf_id][2] + relic * dt)
                else:
                    loglikelyhood -= n_leafs * relic * dt
            loglikelyhood -= n_no_inf_neighbors * relic * dt

            #calculating multiplier for infection
            neighbors = underlying.get_in_neighbors_for_node(newinf_id)
            inf_rate = 0
            for inf_id in neighbors & infected: #calculate total infection rate
                inf_rate += virulences[inf_id][1]
            loglikelyhood += math.log(inf_rate + relic)

            infected.add(newinf_id)
            virulences[newinf_id] = [halflife, theta, 0.]
            if newinf_id in susceptible:
                susceptible.remove(newinf_id)
            if echo:
                print(str(time) + ' ' + str(loglikelyhood))
        return loglikelyhood
    def estimate_SI_relic_continuous(cls, underlying: Network, theta: float, relic: float, outcome: dict,
                                     initials: set, immunes: set = set(), tmax=1000.0, echo = False):
        time = .0
        my_outcome = []
        for key, value in outcome.items():
            my_outcome.append((key, value))
        my_outcome.sort(key=lambda x: x[1])

        susceptible = set(underlying.nodes_ids)
        loglikelyhood = .0
        infected = set()
        infected |= initials
        susceptible -= immunes | infected
        leafs_dict = {}
        n_no_inf_neighbors = 0

        nn = 0
        for node_id in underlying.nodes_ids: #make separate storage for leafs never infected (>99% of al nodes)
            neighbors = underlying.get_in_neighbors_for_node(node_id)
            if len(neighbors) == 1 and node_id not in outcome.keys():
                for n in neighbors:
                    if n in (outcome.keys() | initials):
                        if n not in leafs_dict.keys():
                            leafs_dict[n] = 0
                        leafs_dict[n] += 1
                    else:
                        n_no_inf_neighbors += 1  #leafs having no infected neighbors (>80% of all nodes)
                    nn += 1
                    if node_id in susceptible:
                        susceptible.remove(node_id)
                    break
        prev_time = .0

        for newinf_id, inf_time in my_outcome:
           # print('PyNInfTot: ' + str(len(infected)))
            if inf_time == 0.0:
                continue
            dt = inf_time - prev_time
            prev_time = inf_time
            neighbors = underlying.get_in_neighbors_for_node(newinf_id)
            n_infected = len(neighbors & infected)
            loglikelyhood += math.log(n_infected * theta + len(infected) * relic)
            for sus_id in susceptible:
                sus_neighbors = underlying.get_in_neighbors_for_node(sus_id)
                sus_n_infected = len(sus_neighbors & infected)
                if sus_n_infected > 0:
                    loglikelyhood -= (sus_n_infected * theta + len(infected) * relic) * dt
                else:
                    loglikelyhood -= len(infected) * relic * dt
            for nonleaf_id, n_leafs in leafs_dict.items():
                if nonleaf_id in infected:
                    loglikelyhood -= n_leafs * (theta + len(infected) * relic) * dt
                else:
                    loglikelyhood -= n_leafs * len(infected) * relic * dt
            loglikelyhood -= n_no_inf_neighbors * len(infected) * relic * dt

            infected.add(newinf_id)
            if newinf_id in susceptible:
                susceptible.remove(newinf_id)
            if echo:
                print(str(prev_time) + ' ' + str(loglikelyhood))
        return loglikelyhood
Example #22
0
class ICNetworkManager(NetworkManager):
    def __init__(self, net=Network(), name='', base_dir=''):
        super().__init__(net, name, base_dir)
        self.post_meta = {}
        self.posters = {}
        self.hiddens = set()
        self.likers = set()
        self.timestamp = datetime.datetime.now()

    def get_data_dict(self):
        data_dict = super().get_data_dict()
        data_dict['post_meta'] = self.post_meta
        data_dict['posters'] = self.posters
        data_dict['hiddens'] = self.hiddens
        data_dict['likers'] = self.likers
        data_dict['timestamp'] = self.timestamp
        return data_dict

    def set_data_dict(self, data_dict):
        super().set_data_dict(data_dict)
        self.post_meta = data_dict['post_meta']
        self.posters = data_dict['posters']
        self.hiddens = data_dict['hiddens']
        self.likers = data_dict['likers']
        self.timestamp = data_dict['timestamp']

    def crawl_next(self):
        if len(self.crawl_plan) == 0:
            # print('Crawl plan is length of zero')
            return 0

        crawler = self.crawl_plan[0]
        result = self.crawl_post(crawler)

        if result == 'empty':
            self.crawl_plan.pop(0)
        if result != 'error':
            return 1
        else:
            return -1

    def crawl_post(self, crawler):
        if crawler['stage'] == 0:
            source_id = crawler['source_id']
            post_id = crawler['post_id']
            meta = crlr.get_root_post_for_wall_with_meta(source_id, post_id)
            if vk.is_error(meta):
                if vk.error_code(
                        meta) != 666:  #666 is the code if no root post found
                    print('Error: ' + str(meta['error']['error_code']) + ' ' +
                          meta['error']['error_msg'])
                    return 'error'
                return 'empty'
            self.post_meta = meta
            self.posters[source_id] = self.post_meta['postinfo']
            if self.posters[source_id].get('likes') is not None:
                crawler['likes_to_process'] |= self.posters[source_id]['likes']
                crawler['stage'] = 1
                return 'done'
            return 'empty'
        elif crawler['stage'] == 1:
            source_id = crawler['source_id']
            post_id = crawler['post_id']
            likes_to_process = crawler['likes_to_process']
            likes_processed = crawler['likes_processed']
            if len(likes_to_process) == 0:
                return 'empty'
            user_id = likes_to_process.pop()
            content_md5 = self.post_meta['md5']
            search_string = self.post_meta['search_string']
            source_date = self.post_meta['postinfo']['date']
            new_post_info = crlr.find_post_on_wall(
                user_id,
                content_md5,
                search_string,
                source_id,
                source_date,
                use_cache=True,
                cache_date_utc=(self.timestamp.timestamp() - 25200),
                original_id=post_id)
            if vk.is_error(new_post_info):
                likes_to_process.add(user_id)
                print('Error: ' + str(new_post_info['error']['error_code']) +
                      ' ' + new_post_info['error']['error_msg'])
                return 'error'
            if new_post_info['type'] == 'poster':
                print(new_post_info)
                if vk.is_error(new_post_info['likes']):
                    if vk.error_code(new_post_info['likes']) == 15:
                        new_post_info['likes'] = set()
                self.posters[user_id] = new_post_info
                likes_processed.add(user_id)
                if len(new_post_info['likes']):
                    likes_to_process |= new_post_info['likes'] - likes_processed
                if len(new_post_info['copy_history']):
                    for copy_case in new_post_info['copy_history']:
                        if copy_case['owner_id'] not in likes_processed:
                            likes_to_process.add(copy_case['owner_id'])
                        if copy_case['from_id'] not in likes_processed:
                            likes_to_process.add(copy_case['from_id'])
            elif new_post_info['type'] == 'hidden':
                self.hiddens.add(user_id)
            elif new_post_info['type'] == 'liker':
                self.likers.add(user_id)

    def schedule_crawl_post_from_source(self, source_id, post_id):
        self.post_meta = {}
        self.posters = {}
        self.hiddens = set()
        self.likers = set()

        crawler = {
            'type': 'post',
            'stage': 0,
            'source_id': source_id,
            'post_id': post_id,
            'likes_to_process': set(),
            'likes_processed': set()
        }

        self.crawl_plan.append(crawler)

    def remake_network(self,
                       possible_links: dict,
                       uselikes=True,
                       usehiddens=True,
                       dynamic=True,
                       logdyn=False,
                       start_from_zero=False):
        # print('This method updates network from post_meta, hiddens, likers etc.')
        self.network = Network()
        if dynamic:
            self.network.nodes_attributes.append({
                'id': 'start',
                'title': 'start',
                'type': 'float'
            })
            self.network.nodes_attributes.append({
                'id': 'n',
                'title': 'Underlying_degree',
                'type': 'integer'
            })
            self.network.nodes_attributes.append({
                'id': 'g',
                'title': 'Is_group',
                'type': 'boolean'
            })
            self.network.links_attributes.append({
                'id': 'start',
                'title': 'start',
                'type': 'float'
            })
            self.network.links_attributes.append({
                'id': 'delay',
                'title': 'delay',
                'type': 'float'
            })
        if usehiddens:
            for node_id in self.hiddens:
                self.network.add_node(node_id)
        if uselikes:
            for node_id in self.likers:
                self.network.add_node(node_id)
        nodes = self.posters.keys()
        min_date = float("inf")
        if start_from_zero:
            for node_id in nodes:
                date = self.posters[node_id]['date']
                if date < min_date:
                    min_date = date
        for node_id in nodes:
            self.network.add_node(node_id)
            if node_id > 0:
                self.network.add_meta_for_node(node_id, {'g': "False"})
            else:
                self.network.add_meta_for_node(node_id, {'g': "True"})
            date = self.posters[node_id]['date']
            neighs_set = possible_links.get(node_id)
            if neighs_set:
                self.network.add_meta_for_node(node_id, {'n': len(neighs_set)})
            else:
                self.network.add_meta_for_node(node_id, {'n': 0})
            if start_from_zero:
                date -= min_date
            if dynamic:
                if logdyn:
                    self.network.add_meta_for_node(
                        node_id, {'start': math.log(date + 1)})
                else:
                    self.network.add_meta_for_node(node_id, {'start': date})
            for node2_id in nodes:
                if node2_id != node_id:
                    date2 = self.posters[node2_id]['date']
                    if start_from_zero:
                        date2 -= min_date
                    if date < date2:
                        if neighs_set and node2_id in neighs_set:
                            self.network.add_link(node_id,
                                                  node2_id,
                                                  mutual=False)
                            self.network.add_meta_for_link(
                                node_id, node2_id, {'delay': date2 - date})
                            if dynamic:
                                if logdyn:
                                    self.network.add_meta_for_link(
                                        node_id, node2_id,
                                        {'start': math.log(date2 + 1)})
                                else:
                                    self.network.add_meta_for_link(
                                        node_id, node2_id, {'start': date2})
                        # print('Link: ' + str(node_id) + ' -> ' + str(node2_id))
            # print(str(node_id) + ' : ' + str(self.posters[node_id]))

    def get_minimum_delay(self):
        min_delay = float('inf')
        for link_key in self.network.links.keys():
            delay = self.network.meta_for_link(link_key[0], link_key[1],
                                               'delay')
            if delay < min_delay:
                min_delay = delay
        return min_delay

    def get_outcome(self, normalization_factor=1.0):
        min_date = float("inf")
        outcome = {}
        for node_id, node_data in self.posters.items():
            date = node_data['date']
            if date < min_date:
                min_date = date
        for node_id, node_data in self.posters.items():
            outcome[node_id] = (node_data['date'] -
                                min_date) / normalization_factor
        return outcome

    def get_outcome_connected_only(self,
                                   possible_links: dict,
                                   normalization_factor=1.0):
        outcome = self.get_outcome(normalization_factor)
        self.remake_network(possible_links)
        connected_nodes = set()
        border = set()
        for node_id, time in outcome.items():
            if time <= .0:
                border.add(node_id)
        while len(border):
            new_border = set()
            for node_id in border:
                node = self.network.nodes.get(node_id)
                print(node)
                if node:
                    if len(node['out']):
                        new_border |= set(node['out'])
            connected_nodes |= border
            new_border -= connected_nodes
            border = new_border

        new_outcome = {}
        for node_id, time in outcome.items():
            if node_id in connected_nodes:
                new_outcome[node_id] = time

        return new_outcome
 def __init__(self):
     self.cascades_network = Network()
     self.underlying = Network()
     pass
def make_test_network():
    ntw = Network(optimisation=NetworkOptimisation.id_only)
    for i in range(31):
        ntw.add_node(i + 1)
    ntw.add_link(1, 2)
    ntw.add_link(1, 3)
    ntw.add_link(2, 3)
    ntw.add_link(3, 4)
    ntw.add_link(4, 5)
    ntw.add_link(4, 6)
    ntw.add_link(5, 6)
    ntw.add_link(4, 7)
    ntw.add_link(7, 8)
    ntw.add_link(7, 9)
    ntw.add_link(7, 10)
    ntw.add_link(8, 10)
    ntw.add_link(9, 10)
    ntw.add_link(9, 11)
    ntw.add_link(11, 12)
    ntw.add_link(11, 13)
    ntw.add_link(12, 13)
    ntw.add_link(13, 14)
    ntw.add_link(8, 15)
    ntw.add_link(3, 16)
    ntw.add_link(16, 17)
    ntw.add_link(17, 18)
    ntw.add_link(18, 19)
    ntw.add_link(19, 20)
    ntw.add_link(15, 20)
    ntw.add_link(1, 21)
    ntw.add_link(1, 22)
    ntw.add_link(1, 23)
    ntw.add_link(1, 24)
    ntw.add_link(1, 25)
    ntw.add_link(1, 26)
    ntw.add_link(2, 21)
    ntw.add_link(2, 22)
    ntw.add_link(2, 23)
    ntw.add_link(2, 24)
    ntw.add_link(2, 25)
    ntw.add_link(2, 26)
    ntw.add_link(3, 21)
    ntw.add_link(3, 22)
    ntw.add_link(3, 23)
    ntw.add_link(3, 24)
    ntw.add_link(3, 25)
    ntw.add_link(3, 26)
    return ntw
    def estimate_SI_decay_confirm_relicexp_hetero(cls, underlying: Network, theta: float,
                                                  decay: float, confirm: float, relic: float, outcome: dict,
                                                  thetas: dict = None, initials: set = None, immunes: set = set(),
                                                  immune_p=.0, initial_p=.0, tmax=1000.0, dt=1, echo=False):
        time = .0
        my_outcome = outcome.copy()
        susceptible = set(underlying.nodes_ids)
        probability = 1.
        infected = set()
        infected |= initials
        susceptible -= immunes | infected
        i = 0
        dprob_not = 1.
        while time < tmax and len(susceptible) > 0:
            time += dt
            new_infected = set()
            dprob_inf = 1.
            totrel=0
            for node_id in susceptible:
                neighbors = underlying.get_in_neighbors_for_node(node_id)

                infected_nbrs = neighbors & infected
                p_not_infected = 1.
                relic_total = .0
                for infected_id in infected:
                    if outcome.get(infected_id):
                        relic_total += math.exp(-decay * (time - outcome[infected_id]))
                    else:
                        relic_total += math.exp(-decay * time)
                relic_total *= relic
                totrel = relic_total
                if len(infected_nbrs) > 0:
                    for neighbor_id in infected_nbrs:
                        time_gone = outcome.get(neighbor_id)
                        if time_gone:
                            time_gone = time - time_gone
                        else:  # initialy infected
                            time_gone = time
                        if thetas and thetas.get(neighbor_id):
                            p_not_infected *= (1. - thetas[neighbor_id] * dt * (math.exp(-time_gone * decay)))
                        else:
                            p_not_infected *= (1. - theta * dt * (math.exp(-time_gone * decay)))
                p_not_infected *= (1. - relic_total * dt)
                if node_id in my_outcome.keys() and my_outcome[node_id] <= time:
                    probability *= 1.0 - p_not_infected
                    dprob_inf *= 1.0 - p_not_infected
                    new_infected.add(node_id)
                else:
                    probability *= p_not_infected
                    dprob_not *= p_not_infected
            for node_id in new_infected:
                my_outcome.pop(node_id)
            susceptible -= new_infected
            infected |= new_infected
            # print(str(probability) + ' ' + str(infected))
            if echo and len(new_infected):
                #print(str(list(new_infected)[0]) + ' ' + str(time) + ' ' + str(math.log(probability/(dt**(len(outcome)-1)))))
                #print(str(list(new_infected)[0]) + ' ' + str(time) + ' ' + str(math.log(dprob_inf / dt)))
                print(str(list(new_infected)[0]) + ' ' + str(time) + ' ' + str(math.log(dprob_not)) + ' ' + str(math.log(dprob_inf / dt)) + ' ' + str(math.log(probability/(dt**(len(infected-initials))))))
                print('nr'+str(len(susceptible|new_infected)) + ' ' + str(totrel))
                dprob_not = 1.
        #print('tail ' + str(time) + ' ' + str(math.log(dprob_not)) + ' ' + str(math.log(probability/(dt**(len(infected-initials))))))
        #print(time)
        return probability
Example #26
0
 def __init__(self, net=Network(), name='', base_dir=''):
     self.network = net
     self.name = name
     self.base_dir = base_dir
     self.source = NetworkSource.vkontakte
     self.crawl_plan = []