python实现最大熵模型

2023-11-02

本文参考nltk MaxentClassifier实现了一个简单的最大熵模型,主要用于理解最大熵模型中一些数学公式的实际含义。 
最大熵模型:
Pw(y|x)Zw(x)=1Zw(x)exp(∑i=1nwifi(x,y))=∑yexp(∑i=1nwifi(x,y))
Pw(y|x)=1Zw(x)exp(∑i=1nwifi(x,y))Zw(x)=∑yexp(∑i=1nwifi(x,y))

这里fi(x,y)fi(x,y)代表特征函数,wiwi代表每个特征函数对于的权值。
如何计算测试数据x被分为类别y的概率呢? 
总结成一句话:我们把x和y传给每个特征函数得到相应的特征值(0或者1),然后乘上相应的权值,最后通过softmax得到。

现在面临两个问题。 
1.这里的fi(x,y)fi(x,y)究竟是什么鬼,如何得到? 
2.wiwi又如何求得?

先来看看第一个问题。 
fi(x,y)fi(x,y)反映的是x和y的特征,也就是说它是对输入和输出同时抽取特征的 
它的定义是
f(x,y)={1, x与y满足某一事实0, 否则
f(x,y)={1, x与y满足某一事实0, 否则

值得注意的是,这里在判断x,y是否满足某一事实的时候不是简单判断x整体与y的关系,而是判断x的特征与y的关系。举个例子:
x=dict(a=1, b=1, c=1)
y='1'
这样一个训练数据,我们对它进行特征提取时: 
对x的第一个特征抽取,用一个三元组表示就是(x某一特征名,特征名对应的值,y) 
分别对x的特征进行抽取得到三个特征函数: 
(‘a’,1,’1’) 
(‘b’,1,’1’) 
(‘c’,1,’1’) 
抽取样本中所有特征函数的代码实现:

def maxent_train(train_toks):
    ...
    mapping = {}  # maps (fname, fval, label) -> fid
    for(tok, label) in train_toks:
        for(fname, fval) in tok.items():
            if (fname,fval,label) not in mapping:
                mapping[(fname,fval,label)] = len(mapping)
    ...

代码中mapping存储了所有特征函数,所以判断x,y是否满足某一事实就是看mapping能不能找到(x某一特征名,特征名对应的值,y)这样的三元组。

来看看第二个问题,如何求wiwi 
我们通过GIS算法求它,这里省略数学推导直接看结果。 
算法流程如下: 
1.任意初始化wiwi,一般为0:
w(0)i=0,i∈{1,2,3,...,n}
wi(0)=0,i∈{1,2,3,...,n}

这里的下标表示第ii个特征对于的ww,上标表示第t轮迭代。 
2.重复以下更新直至收敛:
w(t+1)i=w(t)i+1ClogEp^(fi)Ep(n)(fi),i∈{1,2,...,n}
wi(t+1)=wi(t)+1Clog⁡Ep^(fi)Ep(n)(fi),i∈{1,2,...,n}

其中C一般取样本的最大特征数,反应了ww更新速度。 
Ep^(f)=∑x,yP^(x,y)f(x,y)
Ep^(f)=∑x,yP^(x,y)f(x,y)

表示的是某一个特征函数关于经验分布P^(x,y)P^(x,y)的期望值 
Ep(f)=∑x,yP^(x)P(y|x)f(x,y)
Ep(f)=∑x,yP^(x)P(y|x)f(x,y)

表示的是某一个特征函数关于模型P(y|x)P(y|x)与经验分布P^(x)P^(x)的期望值
先来看P^(x,y)P^(x,y)和P^(x)P^(x) 
P^(X=x,Y=y)=v(X=x,Y=y)N
P^(X=x,Y=y)=v(X=x,Y=y)N
P^(X=x)=v(X=x)N
P^(X=x)=v(X=x)N

其中v(X=x,Y=y)v(X=x,Y=y)表示样本(x,y)(x,y)出现的频率,v(X=x)v(X=x)表示样本xx出现的频率,NN表示样本个数。 
由于我们在训练时,样本数据存在唯一性,因此:
P^(X=x,Y=y)=P^(X=x)=1N
P^(X=x,Y=y)=P^(X=x)=1N

所以有:
Ep^(f)=1N∑x,yf(x,y)
Ep^(f)=1N∑x,yf(x,y)
Ep(f)=1N∑x,yP(y|x)f(x,y)
Ep(f)=1N∑x,yP(y|x)f(x,y)
Ep^(fi)Ep(n)(fi)=∑x,yfi(x,y)∑x,yP(y|x)fi(x,y)
Ep^(fi)Ep(n)(fi)=∑x,yfi(x,y)∑x,yP(y|x)fi(x,y)

∑x,yfi(x,y)∑x,yfi(x,y)表示的所有样本在被某一个特征函数抽取的特征值之和,代码实现如下:
 

def calculate_empirical_fcount(train_toks, mapping):
    fcount = np.zeros(len(mapping))
    for tok, label in train_toks:
        for(index, val) in encode(tok,label,mapping):
            fcount[index] += val
    return fcount

fcount结构为{特征id,特征值之和} 
求P(y|x)P(y|x)的实现如下:

def prob(tok, labels, mapping, weights):
    prob_dict = {}
    for label in labels:
        total = 0.0
        for(index,val) in encode(tok,label,mapping):
            total += weights[index]*val
        prob_dict[label] = np.exp(total)
    value_sum = sum(list(prob_dict.values()))
    for(label, value) in prob_dict.items():
        prob_dict[label] = prob_dict[label]/value_sum
    return prob_dict

∑x,yP(y|x)fi(x,y)∑x,yP(y|x)fi(x,y)的实现:

def calculate_estimated_fcount(train_toks, mapping, labels, weights):
    fcount = np.zeros(len(mapping))
    for tok, label in train_toks:
        prob_dict = prob(tok,labels,mapping,weights)
        for label, p in prob_dict.items():
            for (index, val) in encode(tok, label, mapping):
                fcount[index] += p*val
    return fcount



完整代码如下:
 

import numpy as np
def encode(featureset, label, mapping):
    encoding = []
    for (fname, fval) in featureset.items():
        if(fname,fval,label) in mapping:
            encoding.append((mapping[(fname,fval,label)],1))
    return encoding

def calculate_empirical_fcount(train_toks, mapping):
    fcount = np.zeros(len(mapping))
    for tok, label in train_toks:
        for(index, val) in encode(tok,label,mapping):
            fcount[index] += val
    return fcount

def prob(tok, labels, mapping, weights):
    prob_dict = {}
    for label in labels:
        total = 0.0
        for(index,val) in encode(tok,label,mapping):
            total += weights[index]*val
        prob_dict[label] = np.exp(total)
    value_sum = sum(list(prob_dict.values()))
    for(label, value) in prob_dict.items():
        prob_dict[label] = prob_dict[label]/value_sum
    return prob_dict

def calculate_estimated_fcount(train_toks, mapping, labels, weights):
    fcount = np.zeros(len(mapping))
    for tok, label in train_toks:
        prob_dict = prob(tok,labels,mapping,weights)
        for label, p in prob_dict.items():
            for (index, val) in encode(tok, label, mapping):
                fcount[index] += p*val
    return fcount

def maxent_train(train_toks):
    mapping = {}  # maps (fname, fval, label) -> fid
    labels = set()
    feature_name = set()
    for(tok, label) in train_toks:
        for(fname, fval) in tok.items():
            if (fname,fval,label) not in mapping:
                mapping[(fname,fval,label)] = len(mapping)
            feature_name.add(fname)
        labels.add(label)
    C = len(feature_name)+1
    Cinv = 1/C
    empirical_fcount = calculate_empirical_fcount(train_toks,mapping)
    weights = np.zeros(len(empirical_fcount))

    iter = 1
    while True:
        if iter == 100:
            break
        estimated_fcount = calculate_estimated_fcount(train_toks, mapping, labels, weights)
        weights += (empirical_fcount / estimated_fcount) * Cinv
        iter+=1
    return weights, labels, mapping

if __name__ == '__main__':
    train_data = [
        (dict(a=1, b=1, c=1), '1'),
        (dict(a=1, b=1, c=0), '0'),
        (dict(a=0, b=1, c=1), '1')]

    maxent_train(train_data)

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python实现最大熵模型 的相关文章

  • 将 JSON 发布到 Python CGI

    我已经安装了 Apache2 并且 Python 可以工作 但我有一个问题 我有两页 一个是 Python 页面 另一个是带有 JQuery 的 Html 页面 有人可以告诉我如何让我的 ajax 帖子正常工作吗
  • 在 Python 2.7 中出现“ImportError:无法导入名称 HTTPSConnection”错误

    我正在尝试在 AWS ElasticBeanstalk 中部署 django 当我按照所示步骤操作时here http docs aws amazon com elasticbeanstalk latest dg create deploy
  • 如何在 Debian 上的 virtualenv 中安装 numpy?

    注 参见这另一篇文章 https stackoverflow com questions 6442754 how to install h5py numpylibhdf5 as non root on a debian linux syst
  • scipy.optimize on pandas dataframe

    我试图搜索它 但结果很差 有人可以向我解释一下如何在 Pandas DataFrame 上执行 optimize minimize 以便最小化 DataFrame 中的类别和结果列之间的错误 考虑这个例子 import pandas as
  • Python 转换矩阵

    我有一个如下所示的列表 2 1 3 1 2 3 1 2 2 2 我想要的是一个转换矩阵 它向我显示如下序列 1 后跟 1 的频率是多少 1 后面跟着 2 的频率是多少 1 后跟 3 的频率是多少 2 后跟 1 的频率是多少 2 后跟 2 的
  • 雅虎财务请求功能出现 404 客户端错误

    yahoo Financials的请求功能出现404 Client Error 直接点击以下网址没有问题 https finance yahoo com quote AAPL financials p AAPL https finance
  • 用 Python 绘制直方图

    我有两个列表 x 和 y x 包含字母表 A Z Y 包含它们在文件中的频率 我尝试研究如何在直方图中绘制这些值 但在理解如何绘制它方面没有成功 n bins patches plt hist x 26 normed 1 facecolor
  • Django 多对多关系(类别)

    我的目标是向我的 Post 模型添加类别 我希望以后能够按不同类别 有时是多个类别 查询所有帖子 模型 py class Category models Model categories 1 red 2 blue 3 black title
  • 查找与另一列 Pandas 中的唯一值关联的列中的值的交集

    如果我有一个像这样的数据框 非常小的例子 col1 col2 0 a 1 1 a 2 2 b 1 3 b 2 4 b 4 5 c 1 6 c 2 7 c 3 我想要所有的交集col2当价值观与其独特性相关时col1值 因此在这种情况下 交集
  • 高级描述熊猫

    有没有像 pandas 那样更高级的功能 通常我会继续这样 r pd DataFrame np random randn 1000 columns A r describe 我会得到一份很好的总结 就像这样 A count 1000 000
  • Seaborn 中没有线性拟合的散点图

    我想知道是否有办法关闭seaborn中的线性拟合lmplot或者是否有一个等效函数可以生成散点图 当然 我也可以使用 matplotlib 但是 我发现 seaborn 中的语法和美学非常吸引人 例如 我想绘制以下情节 import sea
  • 是否可以在Python中将日+月(不是年)与当前日+月进行比较?

    我正在获取 5 月 10 日 格式的数据 我试图弄清楚它是今年还是明年 该日期仅一年 因此 5 月 10 日表示 2015 年 5 月 10 日 而 5 月 20 日表示 2014 年 5 月 20 日 为此 我想将字符串转换为日期格式并进
  • 如何按 pandas 中的值对系列进行分组?

    我现在有一只熊猫Series与数据类型Timestamp 我想按日期对其进行分组 并且每组中有许多行具有不同的时间 看似显而易见的方法类似于 grouped s groupby lambda x x date 然而 熊猫的groupby按索
  • 从 wxPython 事件处理程序中调用函数

    我正在努力寻找一种在 wxPython 事件处理函数中使用函数的方法 假设我有一个按钮 单击该按钮时 它会使用事件处理程序运行一个名为 OnRun 的函数 但是 用户忘记单击 OnRun 按钮之前的 RadionButton 我想弹出一个
  • 如何展平解析树并存储在字符串中以进行进一步的字符串操作 python nltk

    我正在尝试从树结构中获取扁平树 如下所示 我想将整个树放在一个字符串中 就像没有检测到坏树错误一样 S NP SBJ NP DT The JJ high JJ seven day PP IN of NP DT the CD 400 NNS
  • Django 将 JSON 数据传递给静态 getJSON/Javascript

    我正在尝试从 models py 中获取数据并将其序列化为views py 中的 JSON 对象 模型 py class Platform models Model platformtype models CharField max len
  • pandas.read_fwf 忽略提供的数据类型

    我正在从文本文件导入数据框 我想指定列的数据类型 但 pandas 似乎忽略了dtype input 一个工作示例 from io import StringIO import pandas as pd string USAF WBAN S
  • 如何同时接受int和float类型的输入?

    我正在制作一个货币转换器 如何让 python 同时接受整数和浮点数 我就是这样做的 def aud brl amount From to ER 0 42108 if amount int if From strip aud and to
  • 基于值的 matplotlib 条形图颜色

    有没有一种方法可以根据条形图的值对条形图的条形进行着色 例如 values below 0 5 red values between 0 5 to 0 green values between 0 to 08 blue etc 我找到了一些
  • Biopython 可以执行 Seq.find() 来解释歧义代码吗

    我希望能够在 Seq 对象中搜索考虑歧义代码的子序列 Seq 对象 例如 以下内容应该是正确的 from Bio Seq import Seq from Bio Alphabet IUPAC import IUPACAmbiguousDNA

随机推荐

  • [Transformer]CSWin Transformer: A General Vision Transformer Backbone with Cross-Shaped Windows

    CSWin Transformer 基于交叉十字形窗口的视觉Transformer框架 Abstract Section I Introduction Section II Related Work Section III Method P
  • 使用数字滤波器处理音频噪声(附Matlab程序)

    本篇文章主要介绍使用窗函数法构造FIR数字滤波器 并且滤除音频文件的噪声 以下为完整的程序 修改一下文件的位置 直接复制应该就可以 1 音频文件的采集与分析 Matlab输入的音频文件需要 wav 文件 可以使用一些软件转换格式 例如酷狗音
  • C#音频采集 (笔记)

    using System using System Collections Generic using System Text using System IO using System Threading using Microsoft D
  • Effective C++第七章-模板和泛型编程之模板特化和代码膨胀

    模板特化 class A public void func1 void func2 class B public void func1 void func2 template
  • 用JS的canvas实现数字签名

    用JS的canvas实现数字签名 思路 先创建画布 鼠标按下 同时随着鼠标的移动来绘制签名 最后鼠标松开绘制结束 直接上代码啦
  • electron 1. hello world

    cnpm init y cnpm i electron D 安装electron package json name news windows version 1 0 0 description main main js scripts t
  • 爬取电影天堂

    电影天堂爬虫之网页分析 from lxml import etree import requests BASE DOMAIN http www ygdy8 net url http www ygdy8 net html gndy dyzz
  • java中的sleep()和wait()的区别

    对于sleep 方法 我们首先要知道该方法是属于Thread类中的 而wait 方法 则是属于Object类中的 sleep 方法导致了程序暂停执行指定的时间 让出cpu该其他线程 但是他的监控状态依然保持者 当指定的时间到了又会自动恢复运
  • Java中的桥接模式(Bridge Pattern)

    Java中的桥接模式 Bridge Pattern Java中的桥接模式 Bridge Pattern 是一种结构性设计模式 它将抽象部分和实现部分分离 使它们可以独立变化 同时通过桥接对象将它们连接起来 桥接模式通过将继承关系转变为对象组
  • 简单了解Docker、Dubbo

    简单了解Docker Dubbo 以Docker为例的容器 Docker是什么 Docker的原理 以Dubbo为例的RPC调用框架 如何理解REST RPC Dubbo是什么 简单了解Docker Dubbo 以Docker为例的容器 D
  • 分号和逗号

    分号是语句的结束字符 逗号是声明变量时分割符 分号一般表示语句的终结 或者用来分隔for语句中的3段 逗号一般用来分隔先后两条子句 或在函数定义或调用中分隔参数 如 var i 0 j 2 for var k 0 k lt j k i i
  • 【华为OD机试真题】密室逃生游戏(python)100%通过率 超详细代码注释 代码优化

    华为OD机试真题 2022 2023 真题目录 点这里 华为OD机试真题 信号发射和接收 试读 点这里 华为OD机试真题 租车骑绿道 试读 点这里 密室逃生游戏 题目描述 小强正在参加 密室逃生 游戏 当前关卡要求找到符合给定 密码 K 升
  • 爬虫时如何利用BeautifulSoup获取我们需要的数据?

    爬虫大致可以分为三步 第一步 发送request请求获得html内容 第二步 清洗数据 即从html原网页数据中筛选我们需要的数据 第三步 将需要的数据储存 在第二步筛选数据是 我们往往可以利用BeautifulSoup来完成 下面就如何利
  • 数据结构:线性表(顺序存储)顺序表类(实现顺序表的创建,输出,插入,删除功能)

    线性表顺序存储一般就是以数组的形式存储 一切都是对数组的操作 下面给出一个类定义的头文件 和一个实例 顺序表类 文件名 sq LList h include
  • jquery.入口函数_5个jQuery.each()函数示例

    jquery 入口函数 这是jQuery each 函数的广泛概述 此函数是jQuery最重要和最常用的函数之一 在本文中 我们将找出原因 并看看如何使用它 什么是jQuery each jQuery的each 函数用于遍历目标jQuery
  • python的class(类)中的object是什么意思?

    那写object和不写object有什么区别 好的 再用代码来理解它们的区别 coding utf 8 author zhengtong class Person 不带object name zhengtong class Animal o
  • 教女朋友一周学会 python 爬虫_1

    今天开始我将简单介绍一下网络爬虫 并开始带大家学习如何写爬虫 一 爬虫介绍 1 什么是爬虫 你可以把互联网想想成一个巨大的蜘蛛网 而爬虫就是一个小蜘蛛在网的各个节点中穿梭 就像探测机器一样 基本操作就是模拟人去浏览各个网站 浏览数据 查看信
  • 图像识别检测题(1)

    1 下列关于神经网络训练 错误说法是 A 激活函数的选择不会影响网络训练的结果 B 我们经常会使用Xavier初始化方法初始化网络权重 C batch size太小 训练loss震荡可能会比较大 D Adam是一种常用的优化算法 2 下面可
  • PBR:应用于虚幻引擎4贴图和材质创建的启示

    PBR 应用于虚幻引擎4贴图和材质创建的启示 Li Wen Lei HuNing 在 2015 10 28 23 00 31 新闻 Share on Facebook Share on Twitter Share on Google Sha
  • python实现最大熵模型

    本文参考nltk MaxentClassifier实现了一个简单的最大熵模型 主要用于理解最大熵模型中一些数学公式的实际含义 最大熵模型 Pw y x Zw x 1Zw x exp i 1nwifi x y yexp i 1nwifi x