Browse Source

完善打包脚本

master
张献维 2 weeks ago
parent
commit
542fcc11a8
  1. 2
      .gitignore
  2. 31
      Dockerfile
  3. 301
      README.md
  4. 7
      build.py
  5. 25
      install.sh
  6. 44
      institution_matcher.spec
  7. 1
      run.sh
  8. 8
      需求.md

2
.gitignore

@ -5,3 +5,5 @@
/output/*.xlsx
/logs/*.log
/build/institution_matcher/
/dist/

31
Dockerfile

@ -0,0 +1,31 @@
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 安装系统依赖
RUN apt-get update && apt-get install -y \
gcc \
g++ \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件
COPY requirements.txt .
# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 构建可执行文件
RUN python build.py
# 创建输出目录
RUN mkdir -p output logs temp
# 设置环境变量
ENV PYTHONPATH=/app/src
# 默认命令
CMD ["python", "main.py", "--help"]

301
README.md

@ -2,47 +2,21 @@
## 项目简介
本项目用于匹配新疆各政企单位的机构名称,支持简称匹配和模糊匹配功能。主要解决A_TREE和B_TREE两张表中机构数据的名称匹配问题。
本项目用于匹配新疆各政企单位的机构名称,支持简称匹配和模糊匹配功能。
## 功能特性
- ✅ 支持达蒙DM数据库连接
- ✅ 智能机构名称匹配算法
- ✅ 简称自动识别和匹配
- ✅ **关键词识别和匹配**
- ✅ **层次结构分析和归属信息提取**
- ✅ 多种输出格式(CSV、Excel、JSON)
- ✅ 详细的匹配报告和统计
- ✅ 支持ARM架构部署
- ✅ 完整的日志记录和进度显示
- ✅ 单元测试覆盖
## 项目结构
```
make2tree/
├── src/ # 源代码目录
│ ├── __init__.py
│ ├── config.py # 配置管理
│ ├── database.py # 数据库操作
│ ├── matcher.py # 机构名称匹配
│ └── output.py # 输出管理
├── tests/ # 测试目录
│ ├── __init__.py
│ └── test_matcher.py # 匹配器测试
├── main.py # 主程序
├── build.py # 打包脚本
├── test_data.py # 测试数据生成
├── run_tests.py # 测试运行脚本
├── requirements.txt # 依赖包
├── config.yaml # 配置文件
└── README.md # 项目文档
```
- 支持达蒙DM数据库连接
- 智能机构名称匹配算法
- 简称自动识别和匹配
- 多种输出格式(CSV、Excel、JSON)
- 详细的匹配报告和统计
- 支持ARM架构部署
## 安装要求
- Python 3.8+
- 达蒙DM数据库驱动 (dmPython)
- 达蒙DM数据库驱动
- 相关Python依赖包
## 快速开始
@ -69,20 +43,7 @@ database:
### 3. 运行程序
```bash
# 基本运行
python main.py
# 指定配置文件
python main.py --config config.yaml
# 指定输出目录
python main.py --output-dir output
# 保存结果到数据库
python main.py --save-to-db
# 调整匹配参数
python main.py --threshold 0.8 --max-matches 5
```
### 4. 使用打包版本
@ -97,264 +58,32 @@ python build.py
## 命令行参数
| 参数 | 简写 | 说明 | 默认值 |
|------|------|------|--------|
| `--config` | `-c` | 配置文件路径 | `config.yaml` |
| `--output-dir` | `-o` | 输出目录 | `output` |
| `--save-to-db` | - | 保存结果到数据库 | `False` |
| `--threshold` | `-t` | 相似度阈值 | `0.8` |
| `--max-matches` | `-m` | 最大匹配数 | `5` |
- `--config, -c`: 配置文件路径
- `--output-dir, -o`: 输出目录
- `--save-to-db`: 保存结果到数据库
- `--threshold, -t`: 相似度阈值
- `--max-matches, -m`: 最大匹配数
## 输出文件
程序运行后会生成以下文件:
- `matching_results_YYYYMMDD_HHMMSS.csv`: 匹配结果CSV文件
- `matching_results_YYYYMMDD_HHMMSS.xlsx`: 匹配结果Excel文件(包含多个工作表)
- `matching_results_YYYYMMDD_HHMMSS.xlsx`: 匹配结果Excel文件
- `matching_report_YYYYMMDD_HHMMSS.json`: 匹配报告JSON文件
## 匹配算法
### 相似度计算
使用多种算法计算机构名称相似度:
- 完全匹配:100%相似度
- 高度匹配:85%-99%相似度
- 中度匹配:75%-84%相似度
- 低度匹配:70%-74%相似度
### 简称支持
## 简称支持
支持常见机构简称,如:
- 妇女联合会 → 妇联
- 政治协商会议 → 政协
- 人民代表大会常务委员会 → 人大常委会
- 人民政府 → 政府
- 发展和改革委员会 → 发改委
- 人力资源和社会保障局 → 人社局
- 卫生健康委员会 → 卫健委
- 应急管理局 → 应急局
- 市场监督管理局 → 市场监管局
- 生态环境局 → 环保局
- 住房和城乡建设局 → 住建局
- 交通运输局 → 交通局
- 农业农村局 → 农业局
- 文化和旅游局 → 文旅局
- 退役军人事务局 → 退役军人局
- 医疗保障局 → 医保局
### 关键词识别
系统能够自动识别机构名称中的关键词,包括:
#### 政府机构关键词
- 办公厅、办公室、委员会、局、厅、部、处、科、股
- 妇联、工会、团委、残联、科协、文联、侨联、台联
- 工商联、红十字会、慈善总会、志愿者协会
#### 事业单位关键词
- 中心、站、所、院、校、馆、园、场、队、组
- 医院、学校、图书馆、博物馆、文化馆、体育馆
#### 企业单位关键词
- 公司、集团、企业、厂、矿、农场、林场、牧场
#### 特殊机构关键词
- 党校、行政学院、社会主义学院、团校、妇干校
- 参事室、文史馆、地方志办、研究室
#### 统计相关关键词
- 统计局、调查队、普查中心、统计站
### 层次结构分析
系统能够通过父节点和上级节点分析机构的归属信息:
#### 行政区划层次
- **省级**: 自治区、省、直辖市
- **市级**: 市、自治州、地区、盟
- **县级**: 县、自治县、区、旗、市辖区
- **乡级**: 乡、镇、街道、民族乡
- **村级**: 村、社区、居委会、村委会
#### 层次结构示例
```
新疆维吾尔自治区 (省级)
└── 乌鲁木齐市 (市级)
└── 天山区 (县级)
└── 新疆维吾尔自治区妇女联合会 (机构)
```
系统会提取每个机构的完整归属路径,用于更精确的匹配。
## 匹配结果字段
匹配结果包含以下字段:
### 基本信息
- `a_id`: A_TREE机构ID
- `a_name`: A_TREE机构名称
- `b_id`: B_TREE机构ID
- `b_name`: B_TREE机构名称
### 相似度信息
- `similarity_score`: 综合相似度分数
- `name_similarity`: 名称相似度分数
- `keyword_similarity`: 关键词相似度分数
- `admin_similarity`: 行政区划相似度分数
- `match_type`: 匹配类型
### 关键词信息
- `a_keywords`: A_TREE机构关键词
- `b_keywords`: B_TREE机构关键词
### 行政区划信息
- `a_province`: A_TREE机构所属省份
- `a_city`: A_TREE机构所属城市
- `a_county`: A_TREE机构所属区县
- `b_province`: B_TREE机构所属省份
- `b_city`: B_TREE机构所属城市
- `b_county`: B_TREE机构所属区县
## 测试
### 运行测试
```bash
# 运行所有测试
python run_tests.py
# 运行特定测试
python -m unittest tests.test_matcher
```
### 生成测试数据
```bash
python test_data.py
```
## 部署
### ARM架构部署
```bash
# 构建ARM版本
python build.py
# 安装到系统
sudo ./install.sh
```
### Docker部署
```bash
# 构建Docker镜像
docker build -t institution-matcher .
# 运行容器
docker run -v $(pwd)/output:/app/output institution-matcher
```
## 配置说明
### 数据库配置
```yaml
database:
host: "localhost" # 数据库主机
port: 5236 # 数据库端口
username: "your_username" # 用户名
password: "your_password" # 密码
database: "your_database" # 数据库名
charset: "utf8" # 字符集
```
### 匹配配置
```yaml
matching:
similarity_threshold: 0.8 # 相似度阈值
max_matches: 5 # 最大匹配数
enable_abbreviation: true # 启用简称匹配
```
### 日志配置
```yaml
logging:
level: "INFO" # 日志级别
format: "{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}"
file: "logs/matching.log" # 日志文件
rotation: "10 MB" # 日志轮转大小
retention: "30 days" # 日志保留时间
```
## 性能优化
- 使用pandas进行高效数据处理
- 支持批量匹配操作
- 进度条显示处理进度
- 内存优化的相似度计算
- 层次结构缓存机制
## 故障排除
### 常见问题
1. **数据库连接失败**
- 检查数据库配置信息
- 确认网络连接正常
- 验证用户权限
2. **匹配结果为空**
- 降低相似度阈值
- 检查数据格式是否正确
- 确认机构名称不为空
3. **内存不足**
- 减少最大匹配数
- 分批处理数据
- 增加系统内存
## 开发指南
### 添加新的简称映射
`src/matcher.py` 中的 `_load_abbreviation_map` 方法中添加新的映射:
```python
abbreviation_map = {
"新机构全称": "新机构简称",
# ... 其他映射
}
```
### 添加新的关键词
`src/matcher.py` 中的 `_load_institution_keywords` 方法中添加新的关键词:
```python
keywords = {
"新关键词1", "新关键词2",
# ... 其他关键词
}
```
### 扩展匹配算法
`src/matcher.py` 中的 `calculate_similarity` 方法中添加新的相似度算法。
## 许可证
MIT License
## 贡献
欢迎提交Issue和Pull Request来改进这个项目。
## 联系方式
如有问题或建议,请通过以下方式联系:
- 提交GitHub Issue
- 发送邮件至项目维护者

7
build.py

@ -97,13 +97,16 @@ def build_executable():
"--onefile", # 打包成单个文件
"--console", # 控制台应用
"--name", "institution_matcher", # 可执行文件名称
"--add-data", "config.yaml;.", # 添加配置文件
"--add-data", "src;src", # 添加源代码目录
"--add-data", "config.yaml:.", # 添加配置文件
"--add-data", "src:src", # 添加源代码目录
"--paths", "src", # 添加src目录到Python路径
"--hidden-import", "dmPython",
"--hidden-import", "pandas",
"--hidden-import", "numpy",
"--hidden-import", "loguru",
"--hidden-import", "fuzzywuzzy",
"--hidden-import", "fuzzywuzzy.fuzz",
"--hidden-import", "fuzzywuzzy.string_utils",
"--hidden-import", "python-Levenshtein",
"--hidden-import", "yaml",
"--hidden-import", "tqdm",

25
install.sh

@ -0,0 +1,25 @@
#!/bin/bash
# 机构名称匹配工具安装脚本
echo "正在安装机构名称匹配工具..."
# 创建安装目录
INSTALL_DIR="/usr/local/bin/institution_matcher"
sudo mkdir -p $INSTALL_DIR
# 复制可执行文件
sudo cp dist/institution_matcher $INSTALL_DIR/
sudo chmod +x $INSTALL_DIR/institution_matcher
# 创建配置文件目录
CONFIG_DIR="/etc/institution_matcher"
sudo mkdir -p $CONFIG_DIR
# 复制配置文件
sudo cp config.yaml $CONFIG_DIR/
# 创建软链接
sudo ln -sf $INSTALL_DIR/institution_matcher /usr/local/bin/institution_matcher
echo "安装完成!"
echo "使用方法: institution_matcher --help"

44
institution_matcher.spec

@ -0,0 +1,44 @@
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['main.py'],
pathex=['src'],
binaries=[],
datas=[('config.yaml', '.'), ('src', 'src')],
hiddenimports=['dmPython', 'pandas', 'numpy', 'loguru', 'fuzzywuzzy', 'fuzzywuzzy.fuzz', 'fuzzywuzzy.string_utils', 'python-Levenshtein', 'yaml', 'tqdm', 'openpyxl'],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='institution_matcher',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)

1
run.sh

@ -0,0 +1 @@
./dist/institution_matcher --config config.yaml --a-csv data/a.csv --b-csv data/b.csv --output-csv output/result.csv --threshold 0.85 --max-matches 10

8
需求.md

@ -14,6 +14,14 @@
2. 有的机构存在全程,有的机构存在简称
3. 存在全程的机构多数包含归属的省(或自治区)市(或自治州、地区)县(或自治县、区)
4. 而机构简称,也可以通过父节点和上级节点,直到其归属的的省(或自治区)市(或自治州、地区)县(或自治县、区)
6. 在完善基本法人单位匹配后,针对该法人单位的下级节点(基本为内设单位或内部法人单位)
1. 内部法人单位按照法人单位进行匹配
2. 该内部的内设机构按照同法人单位下进行内设单位的匹配
3. 部分单位可能存在名称包含“内设单位”机构,其内部其实和对应法人单位下内设机构是对应的
4. 需要注意数据部分
a. 多数公务员机构的内设机构为“某某科”(为公务员单位),有别于“某某中心”(为事业单位)
b. 部分法人单位机构的内设机构A与对应的法人单位B下的内设机构C可能存在为 A = B + C
5. 部分单位可能存在不匹配情况,不匹配时,请将A_TREE需要移入B_TREE的数据输出到 c.csv 中
## 需要完成