N-gram Language Model

2022-08-03,

import numpy as np
example = np.array([['他', '是', '一个', '人'],
       ['他', '是', '人', '一个'],
       ['他', '一个', '是', '人'],
       ['他', '一个', '人', '是'],
       ['他', '人', '是', '一个'],
       ['他', '人', '一个', '是'],
       ['是', '他', '一个', '人'],
       ['是', '他', '人', '一个'],
       ['是', '一个', '他', '人'],
       ['是', '一个', '人', '他'],
       ['是', '人', '他', '一个'],
       ['是', '人', '一个', '他'],
       ['一个', '他', '是', '人'],
       ['一个', '他', '人', '是'],
       ['一个', '是', '他', '人'],
       ['一个', '是', '人', '他'],
       ['一个', '人', '他', '是'],
       ['一个', '人', '是', '他'],
       ['人', '他', '是', '一个'],
       ['人', '他', '一个', '是'],
       ['人', '是', '他', '一个'],
       ['人', '是', '一个', '他'],
       ['人', '一个', '他', '是'],
       ['人', '一个', '是', '他'],
       ['他', '是', '一个', '人'],
       ['他', '是', '一个', '人'],
       ['它', '是', '一个', '模型'],
       ['它', '是', '模型', '一个'],
       ['它', '一个', '是', '模型'],
       ['它', '一个', '模型', '是'],
       ['它', '模型', '是', '一个'],
       ['它', '模型', '一个', '是'],
       ['是', '它', '一个', '模型'],
       ['是', '它', '模型', '一个'],
       ['是', '一个', '它', '模型'],
       ['是', '一个', '模型', '它'],
       ['是', '模型', '它', '一个'],
       ['是', '模型', '一个', '它'],
       ['一个', '它', '是', '模型'],
       ['一个', '它', '模型', '是'],
       ['一个', '是', '它', '模型'],
       ['一个', '是', '模型', '它'],
       ['一个', '模型', '它', '是'],
       ['一个', '模型', '是', '它'],
       ['模型', '它', '是', '一个'],
       ['模型', '它', '一个', '是'],
       ['模型', '是', '它', '一个'],
       ['模型', '是', '一个', '它'],
       ['模型', '一个', '它', '是'],
       ['模型', '一个', '是', '它'],
       ['它', '是', '一个', '模型'],
       ['它', '是', '一个', '模型']], dtype='<U2')

corpora = ["".join(list(i)) for i in example]

def slide(data,N,start,end,m,n):
    return np.array([data[i,j] for i,j in zip(start,end-N) if j > N and j < n ])

def prob_dict(corpus):
    m,n = corpus.shape
    distion = np.unique(corpus)
    return np.array([[word,(corpus == word).dot(np.ones(n)).dot(np.ones(m))/(m*n)] for word in distion])


def slide_word(textList,n):
    m = len(textList)
    return np.array([textList[i:i+n] for i in range(m) if len(textList[i:i+n]) ==n])

def to_numpy(data):
    if isinstance(data,np.ndarray):
        return data
    else:
        return np.array(data)

def joint_prob(original,corpora,**frequency_list):

    if len(frequency_list)>0:
        frequency_list = frequency_list['frequency_list']
        result = 1
        for word in original:
            try:
                frequency = frequency_list[word]
            except Exception:
                frequency = 0
            result *= frequency
        return result

    original= to_numpy(original)
    n = original.size
    slide_word_n = np.array([slide_word(list(sentence),n) for sentence in corpora ])
    slide_word_one_dim = np.array([j for i in slide_word_n for j in i])
    m = len(slide_word_one_dim)
    slide_word_one_dim
    return ((slide_word_one_dim==original).dot(np.ones(n))==n).dot(np.ones(m))/m

def prob(string,corpora):
    return joint_prob([string],corpora)

def frequency_list_func(corpora):
    unin = ''.join(list(corpora))
    return {word:prob(word,corpora) for word in unin}

frequency_list = frequency_list_func(corpora)

def frequency_sentence(sentence,corpora):
    return {word :prob(word,corpora) for word in sentence}

def cond_prob(PB,PAB,corpora=[],**frequency_list):
    if len(frequency_list)>0:
        frequency_list = frequency_list['frequency_list']
    PAB = joint_prob(PAB,corpora,frequency_list=frequency_list)
    PB = joint_prob([PB],corpora,frequency_list=frequency_list)
    return PAB/PB

def Ngram(sentence,n):
    sentence = to_numpy(sentence)
    m = sentence.size
    return np.array([np.array([sentence[j] for j in range(i) ][-n:]) for i in range(m+1)][1:])

def product(arr):
    n = 1
    for i in arr:
        n *= i
    return n

def NgramLanguageModel(textList,n=2,corpora=corpora,display= False,frequency_dict=frequency_list):
    
    if n ==1:
        model_name = 'Unigram'
    elif n == 2:
        model_name = 'Bigram'
    elif n == 3:
        model_name = 'Trigram'
    else:
        model_name = 'N-gram'

    text , m ,expr = [],len(textList),1
    model_type = n == 1 and 'Bayesian Model' or "Markov Model"


    number = 0
    for arr,char in zip(Ngram(textList,n),textList):
        number += 1
        test_dim = arr.size
        first = char
        PB = prob(char,corpora)

        if test_dim == 1 :
            expr *= PB
            if display:
                text.append({number:[first,PB]})

        elif test_dim > 1:
            PAB = joint_prob(arr,corpora,frequency_list=frequency_dict)
            expr *= (PAB/PB)
            if display:
                text.append({number:[first,arr,PB,PAB]})

    if display:
        return {"{}{}{}".format(model_type,"->",model_name):expr},text
    return {"{}{}{}".format(model_type,"->",model_name):expr}

NgramLanguageModel("它 是 一 个 人".split(),3,display=True)

本文地址:https://blog.csdn.net/weixin_43069769/article/details/107363357

《N-gram Language Model.doc》

下载本文的Word格式文档,以方便收藏与打印。