条件随机场(CRF)原理和实现

CRF原理和代码实现 CRF原理和代码实现说明 阅读详情

对数域操作函数

class Logspace:
    def __init__(self):
        self.LOGZERO =np.nan
    def eexp(self,x):
        if np.isnan(x):
            return 0
        else:
            return np.exp(x)
    def eln(self,x):
        if x == 0:
            return self.LOGZERO
        elif x>0:
            return np.log(x)
        else:
            print 'Wrong!!!\n\t negative input error'
            return np.nan
    def elnsum(self,elnx,elny):
        if np.isnan(elnx):
            return elny
        elif np.isnan(elny):
            return elnx
        elif elnx > elny:
            return elnx + self.eln(1+np.exp(elny-elnx))
        else:
            return elny + self.eln(1+np.exp(elnx-elny))
    def elnproduct(self,elnx,elny):
        if np.isnan(elnx) or np.isnan(elny):
            return self.LOGZERO
        else:
            return elnx + elny
    def elnmatprod(self,elnx,elny):
        #array([[ 0.]])其size是2
        xsize = np.size(np.shape(elnx))
        ysize = np.size(np.shape(elny))

        if xsize == 1 and ysize == 1:
            r = self.LOGZERO
            for i in range(np.shape(elnx)[0]):
                r = self.elnsum(r,self.elnproduct(elnx[i],elny[i]))
            return r
        elif xsize == 1 and not ysize == 1:
            n = np.shape(elny)[1]
            r = np.zeros(n)
            for i in range(n):
                r[i] = self.elnmatprod(elnx,elny[:,i])
            return r
        elif not xsize == 1 and ysize == 1:
            n = np.shape(elnx)[0]
            r = np.zeros(n)
            for i in range(n):
                r[i] = self.elnmatprod(elnx[i,:],elny)
            return r    
        else:
            m,n= np.shape(elnx)
            p = np.shape(elny)[1]
            r = np.zeros((m,p))
            for i in range(m):
                for j in range(p):
                    r[i][j] = self.elnmatprod(elnx[i,:],elny[:,j])
            return r
    def eexpmat(self,elny):
        expy = np.copy(elny)
        if np.size(np.shape(elny)) == 1:
            for i in range(np.shape(elny)[0]):
                expy[i] = self.eexp(expy[i])
        else:
            for i in range(np.shape(elny)[0]):
                for j in range(np.shape(elny)[1]):
                    expy[i][j] = self.eexp(expy[i][j])
        return expy
    def elnmat(self,x):
        elnx = np.copy(x)
        if np.size(np.shape(x)) == 1:
            for i in range(np.shape(x)[0]):
                elnx[i] = self.eln(x[i])
        else:
            for i in range(np.shape(x)[0]):
                for j in range(np.shape(x)[1]):
                    elnx[i,j] = self.eln(x[i,j])
        return elnx  
# 测试举例
logspace = Logspace()
M1 = np.array([1,0.5])
M2 = np.array([[1.3,1.5],[1.8,0.5]])
M3 = np.array([[0.8,1.5],[1.8,0.7]])
M4 = np.array([0,0])

print logspace.eexpmat(logspace.elnmatprod(M1,M2))
print np.dot(logspace.eexpmat(M1),logspace.eexpmat(M2))

[ 19.94836491 14.90077579]
[ 19.94836491 14.90077579]

条件随机场的函数

def read_corps(corpsfile='testchunk.data'):
    #http://www.chokkan.org/software/crfsuite/tutorial.html,该页面有两个网址可下载数据集,该数据集量很大
    #http://blog.dpdearing.com/2011/12/opennlp-part-of-speech-pos-tags-penn-english-treebank/
    tagids = defaultdict(lambda: len(tagids))
    tagids["<S>"] = 0

    corps=[]
    onesentence = []
    words = [ "<S>" ]
    tags  = [   0   ]
    #wordnumcount = 0
    with open(corpsfile,'r') as f:   
        for line in f:
            if len(line)<=1:
                pass
            elif line != '. . O\n': 
                # '. . O\n'表示一句话结束,当一句话未结束则将该单词加入列表onesentence
                onesentence.append(line)
            else: #如果一句话结束,则对该句话的所有出现的单词进行处理,将处理结果存入列表corps               
                for texts in onesentence:
                    #wordnumcount += 1
                    w_t = texts.strip().split(" ")
                    #print w_t
                    try: 
                        #由于表示数字的字符串变化较多,为了减少其干扰,这里将其检测出来并替换掉
                        float(w_t[0].strip().replace(',',''));
                        #print w_t
                        words.append('#CD#')
                    except: 
                        words.append(w_t[0].lower()) 
                    #if w_t[1] in{ '``',',',"''",'$','#',')','('}:
                    #    print w_t
                    tags.append(tagids[w_t[1]])
                words.append("<S>") #words是一句话的单词组成的列表
                tags.append(0)      #tags是一句话的标注组成的列表,与单词列表words一一对应
                if np.shape(words)[0] > 2: #排除掉空句子
                    corps.append((words,tags))

                #对onesentence,words和tags重新初始化
                onesentence = []
                words = [ "<S>" ]
                tags  = [   0   ]
    #print '一共出现的单词个数:'+np.str(wordnumcount)
    #一共出现的单词个数:40377
    return corps,tagids
def getfeatureTS(corps):
    featuresets = set() #特征的集合
    featureT = [] #转移特征的列表,比如列表元素('T', 2, 3)表示从状态2转到特征3
    featureS = [] #状态特征的列表,比如列表元素('S','Confidence', 1)
    for corp in corps:
        for i in range(np.shape(corp[0])[0]):
            if corp[0][i] == '<S>':
                continue
            if ('S',corp[0][i],corp[1][i]) not in featuresets:
                featuresets.add(('S',corp[0][i],corp[1][i]))
                featureS.append(('S',corp[0][i],corp[1][i]))
            if corp[0][i-1] != '<S>':
                if ('T',corp[1][i-1],corp[1][i]) not in featuresets:
                    featuresets.add(('T',corp[1][i-1],corp[1][i]))
                    featureT.append(('T',corp[1][i-1],corp[1][i]))
    featureTS = featureT+featureS
    words2tagids = words2tagidfromfeatureS(featureS)
    return featureTS,words2tagids
def getpriorfeatureE(corps,featureTS):
    #计算先验特征期望值
    N = np.shape(corps)[0] #训练样本数
    K = np.shape(featureTS)[0] #特征数
    priorfeatureE = np.zeros(K) 

    for corp in corps: 
        for i in range(np.shape(corp[0])[0]):
            if corp[0][i] == '<S>':
                continue 
            try:
                idex = featureTS.index(('S', corp[0][i], corp[1][i]))
                priorfeatureE[idex] += 1.0
            except:
                pass
            try:
                idex = featureTS.index(('T', corp[1][i-1], corp[1][i]))
                priorfeatureE[idex] += 1.0
            except:
                pass
    priorfeatureE /=N
    #plt.plot(priorfeatureE) 
    #从特征的先验期望值可以看出无论是转移特征(从横坐标0开始)还是状态特征(从横坐标318开始),先被记录的先验期望值越大
    return priorfeatureE
def words2tagidfromfeatureS(featureS):
    #统计所有单词分别对应的词性列表
    words2tagids = {}
    for feature in featureS:
        word = feature[1]
        state = feature[2]
        if word in words2tagids:
            words2tagids[word].append(state)
        else:
            words2tagids[word] = [state]

    #lennums列表统计单词对应的词性的长度的分布
    #lennums = [[lenlist.count(i) for i in range(1,max(lenlist)+1)] 
    #           for lenlist in [[len(words2tagids[i]) for i in words2tagids]]][0]
    #lennums = [3760, 389, 32, 1]
    return words2tagids
def getpostfeatureE(weights,corps,featureTS,words2tagids):
    K = np.shape(featureTS)[0] #特征数
    postfeatureE = np.zeros(K) #特征的后验期望值
    N = np.shape(corps)[0]
    for corpidx in range(N):
        corp = corps[corpidx][0][1:-1]

        lencorp = np.size(corp) #语料长度,即句子中的单词数
        Mlist = {}
        Mlist['mat'] = ['']*(lencorp+1)
        Mlist['dim'] = [words2tagids[corp[i]] for i in range(lencorp)]
        Mlist['len'] = [np.size(words2tagids[corp[i]]) for i in range(lencorp)]
        for i in range(lencorp+1):
            if i == 0:#第一个矩阵,只有状态特征的行向量
                d = Mlist['len'][0]
                Mlist['mat'][i] = np.zeros((1,d))
                for j in range(d):
                    Mlist['mat'][i][0,j] = weights[featureTS.index(('S', corp[0], words2tagids[corp[0]][j]))]        
                continue
            if i == lencorp:#最后一个矩阵,元素为0的列向量矩阵
                Mlist['mat'][i] = np.zeros((Mlist['len'][-1],1))
                continue
            #既非第一个矩阵,亦非第二个矩阵,每个元素要计算状态特征和转移特征
            Mlist['mat'][i] = np.zeros((Mlist['len'][i-1],Mlist['len'][i]))
            for d1 in range(Mlist['len'][i-1]):
                for d2 in range(Mlist['len'][i]):
                    id1 = words2tagids[corp[i-1]][d1]
                    id2 = words2tagids[corp[i]][d2]
                    try:
                        Sweight = weights[featureTS.index(('S', corp[i], id2))] 
                    except:
                        Sweight = 0
                    try:
                        Tweight = weights[featureTS.index(('T', id1, id2))]
                    except:
                        Tweight = 0
                    Mlist['mat'][i][d1,d2] = Sweight + Tweight 

        #return  Mlist,corps[0]
        #return 0

        z = np.array([[0]])
        for i in range(lencorp+1):
            z = logspace.elnmatprod(z,Mlist['mat'][i])

        Alphalist = ['']*(lencorp+2)
        Betalist = ['']*(lencorp+2)
        Alphalist[0] = np.zeros((1,1))  # 第一个前向向量:1*1的矩阵
        Betalist[-1] = np.zeros((Mlist['len'][-1],1))
        #Alphalist里的元素是单行矩阵,Betalist里的元素是单列矩阵
        for i in range(1,lencorp+2): 
            #print i,np.shape(Alphalist[i-1]),np.shape(Mlist['mat'][i-1])
            Alphalist[i] = logspace.elnmatprod(Alphalist[i-1],Mlist['mat'][i-1])
        for i in range(lencorp,-1,-1):
            Betalist[i] = logspace.elnmatprod(Mlist['mat'][i],Betalist[i+1])


        for i in range(1,lencorp+1):
            d1,d2 = np.shape(Mlist['mat'][i-1])
            #print d1,d2,Mlist['dim'][i-2],Mlist['dim'][i-1] # 3,2,34
            #print '================'
            for di in range(d1):
                for dj in range(d2):
                    # i=1时,没有转移特征;i=lencorp+1时,转移特征和状态特征都没有 
                    plocal = logspace.eexp(logspace.elnproduct(logspace.elnproduct(logspace.elnproduct(Alphalist[i-1][0,di],
                                                                 Mlist['mat'][i-1][di,dj]),Betalist[i][dj,0]),-z[0,0]))
                    if i == 1:#只有状态特征
                        try:
                            Sidex =  featureTS.index(('S', corp[i-1], Mlist['dim'][i-1][dj]))
                            postfeatureE[Sidex] += plocal
                        except:
                            pass
                    else:
                        try:
                            Sidex =  featureTS.index(('S', corp[i-1], Mlist['dim'][i-1][dj]))
                            postfeatureE[Sidex] += plocal
                        except:
                            pass
                        try: 
                            Tidex = featureTS.index(('T', Mlist['dim'][i-2][di], Mlist['dim'][i-1][dj]))
                            postfeatureE[Tidex] += plocal
                        except:#如果该转移特征bucunza不存在,直接忽略
                            pass

            #aM = logspace.elnmatprod(Alphalist[i-1],Mlist['mat'][i-1])
            #aMb = logspace.elnmatprod(aM,Betalist[i])
            #print promat
            #backuppromat.append(promat)
    postfeatureE /= N
    return postfeatureE

def getliknegvalue(weights,corps,featureTS,words2tagids):
    #目标函数是对对数似然函数取负,故要使其最小化
    K = np.shape(featureTS)[0] #特征数
    N = np.shape(corps)[0]

    liknegvalue = 0

    for corpidx in range(N):
        corp = corps[corpidx][0][1:-1]
        tag = corps[corpidx][1][1:-1]

        lencorp = np.size(corp) #语料长度,即句子中的单词数
        Mlist = {}
        Mlist['mat'] = ['']*(lencorp+1)
        Mlist['dim'] = [words2tagids[corp[i]] for i in range(lencorp)]
        Mlist['len'] = [np.size(words2tagids[corp[i]]) for i in range(lencorp)]
        for i in range(lencorp+1):
            if i == 0:#第一个矩阵,只有状态特征的行向量
                d = Mlist['len'][0]
                Mlist['mat'][i] = np.zeros((1,d))
                for j in range(d):
                    Mlist['mat'][i][0,j] = weights[featureTS.index(('S', corp[0], words2tagids[corp[0]][j]))]        
                continue
            if i == lencorp:#最后一个矩阵,元素为0的列向量矩阵
                Mlist['mat'][i] = np.zeros((Mlist['len'][-1],1))
                continue
            #既非第一个矩阵,亦非第二个矩阵,每个元素要计算状态特征和转移特征
            Mlist['mat'][i] = np.zeros((Mlist['len'][i-1],Mlist['len'][i]))
            for d1 in range(Mlist['len'][i-1]):
                for d2 in range(Mlist['len'][i]):
                    id1 = words2tagids[corp[i-1]][d1]
                    id2 = words2tagids[corp[i]][d2]
                    try:
                        Sweight = weights[featureTS.index(('S', corp[i], id2))] 
                    except:
                        Sweight = 0
                    try:
                        Tweight = weights[featureTS.index(('T', id1, id2))]
                    except:
                        Tweight = 0
                    Mlist['mat'][i][d1,d2] = Sweight + Tweight 

        numerator = 0
        denominator= np.array([[0]])
        for i in range(lencorp+1):
            denominator = logspace.elnmatprod(denominator,Mlist['mat'][i])  
            if i == 0:
                numerator = logspace.elnproduct(numerator,Mlist['mat'][i][0,Mlist['dim'][i].index(tag[i])])
            elif i < lencorp:
                numerator = logspace.elnproduct(numerator,Mlist['mat'][i][Mlist['dim'][i-1].index(tag[i-1]),Mlist['dim'][i].index(tag[i])])

        liknegvalue += (denominator - numerator)/N
    return liknegvalue[0,0]

def getgradients(priorfeatureE,weights,corps,featureTS,words2tagids):
    postfeatureE = getpostfeatureE(weights,corps,featureTS,words2tagids)

    return postfeatureE - priorfeatureE

L-BFGS函数用于数值优化

def twoloop(s, y, rho,gk):
    # 被lbfgs函数调用
    n = len(s) #向量序列的长度

    if np.shape(s)[0] >= 1:
        #h0是标量,而非矩阵
        h0 = 1.0*np.dot(s[-1],y[-1])/np.dot(y[-1],y[-1])
    else:
        h0 = 1

    a = np.empty((n,))

    q = gk.copy() 
    for i in range(n - 1, -1, -1): 
        a[i] = rho[i] * np.dot(s[i], q)
        q -= a[i] * y[i]
    z = h0*q

    for i in range(n):
        b = rho[i] * np.dot(y[i], z)
        z += s[i] * (a[i] - b)

    return z   

def lbfgs(fun = getliknegvalue,gfun = getgradients,x0 = weights,corps = corps,
          featureTS = featureTS,words2tagids = words2tagids,
          priorfeatureE = priorfeatureE,m=10,maxk = 20):
    # fun和gfun分别是目标函数及其一阶导数,x0是初值,m为储存的序列的大小
    rou = 0.55
    sigma = 0.4
    epsilon = 1e-5
    k = 0
    n = np.shape(x0)[0] #自变量的维度

    s, y, rho = [], [], []

    while k < maxk :

        gk = gfun(priorfeatureE,x0,corps,featureTS,words2tagids)
        if np.linalg.norm(gk) < epsilon:
            break

        dk = -1.0*twoloop(s, y, rho,gk)

        m0=0;
        mk=0
        funcvalue = fun(x0,corps,featureTS,words2tagids)
        while m0 < 20: # 用Armijo搜索求步长
            if fun(x0+rou**m0*dk,corps,featureTS,words2tagids) < funcvalue+sigma*rou**m0*np.dot(gk,dk): 
                mk = m0
                break
            m0 += 1


        x = x0 + rou**mk*dk
        sk = x - x0
        yk = gfun(priorfeatureE,x,corps,featureTS,words2tagids) - gk   

        if np.dot(sk,yk) > 0: #增加新的向量
            rho.append(1.0/np.dot(sk,yk))
            s.append(sk)
            y.append(yk)
        if np.shape(rho)[0] > m: #弃掉最旧向量
            rho.pop(0)
            s.pop(0)
            y.pop(0)

        k += 1
        x0 = x
        print '迭代次数:%d, 函数值:%f'%(k,funcvalue)
    return x0, fun(x0,corps,featureTS,words2tagids)#,k#分别是最优点坐标,最优值,迭代次数

条件随机场的测试

from collections import defaultdict
corps,tagids = read_corps('mycrfdata.data')
featureTS,words2tagids = getfeatureTS(corps) #得到总的特征列表featureTS
K = np.shape(featureTS)[0] #总的特征数
N = np.shape(corps)[0] #训练样本数
priorfeatureE = getpriorfeatureE(corps,featureTS) #计算特征的先验期望值


weights = np.array([1.0/K]*K)


#postfeatureE = getpostfeatureE(weights,corps,featureTS,words2tagids)
#liknegvalue = getliknegvalue(weights,corps,featureTS,words2tagids)
weights,likelyfuncvalue = lbfgs(fun = getliknegvalue,gfun = getgradients,x0 = weights,corps = corps,
                                featureTS = featureTS,words2tagids = words2tagids,
                                priorfeatureE = priorfeatureE,m=10,maxk = 40)
迭代次数:1, 函数值:4.517425
迭代次数:2, 函数值:3.402287
迭代次数:3, 函数值:2.591947
迭代次数:4, 函数值:1.961000
迭代次数:5, 函数值:1.511211
迭代次数:6, 函数值:1.164718
迭代次数:7, 函数值:1.011021
迭代次数:8, 函数值:0.863806
迭代次数:9, 函数值:0.764431
迭代次数:10, 函数值:0.685292
迭代次数:11, 函数值:0.610862
迭代次数:12, 函数值:0.567107
迭代次数:13, 函数值:0.524796
迭代次数:14, 函数值:0.495254
迭代次数:15, 函数值:0.466203
迭代次数:16, 函数值:0.443137
迭代次数:17, 函数值:0.422248
迭代次数:18, 函数值:0.406402
迭代次数:19, 函数值:0.396005
迭代次数:20, 函数值:0.386036
迭代次数:21, 函数值:0.380390
迭代次数:22, 函数值:0.380207
迭代次数:23, 函数值:0.376401
迭代次数:24, 函数值:0.375102
迭代次数:25, 函数值:0.370988
迭代次数:26, 函数值:0.366604
迭代次数:27, 函数值:0.360824
迭代次数:28, 函数值:0.355004
迭代次数:29, 函数值:0.351590
迭代次数:30, 函数值:0.347119
迭代次数:31, 函数值:0.344447
迭代次数:32, 函数值:0.341149
迭代次数:33, 函数值:0.337679
迭代次数:34, 函数值:0.335245
迭代次数:35, 函数值:0.332701
迭代次数:36, 函数值:0.329436
迭代次数:37, 函数值:0.326451
迭代次数:38, 函数值:0.324949
迭代次数:39, 函数值:0.321441
迭代次数:40, 函数值:0.319166
迭代次数:41, 函数值:0.315978
迭代次数:42, 函数值:0.312033
迭代次数:43, 函数值:0.308039
迭代次数:44, 函数值:0.305588
迭代次数:45, 函数值:0.302214

è¿éåå¾çæè¿°

import codecs
#读取中文文本,首先要把文本文件保存成utf-8格式,默认的ANSI格式文件读取后不能正确打印中文字符
likelihoodlist = []
with codecs.open('loglikelihood.txt','r','utf-8') as f: 
    for line in f:
        #u'\uff1a'是中文符号“:”
        likelihoodlist.append(float(line.split(u'\uff1a')[-1].split()[0]))
plt.plot(likelihoodlist[:100],'-k')
plt.plot(likelihoodlist[:100],'+r')
plt.title(u'L-BFGS训练CRF的收敛曲线',{'fontname':'STFangsong','fontsize':18})
plt.xlabel(u'迭代次数',{'fontname':'STFangsong','fontsize':18})
plt.ylabel(u'对数似然函数取负值',{'fontname':'STFangsong','fontsize':18})

è¿éåå¾çæè¿°

from scipy.stats.kde import gaussian_kde

# this create the kernel, given an array it will estimate the probability over that values
kde = gaussian_kde(priorfeatureE)
# these are the values over wich your kernel will be evaluated
dist_space = linspace( min(priorfeatureE)-0.01*(max(priorfeatureE)-min(priorfeatureE)), max(priorfeatureE), 100 )
# plot the results
plt.plot(dist_space, kde(dist_space))
plt.title(u'特征的先验期望取值的密度分布',{'fontname':'STFangsong','fontsize':18})
plt.xlabel(u'特征的先验期望取值',{'fontname':'STFangsong','fontsize':18})
plt.ylabel(u'密度估计',{'fontname':'STFangsong','fontsize':18})

è¿éåå¾çæè¿°

from scipy.stats.kde import gaussian_kde

#weights是训练的权值列表,由于训练时间长,得到并不容易,故先保存
np.savetxt('crfweights.out', weights, delimiter=',')  #
data = np.genfromtxt('crfweights.out', delimiter=',')


# this create the kernel, given an array it will estimate the probability over that values
kde = gaussian_kde(data)
# these are the values over wich your kernel will be evaluated
dist_space = linspace( min(data)-0.01*(max(data)-min(data)), max(data), 400 )

fig,axes = plt.subplots(nrows=2,ncols=1,figsize=(12,10))
plt.subplots_adjust(wspace = None,hspace=0.3)

axes[0].plot(data)
axes[0].set_title(u'迭代训练500次的特征权值图',{'fontname':'STFangsong','fontsize':18})
axes[0].set_xlabel(u'特征(5331个)',{'fontname':'STFangsong','fontsize':18})
axes[0].set_ylabel(u'权值大小',{'fontname':'STFangsong','fontsize':18})

axes[1].plot(dist_space, kde(dist_space),'k',marker = u'$\circ$')
axes[1].set_title(u'迭代训练500次的特征权值密度分布',{'fontname':'STFangsong','fontsize':18})
axes[1].set_xlabel(u'特征权值大小',{'fontname':'STFangsong','fontsize':18})
axes[1].set_ylabel(u'密度估计',{'fontname':'STFangsong','fontsize':18})

势函数:势,英语potential,就是有一种潜力,由一种能量转化为别的能量的潜力,描述这种潜力的函数,应该就是叫势函数。势函数到处可见,凡是涉及到能量描述和转换的地方,都会涉及到势函数,还有生物势、化学势。统计物理里面涉及到很多这方面的知识。
标注问题:在自然语言处理中有一个常见的任务,即标注。常见的有:1)词性标注(Part-Of-Speech Tagging),将句子中的每个词标注词性,例如名词、动词等;2)实体标注(Name Entity Tagging),将句子中的特殊词标注,例如地址、日期、人物姓名等。
http://blog.youkuaiyun.com/lanxu_yy/article/details/36245161
条件随机场(Conditional random fields)
http://blog.youkuaiyun.com/chlele0105/article/details/14897761
条件随机场简介(Introduction to Conditional Random Fields)
说明了特征函数的内容
http://blog.echen.me/2012/01/03/introduction-to-conditional-random-fields/
条件随机场的Python例子
https://github.com/huangzhengsjtu/pcrf/
http://flexcrfs.sourceforge.net/flexcrfs.pdf
CRF++的简单使用
http://blog.youkuaiyun.com/felomeng/article/details/4288492
Using CRF for Image Segmentation in Python
http://sloblog.io/~ankl/B-SrKYr2qJw/using-crf-for-image-segmentation-in-python-step-1
http://www.inference.phy.cam.ac.uk/hmw26/crf/
《Conditional Random Fields: An Introduction》内容不错
 

 

18、条件随机场(CRF):原理、实现与应用 本文深入探讨了条件随机场(CRF)的原理、实现与在文本分析中的应用。从线性链CRF的基本概念和马尔可夫性质出发,详细介绍了势函数、转移与状态特征函数等核心组件,并结合股票分析师推荐信息提取的实际案例,展示了CRF模型的构建、训练与预测全过程。文章还比较了CRF与HMM、LSTM等序列模型的优劣,分析了其在实际应用中的优势与挑战,并展望了其与深度学习融合、自动化特征工程等未来发展方向,为读者提供了一套完整的CRF理论与实践指南。 阅读详情

相关推荐

在PLC中将十六进制数据转换为浮点数(通常遵循IEEE 754标准)需要理解数据存储格式,并按以下步骤操作:

通过以上步骤,您可以在PLC中实现十六进制到浮点数的转换。T DBD20 // 将数据传送到浮点数变量(如DB1.DBD20)指数位(8位):实际指数 = 存储值 - 127(偏移量)。:必须确认PLC的存储顺序(大端或小端),否则结果错误。将两个16位寄存器合并为32位数据,需注意。尾数位(23位):隐含前导1,实际值为。:确保32位数据在寄存器中连续且对齐。符号位(1位):0表示正,1表示负。:高位寄存器在前(如西门子PLC)。:低位寄存器在前(如三菱FX系列)。,误差因截断导致)。

K11mvp的博客 4416

条件随机场(CRF)从入门到实战:原理剖析与Python实现

本文深入浅出地介绍了条件随机场(CRF)的核心原理与实战应用。通过“看图说话”的比喻,阐释了CRF如何利用全局上下文信息进行序列标注,并对比了其与HMM的差异。文章重点剖析了CRF的数学直觉,即通过状态特征和转移特征函数进行“打分”,并详细演示了如何使用Python从零实现维特比解码算法,以及如何利用CRFsuite库进行命名实体识别(NER)的完整工业级实战。

weixin_29188997的博客 96

Canoe CAPL TCP通信避坑指南:从OnTcpConnect回调不触发到Socket句柄管理

本文详细解析了Canoe CAPL中TCP通信的常见问题与解决方案,包括OnTcpConnect回调不触发的三大原因、Socket句柄管理的内存泄漏风险、数据发送截断规则等。通过实战案例和代码示例,帮助开发者规避TCP通信中的典型陷阱,提升车载网络测试的稳定性和可靠性。

weixin_26976635的博客 358

全连接条件随机场_一文理解条件随机场CRF

写在前面:本文先写的渣英文再渣翻译,请见谅。Intro2 Conditional Random Field(CRF)1.1 CRF能用来做什么?CRF 是一个序列化标注算法(sequence labeling algorithm),接收一个输入序列如 并且输出目标序列 ,也能被看作是一种seq2seq模型。这里使用大写 X,Y 表示序列。例如,在词性标注任务中,输入序列为一串单词,输出序列就是相...

weixin_39633171的博客 637

使用Gromacs进行蛋白和配体小分子的动力学模拟+结果分析全流程教程

先选protein,选择non-water,使用pymol打开delWater.pdb,输入util.ss('all')展示cartoon,点击file-Export Moive as-MPEG。这一步完成后,文件夹中会出现以下三个文件,其中gro 文件用于记录蛋白的初始坐标,top 文件记录蛋白的拓扑信息和力场信息,itp 与top文件类似。接下来使用Spdbv软件打开蛋白,如果蛋白中存在原子缺失情况,就会出现以下的提示,如果不存在就不会显示,同时保存为rep.pdb。

weixin_46587777的博客 2849

从零开始写一个RTSP服务器(一)RTSP协议讲解

从零开始写一个RTSP服务器系列 从零开始写一个RTSP服务器(一)不一样的RTSP协议讲解 从零开始写一个RTSP服务器(二)RTP传输H.264(待写) 从零开始写一个RTSP服务器(三)一个传输H.264的RTSP服务器(待写) 从零开始写一个RTSP服务器(四)RTP传输AAC(待写) 从零开始写一个RTSP服务器(五)一个传输AAC的RTSP服务器(待写) 从零开始写一个RTSP服务器(...

JT同学的博客 7万+

机器学习(有监督)——条件随机场CRF

以命名实体为例:类别[B,I,O],B表示名字的第一个字,I表示名字后面的字,O表示不是名字的字。则序列X[他,叫,王,小,明,。],对应的标签Y[O,O,B,I,I,O]。input3->结束中:三个标签里最优的标签是label2,往回找input2->input3的最优标签是label3,同理input1->input2是label3,所以最优标签状态就是label3、label3、label2)。实际上就是所有路径得分之和:1-1-1、1-1-2、1-1-3、......、3-3-2、3-3-3。

qq_57832544的博客 2978

Spring AI Alibaba实战训练营-20 基于注解驱动的MCP快速开发入门指南

本文详细讲解如何使用SpringAiAlibaba快速开发基于注解驱动的MCP应用。文章详细介绍了MCP协议并且重点介绍了Spring AI通过注解驱动的开发方式简化MCP服务开发。具体包括服务端和客户端的注解使用、城市最新时间查询MCP项目结构概览(服务端和客户端模块)以及环境配置要求。

program哲学 294

图像分割后图像之全连接CRFs后处理

目前图像像素级语义分割比较流行使用深度学习全卷积神经网络FCN或者各种FCN的改进版U-Net、V-Net、SegNet等方法。这些模型中使用了反卷积层进行上采样操作,虽然能够将特征图恢复至原图尺寸,但也造成了特征的损失,自然而然产生了分类目标边界模糊的问题。为了得到更精确的最终分类结果,通常要进行一些图像后处理。全连接CRFs是在目前深度学习图像分割应用中常用的一种图像后处理方式,它是CRFs的...

qq_43258953的博客 1万+

【EB-03】 AUTOSAR builder与EB RTE集成

打开EB工具后,在EB的步骤是:执行MultiTask(2)-> Mapping Component to Partitions(4)->Task Mapping(5)-> SvcAs_Trigger(7)-> Code Generation(8)如涉及新增BSW Module,也需要重复以上步骤。

libuping2023的博客 960

Simulink仿真模块 - Data Type Conversion

Data Type Conversion将输入信号转换为指定的数据类型 在仿真库中的位置为: Simulink / 常用模块 Simulink / Signal Attributes 模型为: 说明 DataTypeConversion模块可将任何 Simulink®数据类型的输入信号转换为您指定的数据类型。 注意 要通过指定模块参数来控制输出数据类型,或者要从下游模块继承数据类型,使用DataTypeConversion模块。要...

jk_101的博客 2519

全连接条件随机场_【图像后处理】python实现全连接CRFs后处理

前言目前图像像素级语义分割比较流行使用深度学习全卷积神经网络FCN或者各种FCN的改进版U-Net、V-Net、SegNet等方法。这些模型中使用了反卷积层进行上采样操作,虽然能够将特征图恢复至原图尺寸,但也造成了特征的损失,自然而然产生了分类目标边界模糊的问题。为了得到更精确的最终分类结果,通常要进行一些图像后处理。全连接CRFs是在目前深度学习图像分割应用中常用的一种图像后处理方式,它是CRF...

weixin_39662611的博客 3120

一、适配显示服务

基于rk3568适配显示服务,调动gpu;

XiaoC_Android的博客 1001

条件随机场(CRF)详解:原理、算法与实现(深入浅出)

条件随机场(CRF)

weixin_46713695的博客 6113

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

NER系列:CRF条件随机场原理简介,深入理解CRF源码实现

命名实体识别(Named Entity Recognition,NER),是指识别文本中**有特定意义的实体**的**边界**和**类别**,所指的实体包括人名、地名、机构名,或者某种具有特定业务含义的词组等,NER的目标是识别出这些特定词组在文本中的位置,并且给该位置下的词组标记出正确的实体业务含义类别。

2401_85325397的博客 1031

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

机器学习--条件随机场(CRF)原理和实现

对数域操作函数 class Logspace:     def __init__(self):         self.LOGZERO =np.nan     def eexp(self,x):         if np.isnan(x):             return 0         else:             return np.exp(x)    

HuFeiHu 8146

crf的实现 keras_条件随机场CRF原理介绍 以及Keras实现

本文是对CRF基本原理的一个简明的介绍。当然,“简明”是相对而言中,要想真的弄清楚CRF,免不了要提及一些公式,如果只关心调用的读者,可以直接移到文末。图示#按照之前的思路,我们依旧来对比一下普通的逐帧softmax和CRF的异同。逐帧softmax#CRF主要用于序列标注问题,可以简单理解为是给序列中的每一帧都进行分类,既然是分类,很自然想到将这个序列用CNN或者RNN进行编码后,接一个全连接层...

weixin_39955925的博客 663

条件随机场(CRF)的原理与实现

一、概率无向图模型 模型定义 又称马尔科夫随机场。设有联合概率分布P(Y),由无向图G=(V,E)表示,结点V表示随机变量,边E表示随机变量之间的依赖关系。如果P(Y)满足成对、局部或全局马尔科夫性,就此联合概率分布为概率无向图模型。 成对马尔科夫性 u和v是无向图G中任意两个没有边连接的结点,其他结点为O,成对马尔科尔性是指YOY_OYO​的条件下,YuY_uYu​和YvY_vYv​是条件独立的,即 P(Yu,Yv∣YO)=P(Yu∣YO)P(Yv∣YO)P(Y_u,Y_v|Y_O) = P(Y_u|Y_

sgyuanshi的博客 1762

经典算法复现!(条件随机场)CRF原理及实现代码

Datawhale作者:丁媛媛,Datawhale优秀学习者寄语:本文先对马尔可夫过程及隐马尔可夫算法进行了简单的介绍;然后,对条件随机场的定义及其三种形式进行了详细推导;最后,介绍...

fengdu78的博客 7855

【条件随机场】Linear Chain CRF原理和实现(上)

这篇文章结合代码讲解线性链CRF的理论和实现,帮助读者彻底理解CRF的所有细节,从「听说过这个概念」达到「可以用起来」的水平。

WinterShiver 1169

求任意两点最大举例 迪杰斯特拉_全方位理解条件随机场(CRF):原理、应用举例、CRF++实现...

全方位理解条件随机场(CRF):原理、应用举例、CRF++实现参考文献:https://www.jianshu.com/p/55755fc649b1https://www.cnblogs.com/pangxiaodong/archive/2011/11/21/2256264.html李航《统计学习方法》1、基本概念:随机场是由若干个位置组成的整体,当给每一个位置中按照某种分布随机赋予一个值之后,其...

weixin_39663933的博客 273

条件随机场(CRF)极简原理与超详细代码解析

本文将以pytorch版本CRF的一个实现为例,尽可能详细地说明CRF是怎样实现的,对代码的解释几乎精细到每一行,相信你耐心读完本文,会从实践的角度对CRF的理解更加深刻。

weixin_44826203的博客 2万+

CRF条件随机场----原理讲解和代码实现(命名实体识别--序列标注问题)

1、CRF条件随机场引入 几个概念介绍: 随机场:由若干个位置组成的整体,当给每一个位置中按照某种分布随机赋予一个值之后,其全体就叫做随机场 马尔科夫随机场:马尔科夫随机场是随机场的特例,它及假设随机场中某个位置的赋值仅仅与和它相邻的位置的赋值有关,与其不相邻的位置的值无关 条件随机场:CRF是马尔科夫随机场的特例,它假设马尔科夫随机场中只有X和Y两种变量,且X一般是...

weixin_41097516的博客 3870

CRF 条件随机场

目录 1. 基本概念 1.1 各种随机场 1.2 CRF模型的训练原理 1.3 条件随机场的参数化形式 1.4条件随机场对应的简化概率表达 2. 例子 定义CRF中的特征函数 从特征函数到概率 CRF与逻辑回归的比较 CRF与HMM的比较 HMM和CRF区别 3. Tensorflow实现 tf.contrib.crf (1)tf.contrib.......

满腹的小不甘 6817

crf的实现 keras_简明条件随机场CRF介绍 | 附带纯Keras实现

作者丨苏剑林单位丨广州火焰信息科技有限公司研究方向丨NLP,神经网络个人主页丨kexue.fm笔者去年曾写过文章《果壳中的条件随机场(CRF In A Nutshell)》,以一种比较粗糙的方式介绍了一下条件随机场(CRF)模型。然而那篇文章显然有很多不足的地方,比如介绍不够清晰,也不够完整,还没有实现,在这里我们重提这个模型,将相关内容补充完成。本文是对 CRF 基本原理的一个简明的介绍。当然,...

weixin_39567013的博客 165
上一篇: 车牌识别实践(python+OpenCV+CNN)
下一篇: NLP项目汇总
CopperDong
博客等级 码龄14年 1205粉丝 466原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值