You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

企业名称匹配模型选型咨询:解决多命名规范下的同企识别问题

企业名称同主体分组识别方案(针对大规模多规范数据集)

核心思路

针对50万条来自不同基金、命名规则混乱的企业名称,传统字符串匹配(Levenshtein距离、模糊匹配)无法处理语义一致但后缀差异大的情况,ChatGPT小批量可行但不支持大规模计算。推荐采用预训练语言模型生成语义嵌入 + 近似近邻聚类的方案,既保留语义理解能力,又能高效处理百万级数据。

推荐方案细节

1. 预处理规则(前置步骤)

先通过正则批量清洗常见冗余后缀/前缀,减少无效噪声,提升后续模型效果:

  • 移除基金常用后缀:Common Stock、Ordinary Shares、Class A/B/C、Preferred Stock
  • 统一企业后缀格式:将Inc、Corp、LLC、Ltd等统一替换为无后缀形式(或保留一种)
  • 大小写归一化:全部转为小写(适配英文预训练模型)

2. 语义嵌入生成(预训练模型)

使用轻量型预训练语言模型(如DistilBERT)将企业名称转换为高维语义向量,这类模型能捕捉"Apple Inc"与"Apple Common Stock"的核心语义关联,远优于字符串匹配。

3. 大规模聚类分组

用FAISS库实现近似近邻检索,快速将语义向量相似的企业名称归为同一组,解决50万条数据的计算效率问题。

演示代码与示例数据

示例数据(模拟多基金命名)

id,fund_source,company_name
1,Alpha Fund,Apple Inc
2,Beta Fund,Apple Common Stock
3,Alpha Fund,Microsoft Corp
4,Beta Fund,Microsoft Ordinary Shares
5,Gamma Fund,Google LLC
6,Gamma Fund,Google Class A Common Stock
7,Alpha Fund,Amazon.com Inc
8,Beta Fund,Amazon Common Stock
9,Delta Fund,Facebook Inc
10,Delta Fund,Facebook Class B Common Stock

完整实现代码

import pandas as pd
import re
import torch
from transformers import DistilBertTokenizer, DistilBertModel
import faiss
import numpy as np

# ---------------------- 1. 数据加载与预处理 ----------------------
def clean_company_name(name):
    # 转为小写
    name = name.lower()
    # 移除常见基金后缀
    suffixes_to_remove = [
        r'\bcommon stock\b', r'\bordinary shares\b', r'\bclass [a-z]\b',
        r'\bpreferred stock\b', r'\binc\b', r'\bcorp\b', r'\bllc\b', r'\bltd\b'
    ]
    for suffix in suffixes_to_remove:
        name = re.sub(suffix, '', name, flags=re.IGNORECASE)
    # 去除多余空格
    name = re.sub(r'\s+', ' ', name).strip()
    return name

# 加载示例数据(实际替换为你的50万条数据集)
df = pd.read_csv('company_names.csv')
df['cleaned_name'] = df['company_name'].apply(clean_company_name)

# ---------------------- 2. 生成语义嵌入 ----------------------
# 加载预训练模型与tokenizer(英文场景用distilbert-base-uncased)
tokenizer = DistilBertTokenizer.from_pretrained('distilbert-base-uncased')
model = DistilBertModel.from_pretrained('distilbert-base-uncased')
model.eval()

def get_embedding(text):
    inputs = tokenizer(text, return_tensors='pt', padding=True, truncation=True, max_length=32)
    with torch.no_grad():
        outputs = model(**inputs)
    # 取<[BOS_never_used_51bce0c785ca2f68081bfa7d91973934]>的均值作为文本嵌入
    embedding = outputs.last_hidden_state.mean(dim=1).squeeze().numpy()
    return embedding

# 批量生成嵌入(可分批次处理50万条数据,避免内存溢出)
embeddings = np.array([get_embedding(name) for name in df['cleaned_name']])

# ---------------------- 3. FAISS聚类分组 ----------------------
# 构建FAISS索引
dimension = embeddings.shape[1]
index = faiss.IndexFlatL2(dimension)
index.add(embeddings)

# 检索相似向量(设置距离阈值,这里用0.5可根据实际调整)
distance_threshold = 0.5
_, indices = index.search(embeddings, k=len(df))

# 生成分组ID(连通分量分组)
visited = set()
group_id = 0
df['group_id'] = 0

for i in range(len(df)):
    if i not in visited:
        # 找到所有与当前样本相似的样本
        similar_indices = indices[i][np.where(indices[i] != i)[0]]
        similar_indices = [idx for idx in similar_indices if faiss.distance(embeddings[i], embeddings[idx]) <= distance_threshold]
        # 标记所有相似样本为同一组
        for idx in [i] + similar_indices:
            if idx not in visited:
                visited.add(idx)
                df.loc[idx, 'group_id'] = group_id
        group_id += 1

# 输出结果
print(df[['company_name', 'cleaned_name', 'group_id']])

优化建议

  • 批量处理:50万条数据需分批次生成嵌入,每批次处理1000-2000条,避免内存不足
  • 模型轻量化:若速度要求高,可替换为更轻量的模型如distilbert-base-uncased-finetuned-sst-2-english,或用Sentence-BERT专门做文本匹配
  • 阈值调整:FAISS的距离阈值需根据实际数据调整,可通过小批量验证找到最优值
  • 规则补充:可针对特定基金的命名规则补充自定义正则,进一步提升预处理效果

内容的提问来源于stack exchange,提问作者Lypse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 07:26:12