当前位置:首页>python>名师讲堂|使用 Python 语言测算专利的创新突破度:ACD指数和mACD指数

名师讲堂|使用 Python 语言测算专利的创新突破度:ACD指数和mACD指数

  • 2026-10-11 07:44:11
名师讲堂|使用 Python 语言测算专利的创新突破度:ACD指数和mACD指数

由于借助 AI 工具学习编程已经变得非常容易了,因此之后的课程就不再默认进行视频讲解了,如果特别需要视频讲解也可以联系李老师预约讲解~讲义材料学习过程中遇到的问题也可以及时与李老师联系。

购买 RStata 名师讲堂会员即可参加该课程啦(之前的和未来的都可以参加)!

价格:2800/年 或者 4800/长期

购买会员可以从这里下单:https://rstata.duanshu.com/#/card/list/

名师讲堂会员权益:

  1. 参加每个月 3~4 次的名师讲堂课程;
  2. 参加平台上的其他 R 语言和 Stata 的课程;
  3. 以会员折扣价购买我们分享的数据资料(10 元/份);
  4. 课程内外的提问解答服务(课程外的尽量帮忙解决)。

* 如果发票可添加小编微信 r_stata2 (RStata 李老师)开具。如需数据资料,购买后可添加小编微信免费领取数据折扣卡。

更多关于 RStata 会员的更多信息可添加微信号 r_stata2 咨询:

课程主页(点击文末的阅读原文即可跳转):https://rstata.duanshu.com/#/brief/course/ba3a14585f3f4ee4af29333510b956eb


本次课程在原始 CD 指数(Funk & Owen-Smith, 2017)的基础上,介绍徐照宜等(2023)在《金融研究》上发表的改进算法:ACD 指数和 mACD 指数。改进的核心是解决"从未被引用专利"的歧义问题,以及调整分母以更好地反映专利的突破性。

本课程提供 Python 版本 的完整实现,通过 reticulate 包在 R Markdown 中调用 Python,与 R 语言版本计算结果完全一致。

附件中提供了相关论文 PDF 和计算代码。

一、背景:原始 CD 指数及其问题

1.1 CD 指数公式

CD 指数由 Funk & Owen-Smith (2017) 提出,用于衡量专利的创新突破程度:

1.2 三种引用情况的 CD 值

论文中的示意图如下:

1.3 原始 CD 指数的问题

  1. 从未被引用的专利 CD = 0:这与"渐进性专利"的 CD = -1 混淆
  2. 正负值相抵:多个专利的 CD 值正负相抵,汇总时相互抵消

二、改进的 ACD 和 mACD 指数

2.1 ACD 公式(论文原文)

2.2 mACD 公式(论文原文)

2.3 关键变量定义

2.4 三种引用情况的分子值

2.5 公式简化

2.6 ACD 值含义

# 此处内容需下载讲义材料查看~

2.7 mACD 的特殊意义

mACD = m_t × ACD,体现了专利在整体知识网络中的累积效应:

  • m_t 越大,说明目标专利及其后向引用专利被越多专利引用
  • mACD 可以大于 2,反映该专利在知识网络中的影响力越大

2.8 三个指数的关系

三、使用 reticulate 创建与管理 Python 虚拟环境

在 R 中通过 reticulate 包来调用 Python,最好的实践是为项目创建一个专属的 Python 虚拟环境,将所需依赖隔离到独立空间,避免与系统 Python(如 Anaconda)发生版本冲突。

重要说明(避免"已初始化"报错):reticulate 在 R 会话中只能绑定一次 Python——一旦某个 {python} 代码块运行,Python 解释器就被锁定,之后再调用 use_virtualenv() 会报错:

ERROR: The requested version of Python cannot be used, as another version has already been initialized.

因此,虚拟环境的激活必须在所有 {python} 代码块之前完成。本文档的解决方案是在 setup chunk 中通过 Sys.setenv(RETICULATE_PYTHON = ...) 提前锁定 Python 路径,这是 reticulate 选取 Python 的最高优先级入口。

3.1 安装 reticulate(仅首次)

# 设置 CRAN 镜像(knit 时 R 处于非交互模式,不会自动选择镜像)
options(repos = c(CRAN = "https://mirrors.tuna.tsinghua.edu.cn/CRAN/"))
# 仅在尚未安装时才安装,避免每次 knit 都重装
if (!requireNamespace("reticulate", quietly = TRUE)) {
  install.packages("reticulate")
  message("reticulate 安装完成!")
} else {
  message("reticulate 已安装,版本:", packageVersion("reticulate"))
}

3.2 虚拟环境初始化原理(已在 setup chunk 中完成)

本文档的 setup chunk(隐藏运行)包含如下逻辑:

library(reticulate)
.venv_name   <-".venv"
.venv_python <- virtualenv_python(.venv_name)
# 虚拟环境不存在时自动创建
if(!file.exists(.venv_python)){
  virtualenv_create(.venv_name)
  .venv_python <- virtualenv_python(.venv_name)
}
# 通过环境变量抢先锁定 Python(优先级最高,早于任何 {python} chunk)
Sys.setenv(RETICULATE_PYTHON = .venv_python)
use_virtualenv(.venv_name, required =TRUE)

3.3 在虚拟环境中安装 Python 包(仅首次)

# 检查关键包是否已安装,缺失的才安装
py_pkgs <- c("numpy", "pandas")
installed <- py_list_packages(".venv")$package
need_install <- setdiff(py_pkgs, installed)
if (length(need_install) > 0) {
  virtualenv_install(".venv", packages = need_install)
  message("已安装缺失的包:", paste(need_install, collapse = ", "))
} else {
  message("所有 Python 包已就绪,无需安装")
}

3.4 验证激活状态

# 验证当前绑定的 Python 路径(应指向 .venv 目录)
py_config()

3.5 虚拟环境管理常用命令

# 查看所有已创建的虚拟环境
virtualenv_list()
# 删除虚拟环境(当不再需要时)
# virtualenv_remove(".venv")
# 升级某个包
# virtualenv_install(".venv", packages = "pandas", ignore_installed = TRUE)

四、数据来源与处理过程

4.1 原始数据

本课程使用的数据来源于中国专利数据库,包含 1985-2024年 上市公司申请的专利及其引用关系数据。

4.2 数据文件说明

本 Python 版本使用从 R 版本 RDS 文件转换的 CSV 格式数据:

处理方法可以参考 R 语言版本的课程。另外这三个文件已经可以用来计算全部上市公司 ACD 和 mACD 指数了,无需额外再处理了。

文件名
行数
列名
说明
patent_citations2.csv
46,102,368
newipzlid, newipzlid2, date, date2
5年窗口筛选后的引用数据
nobackrefs.csv
8,277,416
newipzlid2, cd_index
没有后向引用的专利(cd_index = 1)
patents_with_citations.csv
23,330,294
newipzlid
所有具有引用与被引用信息的专利ID列表

变量说明:

  • newipzlid:引用专利的ID(申请日的专利)
  • newipzlid2:被引用专利的ID(被引用的专利)
  • date:引用专利的申请日期
  • date2:被引用专利的申请日期

4.3 数据读取

读取本课程提供的处理后数据:

import pandas as pd
import numpy as np
from pathlib import Path
# 设置数据路径
DATA_DIR = Path(".")
# 读取专利引用数据(5年窗口)
print("正在读取数据...")
patent_citations2 = pd.read_csv(DATA_DIR / "patent_citations2.csv")
print(f"专利引用数据行数: {len(patent_citations2):,}")
# 转换日期列
patent_citations2['date'] = pd.to_datetime(patent_citations2['date'])
patent_citations2['date2'] = pd.to_datetime(patent_citations2['date2'])
# 读取上市公司专利数据
sspat = pd.read_csv(DATA_DIR / "2010年上市公司与专利数据匹配结果.csv")
print(f"上市公司专利数: {len(sspat):,}")
# 读取无后向引用专利
nobackrefs = pd.read_csv(DATA_DIR / "nobackrefs.csv")
print(f"无后向引用专利数: {len(nobackrefs):,}")
print("\n专利引用数据预览:")
print(patent_citations2.head())

专利引用数据的变量说明:

  • newipzlid:引用专利的ID(引用方)
  • newipzlid2:被引用专利的ID(被引用方)
  • date:引用专利的申请日期
  • date2:被引用专利的申请日期

五、计算示例

5.1 单个专利的计算逻辑

以某个专利为例,详细展示 ACD 和 mACD 的计算过程:

# 以某个专利为例
patent_id = 20190809613
# 获取目标专利信息
target_patent = patent_citations2[patent_citations2['newipzlid2'] == patent_id]
print("目标专利信息:")
print(target_patent)

步骤 1:获取后向引用专利

# 此处代码需下载讲义材料查看~

步骤 4:计算三种情况的专利集合

  • parta:既引用目标专利又引用后向引用专利
  • partb:只引用目标专利但不引用后向引用专利
  • partc:只引用后向引用专利但不引用目标专利
# 三种情况的专利集合
part1_set = set(part1)
part2_set = set(part2)
parta = len(part1_set & part2_set)  # 既引用目标又引用后向引用
partb = len(part1_set - part2_set)  # 只引用目标专利
partc = len(part2_set - part1_set)  # 只引用后向引用专利
print(f"parta (既引用目标又引用后向引用): {parta}")
print(f"partb (只引用目标专利): {partb}")
print(f"partc (只引用后向引用专利): {partc}")

步骤 5:计算 n_t 和 m_t

  • n_t = parta + partb(引用目标专利的专利数)
  • m_t = parta + partb + partc(引用目标专利或后向引用专利的专利总数)
n_t = parta + partb
m_t = parta + partb + partc
print(f"n_t = {n_t}")
print(f"m_t = {m_t}")

步骤 6:计算 ACD 和 mACD

# 此处代码需下载讲义材料查看~

5.2 封装计算函数

将上述逻辑封装成函数,方便批量计算:

# 此处代码需下载讲义材料查看~
# 测试函数
test_result = calc_patent_acd_macd(20190809613, patent_citations2)
print("测试结果:")
print(test_result)

六、批量计算与多线程优化

6.1 筛选需要计算的专利

并非所有专利都需要计算。如果某个专利没有后向引用,则所有引用它的专利都落在 partb,ACD = 2:

# 没有后向引用的专利
nobackrefs_ids = set(nobackrefs['newipzlid2'].tolist())
all_cited_patents = set(patent_citations2['newipzlid2'].unique())
patents_with_backrefs = all_cited_patents - nobackrefs_ids
print(f"无后向引用专利数: {len(nobackrefs_ids):,}")
print(f"有后向引用专利数: {len(patents_with_backrefs):,}")

6.2 批量计算

读取上市公司专利数据,只计算需要计算的专利:

# 筛选上市公司中有后向引用的专利
sspat_ids = set(sspat['newipzlid'].unique())
need_calc_ids = list(sspat_ids & patents_with_backrefs)
print(f"需要计算的有后向引用的上市公司专利数: {len(need_calc_ids):,}")
# 测试:计算前10个专利
test_ids = need_calc_ids[:10]
results = []
for pid in test_ids:
    result = calc_patent_acd_macd(pid, patent_citations2)
    results.append(result)
results_df = pd.DataFrame(results)
print("\n批量计算结果:")
print(results_df.to_string(index=False))

6.3 多线程计算

由于计算量较大,使用多线程加速(需在独立脚本中执行):

注意:在 Rmd 文档中,由于 reticulate 的限制,多线程代码需要在独立的 Python 脚本中执行。以下是多线程脚本的关键代码示例。

# 此处代码需下载讲义材料查看~

七、结果汇总

7.1 合并计算结果

将计算结果与上市公司专利数据合并:

# 合并到上市公司专利数据
patent_with_backrefs = sspat.merge(
    results_df,
    on='newipzlid',
    how='inner'
)
print(f"有后向引用的上市公司专利数: {len(patent_with_backrefs):,}")

7.2 结果展示

print("计算结果预览:")
print(results_df.to_string(index=False))

7.3 统计汇总

print("\n=== ACD 统计 ===")
print(results_df['ACD'].describe())
print("\n=== mACD 统计 ===")
print(results_df['mACD'].describe())

7.4 公司层面汇总

将专利层面的 ACD/mACD 汇总到公司-年份层面:

# 添加公司信息
# 此处代码需下载讲义材料查看~

八、附件说明

本课程提供了以下附件:

8.1 数据文件

文件名
行数
说明
patent_citations2.csv
46,102,368
推荐使用
:5年窗口筛选后的引用数据
nobackrefs.csv
8,277,416
无后向引用的专利(ACD=2)
patents_with_citations.csv
23,330,294
具有引用与被引用信息的专利ID列表

8.2 代码文件

文件名
说明
acd_macd.py
核心计算模块
计算ACD_mACD.py
单线程计算脚本
计算ACD_mACD_多线程.py
多线程计算脚本
合并汇总ACD_mACD.py
结果合并和汇总脚本

8.3 参考文件

文件名
说明
金融科技、数字化转型与企业突破性创新——基于全球专利引用复杂网络的分析_徐照宜.pdf
参考文献
pic1.png
论文中三种引用情况示意图

8.4 直接运行 Python 脚本

如果不想在 Rmd 中运行,也可以直接使用终端执行 Python 脚本:

# 进入项目目录
cd"使用 Python 语言测算专利的创新突破度:ACD指数和mACD指数"
# 激活虚拟环境(使用独立 venv)
python3 -m venv venv
source venv/bin/activate
pip install pandas numpy
# 运行计算脚本
python 计算ACD_mACD.py
python 计算ACD_mACD_多线程.py
python 合并汇总ACD_mACD.py

九、参考文献

  1. Funk, R. J., & Owen-Smith, J. (2017). A dynamic network measure of technological change. Management Science, 63(12), 4174-4187.

  2. 徐照宜, 巩冰, 陈彦名, 成程. 金融科技、数字化转型与企业突破性创新——基于全球专利引用复杂网络的分析[J]. 金融研究, 2023(10): 47-65.

如何参加课程?

购买 RStata 名师讲堂会员即可参加该课程啦(之前的和未来的都可以参加)!

价格:2800/年 或者 4800/长期

购买会员可以从这里下单:https://rstata.duanshu.com/#/card/list/

名师讲堂会员权益:

  1. 参加每个月 3~4 次的名师讲堂课程;
  2. 参加平台上的其他 R 语言和 Stata 的课程;
  3. 以会员折扣价购买我们分享的数据资料(10 元/份);
  4. 课程内外的提问解答服务(课程外的尽量帮忙解决)。

* 如果发票可添加小编微信 r_stata2 (RStata 李老师)开具。如需数据资料,购买后可添加小编微信免费领取数据折扣卡。

更多关于 RStata 会员的更多信息可添加微信号 r_stata2 咨询:

课程主页(点击文末的阅读原文即可跳转):https://rstata.duanshu.com/#/brief/course/ba3a14585f3f4ee4af29333510b956eb

最新文章

随机文章