关于 InferMap
InferMap 是一款模式映射引擎,可将混乱的源字段匹配到目标模式,并给出置信度分数和可读的推理说明。它提供 Python 和 TypeScript 包,适用于数据管道、应用和命令行探索;此仓库已归档,开发已转至 goldenmatch monorepo。
主要功能
- 01使用七种评分器匹配字段
- 02优化一对一映射分配
- 03提供置信度和映射说明
- 04支持领域词典与置信度校准
- 05提供 Python 和 TypeScript 包
- 06通过命令行检查映射
适用场景
- 01映射 CSV 导出文件的列
- 02对齐不同数据库表的字段
- 03在应用中集成模式匹配
- 04使用已保存映射重命名列
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://infermap-mcp-production.up.railway.app/mcp/claude mcp add --transport http benseverndev-oss-infermap https://infermap-mcp-production.up.railway.app/mcp/{"mcpServers":{"benseverndev-oss-infermap":{"type":"http","url":"https://infermap-mcp-production.up.railway.app/mcp/"}}}在 Cursor 中打开{"servers":{"benseverndev-oss-infermap":{"type":"http","url":"https://infermap-mcp-production.up.railway.app/mcp/"}}}在 VS Code 中打开{"mcpServers":{"benseverndev-oss-infermap":{"type":"http","url":"https://infermap-mcp-production.up.railway.app/mcp/"}}}{"mcpServers":{"benseverndev-oss-infermap":{"serverUrl":"https://infermap-mcp-production.up.railway.app/mcp/"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
详细介绍
已迁移。 此仓库已迁入
benzsevern/goldenmatch单体仓库,路径为packages/python/infermap (and packages/typescript/infermap)/。此仓库已归档;后续开发将在单体仓库中进行。
infermap
由推理驱动的模式映射引擎。
将杂乱的源列映射到已知目标模式——准确、可解释且无需任何配置。
由 Ben Severn 构建。
📖 Wiki · 🌐 文档 · 🧪 示例 · 💬 讨论 · 🐛 问题
infermap 是一个模式映射引擎。提供任意两组字段(CSV、DataFrame、数据库表或内存记录),它就能判断哪个源字段对应哪个目标字段,并给出置信度分数和易于理解的推理说明。提供 PyPI 上的 Python 包和 npm 上的 TypeScript 包,映射决策通过共用的黄金测试一致性套件进行逐位验证。
目录
安装
Python
pip install infermap
可选的数据库扩展:
pip install infermap[postgres] # psycopg2-binary
pip install infermap[mysql] # mysql-connector-python
pip install infermap[duckdb] # duckdb
pip install infermap[all] # all extras
TypeScript / Next.js
npm install infermap
核心入口点没有运行时依赖。开箱即兼容 Next.js Server Components、Route Handlers、Server Actions 和 Edge Runtime。完整参考请参阅包 README。
快速开始
Python
import infermap
# Map a CRM export CSV to a canonical customer schema
result = infermap.map("crm_export.csv", "canonical_customers.csv")
for m in result.mappings:
print(f"{m.source} -> {m.target} ({m.confidence:.0%})")
# fname -> first_name (97%)
# lname -> last_name (95%)
# email_addr -> email (91%)
# Apply mappings to rename DataFrame columns
import polars as pl
df = pl.read_csv("crm_export.csv")
renamed = result.apply(df)
# Save mappings to a reusable config file
result.to_config("my_mapping.yaml")
# Reload later — no re-inference needed
saved = infermap.from_config("my_mapping.yaml")
TypeScript
import { map } from "infermap";
const crm = [
{ fname: "John", lname: "Doe", email_addr: "[email protected]" },
{ fname: "Jane", lname: "Smith", email_addr: "[email protected]" },
];
const canonical = [
{ first_name: "", last_name: "", email: "" },
];
const result = map({ records: crm }, { records: canonical });
for (const m of result.mappings) {
console.log(`${m.source} → ${m.target} (${m.confidence.toFixed(2)})`);
}
// fname → first_name (0.44)
// lname → last_name (0.48)
// email_addr → email (0.69)
在 Next.js 中,可直接将其用于 Route Handler——无需配置即可在 Edge Runtime 上运行:
// app/api/infer/route.ts
import { map } from "infermap";
export const runtime = "edge";
export async function POST(req: Request) {
const { sourceCsv, targetCsv } = await req.json();
const result = map({ csvText: sourceCsv }, { csvText: targetCsv });
return Response.json(result);
}
工作原理
每对字段都会经过由 7 个评分器 组成的流程。每个评分器会返回 [0.0, 1.0] 范围内的分数,或放弃评分(None/null)。引擎通过加权平均合并分数(至少需要 2 个评分器参与),然后使用 匈牙利算法进行最优的一对一分配。
| 评分器 | 权重 | 检测内容 |
|---|---|---|
| ExactScorer | 1.0 | 不区分大小写的名称完全匹配 |
| AliasScorer | 0.95 | 已知字段别名(fname ↔ first_name、tel ↔ phone)和领域词典 |
| InitialismScorer | 0.75 | 缩写形式的名称(assay_id ↔ ASSI、confidence_score ↔ CONSC) |
| PatternTypeScorer | 0.7 | 根据样本值推断的语义类型——email、date_iso、phone、uuid、url、zip、currency |
| ProfileScorer | 0.5 | 统计特征相似度——数据类型、空值率、唯一值率、长度、基数 |
| FuzzyNameScorer | 0.4 | 规范化字段名称的 Jaro-Winkler 相似度(包含常见前缀规范化) |
| LLMScorer | 0.8 | 可插拔的 LLM 评分器(默认使用桩实现) |
引擎还会执行 常见前缀规范化——自动移除架构中统一使用的前缀,例如 prospect_,这样比较 City 和 prospect_City 时,就相当于比较 City 和 City。此外,可选的置信度校准会在分配后将原始分数转换为校准后的概率(真实数据上的 ECE 从 0.46 降至 0.005)。
功能
| Python | TypeScript | |
|---|---|---|
| 7 个内置评分器 | ✅ | ✅ |
| 匈牙利算法分配 | ✅ (scipy) | ✅ (随附实现) |
| 自定义评分器 | @infermap.scorer | defineScorer() |
| 领域词典 | ✅ (YAML) | ✅ (内联) |
| 置信度校准 | ✅ (Identity/Isotonic/Platt) | ✅ |
| 评分矩阵检查 | ✅ | ✅ |
| 内存数据 | Polars、Pandas、list[dict] | Array<Record> |
| 文件提供程序 | CSV、Parquet、XLSX | CSV、JSON |
| 架构定义文件 | YAML + JSON | JSON |
| 数据库提供程序 | SQLite、Postgres、DuckDB | SQLite、Postgres、DuckDB |
| 引擎配置 | YAML | JSON |
| 已保存的映射格式 | YAML | JSON |
| CLI | ✅ (Typer) | ✅ (node:util) |
| 应用于 DataFrame | ✅ | ❌(通过 CLI 重写 CSV) |
| 兼容边缘运行时 | ❌ | ✅ |
| 零运行时依赖 | 不适用 | ✅ |
| 准确率基准 | ✅(162 个案例,F1 为 0.84) | ✅(与另一实现的差异在 0.0005 以内) |
我该使用哪个包?
| 如果你要…… | 使用 |
|---|---|
| 构建 Python 数据管道或笔记本 | Python |
| 构建 Next.js 应用、Node 服务或浏览器工具 | TypeScript |
| 在无服务器边缘函数中运行映射 | TypeScript(零 Node 内置模块) |
| 在命令行上临时探索 CSV | Python CLI 功能更多;TS CLI 更精简 |
| 两者都用——Python 后端 + Next.js 管理界面 | 两者——输出可通过 JSON 配置格式互通 |
v0.3 新增内容
真实数据上的 F1 提升 18.3 个百分点,得益于四项叠加改进:
v0.2 baseline F1 0.657
+ min_conf 0.2 F1 0.765 (+10.8pp — empirically tuned threshold)
+ prefix-strip F1 0.821 (+5.6pp — City vs prospect_City now works)
+ InitialismScorer F1 0.840 (+1.9pp — ASSI, CONSC, RELATIT now work)
新功能:
- 领域词典 —
MapEngine(domains=["healthcare"])会加载针对你所在领域整理的别名。内置:generic(默认)、healthcare、finance、ecommerce。请参阅examples/09_domain_dictionaries.py。 - 置信度校准 —
MapEngine(calibrator=cal)会将原始分数转换为校准后的概率。内置:IsotonicCalibrator、PlattCalibrator。Valentine 的 ECE:0.46 → 0.005。请参阅examples/10_calibration.py。 - InitialismScorer — 匹配缩写式列名(
assay_id ↔ ASSI)。ChEMBL 的 F1:0.524 → 0.819。 - 常见前缀规范化 — 在模糊匹配前自动去除
prospect_、assays_等前缀。 - Valentine 语料库 — 来自 Valentine 基准测试的 82 个真实模式匹配案例,可用于准确性测试。
- 完整的 TypeScript 功能对等 — 已移植所有新功能。186 项 TS 测试。基准测试 F1 与 Python 相差不到 0.0005。
自定义评分器
Python
import infermap
from infermap.types import FieldInfo, ScorerResult
@infermap.scorer("prefix_scorer", weight=0.8)
def prefix_scorer(source: FieldInfo, target: FieldInfo) -> ScorerResult | None:
if source.name[:3].lower() != target.name[:3].lower():
return None
return ScorerResult(score=0.85, reasoning=f"Shared prefix '{source.name[:3]}'")
from infermap.engine import MapEngine
from infermap.scorers import default_scorers
engine = MapEngine(scorers=[*default_scorers(), prefix_scorer])
TypeScript
import { MapEngine, defaultScorers, defineScorer, makeScorerResult } from "infermap";
const prefixScorer = defineScorer(
"prefix_scorer",
(source, target) => {
if (source.name.slice(0, 3).toLowerCase() !== target.name.slice(0, 3).toLowerCase()) {
return null;
}
return makeScorerResult(0.85, `Shared prefix '${source.name.slice(0, 3)}'`);
},
0.8 // weight
);
const engine = new MapEngine({
scorers: [...defaultScorers(), prefixScorer],
});
CLI 示例
两个包中的 CLI 用法相同:
# Map two files and print a report
infermap map crm_export.csv canonical_customers.csv
# Map and save the config (Python: --save, TS: -o)
infermap map crm_export.csv canonical_customers.csv -o mapping.json
# Apply a saved mapping to rename columns
infermap apply crm_export.csv --config mapping.json --output renamed.csv
# Inspect the schema of a file or DB table
infermap inspect crm_export.csv
infermap inspect "sqlite:///mydb.db" --table customers
# Validate a saved config against a source
infermap validate crm_export.csv --config mapping.json --required email,id --strict
配置参考
两个包都接受引擎配置(评分器权重覆盖 + 别名扩展)。Python 使用 YAML,TypeScript 使用 JSON;结构完全相同。
# Python: infermap.yaml
domains:
- healthcare
- finance
scorers:
LLMScorer:
enabled: false
FuzzyNameScorer:
weight: 0.3
aliases:
order_id:
- order_num
- ord_no
// TypeScript: infermap.config.json
{
"scorers": {
"LLMScorer": { "enabled": false },
"FuzzyNameScorer": { "weight": 0.3 }
},
"aliases": {
"order_id": ["order_num", "ord_no"]
}
}
完整的注释版参考请参阅 infermap.yaml.example。
文档
- 📖 Wiki — 两种语言的完整参考
- 🌐 文档网站
- 🧪 示例
- Python 示例 — 10 个带编号的脚本,涵盖基础映射、数据库、自定义评分器、配置、领域词典、校准和分数矩阵检查
- TypeScript 示例 — 基础映射、Next.js Edge Runtime、自定义评分器、数据库、领域词典、保存与复用
- 📓 在 Colab 中打开 — Python 笔记本
- 💬 GitHub 讨论区
- 🐛 问题跟踪器
作者
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。