构建个人 BCC 语料库
使用 LangSC 开发包,在本地构建、索引和检索属于你自己的语料库
BCC(BCC Corpus)是 LangSC(语言结构计算开发包)的语料库检索引擎模块。 它支持基于模式的语料检索和统计分析,能够对任意文本语料建立索引并提供高效检索。 你可以用它在本地构建个性化语料库,进行词频统计、上下文浏览、搭配分析等操作。
安装与初始化
安装 LangSC
pip install LangSC
依赖包:
| 依赖包 | 说明 |
|---|---|
pywin32 | Windows 平台必需 |
requests | HTTP 请求 |
chardet | 文件编码检测 |
初始化 BCC 实例
from LangSC import BCC
# 指定语料数据目录
bcc = BCC("Corpus")
初始化时,BCC 会自动检测指定路径下的索引状态。如果有未索引的资源文件,会自动进行索引构建。
索引完成后记录到 IdxLog_BCC.txt,下次初始化时通过时间戳比较避免重复索引。
准备语料文件
将你的文本语料文件放入一个目录中(如 Corpus/)。BCC 支持纯文本格式的语料文件。
语料应为 gb18030 编码的文本,每行为一个句子或段落。
索引构建
当你用 BCC("Corpus") 初始化时,引擎会自动扫描目录并为未索引的文件构建索引。
你也可以通过 IndexBCC 方法手动触发索引构建:
from LangSC import BCC
bcc = BCC("Corpus")
# 手动触发索引(传入文件列表名)
bcc.IndexBCC("filelist.txt")
索引完成后,后续初始化将直接加载已有索引,启动速度大幅提升。
语料格式
BCC 语料支持两大类数据格式:基本格式(不含元数据)和扩展格式(包含元数据)。
基本格式(Object 按行排列)
Object
Object
Object
...
| 类型 | 格式特征 | 示例 |
|---|---|---|
| 无标注生语料 | 原始连续文本 | 茶在中国有几千年的历史,是中国最常见的饮料。 |
| 单元切分语料 | 单元之间用空格分隔(词/组块) | 茶 在 中国 有 几 千 年 的 历史 , 是 中国 最 常见 的 饮料 。 |
| 单元性质标注语料 | 对象后接 / 和标记(词性/组块) | 茶/n 在/p 中国/ns 有/v ... 。/w |
| 括号结构树 | 用嵌套括号表示树结构 | (ROOT(IP(NP-SBJ(n 茶))(VP-PRD(v 是))...)) |
扩展格式(带元数据)
Doc DocName
#Global K1=V1;K2=V2;...
#Group pos=Info
Item: Object
Item: Object
...
#Group pos=Info
Item: Object
...
Doc DocName2
...
| 字段 | 作用 | 格式 | 说明 |
|---|---|---|---|
Doc | 子语料库起始标记 | Doc 文档名 | 标记一个子语料库/文档单元开始 |
#Global | 全局属性声明 | #Global K1=V1;K2=V2;... | 作用于当前 Doc 内全部语料 |
#Group pos=Info | 局部属性声明 | #Group pos=title | 作用于后续一组 Item,直到下一组或下一 Doc |
Item: | 语料条目标记 | Item: 我在中国学汉语。 | Item 后跟一个具体语言对象(Object) |
BCC 检索语言
BCC 检索引擎接受一种专用的检索语言,完整格式如下:
查询对象{条件}[范围]操作(参数)
例如:喜欢(n){len($1)=2}[(0,100)]Context(10,0,100)。
| 部分 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|
| 查询对象 | 必填 | — | 检索的核心内容 |
{条件} | 可选 | 空 | 过滤条件 |
[范围] | 可选 | 全语料 | 语料子集限定 |
操作(参数) | 可选 | Context(10,0,100) | 输出形式 |
查询对象是必填内容,最简检索式可仅包含查询对象,例如:喜欢(n)。
检索单元
检索单元是查询的最小构成单位。词性用英文字母表示(n=名词、v=动词、a=形容词等),词形用汉字表示。
| 类型 | 格式 | 示例 | 含义 |
|---|---|---|---|
| 词形 | 词形 | 喜欢 | 词形含“喜欢”的任意词 |
| 词性 | 词性 | n | 任意名词 |
| 组块符号+内部描述 | 组块符号[单元内部描述] | VP-PRD[喜欢] | 在组块节点上限定其内部单元内容 |
连接符与通配符
连接符写在两个检索单元之间,表示位置关系:
| 连接符 | 写法 | 符号含义 | 示例 | 示例含义 |
|---|---|---|---|---|
| 紧邻 | 直接相连或空格 | 两个词线性相邻 | 喜欢n | 匹配“喜欢”后紧邻一个名词的结构 |
| 离合 | * | 表示不跨标点的离合或接续 | 洗*澡 | 匹配“洗…澡”且中间部分不跨标点 |
| 离合 | ^ | 表示不跨标点或跨标点的离合或接续 | 吃^水果 | 匹配“吃…水果”,中间可不跨标点也可跨标点 |
通配符用于匹配不固定内容:
| 符号 | 符号含义 | 示例 | 示例含义 |
|---|---|---|---|
. | 任意一个字符 | 洗..澡 | 匹配“洗+任意两个字符+澡” |
~ | 任意一个词 | 洗~澡 | 匹配“洗+任意一个词+澡” |
组块内描述
方括号用于描述组块节点的内部单元结构:
| 写法 | 含义 |
|---|---|
VP-PRD[]MOD[] | 匹配谓词性述语组块后接修饰性组块 |
VP-PRD[]MOD[过来] | 匹配 MOD 组块内部包含“过来”的结构 |
VP-PRD[](MOD[]){$1=[下去 上来 过去 过来]} | 对括号限定的组块结果再做集合过滤 |
VP-PRD[喜欢]NP-OBJ[] | 匹配述语组块内部含“喜欢”,且后接宾语组块 |
条件与范围
花括号内写过滤条件。$1、$2 等代表查询对象中第1个、第2个限定成分:
内容限制
| 形式 | 含义 | 示例 |
|---|---|---|
{} | 无条件 | a的n{} |
$n=[] | 内容属于集合 | VP-PRD[](MOD[]){$1=[过来 下来]} |
$n!=[] | 内容不属于集合 | (a)的女生{$1!=[漂亮 可爱 美丽]} |
$n=$k | 内容相同 | (v)一(v){$1=$2} |
$n!=$k | 内容不同 | (v)一(v){$1!=$2} |
beg($n)=[] | 以某元素开头 | beg($1)=[被] |
beg($n)!=[] | 不以某元素开头 | beg($1)!=[被] |
end($n)=[] | 以某元素结尾 | end($1)=[犯罪] |
end($n)!=[] | 不以某元素结尾 | end($1)!=[犯罪] |
mid($n)=[] | 包含某元素 | mid($1)=[打击] |
mid($n)!=[] | 不包含某元素 | mid($1)!=[打击] |
长度限制
| 形式 | 含义 | 示例 |
|---|---|---|
len($n)=x | 长度等于 x | (a)的女生{len($1)=2} |
len($n)>x | 长度大于 x | (nr)说 m q{len($1)>1} |
len($n)<x | 长度小于 x | (nr)说 m q{len($1)<4} |
len($n)=len($k) | 两者长度相同 | (v)一(v){len($1)=len($2)} |
len($n)!=len($k) | 两者长度不同 | (v)一(v){len($1)!=len($2)} |
输出限制
| 形式 | 含义 | 示例 |
|---|---|---|
print($n) | 将输出对象限定为第 n 个限定成分 | 喜欢(n){print($1)} |
方括号内写语料范围限定,每组 (起始ID, 结束ID) 用 ; 分隔:
[(0,713)] → 只检索 0~713 范围
[(0,713);(714,928)] → 检索两个范围的并集
操作
操作决定输出形式,写在检索式末尾:
| 操作 | 参数 | 说明 |
|---|---|---|
Context(窗口大小, 页码, 每页条数) | 默认 10,0,100 | 上下文浏览 |
Freq(最大条数) | 默认 1000 | 频率统计 |
Freq(最大条数, 统计对象, 上下文数) | 完整参数 | 指定统计对象的频率 |
Count() | — | 计数统计 |
复合查询
两个独立检索式之间用 AND 或 NOT 连接(前后须有空格):
查询A AND 查询B → 在B的结果范围内检索A
查询A NOT 查询B → 在排除B的结果后检索A
API 参考
Run 方法
from LangSC import BCC
bcc = BCC("Corpus")
# 频率检索(默认 Command="Freq")
Ret = bcc.Run("a的n")
# 上下文检索(KWIC 格式)
Ret = bcc.Run("a的n", Command="Context", Number=100)
# 计数
Ret = bcc.Run("a的n", Command="Count")
参数详解
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
Command | str | "Freq" | 输出模式:Freq / Context / Count |
Number | int | 100 | 输出结果数量 |
Target | str | "$Q" | 频率统计的目标(Freq模式) |
WinSize | int | 20 | 上下文窗口大小(Context模式) |
PageNo | int | 0 | 分页页码(从0开始) |
Service | str | "" | 指定远程检索服务 |
当 Python 参数与检索式中的操作同时指定时,Python 参数优先。
词表管理
可以预先定义词表,在查询条件中引用:
# 添加词表
bcc.AddBCCKV("HSK1Level", "爱 八 爸爸 吧 白天 百 半 包子 杯子 本 边")
bcc.AddBCCKV("PersonalPronouns", "我 你 他 她 我们 你们 他们")
# 在查询条件中使用词表
Ret = bcc.Run("a的(~){$1=[HSK1Level]}", Command="Freq", Number=200000)
Ret = bcc.Run("(nr)说{$1=[PersonalPronouns]}", Command="Freq", Number=200000)
# 查看已定义的词表
KVs = bcc.GetBCCKV()
# 查看指定词表
KVs = bcc.GetBCCKV("HSK1Level")
# 清除指定词表
bcc.ClearBCCKV("HSK1Level")
# 清除所有词表
bcc.ClearBCCKV()
管理命令
以下命令可直接作为 CallBCC() 的 Query 参数传入:
| 命令 | 说明 |
|---|---|
AddTag(标签,值) / AddKV(键=值) | 添加标签/键值对 |
GetTags() / GetKeys() | 获取所有标签名 |
GetTagVal(键名) | 获取指定标签的值 |
ClearTag() / ClearKV() | 清除所有标签 |
SetMax(数值) | 设置最大检索数 |
SpeedUp(数值) | 设置加速参数 |
AddLimit(起始,结束) | 添加语料范围限制 |
ClearLimit() | 清除所有范围限制 |
示例:基础检索
from LangSC import BCC
bcc = BCC("Corpus")
# 1. "形容词+的+名词" 高频搭配
Ret = bcc.Run("a的n", Command="Freq", Number=500)
print(Ret)
# 2. "动词+得+形容词" 上下文实例
Ret = bcc.Run("v得a", Command="Context", Number=50)
print(Ret)
# 3. 把字句的频率分布
Ret = bcc.Run("把n*v", Command="Freq")
print(Ret)
# 4. “的”后接任意一词的使用情况(~ 通配一个词)
Ret = bcc.Run("的~", Command="Freq", Number=200)
print(Ret)
# 5. 任意一词后接“的+名词”结构
Ret = bcc.Run("~的n", Command="Context", Number=100)
print(Ret)
# 6. 限定范围的检索
Ret = bcc.Run("n喜欢v{}[(0,713);(714,928)]Context(20,0,10)")
print(Ret)
# 7. 仅获取匹配计数
Ret = bcc.Run("a的n", Command="Count")
print(Ret)
# 8. 分页获取上下文
Ret = bcc.Run("a的n", Command="Context", Number=100, PageNo=0) # 第1页
Ret = bcc.Run("a的n", Command="Context", Number=100, PageNo=1) # 第2页
# 9. 按特定目标统计频率
Ret = bcc.Run("a的n", Command="Freq", Target="$1", Number=500)
print(Ret)
示例:词表检索
from LangSC import BCC
bcc = BCC("Corpus")
# 定义情感词表并检索
bcc.AddBCCKV("emotion", "喜欢 爱 讨厌 恨")
Ret = bcc.Run("v的n{$1=[emotion]}", Command="Freq")
print(Ret)
# 清除词表
bcc.ClearBCCKV("emotion")
示例:高级检索
from LangSC import BCC
bcc = BCC("Corpus")
# 1. 最简查询——纯词形
Ret = bcc.Run("喜欢", Command="Freq", Number=100)
# 2. 词性+词形组合
Ret = bcc.Run("n喜欢v", Command="Context", Number=50)
# 3. 助词后接任意一词统计(~ 通配一个词)
Ret = bcc.Run("u~", Command="Freq", Number=200)
# 4. 不跨标点离合/接续检索
Ret = bcc.Run("n*v", Command="Context", Number=100)
# 5. 带条件的检索
Ret = bcc.Run("(v)一(v){$1=$2}", Command="Freq")
# 6. 带范围限制的检索
Ret = bcc.Run("n喜欢v{}[(0,713);(714,928)]", Command="Context", Number=50)
# 7. NOT 排除查询
Ret = bcc.Run("n喜欢v{}Context() NOT 的{}")
# 8. AND 交集查询
Ret = bcc.Run("n喜欢v{}Context() AND 的{}")
# 9. 组块内描述检索
Ret = bcc.Run("VP-PRD[]MOD[过来]", Command="Freq", Number=100)
API 速查表
| 方法 | 说明 |
|---|---|
BCC(dataPath) | 构造函数(自动索引+加载) |
Run(Query) | 频率检索(默认) |
Run(Query, Command="Context") | 上下文检索 |
Run(Query, Command="Count") | 计数检索 |
Run(Query, Command="Freq", Number=N) | 限定数量的频率检索 |
Run(Query, Target="$1") | 指定统计目标 |
CallBCC(query) | 执行原始 BCC 查询 |
AddBCCKV(Key, Val) | 添加检索词表 |
GetBCCKV(Key) | 查看词表 |
ClearBCCKV(Key) | 清除指定词表 |
ClearBCCKV() | 清除所有词表 |
IndexBCC(filelistname) | 构建语料索引 |