Exemplo n.º 1
0
def corpus_cooccurrences(corpus_dir_path):
    """
    FR : Compte les cooccurrences entre paires de mots dans le corpus donné 
    et les retournes sous forme de dict.\n
    EN : Count the cooccurrences between pair of words in the given corpus and return the in a dict.\n
    Parameters
    ----------
    corpus_dir_path : str\n
        FR : Emplacement du corpus\n
        EN : The corpus path\n
    Returns
    -------
    cooc_dic : dic{word1 : str , cooc : dic{word2 : str , nb_cooc_word1_word2 : int}}\n
        FR : Dictionnaire contenant les paire toutes les paires de mots rencontrées dans le corpus
        ainsi que leur nombre d'occurences respectives.\n
        EN : Dictionary with all the pair of word seen in the corpus
        and the number of time each pair has been sighted.\n
    """
    cooc_dic = defaultdict(lambda : defaultdict(int))
    sid = 0 # Id de la phrase
    sentence_first_word_id = 0 
    for data, sentences in corpus_batcher(corpus_dir_path):
        del sentences
        # Transforme la DataFrame en matrice numpy pour optimiser la lecture iterrative
        data = data[['Lemma']].reset_index().to_numpy()
        for n,row in enumerate(data):
            # parcour tout les mots de la phrase avant le mot actuel (n)
            for a in data[sentence_first_word_id:n]:
                cooc_dic[row[2]][a[2]]+=1
                cooc_dic[a[2]][row[2]]+=1
            # met à jour l'id du premier mot de la phrase lorsque l'on change de phrase
            if sid != row[0] : 
                sid = row[0]
                sentence_first_word_id = n
    return {word1 : {word2 : count for word2, count in dic.items()} for word1, dic in cooc_dic.items()}
Exemplo n.º 2
0
def expressions_cooccurrences(corpus_dir_path, expressions):
    """
    FR : Compte les cooccurrences entre les expressions fournies en entré et les mots du corpus.\n
    EN : Count cooccurrences between the given expressions and corpus' words.\n
    Parameters
    ----------
    corpus_dir_path : str\n
        FR : Emplacement du corpus\n
        EN : The corpus path\n
    expressions : list<(str,str)>\n
        FR : liste des expressions dont on veut les coccurrences\n
        EN : list of the expressions of which we want the coccurrences\n
    Returns
    -------
    exp_dic : dic{exp : (noun : str,verb : str) , cooc : dic{word : str , nb_cooc_exp_word : int}}\n
        FR : Dictionnaire contenant pour chaque expression les mots avec lequelles celle-ci
        cooccurre ainsi que le nombre de coccurences respective\n
        EN : Dictionary with, for each expression, the word cooccurring with said expression and
        the number of cooccurrence
    """
    cooc_dic = defaultdict(lambda : defaultdict(int))
    if expressions == []: return cooc_dic
    last_word_sid = 0
    for data, sentences in corpus_batcher(corpus_dir_path):
        data = data.reset_index().to_numpy()
        word_occurrences = defaultdict(int)
        verbs = defaultdict(lambda :-1)
        nouns = defaultdict(lambda :-2)
        for n,end_row in enumerate(data):
            if last_word_sid != end_row[0] :
                if len(verbs) != 0 and len(nouns) != 0:
                    for expression in expressions:
                        if verbs[expression] == nouns[expression]:
                            for word, occurences in word_occurrences.items():
                                if word not in expression:
                                    cooc_dic[expression][word] += occurences#*C[exp]
                word_occurrences = defaultdict(int)
                verbs = defaultdict(lambda :-1)
                nouns = defaultdict(lambda :-2)
                last_word_sid = end_row[0]
            word_occurrences[end_row[3]]+=1
            
            if end_row[4] == 'NOUN':
                for expression in expressions:
                    if end_row[3] == expression[1]:
                        nouns[expression] = end_row[7]
            if end_row[4] == 'VERB':
                for expression in expressions:
                    if end_row[3] == expression[0]:
                        verbs[expression] = end_row[1]
    return cooc_dic
Exemplo n.º 3
0
def get_LVCs(corpus_dir_path):
  dic1 = {}
  dic2 = defaultdict(list)

  X = None
  for data, sentence in corpus_batcher('Test'):
    X = data
    for (SId, Id),row in data.iterrows():
      if row['Mwe'] != '*' and row['Mwe'] != '_':
        for mwe in row['Mwe'].split(';'):
          tmp = mwe.split(':')
          if len(tmp) != 1:
            dic1[(SId, tmp[0])] = tmp[1]
          dic2[(SId, tmp[0])].append(row[['Lemma', 'UPosTag']].tolist())
  dic = {k : something(v) for k,v in dic2.items() if 'LVC' in dic1[k] }
  dic = {k : v for k, v in dic.items() if v is not None}
  dic = {v for k, v in dic.items() }
  return pd.DataFrame(dic, columns=['NOUN', 'VERB']).set_index(['NOUN', 'VERB'])
Exemplo n.º 4
0
def find_candidats(corpus_dir_path: str) -> (pd.DataFrame):
    """
    FR : Génère une DataFrame de tous les couples (nom, verbe) du corpus pour lesquelles le
    verbs pointe sur le nom, et compte le nombre d'occurence de chaque candidats\n 
    EN : Creates the DataFrame of all the (noun, verb) in the corpus where the verb points towards
    the noun and count the number of occurences of each candidates.\n
    Params
    ------
    corpus_dir_path :\n
        FR : Emplacement du corpus\n
        EN : The corpus path\n
    Returns
    -------
    candidats : DataFrame[('NOUN', 'VERB') : (9,)]\n
        FR : Tableau des candidats, toutes colonnes à 0 sauf, la première représentant le
        nombre d'occurence du candidat\n
        EN : Table of the candidats, all columns at 0 except the first describing the
        number of occurences of the candidat.\n   
    """
    #ONEDAY manage insertion
    candidates = {}
    for data, sentences in corpus_batcher(corpus_dir_path, batch_size=100_000):
        verbs = data.loc[data.UPosTag == 'VERB']  #select the line with verbs
        nouns = data.loc[data.UPosTag == 'NOUN']  #select the line with nouns
        #keeps the couples noun-verb where the noun point to the verb
        candidats = (pd.merge(nouns,
                              verbs,
                              left_on=['SId', 'Head'],
                              right_on=['SId', 'Id'],
                              suffixes=['_n', '_v']))[['Lemma_n', 'Lemma_v']]
        # count the number of occurences
        for row in candidats.to_numpy():
            candidates.setdefault((row[0], row[1]),
                                  [0, 0, 0, 0, 0, 0, 0, 0, 0])[0] += 1
    #generate the candidates dataframe
    candidates = pd.DataFrame(data=candidates).transpose()
    candidates.index.names = ['NOUN', 'VERB']
    candidates.set_axis([
        'N', 'P', 'P_n', 'P_v', 'dist', 'P_obl', 'P_subj', 'P_obj', 'P_other'
    ],
                        axis=1,
                        inplace=True)
    return candidates
Exemplo n.º 5
0
def find_all_patterns(corpus_dir_path: str) -> list:
    """
    FR : Trouve tout les patrons syntaxique du corpus \n
    EN : Find all the syntaxical patterns of the corpus\n
    Params
    ------
    corpus_dir_path : str\n
        FR : Emplacement du corpus\n
            EN : The corpus path\n
    Returns
    -------
    all_patterns : list[(Sid : int, (word1 :str, word2 :str, pattern : list[pos : str,]))]\n
        FR : Liste des patrons syntaxique avec l'id de leur phrase
        et du mot avant et après le patron\n
        EN : Liste of the syntaxical pattern with th id ofthe sentence
        and the word before and after the pattern \n
    """
    d = {}
    for data, sentences in corpus_batcher(corpus_dir_path):
        verbes = data.loc[data.UPosTag == 'VERB']
        nouns = data.loc[data.UPosTag == 'NOUN']
        candidates = pd.merge(nouns.reset_index(),
                              verbes.reset_index(),
                              left_on=['SId', 'Head'],
                              right_on=['SId', 'Id'],
                              suffixes=['_n', '_v']).set_index('SId')
        all_patterns = []
        temp = []
        sentence_sid = -1
        gen = couples_per_sentences(candidates)
        for (Sid, Id), pos in data['UPosTag'].iteritems():
            try:
                while (sentence_sid < Sid):
                    sentence_sid, sentence_couples = next(gen)
                    all_patterns.append((sentence_sid, sentence_couples))
                    #print(si, Sid)
                for curr_couple in sentence_couples:
                    if int(Id) > curr_couple[0] and int(Id) < curr_couple[1]:
                        curr_couple[2].append(pos)
            except:
                pass
        return all_patterns
Exemplo n.º 6
0
def get_candidats_pattern_frequency(corpus_dir_path: str) -> pd.DataFrame:
    """
    FR : Calcule pour chaque candidat du corpus la fréquence des patrons fréquent\n
    EN : Compute for each candidat of the corpus the frequency of the frequent patterns\n
    Params
    ------
    corpus_dir_path : str\n
        FR : Emplacement du corpus\n
        EN : The corpus path\n
    Returns
    -------
    frequent_pattern_frequency : DataFrame\n
        FR : Tableau des candidats et leur fréquence associer à chaque patron fréquent\n
        EN : Table of the candidats and their associated frequence to each frequent pattern.\n
    """
    all_patterns = find_all_patterns(corpus_dir_path)
    frequent_patterns = get_most_frequent_patterns(all_patterns)
    dic = defaultdict(lambda: defaultdict(int))
    n = 0
    for data, sentences in corpus_batcher(corpus_dir_path):
        last = data.iloc[-1].name[0]
        for Sid, patterns in all_patterns[n:]:
            if Sid > last:
                break
            #ONEDAY should add a pattern "other" frequence would be more accurate from it
            for id_w1, id_w2, pattern in patterns:
                if tuple(pattern) in frequent_patterns:
                    lemma_w1 = data.loc[(Sid, str(id_w1))]['Lemma']
                    lemma_w2 = data.loc[(Sid, str(id_w2))]['Lemma']
                    if data.loc[(Sid, str(id_w1))]['UPosTag'] == 'VERB':
                        dic[(lemma_w2, lemma_w1)][tuple(pattern)] += 1
                    else:
                        dic[(lemma_w1, lemma_w2)][tuple(pattern)] += 1
            n += 1
    res = pd.DataFrame.from_dict(dic, orient='index').fillna(0)
    res.columns = frequent_patterns
    res.index.names = ('NOUN', 'VERB')
    res = res.div(res.sum(axis=1), axis=0)
    return res
Exemplo n.º 7
0
def compute_features(corpus_dir_path: str,
                     candidates: pd.DataFrame) -> pd.DataFrame:
    """
    FR : Calcul diverses mesures pour chacun des candidats en se basant sur le corpus\n
    EN : Compute various features for each of the candidats by using the corpus \n
    Params
    ------
    corpus_dir_path : str\n
        FR : Emplacement du corpus\n
        EN : The corpus path\n
    couples : DataFrame[('NOUN', 'VERB') : (9,)]\n
        FR : Tableau des candidats, toutes colonnes doivent être à 0,
        sauf la première représentant le nombre d'occurence du candidat\n
        EN : Table of the candidats, all columns should be at 0 
        except the first describing the number of occurences of the candidat.\n
    Returns
    -------
    features : DataFrame[('NOUN', 'VERB') : (15,)]\n
        FR : Tableau des candidats, toutes les colonnes mise à jour\n
        EN : Candidats table, all columns updated\n
    See also
    --------
    find_candidats\n
    """
    for data, sentences in corpus_batcher(corpus_dir_path, batch_size=100_000):
        '''
        Les diverses comptes sont réalisés sur des batchs du corpus,
        la df 't' sert de tampon afin d'ajouter le resultat des comptes au df concerné
        '''
        #### Setup ####

        # isole les verbes, nom, (nom, verbe) du batch dans des df
        v = data.loc[data.UPosTag == 'VERB']
        n = data.loc[data.UPosTag == 'NOUN']
        s = pd.merge(n.reset_index(),
                     v.reset_index(),
                     left_on=['SId', 'Head'],
                     right_on=['SId', 'Id'],
                     suffixes=['_n', '_v']).set_index('SId')

        #### Distance nom, verbe ####

        # Pour chaque couple (nom, verbe) unique; fait la somme des distance (nombre de mots) entre le nom est le verbe des instances de (nom, verbe)
        t = s.assign(
            dist=np.abs(pd.to_numeric(s.Id_n) -
                        pd.to_numeric(s.Id_v))).groupby(['Lemma_n',
                                                         'Lemma_v']).sum()
        add_to_col(candidates, t, 'dist')

        #### Fréquence relation ####

        # Pour chaque couple (nom, verbe) ; compte le nombre de fois où le couple est lié par une relation de type
        # obj, obl ou subj
        t = s[['DepRel_n', 'Lemma_n', 'Lemma_v'
               ]].assign(N_rel=0).groupby(['DepRel_n', 'Lemma_n',
                                           'Lemma_v']).count()
        add_to_col(candidates, t.loc[('obj')], 'P_obj')
        add_to_col(candidates, t.loc[('obl')], 'P_obl')
        add_to_col(candidates, t.loc[('nsubj')], 'P_subj')

    #### Distance nom, verbe ####

    # Pour chaque couple (nom, verbe) ; calcule la distanc moyenne entre le nom et le verbe

    candidates.update(
        pd.DataFrame({'dist': candidates['dist'] / candidates['N']}))

    #### Probablitées ####
    candidates.update(
        pd.DataFrame({'P': candidates['N'] / candidates['N'].sum()}))

    candidates.update(
        pd.merge(candidates,
                 pd.DataFrame({
                     'P_n':
                     candidates['N'].groupby('NOUN').sum() /
                     candidates['N'].sum()
                 }),
                 left_on='NOUN',
                 right_index=True,
                 suffixes=['a', ''])['P_n'])

    candidates.update(
        pd.merge(candidates,
                 pd.DataFrame({
                     'P_v':
                     candidates['N'].groupby('VERB').sum() /
                     candidates['N'].sum()
                 }),
                 left_on='VERB',
                 right_index=True,
                 suffixes=['a', ''])['P_v'])

    # Pour chaque couple nom, verbe ; calcule la probabilité qu'un nom quelconque soit le nom en question sachant le verbe
    candidates = candidates.assign(P_n_given_v=candidates['P'] /
                                   candidates['P_v'])
    # Pour chaque couple nom, verbe ; calcule la probabilité qu'un verbe quelconque soit le verbe en question sachant le nom
    candidates = candidates.assign(P_v_given_n=candidates['P'] /
                                   candidates['P_n'])
    # Pour chaque nom ; calcule la variance de la probabilité du nom
    candidates = candidates.assign(V_n=candidates['P_n'] *
                                   (1 - candidates['P_n']))
    # Pour chaque verbe ; calcule la variance de la probabilité du verbe
    candidates = candidates.assign(V_v=candidates['P_v'] *
                                   (1 - candidates['P_v']))
    # Pour chaque couple (nom, verbe) ; calcule la covariance de la probabilité du nom et la probabilité du verbe
    candidates = candidates.assign(V=candidates['P'] -
                                   (candidates['P_n'] * candidates['P_v']))
    # Pour chaque cuple (nom, verbe) ; calcule la corrélation entre la probabilité du nom et la probabilité du verbe
    candidates = candidates.assign(
        corr=candidates['V'] /
        (np.sqrt(candidates['V_n']) * np.sqrt(candidates['V_v'])))
    # Pour chaque couple nom, verbe ; calcule le pmi
    candidates = candidates.assign(pmi=np.log(candidates['P_n_given_v'] /
                                              candidates['P_n']))

    #### Fréquence relation ####

    #Pour chaque couple nom, verbe ; calcule la fréquence à laquelle le nom est objet du verbe
    candidates.update(
        pd.DataFrame({'P_obj': candidates['P_obj'] / candidates['N']}))
    #Pour chaque couple nom, verbe ; calcule la fréquence à laquelle le nom est oblique du verbe
    candidates.update(
        pd.DataFrame({'P_obl': candidates['P_obl'] / candidates['N']}))
    #Pour chaque couple nom, verbe ; calcule la fréquence à laquelle le nom est sujet du verbe
    candidates.update(
        pd.DataFrame({'P_subj': candidates['P_subj'] / candidates['N']}))
    #Pour chaque couple nom, verbe ; calcule la fréquence à laquelle le nom n'est, ni objet, oblique ou sujet du verbe
    candidates.update(
        pd.DataFrame({
            'P_other':
            1 -
            (candidates['P_obj'] + candidates['P_obl'] + candidates['P_subj'])
        }))

    candidates = candidates.drop(['N'], axis=1)
    return candidates.fillna(0)