【原创】cython and python for kenlm
未经允许不可转载
Kenlm相关知识
Kenlm下载地址
kenlm中文版本训练语言模型
如何使用kenlm训练出来的模型C++版本
关于Kenlm模块的使用及C++源码说明
加载Kenlm模块命令
qy@IAT-QYVPN:~/Documents/kenlm/lm$ ../bin/query -n test.arpa
Kenlm模块C++源码说明
query的主入口文件:query_main.cc
query的执行函数文件:ngram_query.hh
注意:
默认执行的是query_main.cc文件96行的
Query<ProbingModel>(file, config, sentence_context, show_words);
而不是lm/wrappers/nplm.hh,这个封装文件是需要NPLM模块的,参考以下代码,当时疏忽了在这个地方耽误了一些时间
#ifdef WITH_NPLM
} else if (lm::np::Model::Recognize(file)) {
lm::np::Model model(file);
if (show_words) {
Query<lm::np::Model, lm::ngram::FullPrint>(model, sentence_context);
} else {
Query<lm::np::Model, lm::ngram::BasicPrint>(model, sentence_context);
}
#endif
关于Model类的继承关系
- 最基类
virtual_interface.hhlm::base::Model- 次基类
facade.hhlm::base::ModelFacade : public Model- 子类
model.hhlm::ngram::GenericModel : public base::ModelFacade<GenericModel<Search, VocabularyT>, State, VocabularyT>
关于cython的简单说明
cython官网
可以从官网下载最新版本,参考Documentation分类中的Cython Wiki和Cython FAQ了解一些知识。
cython-cpp-test-sample
Wrapping C++ Classes in Cython
cython wrapping of base and derived class
std::string arguments in cython
Cython and constructors of classes
Cython基础--Cython入门
kenlm的python模块封装
接下来,让我们进入正题,在kenlm的源码中实际上已经提供了python的应用。在kenlm/python文件夹中,那么为什么还要再封装python模块呢,因为kenlm中所带的python模块仅仅实现了包含<s>和</s>这种情况下的计算分数的方法,而没有提供不包含这种情况的计算分数的算法,这就是为什么要重新封装python模块的原因。
简单介绍一下python模块使用的必要步骤
- 安装kenlm.so模块到python的目录下,默认直接运行
kenlm目录下的setup.py文件即可安装成功sudo python setup.py install --record log。- 安装成功后,即可运行
python example.py文件,查看运行结果。
如何扩展kenlm的python模块
接下来,正式进入python扩展模块的介绍。kenlm.pxd是cython针对所用到C++类及对象的声明文件,kenlm.pyx是真正要编写的cython功能代码,也是未来python所要调用的类及方法。使用cython的编译命令,可以把kenlm.pxd和kenlm.pyx编译出kenlm.cpp文件。setup.py文件会用到编译出来的kenlm.cpp文件。
- cython编译命令
cython --cplus kenlm.pyx
扩展后的kenlm.pxd文件
from libcpp.string cimport string
cdef extern from "lm/word_index.hh":
ctypedef unsigned WordIndex
cdef extern from "lm/return.hh" namespace "lm":
cdef struct FullScoreReturn:
float prob
unsigned char ngram_length
cdef extern from "lm/state.hh" namespace "lm::ngram":
cdef struct State:
pass
ctypedef State const_State "const lm::ngram::State"
cdef extern from "lm/virtual_interface.hh" namespace "lm::base":
cdef cppclass Vocabulary:
WordIndex Index(char*)
WordIndex BeginSentence()
WordIndex EndSentence()
WordIndex NotFound()
ctypedef Vocabulary const_Vocabulary "const lm::base::Vocabulary"
cdef extern from "lm/model.hh" namespace "lm::ngram":
cdef cppclass Model:
const_Vocabulary& GetVocabulary()
const_State& NullContextState()
void Model(char* file)
FullScoreReturn FullScore(const_State& in_state, WordIndex new_word, const_State& out_state)
void BeginSentenceWrite(void *)
void NullContextWrite(void *)
unsigned int Order()
const_Vocabulary& BaseVocabulary()
float BaseScore(void *in_state, WordIndex new_word, void *out_state)
FullScoreReturn BaseFullScore(void *in_state, WordIndex new_word, void *out_state)
void * NullContextMemory()
扩展后的kenlm.pyx文件
import os
cdef bytes as_str(data):
if isinstance(data, bytes):
return data
elif isinstance(data, unicode):
return data.encode('utf8')
raise TypeError('Cannot convert %s to string' % type(data))
cdef int as_in(int &Num):
(&Num)[0] = 1
cdef class LanguageModel:
cdef Model* model
cdef public bytes path
cdef const_Vocabulary* vocab
def __init__(self, path):
self.path = os.path.abspath(as_str(path))
try:
self.model = new Model(self.path)
except RuntimeError as exception:
exception_message = str(exception).replace('\n', ' ')
raise IOError('Cannot read model \'{}\' ({})'.format(path, exception_message))\
from exception
self.vocab = &self.model.GetVocabulary()
def __dealloc__(self):
del self.model
property order:
def __get__(self):
return self.model.Order()
def score(self, sentence):
cdef list words = as_str(sentence).split()
cdef State state
self.model.BeginSentenceWrite(&state)
cdef State out_state
cdef float total = 0
for word in words:
total += self.model.BaseScore(&state, self.vocab.Index(word), &out_state)
state = out_state
total += self.model.BaseScore(&state, self.vocab.EndSentence(), &out_state)
return total
def full_scores(self, sentence):
cdef list words = as_str(sentence).split()
cdef State state
self.model.BeginSentenceWrite(&state)
cdef State out_state
cdef FullScoreReturn ret
cdef float total = 0
for word in words:
ret = self.model.BaseFullScore(&state,
self.vocab.Index(word), &out_state)
yield (ret.prob, ret.ngram_length)
state = out_state
ret = self.model.BaseFullScore(&state,
self.vocab.EndSentence(), &out_state)
yield (ret.prob, ret.ngram_length)
def full_scores_n(self, sentence):
cdef list words = as_str(sentence).split()
cdef State state
state = self.model.NullContextState()
cdef State out_state
cdef FullScoreReturn ret
cdef int ovv = 0
for word in words:
ret = self.model.FullScore(state,
self.vocab.Index(word), out_state)
yield (ret.prob, ret.ngram_length)
state = out_state
"""""""""""
"""count scores when not included <s> and </s>"""
"""""""""""
def score_n(self, sentence):
cdef list words = as_str(sentence).split()
cdef State state
state = self.model.NullContextState()
cdef State out_state
cdef float total = 0
for word in words:
ret = self.model.FullScore(state,
self.vocab.Index(word), out_state)
total += ret.prob
"""print(total)"""
state = out_state
return total
def __contains__(self, word):
cdef bytes w = as_str(word)
return (self.vocab.Index(w) != 0)
def __repr__(self):
return '<LanguageModel from {0}>'.format(os.path.basename(self.path))
def __reduce__(self):
return (LanguageModel, (self.path,))
【原创】cython and python for kenlm的更多相关文章
- 用Cython加速Python程序以及包装C程序简单测试
用Cython加速Python程序 我没有拼错,就是Cython,C+Python=Cython! 我们来看看Cython的威力,先运行下边的程序: import time def fib(n): i ...
- 原创:用python把链接指向的网页直接生成图片的http服务及网站(含源码及思想)
原创:用python把链接指向的网页直接生成图片的http服务及网站(含源码及思想) 总体思想: 希望让调用方通过 http调用传入一个需要生成图片的网页链接生成一个网页的图片并返回图片链接 ...
- 用Cython加速Python代码
安装Cython pip install Cython 如何使用 要在我们的笔记本中使用Cython,我们将使用IPython magic命令.Magic命令以百分号开始,并提供一些额外的功能,这些功 ...
- Cython保护Python代码
注:.pyc也有一定的保护性,容易被反编译出源码... 项目发布时,为防止源码泄露,需要对源码进行一定的保护机制,本文使用Cython将.py文件转为.so进行保护.这一方法,虽仍能被反编译,但难度会 ...
- 利用Cython对python代码进行加密
利用Cython对python代码进行加密 Cython是属于PYTHON的超集,他首先会将PYTHON代码转化成C语言代码,然后通过c编译器生成可执行文件.优势:资源丰富,适合快速开发.翻译成C后速 ...
- 使用cython把python编译so
1.需求 为了保证线上代码安全和效率,使用python编写代码,pyc可直接反编译,于是把重要代码编译so文件 2.工作 2.1 安装相关库: pip install cython yum insta ...
- 用cython提升python的性能
Boosting performance with Cython Even with my old pc (AMD Athlon II, 3GB ram), I seldom run into ...
- 【原创分享】python获取乌云最新提交的漏洞,邮件发送
#!/usr/bin/env python # coding:utf-8 # @Date : 2016年4月21日 15:08:44 # @Author : sevck (sevck@jdsec.co ...
- [原创博文] 用Python做统计分析 (Scipy.stats的文档)
[转自] 用Python做统计分析 (Scipy.stats的文档) 对scipy.stats的详细介绍: 这个文档说了以下内容,对python如何做统计分析感兴趣的人可以看看,毕竟Python的库也 ...
随机推荐
- 简述FPGA项目之前的一些事
FPGA的设计是一个系统工程,是一种道,会编程会仿真会调试可能更多是一种术.很多这方面的书籍,写什么自顶向下之类的很多,还是停留在方法学上,而对于一个公司的项目来说,FPGA的设计是从立项开始的. 拿 ...
- centos初始化安装
1.yum 安装 nginx rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6. ...
- java多线程(2) 线程同步
我们对线程访问同一份资源的多个线程之间,来进行协调的这个东西,就是线程同步. 例子1:模拟了多个线程操作同一份资源,可能带来的问题: package com.cy.thread; public c ...
- Java 输入一个整数,计算它各位上数字的和。(注意:是任意位的整数)
import java.util.*; /* * 输入一个整数,计算它各位上数字的和. * (注意:是任意位的整数) */ public class Sum02 { public static voi ...
- HTC8X V版 电信上网方法
原始V版电信上网设置,转自百度贴吧(http://tieba.baidu.com/p/3224177802). 修改SIM卡设置 修改MIP_MODE 转自贴吧:http://tieba.baidu. ...
- Hessian简要入门
原本系统之间通信采用Restful Web Service,但其中没有考虑安全性问题,因此决定使用稍微复杂点的二进制协议,Hessian服务. Hessian是一个轻量级的Remoting O ...
- 一些通用的触发移动App崩溃的测试场景
一些通用的触发移动App崩溃的测试场景,如下: 1 验证在有不同的屏幕分辨率,操作系统和运营商的多个设备上的App行为. 2 用新发布的操作系统版本验证App的行为. 3 验证在如隧道,电梯等网络质量 ...
- CentOS 修改源为163和指定epel源和docker安装
首先备份/etc/yum.repos.d/CentOS-Base.repo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-B ...
- Android 4 学习(20):ActionBar
参考<Pro Android 4.0> ActionBar 11.0之后,ActionBar在Activity中默认存在,可以在代码中设置其显示与否: ActionBar actionBa ...
- 跟着太白老师学python day10 函数嵌套, global , nonlocal
函数嵌套: 第一种嵌套方法 def func(): count = 123 def inner(): print(count) inner() func() 第二种嵌套方法 count = 123 d ...