LangSC 使用手册
LangSC(Language Structure Computation)是一个统一的 Python 开发包,集成了自然语言结构分析(GPF)、语料库查询(BCC)和 JSON 结构检索(JSS)三大功能。
当前版本:1.0.6
目录
- 1. 概述
- 2. 安装与配置
- 3. 快速上手
- 4. GPF 类 — 自然语言结构分析
- 5. BCC 类 — 语料库查询
- 6. JSS 类 — JSON 结构检索
- 7. 完整示例
- 8. 数据文件格式说明
- 9. 平台与依赖
- 10. 参考文献
1. 概述
LangSC 包含三个相互独立的核心类:
| 类 | 功能 | 底层库 | 索引日志 |
|---|---|---|---|
| GPF | 基于网格(Lattice/Grid)的自然语言结构分析框架,支持分词、词性标注、句法分析、FSA 规则匹配、数据表查询和可视化 | gpflib |
IdxLog_GPF.txt |
| BCC | 语料库查询引擎,支持词频统计、上下文检索、计数查询和语料索引 | bcclib |
IdxLog_BCC.txt |
| JSS | JSON 结构化数据检索引擎,支持 SQL 风格查询、多表管理和自动建索引 | jsslib |
IdxLog_JSS.txt |
三个类相互独立,按需导入即可,不会加载多余的动态库。例如只使用 JSS 时,不会加载 gpflib 和 bcclib。
架构设计
LangSC/
├── __init__.py # 导出 GPF, BCC, JSS, __version__
├── __version__.py # 版本号(VERSION = (1, 0, 6))
├── _utils.py # 共享工具函数(编码检测、索引日志管理等)
├── gpf.py # GPF 类(封装 gpflib)
├── bcc.py # BCC 类(封装 bcclib)
├── jss.py # JSS 类(封装 jsslib)
├── gpflib.dll / libgpflib.so / libgpflib.dylib
├── bcclib.dll / libbcclib.so / libbcclib.dylib
├── jsslib.dll / libjsslib.so / libjsslib.dylib
├── GPFconfig.txt # GPF 引擎配置
├── BCCconfig.txt # BCC 引擎配置
├── Parser.lua # Lua 查询解析脚本
├── Segment.dat # CRF 分词模型
├── idxPOS.dat # 词性标注数据
├── base.lex # 分词词典(JSS 用)
└── Graph/ # Graphviz 工具(Windows 下自带 dot.exe)
2. 安装与配置
2.1 安装
pip install LangSC
2.2 依赖
| 依赖包 | 用途 | 说明 |
|---|---|---|
pywin32 |
Windows DLL 内存释放 | 仅 Windows 平台自动安装 |
wordcloud |
词云可视化 | GPF 的 ShowCloud 方法使用 |
requests |
HTTP 请求 | GPF 远程句法分析和 Dot 服务使用 |
chardet |
文件编码自动检测 | 全部三个类的文件编码检测使用 |
2.3 系统要求
- Python >= 3.6
- 操作系统:Windows、Linux、macOS
2.4 版本查询
import LangSC
print(LangSC.__version__) # "1.0.6"
3. 快速上手
GPF:句法分析与可视化
from LangSC import GPF
import json
gpf = GPF()
# 句法树分析(远程服务)
text = "中欧班列持续稳定开行,夯实了亚欧大陆互联互通的基础"
js = gpf.Parse(text, Structure="Tree")
gpf.ShowStructure(js, "Dep.png")
BCC:语料库查询
from LangSC import BCC
bcc = BCC("Corpus")
ret = bcc.Run("喜欢{}", Command="Context", PageNo=0, WinSize=30, Number=10)
print(ret)
JSS:JSON 数据检索
from LangSC import JSS
jss = JSS("json")
ret = jss.Run('SELECT * FROM pinyin WHERE PinYin ="da1"')
print(ret)
4. GPF 类 — 自然语言结构分析
GPF(Grid-based Parsing Framework)提供基于网格的自然语言结构分析能力。核心数据结构是网格(Grid/Lattice),其中包含语言单元(Unit)和关系(Relation),支持文本分析、规则匹配、词表查询和结构可视化。
4.1 构造函数
from LangSC import GPF
gpf = GPF(dataPath="./data")
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
dataPath |
str |
"./data" |
数据目录路径,包含 Table 和 FSA 文件 |
说明
- 构造时自动初始化 GPF 网格句柄和 CRF/POS 句柄
- 自动加载 CRF 分词模型(
Segment.dat)和词性标注数据(idxPOS.dat) - 自动检测数据目录状态并执行索引(详见 4.2)
dataPath中的反斜杠会自动转换为正斜杠
4.2 自动索引机制
构造函数调用 _init_gpf_data(dataPath) 自动处理数据索引:
- 检查
dataPath中是否存在IdxLog_GPF.txt索引日志 - 若存在:已是索引目录,直接使用
- 若不存在:视为原始数据目录
- 扫描目录下的 Table 和 FSA 文件
- 创建
dataPathIdx/索引目录 - 逐一索引 Table 和 FSA 文件,并记录到
IdxLog_GPF.txt
- 通过文件时间戳比较,避免重复索引
索引完成后,
self.dataPath指向实际的索引目录路径。
4.3 NLP 分析
Segment(text, table="")
对文本执行 CRF 分词。
result = gpf.Segment("自然语言处理是人工智能的重要方向")
# 返回: "自然 语言 处理 是 人工 智能 的 重要 方向"
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
text |
str |
(必填) | 待分词文本 |
table |
str |
"" |
用户词表名称。为空使用 CRF 模型分词;指定时使用用户词表辅助分词 |
返回值:str,以空格分隔的分词结果。
POS(text, table="")
对文本执行词性标注(先分词,再标注)。
result = gpf.POS("自然语言处理是人工智能的重要方向")
# 返回: "自然/b 语言/n 处理/v 是/v 人工/b 智能/n 的/u 重要/a 方向/n"
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
text |
str |
(必填) | 待标注文本 |
table |
str |
"" |
用户词表名称 |
返回值:str,格式为 词/词性 以空格分隔。
Parse(text, **Others)
统一解析接口,根据 Structure 参数调用不同的解析方式。
# 分词
result = gpf.Parse("自然语言处理", Structure="Segment")
# 词性标注(默认)
result = gpf.Parse("自然语言处理", Structure="POS")
# 句法树(远程服务 https://cit.blcu.edu.cn/stree)
result = gpf.Parse("自然语言处理", Structure="Tree")
# 短语分析(远程服务 https://cit.blcu.edu.cn/chunk/)
result = gpf.Parse("自然语言处理", Structure="Chunk")
# 依存分析(远程服务 https://cit.blcu.edu.cn/dep)
result = gpf.Parse("自然语言处理", Structure="Dep")
# 指定用户词表
result = gpf.Parse("自然语言处理", Structure="Segment", Table="myDict")
# 通过 Web 服务解析
result = gpf.Parse("自然语言处理", Structure="POS", Web=True)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
text |
str |
(必填) | 待解析文本(自动截断至 1024 字符) |
Structure |
str |
"POS" |
解析类型:"Segment" / "POS" / "Tree" / "Chunk" / "Dep" |
Web / IsWeb |
bool |
False |
是否通过 Web 服务解析 |
Table |
str |
"" |
用户词表名称 |
返回值:str,JSON 格式字符串。
Segment:["词1", "词2", ...]POS:["词1/POS1", "词2/POS2", ...]Tree/Chunk/Dep:远程服务返回的 JSON 结构
示例(Demo/GPF2.py):
from LangSC import GPF
import json
gpf = GPF()
Txt = "中欧班列持续稳定开行,夯实了亚欧大陆互联互通的基础"
js = gpf.Parse(Txt, Structure="Tree")
gpf.ShowStructure(js, "Dep.png")
4.4 文本与网格操作
GPF 的核心数据结构是网格(Grid),网格承载文本、Unit 和 Relation。
SetText(text) / SetGridText(text)
设置网格的文本内容。SetGridText 额外执行 GPFInit() 初始化。
gpf.SetText("今天天气很好")
gpf.SetGridText("今天天气很好") # 等价,额外调用 GPFInit
返回值:int,操作状态码。
GetText(begin=0, end=-1) / GetGridText(begin=0, end=-1)
获取网格中的文本。
text = gpf.GetText() # 获取全部文本
text = gpf.GetText(0, 3) # 获取位置 0 到 3 的文本
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
begin |
int |
0 |
起始位置 |
end |
int |
-1 |
结束位置(-1 表示全部) |
返回值:str。
GetGrid() / GetStructure()
获取完整的网格结构。
grid = gpf.GetGrid()
返回值:list,网格结构的 JSON 对象。网格为空时返回 {}。
网格是一个二维结构,返回值为列(Column)的列表,每列包含若干 Unit 编号。
4.5 Unit 操作
Unit 是网格中的基本语言单元,对应一个词或短语,具有位置信息和键值属性。Unit 编号的格式为 "(起始位置,结束位置)",如 "(0,2)"。
AddUnit(text, colNo=-1)
向网格添加 Unit。
unitNo = gpf.AddUnit("天气") # 自动定位
unitNo = gpf.AddUnit("天气", colNo=3) # 指定结束位置(字符位置)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
text |
str |
(必填) | Unit 的文本内容 |
colNo |
int |
-1 |
结束字符位置。-1 时自动查找文本位置 |
返回值:str,Unit 编号(如 "(0,2)")。
示例(Demo/GPF4.py):
from LangSC import GPF
gpf = GPF()
Text = "孩子们都吃撑了"
gpf.SetText(Text)
Child = gpf.AddUnit("孩子们", 2)
All = gpf.AddUnit("都", 3)
Eat = gpf.AddUnit("吃", 4)
Full = gpf.AddUnit("撑了", 6)
AddUnitKV(unitNo, key, val)
为 Unit 添加键值属性。
gpf.AddUnitKV(unitNo, "POS", "n") # 添加词性
gpf.AddUnitKV(unitNo, "Tag", "人名;地名") # 多值用分隔符
| 参数 | 类型 | 说明 |
|---|---|---|
unitNo |
str |
Unit 编号 |
key |
str |
属性名 |
val |
str |
属性值。支持以空格、分号、逗号、制表符分隔的多值,每个值分别添加 |
返回值:int,固定返回 1。
GetWord(unitNo)
获取 Unit 的文本内容。
word = gpf.GetWord(unitNo) # 例如 "天气"
返回值:str。
GetUnit(kv, UnitNo="", UExpress="")
按条件查找 Unit。当参数为整数时,按 FSA 路径号获取。
units = gpf.GetUnit("POS=n") # 查找所有词性为 n 的 Unit
unit = gpf.GetUnit(0) # 按 FSA 路径号获取(整数参数)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
kv |
str 或 int |
(必填) | 查询条件(如 "POS=n")或 FSA 路径号 |
UnitNo |
str |
"" |
限定在某个 Unit 范围内查找 |
UExpress |
str |
"" |
Unit 表达式 |
返回值:条件查找时返回 list / dict(无匹配返回 0);路径号查找时返回 str。
GetUnitKV(unitNo, key="")
获取 Unit 的属性值。别名:GetUnitKVs。
kvs = gpf.GetUnitKV(unitNo) # 获取全部属性 → dict
word = gpf.GetUnitKV(unitNo, "Word") # 获取文本 → str
pos = gpf.GetUnitKV(unitNo, "From") # 获取起始位置 → int
vals = gpf.GetUnitKV(unitNo, "POS") # 获取指定属性 → list
返回值:
key 值 |
返回类型 | 说明 |
|---|---|---|
"" |
dict |
全部属性键值对 |
"Word" / "HeadWord" |
str |
文本(无匹配返回 "") |
"From" / "To" |
int |
位置(无匹配返回 -1) |
| 其他 | list |
属性值列表 |
IsUnit(unitNo, kv)
判断 Unit 是否具有指定属性。
ret = gpf.IsUnit(unitNo, "POS=n") # 判断词性是否为 n
ret = gpf.IsUnit(unitNo, "Type=Word") # 判断类型
返回值:int,匹配返回非零值,不匹配返回 0。
4.6 Relation 操作
Relation 表示两个 Unit 之间的有向关系(如主谓、动宾等)。
AddRelation(unitNo1, unitNo2, role)
添加关系。
gpf.AddRelation(Eat, Child, "sbj") # 吃 → 孩子们,关系为 sbj(主语)
| 参数 | 类型 | 说明 |
|---|---|---|
unitNo1 |
str |
源 Unit 编号 |
unitNo2 |
str |
目标 Unit 编号 |
role |
str |
关系类型 |
返回值:int,固定返回 1。
AddRelationKV(unitNo1, unitNo2, role, key, val)
为关系添加键值属性。
gpf.AddRelationKV(Full, Child, "sbj", "K1", "V1")
返回值:int,固定返回 1。
GetRelation(kv="") / GetRelations(kv="")
获取关系列表。
rels = gpf.GetRelation() # 获取全部关系
返回值:list,每个元素为 [unitNo1, unitNo2, role] 三元组。无关系返回 []。
GetRelationKV(unitNo1, unitNo2, role, key="")
获取关系属性。别名:GetRelationKVs。
kvs = gpf.GetRelationKV(r[0], r[1], r[2]) # 全部属性
kvs = gpf.GetRelationKV(r[0], r[1], r[2], "K1") # 指定属性
返回值:dict。
IsRelation(unitNo1, unitNo2, role, kv="")
判断两个 Unit 之间是否存在指定关系。
ret = gpf.IsRelation(unitNo1, unitNo2, "sbj")
返回值:int,存在返回非零值。
示例(Demo/GPF4.py):
from LangSC import GPF
gpf = GPF()
Text = "孩子们都吃撑了"
gpf.SetText(Text)
Child = gpf.AddUnit("孩子们", 2)
All = gpf.AddUnit("都", 3)
Eat = gpf.AddUnit("吃", 4)
Full = gpf.AddUnit("撑了", 6)
gpf.AddUnitKV(Eat, "POS", "V")
gpf.AddUnitKV(Full, "POS", "V")
gpf.AddRelation(Eat, All, "mod")
gpf.AddRelation(Eat, Full, "mod")
gpf.AddRelation(Eat, Child, "sbj")
gpf.AddRelation(Full, Child, "sbj")
gpf.AddRelationKV(Full, Child, "sbj", "K1", "V1")
R = gpf.GetRelation()
for r in R:
print(r)
print(gpf.GetUnitKV(r[0], "Word"), gpf.GetUnitKV(r[1], "Word"), r[2])
KVs = gpf.GetRelationKV(r[0], r[1], r[2])
for K, Vs in KVs.items():
print(K)
4.7 Grid KV 操作
为整个网格(而非某个 Unit)添加/获取全局属性。
AddGridKV(key, val) / AddTextKV(key, val)
添加网格级属性。
gpf.AddGridKV("Author", "张三")
gpf.AddGridKV("URoot", unitNo) # 设置根节点
返回值:int,固定返回 0。
GetGridKV(key="") / GetGridKVs(key="") / GetTextKV(key="")
获取网格级属性。
kvs = gpf.GetGridKV() # 全部属性
kvs = gpf.GetGridKV("Author") # 指定属性
返回值:dict / list。
4.8 Table 操作
Table 是 GPF 的词表/数据表系统,支持键值查询、前后缀匹配等操作。Table 文件以 Table <表名> 开头(格式见 8.1)。
SetTable(tableName)
设置当前活跃的数据表。
gpf.SetTable("CiDian")
CallTable(tableName, Mode=0)
加载并设置数据表。内部先调用 GPF_AppLexicon 加载,再调用 GPF_SetLexicon 设为当前表。
gpf.CallTable("CiDian")
GetTable()
获取所有已加载的表名。
tables = gpf.GetTable()
返回值:dict。
GetTableItem(tableName="", kv="") / GetItem(tableName="", kv="")
获取表中的条目列表。
items = gpf.GetTableItem("CiDian") # 全部条目
items = gpf.GetTableItem("CiDian", "POS=n") # 按条件过滤
GetTableItems(tableName, kv="")
获取指定表的条目列表。
items = gpf.GetTableItems("CiDian", "POS=n")
返回值:dict / list。
GetTableItemKV(tableName, item="", key="") / GetItemKV(...) / GetTableItemKVs(...)
获取表中某条目的属性。
kvs = gpf.GetTableItemKV("CiDian", "天气") # 全部属性
kvs = gpf.GetTableItemKVs("CiDian", "天气", "POS") # 指定属性
返回值:dict / list。
IsTable(tableName, item="", kv="")
判断表/条目/属性是否存在。
ret = gpf.IsTable("CiDian") # 判断表是否存在
ret = gpf.IsTable("CiDian", "天气") # 判断条目是否存在
ret = gpf.IsTable("CiDian", "天气", "POS=n") # 判断属性是否匹配
返回值:int,存在返回非零值。
GetSuffix(tableName, sentence) / GetPrefix(tableName, sentence)
后缀/前缀匹配。
suffix = gpf.GetSuffix("CiDian", "今天天气很好")
prefix = gpf.GetPrefix("CiDian", "今天天气很好")
返回值:str。
4.9 FSA 操作
FSA 是 GPF 的规则引擎,支持基于有限状态自动机的模式匹配和规则执行。
CallFSA(fsaName, **Others) / RunFSA(fsaName, param="")
执行 FSA 规则。关键字参数自动拼接为 "Key1=Val1;Key2=Val2" 格式传入。
gpf.CallFSA("myRule", Param1="val1", Param2="val2")
gpf.RunFSA("myRule") # 等价于 CallFSA("myRule")
返回值:int,FSA 执行结果长度。
说明:FSA 匹配成功后,会通过 exec() 执行规则中嵌入的 Python 代码。
GetFSAParam(key) / GetParam(key)
获取 FSA 参数。
val = gpf.GetParam("Result")
返回值:str。
GetFSANode(tag="-1") / GetNode(tag)
获取 FSA 节点。
pathNo = gpf.GetNode(0) # 支持整数和字符串参数
返回值:int,路径号。
4.10 索引创建
IndexTable(table_filename)
索引 Table 文件。索引后自动重新加载配置。若存在搭配关系(Collocation),会递归索引搭配表。
gpf.IndexTable("./data/myTable.txt")
返回值:若存在搭配信息返回 dict,否则返回 0。
IndexFSA(rule_filename)
索引 FSA 规则文件。索引后自动重新加载配置。
gpf.IndexFSA("./data/myRule.txt")
返回值:int,操作状态码。
4.11 结构添加
将 JSON 格式的语言结构数据添加到当前网格中。
AddStructure(json_str) / AddGrid(json_str) / AddGridJS(json_str)
添加结构,自动识别类型:
- 若 JSON 包含
"Type"字段:直接调用底层GPF_AddStructure - 否则根据 JSON 结构自动识别为 Graph / Seq / Tree
gpf.AddStructure(json_str)
AddSeq(json_str)
添加序列结构(分词/词性结果)。
# 字符串列表
gpf.AddSeq('["自然/b", "语言/n", "处理/v"]')
# 字典列表(带属性)
gpf.AddSeq('[{"自然": {"POS": "b"}}, {"语言": {"POS": "n"}}]')
示例(Demo/GPF5.py):
from LangSC import GPF
gpf = GPF()
Text = "我们大家很辛苦"
gpf.SetText(Text)
gpf.AddStructure('["我们","大家","很","辛苦"]')
gpf.AddStructure('["我们","大家","很辛苦"]')
gpf.ShowGrid()
Grid = gpf.GetGrid()
for Col in Grid:
for Unit in Col:
print(Unit, gpf.GetUnitKV(Unit, "Word"))
AddTree(json_str)
添加树结构。
gpf.AddTree('{"S": ["NP", {"VP": ["V", "NP"]}]}')
AddGraph(json_str)
添加图结构。
# 三元组列表:[源, 目标, 关系]
gpf.AddGraph('[["喜欢", "我", "SBJ"], ["喜欢", "北京", "OBJ"]]')
# 字典格式:{源: {关系: 目标}}
gpf.AddGraph('{"喜欢": {"SBJ": "我", "OBJ": "北京"}}')
4.12 可视化
GPF 提供多种可视化方法,通过 Graphviz 的 dot 工具生成 PNG 图片。
Show(Json="", **Others)
统一可视化接口。
gpf.Show() # 显示当前网格
gpf.Show(Json=json_str) # 显示 JSON 结构
gpf.Show(Output="output.png") # 指定输出文件
gpf.Show(Relation=True) # 显示关系
gpf.Show(Grid=False, Relation=True) # 只显示关系
gpf.Show(Unit=unitNo) # 显示单个 Unit 详情
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
Json |
str |
"" |
JSON 结构数据 |
Output |
str |
"./gpf.png" |
输出图片路径 |
Relation / IsShowRelation |
bool |
False |
是否显示关系 |
Grid / IsShowGrid |
bool |
True |
是否显示网格 |
Unit |
str |
"" |
显示指定 Unit 的详情 |
ShowStructure(Json="", Img="./gpf.png")
显示结构,自动识别类型(Graph / Seq / Tree / Set / GPFStruct)并调用对应方法。
gpf.ShowStructure(json_str, "output.png")
ShowGrid(Img="./gpf.png", IsShowRel=False, IsShowGrid=True)
显示网格结构。Unit 按类型着色:
| 类型 | 颜色 |
|---|---|
Type=Char |
灰色 |
Type=Word |
绿色 |
Type=Phrase |
浅蓝色 |
Type=Chunk |
金色 |
gpf.ShowGrid("output.png") # 仅网格
gpf.ShowGrid("output.png", IsShowRel=True) # 网格 + 关系
gpf.ShowGrid("output.png", IsShowRel=True, IsShowGrid=False) # 仅关系
ShowRelation(Img="./gpf.png")
显示关系图。等价于 ShowGrid(Img, IsShowRel=True, IsShowGrid=True)。
gpf.ShowRelation("relations.png")
示例(Demo/GPF3.py):
from LangSC import GPF
import json
Line = """
{"Words": ["瑞士", "率先", "破门", ",", "沙其理", "梅开二度", "。"],
"Tags": ["ns", "d", "v", "w", "nr", "i", "w"],
"Relations": [{"U1": 2, "U2":0,"R":"A0","KV":"KV1"},
{"U1": 2, "U2":1,"R":"Mod","KV":"KV2"},
{"U1": 5, "U2":4,"R":"A0","KV":"KV3"}]}"""
S = json.loads(Line)
Txt = "".join(S["Words"])
gpf = GPF()
gpf.SetText(Txt)
ColNo = 0
Units = []
for i in range(len(S["Words"])):
UnitNo = gpf.AddUnit(S["Words"][i], ColNo + len(S["Words"][i]) - 1)
Units.append(UnitNo)
gpf.AddUnitKV(UnitNo, "POS", S["Tags"][i])
ColNo += len(S["Words"][i])
for R in S["Relations"]:
gpf.AddRelation(Units[R["U1"]], Units[R["U2"]], R["R"])
gpf.ShowRelation("r.png")
ShowUnit(Unit, Img="./gpf.png")
显示单个 Unit 的属性详情图。
gpf.ShowUnit(unitNo, "unit_detail.png")
ShowTree(Json) / ShowSeq(Json) / ShowGraph(Json)
返回 Graphviz DOT 脚本字符串(不直接生成文件)。
dot = gpf.ShowTree(json_str) # 树结构 DOT(自上而下)
dot = gpf.ShowSeq(json_str) # 序列结构 DOT(从左到右)
dot = gpf.ShowGraph(json_str) # 图结构 DOT
返回值:str,DOT 脚本。
ShowCloud(Json, Output)
生成词云图片。
gpf.ShowCloud('{"自然": 10, "语言": 8, "处理": 6}', "cloud.png")
| 参数 | 类型 | 说明 |
|---|---|---|
Json |
str |
JSON 格式词频数据 {"词": 频率, ...} |
Output |
str |
输出图片路径 |
4.13 服务调用与 Dot
CallService(sentence, name)
调用远程服务进行文本解析。
result = gpf.CallService("自然语言处理", "Tree")
返回值:str,JSON 字符串。
Dot2Img(Dot, name)
将 Dot 脚本转换为图片(通过 DLL)。
返回值:bytes,图片数据。
DotFile(dot_filename, img_filename)
将 Dot 文件通过远程服务转换为图片文件。
返回值:bool。
DotBuff(dot_data, img_filename)
将 Dot 字符串通过远程服务转换为图片文件。
返回值:bool。
4.14 其他方法
GetLog()
获取 GPF 日志。
返回值:dict。
Reduce(From=0, To=-1, Head=-1)
归约操作,将指定范围的 Unit 归约为一个新 Unit。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
From |
int |
0 |
归约起始位置 |
To |
int |
-1 |
归约结束位置 |
Head |
int |
-1 |
中心词的 FSA 路径号 |
返回值:str,新 Unit 编号。
GPFInit()
手动初始化 GPF 数据(线程安全)。通常无需显式调用。
4.15 GPF 方法速查表
| 分类 | 方法 | 说明 |
|---|---|---|
| NLP | Segment(text, table) |
CRF 分词 |
POS(text, table) |
词性标注 | |
Parse(text, **Others) |
统一解析接口 | |
| 文本/网格 | SetText(text) / SetGridText(text) |
设置文本 |
GetText(begin, end) / GetGridText(begin, end) |
获取文本 | |
GetGrid() / GetStructure() |
获取网格 | |
| Unit | AddUnit(text, colNo) |
添加 Unit |
AddUnitKV(unitNo, key, val) |
添加 Unit 属性 | |
GetWord(unitNo) |
获取 Unit 文本 | |
GetUnit(kv, UnitNo, UExpress) |
查找 Unit | |
GetUnitKV(unitNo, key) |
获取 Unit 属性 | |
IsUnit(unitNo, kv) |
判断 Unit 属性 | |
| Relation | AddRelation(u1, u2, role) |
添加关系 |
AddRelationKV(u1, u2, role, key, val) |
添加关系属性 | |
GetRelation(kv) |
获取关系列表 | |
GetRelationKV(u1, u2, role, key) |
获取关系属性 | |
IsRelation(u1, u2, role, kv) |
判断关系 | |
| Grid KV | AddGridKV(key, val) / AddTextKV(key, val) |
添加网格属性 |
GetGridKV(key) / GetTextKV(key) |
获取网格属性 | |
| Table | SetTable(tableName) |
设置当前表 |
CallTable(tableName) |
加载并设置表 | |
GetTable() |
获取所有表名 | |
GetTableItem(tableName, kv) / GetItem(...) |
获取表条目 | |
GetTableItemKV(...) / GetItemKV(...) |
获取条目属性 | |
IsTable(tableName, item, kv) |
判断表/条目/属性 | |
GetSuffix(tableName, sentence) |
后缀匹配 | |
GetPrefix(tableName, sentence) |
前缀匹配 | |
| FSA | CallFSA(fsaName, **Others) / RunFSA(fsaName) |
执行 FSA |
GetParam(key) / GetFSAParam(key) |
获取 FSA 参数 | |
GetNode(tag) / GetFSANode(tag) |
获取 FSA 节点 | |
| 索引 | IndexTable(filename) |
索引 Table 文件 |
IndexFSA(filename) |
索引 FSA 文件 | |
| 结构添加 | AddStructure(json) / AddGrid(json) |
添加结构(自动识别类型) |
AddSeq(json) |
添加序列 | |
AddTree(json) |
添加树 | |
AddGraph(json) |
添加图 | |
| 可视化 | Show(Json, **Others) |
统一可视化 |
ShowStructure(Json, Img) |
显示结构 | |
ShowGrid(Img, IsShowRel, IsShowGrid) |
显示网格 | |
ShowUnit(Unit, Img) |
显示 Unit 详情 | |
ShowRelation(Img) |
显示关系图 | |
ShowTree(Json) / ShowSeq(Json) / ShowGraph(Json) |
返回 DOT 脚本 | |
ShowCloud(Json, Output) |
词云 | |
| 服务 | CallService(sentence, name) |
调用远程服务 |
Dot2Img(dot, name) |
Dot 转图片 | |
DotFile(dot_file, img_file) |
Dot 文件转图片 | |
DotBuff(dot_data, img_file) |
Dot 字符串转图片 | |
| 其他 | GetLog() |
获取日志 |
Reduce(From, To, Head) |
归约操作 | |
GPFInit() |
手动初始化 |
5. BCC 类 — 语料库查询
BCC 提供语料库查询功能,支持词频统计、上下文检索和语料索引。
5.1 构造函数
from LangSC import BCC
bcc = BCC(dataPath="./data")
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
dataPath |
str |
"./data" |
语料数据目录路径 |
说明
- 自动加载
bcclib动态库 - 自动加载配置文件(
BCCconfig.txt)和 Lua 解析脚本(Parser.lua) - 自动检测并索引语料数据(详见 5.2)
5.2 自动索引机制
构造函数调用 _init_bcc_data(dataPath) 自动处理语料索引:
- 检查
dataPath中是否存在IdxLog_BCC.txt - 若存在:已是索引目录,直接使用
- 若不存在:视为原始语料目录
- 扫描目录下的语料文件(排除 Table 和 FSA 格式)
- 检查
dataPathIdx/是否存在且时间戳一致(避免重复索引) - 若需要索引,调用
IndexBCC对所有语料文件建索引 - 写入
IdxLog_BCC.txt索引日志
5.3 语料查询
CallBCC(query)
执行原始 BCC 查询语句。
result = bcc.CallBCC("学习{}Freq(100,$Q,0)")
result = bcc.CallBCC("学习{}Context(20,0,100)")
result = bcc.CallBCC("学习{}Count()")
| 参数 | 类型 | 说明 |
|---|---|---|
query |
str |
BCC 查询语句 |
返回值:str,JSON 格式查询结果。
查询语句格式:查询词{}操作(参数)
Freq(数量, 目标字段, 上下文条数)— 词频统计Context(窗口大小, 页码, 条数)— 上下文检索Count()— 计数统计
Run(Query, **Others)
高级查询接口,通过关键字参数自动构造查询语句。
# 词频查询(默认)
result = bcc.Run("学习")
# 指定查询模式
result = bcc.Run("学习", Command="Freq", Number=200)
result = bcc.Run("学习", Command="Context", WinSize=30, Number=100, PageNo=0)
result = bcc.Run("学习", Command="Count")
# 带逻辑运算
result = bcc.Run("学习 AND 方法", Command="Freq")
result = bcc.Run("学习 NOT 机器", Command="Freq")
# Lua 格式输出
result = bcc.Run("学习", Command="Freq", Print="Lua")
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
Query |
str |
(必填) | 查询词或查询表达式 |
Command / Output |
str |
"Freq" |
查询模式:"Freq" / "Context" / "Count" |
Number |
int |
100 |
返回条数上限 |
Target |
str |
"$Q" |
目标字段标识符 |
WinSize |
int |
20 |
上下文窗口大小(Context 模式) |
PageNo |
int |
0 |
分页页码(Context 模式) |
Print |
str |
"" |
输出格式,"Lua" 为 Lua 脚本格式 |
Speedup |
int |
1 |
加速选项 |
ContextNum |
int |
0 |
上下文条数(Freq 模式附带上下文时使用) |
返回值:str,查询结果。
查询语句自动生成规则:
- 若
Query不含{},自动追加{} - 若
Query包含换行符,直接作为原始查询传入(不做拼接处理) Freq→Query{}Freq(Number, Target, ContextNum)Context→Query{}Context(WinSize, PageNo, Number)Count→Query{}Count()AND/NOT运算符会在运算符前插入操作表达式
示例(Demo/BCC.py):
from LangSC import BCC
g = BCC("Corpus")
Ret = g.Run("喜欢{}", Command="Context", PageNo=0, WinSize=30, Number=10)
print(Ret)
5.4 KV 操作
BCC 引擎维护一个全局键值存储,可在查询间传递上下文信息。
AddBCCKV(Key, Val)
添加键值对。
bcc.AddBCCKV("Filter", "新闻")
bcc.AddBCCKV("Tags", "人名;地名;机构名")
| 参数 | 类型 | 说明 |
|---|---|---|
Key |
str |
键名 |
Val |
str |
值(多值分隔符自动合并为分号分隔) |
返回值:str。
GetBCCKV(Key="") / GetBCCKVs(Key="")
获取键值。
val = bcc.GetBCCKV("Filter")
all_kvs = bcc.GetBCCKV()
返回值:str。
ClearBCCKV(Key="")
清空键值存储。
bcc.ClearBCCKV()
返回值:str。
5.5 语料索引
IndexBCC(filelistname, **Others)
索引语料文件,支持多种输入格式。
# 1. 索引整个目录(递归扫描)
bcc.IndexBCC("/path/to/corpus_dir")
# 2. 索引文件列表文件(每行一个文件路径)
bcc.IndexBCC("/path/to/filelist.txt")
# 3. 索引单个文件
bcc.IndexBCC("/path/to/corpus.txt")
# 4. 索引 Python 列表
bcc.IndexBCC(["file1.txt", "file2.txt", "file3.txt"])
# 5. 指定索引结构
bcc.IndexBCC("/path/to/corpus", Structure="HZ") # 按汉字(默认)
bcc.IndexBCC("/path/to/corpus", Structure="Segment") # 按分词
| 参数 | 类型 | 说明 |
|---|---|---|
filelistname |
str 或 list |
语料来源:目录路径、文件列表路径、单个文件路径或 Python 文件路径列表 |
Structure |
str |
索引结构:"HZ"(默认,按汉字)、"Segment"(按分词) |
返回值:int,操作状态码。
处理流程:
- 若输入为目录:递归收集所有文件路径
- 若输入为文件列表:直接读取
- 若输入为 Python 列表:写入临时文件
- 对每个文件检测是否为原始文本(非 Table/Doc 格式),若是则预处理为 Doc 格式
- 检测文件编码,非 GBK 编码的文件自动转换
- 调用底层
BCC_IndexBCC构建索引
5.6 BCC 方法速查表
| 方法 | 说明 |
|---|---|
BCC(dataPath) |
构造函数,自动索引+加载 |
Run(Query, **Others) |
高级查询接口 |
CallBCC(query) |
执行原始查询 |
AddBCCKV(Key, Val) |
添加键值 |
GetBCCKV(Key) / GetBCCKVs(Key) |
获取键值 |
ClearBCCKV() |
清空键值 |
IndexBCC(filelistname, **Others) |
索引语料 |
6. JSS 类 — JSON 结构检索
JSS(JSON Structure Search)提供对 JSON 格式数据的结构化检索能力,支持 SQL 风格查询语法和多表管理。
6.1 构造函数
from LangSC import JSS
jss = JSS(dataPath, log_level=0, log_filename='')
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
dataPath |
str |
(必填) | 数据目录路径 |
log_level |
int |
0 |
日志级别(0=关闭) |
log_filename |
str |
"" |
日志文件路径 |
说明
- 自动加载
jsslib动态库 - 使用 10MB 缓冲区
- 支持同时管理多个表(通过
self.handles字典) - 析构函数
__del__自动调用Terminate()释放资源并卸载 DLL
6.2 自动索引机制
构造函数调用 _init_jss_data(dataPath) 自动处理索引:
步骤 1: 检查 dataPath/IdxLog_JSS.txt
├── 存在 → 已是索引目录 → 加载全部子目录中的表 → 完成
└── 不存在 → 步骤 2
步骤 2: 扫描 dataPath 中的 *.json / *.jsonl 文件
├── 无文件 → 完成
└── 有文件 → 步骤 3
步骤 3: 检查 dataPathIdx/IdxLog_JSS.txt
├── 存在且时间戳一致 → 从 dataPathIdx 加载 → 完成
└── 不一致或不存在 → 步骤 4
步骤 4: 执行索引
├── 创建 dataPathIdx/ 目录
├── 逐个处理 *.json / *.jsonl 文件(跳过 cfg_* 前缀)
├── 查找对应的 cfg_<name>.txt(不存在则自动生成)
├── 为每个文件创建索引到 dataPathIdx/<name>/
├── 记录到 IdxLog_JSS.txt
└── 加载全部表 → 完成
6.3 数据目录结构
原始数据目录(以 ./json 为例):
./json/
├── pinyin.jsonl # 数据文件(JSONL 格式)
├── cfg_pinyin.txt # pinyin 的配置文件(可选,缺失时自动生成)
├── books.json # 也支持 JSON 数组格式
└── (cfg_books.txt) # 可选
命名规则
- 数据文件:
<name>.json或<name>.jsonl - 配置文件:
cfg_<name>.txt - 以
cfg_开头的文件在扫描时会被跳过
索引后自动生成的目录:
./jsonIdx/
├── IdxLog_JSS.txt # 索引日志
├── pinyin/ # pinyin 表的索引文件
│ └── (索引数据...)
└── books/ # books 表的索引文件
└── (索引数据...)
6.4 cfg 配置文件
cfg 文件为 JSON 格式,定义表结构和索引策略。
示例(cfg_pinyin.txt):
{
"table_name": "pinyin",
"record_format": "jsonl",
"content": {
"PYId": "PYId",
"PinYin": "PinYin",
"PinYin_FuHao": "PinYin_FuHao",
"DengJi": "DengJi",
"DuYin[]": "DuYin[]",
"ShiPin": "ShiPin",
"TuPian": "TuPian",
"Source": "Source"
},
"index": {
"number": [],
"kv": ["PinYin", "PinYin_FuHao"],
"affix": [],
"bm25": []
}
}
字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
table_name |
string |
表名,用于查询时的 FROM 子句 |
record_format |
string |
数据格式:"jsonl"(每行一条 JSON)或 "json"(JSON 数组) |
content |
object |
字段映射。数组类型字段需加 [] 后缀 |
index.number |
array |
数值索引字段,支持范围查询(>, <, >=, <=) |
index.kv |
array |
键值索引字段,支持精确匹配查询(=) |
index.affix |
array |
词缀索引字段,支持前后缀匹配 |
index.bm25 |
array |
全文检索字段,支持 BM25 相关性排序 |
6.5 cfg 自动生成规则
当 cfg 文件缺失时,JSS 自动读取数据文件的首条记录推断 schema:
-
读取首条记录
.jsonl:读取第一行.json:若为数组取第一个元素,若为对象直接使用
-
生成
content映射- 普通字段:
"field": "field" - 数组字段:
"field[]": "field[]"
- 普通字段:
-
生成
index配置number:仅当字段名为"id"且值为数值类型时加入kv:所有字符串类型字段affix:留空bm25:留空
-
写入
cfg_<name>.txt(UTF-8 编码)
示例:假设 books.jsonl 首条记录为:
{"id": 1, "title": "自然语言处理", "author": "张三", "price": 59.8, "tags": ["NLP", "AI"]}
自动生成的 cfg_books.txt:
{
"table_name": "books",
"record_format": "jsonl",
"content": {
"id": "id",
"title": "title",
"author": "author",
"price": "price",
"tags[]": "tags[]"
},
"index": {
"number": ["id"],
"kv": ["title", "author"],
"affix": [],
"bm25": []
}
}
注意:
price字段虽为数值但字段名不是"id",不会自动加入number索引。若需范围查询,应手动编写 cfg。
6.6 查询
Run(sql_statement, table="")
执行 SQL 风格的查询。
# 单表时无需指定 table
results = jss.Run('SELECT * FROM pinyin WHERE PinYin ="da1"')
# 多表时通过 table 参数指定
results = jss.Run("SELECT * FROM audio WHERE tags = 'pop';", table="audio")
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
sql_statement |
str |
(必填) | SQL 查询语句 |
table |
str |
"" |
指定查询的表名。为空时使用第一个已加载的表 |
返回值:list,查询结果列表。每个元素为一条记录(dict)。未初始化时返回 []。
SQL 语法
| 子句 | 说明 | 示例 |
|---|---|---|
SELECT |
指定返回字段(* 返回全部) |
SELECT id, ci, pinyin |
TOP n |
限制返回条数 | SELECT TOP 10 * |
FROM |
指定表名 | FROM pinyin |
WHERE |
过滤条件 | WHERE PinYin = 'da1' |
AND |
条件与 | WHERE pos = 'n' AND freq > 100 |
OR |
条件或 | WHERE pos = 'n' OR pos = 'v' |
| 运算符 | 说明 | 适用索引类型 |
|---|---|---|
= |
等于 | kv, number |
> |
大于 | number |
< |
小于 | number |
>= |
大于等于 | number |
<= |
小于等于 | number |
示例(Demo/JSS.py):
from LangSC import JSS
g = JSS("json")
Ret = g.Run('SELECT * FROM pinyin WHERE PinYin ="da1"')
print(Ret)
6.7 资源释放
Terminate()
释放所有已加载表的句柄。
jss.Terminate()
说明
- 逐一释放
self.handles中的所有句柄 - 重置
is_init为False - 析构函数
__del__会自动调用,但建议显式调用以确保资源及时释放
6.8 JSS 方法速查表
| 方法 | 说明 |
|---|---|
JSS(dataPath, log_level, log_filename) |
构造函数,自动索引+加载 |
Run(sql_statement, table) |
SQL 查询 |
Terminate() |
释放资源 |
7. 完整示例
7.1 GPF 句法分析与可视化
from LangSC import GPF
import json
gpf = GPF()
Txt = "中欧班列持续稳定开行,夯实了亚欧大陆互联互通的基础"
js = gpf.Parse(Txt, Structure="Tree")
gpf.ShowStructure(js, "Dep.png")
7.2 GPF 手动构建网格与关系
from LangSC import GPF
import json
Line = """
{"Words": ["瑞士", "率先", "破门", ",", "沙其理", "梅开二度", "。"],
"Tags": ["ns", "d", "v", "w", "nr", "i", "w"],
"Relations": [{"U1": 2, "U2":0,"R":"A0","KV":"KV1"},
{"U1": 2, "U2":1,"R":"Mod","KV":"KV2"},
{"U1": 5, "U2":4,"R":"A0","KV":"KV3"}]}"""
S = json.loads(Line)
Txt = "".join(S["Words"])
gpf = GPF()
gpf.SetText(Txt)
# 逐词添加 Unit
ColNo = 0
Units = []
for i in range(len(S["Words"])):
UnitNo = gpf.AddUnit(S["Words"][i], ColNo + len(S["Words"][i]) - 1)
Units.append(UnitNo)
gpf.AddUnitKV(UnitNo, "POS", S["Tags"][i])
ColNo += len(S["Words"][i])
# 添加关系
for R in S["Relations"]:
gpf.AddRelation(Units[R["U1"]], Units[R["U2"]], R["R"])
# 可视化
gpf.ShowRelation("r.png")
7.3 GPF 关系操作
from LangSC import GPF
gpf = GPF()
Text = "孩子们都吃撑了"
gpf.SetText(Text)
Child = gpf.AddUnit("孩子们", 2)
All = gpf.AddUnit("都", 3)
Eat = gpf.AddUnit("吃", 4)
Full = gpf.AddUnit("撑了", 6)
gpf.AddUnitKV(Eat, "POS", "V")
gpf.AddUnitKV(Full, "POS", "V")
gpf.AddRelation(Eat, All, "mod")
gpf.AddRelation(Eat, Full, "mod")
gpf.AddRelation(Eat, Child, "sbj")
gpf.AddRelation(Full, Child, "sbj")
gpf.AddRelationKV(Full, Child, "sbj", "K1", "V1")
gpf.AddRelationKV(Full, Child, "sbj", "K2", "V2")
# 遍历所有关系
R = gpf.GetRelation()
for r in R:
print(r)
print(gpf.GetUnitKV(r[0], "Word"), gpf.GetUnitKV(r[1], "Word"), r[2])
KVs = gpf.GetRelationKV(r[0], r[1], r[2])
for K, Vs in KVs.items():
print(K)
7.4 GPF 序列结构与网格
from LangSC import GPF
gpf = GPF()
Text = "我们大家很辛苦"
gpf.SetText(Text)
# 添加两层分词结构
gpf.AddStructure('["我们","大家","很","辛苦"]')
gpf.AddStructure('["我们","大家","很辛苦"]')
# 显示网格
gpf.ShowGrid()
# 遍历网格
Grid = gpf.GetGrid()
for Col in Grid:
for Unit in Col:
print(Unit, gpf.GetUnitKV(Unit, "Word"))
7.5 BCC 语料库查询
from LangSC import BCC
bcc = BCC("Corpus")
# 上下文检索
ret = bcc.Run("喜欢{}", Command="Context", PageNo=0, WinSize=30, Number=10)
print(ret)
# 词频查询
freq = bcc.Run("学习", Command="Freq", Number=50)
print(freq)
# 计数
count = bcc.Run("学习", Command="Count")
print(count)
# 复合查询
result = bcc.Run("学习 AND 方法", Command="Freq", Number=20)
print(result)
7.6 BCC 语料索引
from LangSC import BCC
bcc = BCC("./corpus_idx")
# 索引整个目录
bcc.IndexBCC("./raw_corpus/")
# 索引文件列表
bcc.IndexBCC("./filelist.txt")
# 索引 Python 列表
bcc.IndexBCC(["./doc1.txt", "./doc2.txt"])
# 以分词模式索引
bcc.IndexBCC("./raw_corpus/", Structure="Segment")
7.7 JSS 数据检索
from LangSC import JSS
# 自动索引 + 加载
jss = JSS("json")
# 精确查询
results = jss.Run('SELECT * FROM pinyin WHERE PinYin ="da1"')
for row in results:
print(row)
# 多条件查询
results = jss.Run("SELECT * FROM pinyin WHERE PinYin = 'da1' AND DengJi = '1';")
# 限制数量
results = jss.Run("SELECT TOP 5 * FROM pinyin;")
# 清理
jss.Terminate()
7.8 JSS 手动编写 cfg
import json
cfg = {
"table_name": "products",
"record_format": "jsonl",
"content": {
"id": "id",
"name": "name",
"category": "category",
"price": "price",
"description": "description",
"tags[]": "tags[]"
},
"index": {
"number": ["id", "price"],
"kv": ["name", "category"],
"affix": ["name"],
"bm25": ["description"]
}
}
with open("./table/cfg_products.txt", "w", encoding="utf-8") as f:
json.dump(cfg, f, indent=4, ensure_ascii=False)
from LangSC import JSS
jss = JSS("./table")
results = jss.Run("SELECT * FROM products WHERE price < 100;", table="products")
8. 数据文件格式说明
8.1 GPF Table 文件格式
Table 文件是纯文本格式,以 Table <表名> 开头,每行一个条目及其属性:
Table CiDian
天气
POS n
拼音 tianqi
北京
POS ns
类型 地名
8.2 GPF FSA 文件格式
FSA 文件以 FSA <规则名> 开头,定义状态转换规则:
FSA PersonRecognize
State Start
Transition ...
8.3 BCC 语料文件格式
BCC 支持两种格式:
Doc 格式(结构化):
Doc 文档名
#Global 字段=值
#Group pos=text
Item:这 是 第 一 句
Item:这 是 第 二 句
Doc行声明文档名#Global行定义全局属性#Group行定义分组属性Item:行为具体语料条目,词之间用空格分隔
原始文本格式:纯文本,IndexBCC 会自动预处理为 Doc 格式(按句号分句,每个字用空格分隔)。
8.4 JSS 数据文件格式
JSONL 格式(*.jsonl):每行一条 JSON 记录
{"id": 1, "ci": "爱", "pos": "v", "pinyin": "ai4"}
{"id": 2, "ci": "被", "pos": "p", "pinyin": "bei4"}
JSON 格式(*.json):JSON 数组
[
{"id": 1, "ci": "爱", "pos": "v", "pinyin": "ai4"},
{"id": 2, "ci": "被", "pos": "p", "pinyin": "bei4"}
]
9. 平台与依赖
9.1 动态库
| 平台 | GPF 库 | BCC 库 | JSS 库 |
|---|---|---|---|
| Windows | gpflib.dll |
bcclib.dll |
jsslib.dll |
| Linux | libgpflib.so |
libbcclib.so |
libjsslib.so |
| macOS | libgpflib.dylib |
libbcclib.dylib |
libjsslib.dylib |
9.2 包内数据文件
| 文件 | 所属类 | 用途 |
|---|---|---|
GPFconfig.txt |
GPF | GPF 引擎配置(Table/FSA 路径、远程服务地址) |
Segment.dat |
GPF | CRF 分词模型 |
idxPOS.dat |
GPF | 词性标注数据 |
BCCconfig.txt |
BCC | BCC 引擎配置(线程、内存、索引参数) |
Parser.lua |
BCC | Lua 查询解析脚本 |
base.lex |
JSS | 分词词典(affix/bm25 索引用) |
Graph/dot.exe |
GPF | Graphviz DOT 工具(Windows 可视化) |
9.3 线程安全
GPF 和 BCC 的初始化操作使用 threading.Lock() 保护,确保多线程环境下不会重复初始化:
| 全局变量 | 所属类 | 说明 |
|---|---|---|
IsCRFInit |
GPF | CRF 分词模型初始化标志 |
IsPOSInit |
GPF | POS 词性标注数据初始化标志 |
IsGPFInit |
GPF | GPF 数据初始化标志 |
IsBCCInit |
BCC | BCC 引擎初始化标志 |
9.4 索引日志文件
每个类使用独立的索引日志文件:
| 日志文件 | 所属类 | 存放位置 |
|---|---|---|
IdxLog_GPF.txt |
GPF | dataPath 或 dataPathIdx/ |
IdxLog_BCC.txt |
BCC | dataPath 或 dataPathIdx/ |
IdxLog_JSS.txt |
JSS | dataPath 或 dataPathIdx/ |
日志格式为 TSV(制表符分隔):
文件名\t时间戳1\t时间戳2
10. 参考文献
说明文档及使用示例:http://gpf.blcu.edu.cn
荀恩东. 自然语言结构计算——GPF结构分析框架 [M]. 北京: 人民邮电出版社. 2022
多线程并行分词/词性
GPF 的本地分词(Segment)与词性标注(POS)是线程安全的:多个线程可共享同一个 GPF 对象并发调用,内部自动为每个线程分配独立的句柄与输出缓冲,ctypes 调用期间释放 GIL,实现真正并行。无需任何额外的类或配置——用法和单线程完全一样。
from LangSC import GPF
from concurrent.futures import ThreadPoolExecutor
g = GPF(dataPath="./data") # 建一个,全局共享
# 可选:g.POS("预热") 先单线程触发一次模型初始化,避免首调延迟
with ThreadPoolExecutor(max_workers=8) as ex:
seg = list(ex.map(g.Segment, texts)) # 并行分词
pos = list(ex.map(g.POS, texts)) # 并行词性
js = list(ex.map(lambda t: g.Parse(t, Structure="POS"), texts)) # 并行 Parse
Web 服务里,进程启动时建一个全局 GPF,各请求线程直接调用即可:
from flask import Flask, request, jsonify
from LangSC import GPF
app = Flask(__name__)
g = GPF(dataPath="./data")
@app.route("/pos", methods=["POST"])
def pos():
return jsonify(g.Parse(request.get_data(as_text=True), Structure="POS"))
边界(重要):线程安全仅覆盖本地 Segment/POS,以及 Parse 的本地 Segment/POS(默认 table="")。Parse 的 Tree/Chunk/Dep(远程 HTTP)无共享状态,可安全并发。其余 CallService/RunFSA/GetGrid 等 Grid/FSA 接口不是线程安全的,如需并发请每线程各建一个 GPF 或自行加锁。内存与句柄:每个真正调用过分词/词性的线程会分配一份独立输出缓冲(约 buf_max_size)和一个底层 CRFPOS 句柄;缓冲随线程/对象回收,但底层句柄在进程存续期间不会释放(本库设计上从不调用 GPF_Term)。因此请使用固定大小的线程池(如 ThreadPoolExecutor(max_workers=N))复用线程,使句柄总数被 N 界定;避免"每个请求新开一个线程"的模式(如 Flask 开发服务器 threaded=True、每请求 threading.Thread),否则底层句柄会随请求数持续增长。上面的 Web 示例请配合固定线程池部署(如 gunicorn --threads N)。
Metadata
Release files for LangSC 2.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| langsc-2.3.0.tar.gz | 26.9 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| langsc-2.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 53.9 MB
Release files / langsc-2.3.0.tar.gz
| Download URL | langsc-2.3.0.tar.gz |
|---|---|
| Size | 26.9 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
65d8af301829873356fd061ccfbd82a31a5cd40d89b8768e013bffeb6848f20c
|
|
BLAKE2b-256 checksum How to use checksums |
cd18ba5c143ea4468b3fdb6cb92295aee850a6ada3643941254f00c78d911dc3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Release files / langsc-2.3.0-py3-none-any.whl
| Download URL | langsc-2.3.0-py3-none-any.whl |
|---|---|
| Size | 27.1 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0b783dbba9b134dcb9eeabaf651cfe0a214b46a48499ba5b05ae4fe3ae28c137
|
|
BLAKE2b-256 checksum How to use checksums |
10f3977ea720ed7a19e71020f3f5c995617946e69bbdf35d84f45aa822fd0a6c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|