名师讲堂|自动化水平测度:使用 Stata 筛选自动化相关专利

传统的专利筛选通常是基于分类号或者关键词的。基于分类号的筛选前提是有相应的分类标准,例如绿色技术专利、绿色低碳技术专利、数字经济产业相关专利、战略新兴专利等,这些之前给大家分享过很多,都可以在平台上找到,例如:

1985~2024 年数字经济产业相关专利筛选结果:https://rstata.duanshu.com/#/brief/course/d5dfb9ca0858457ebc4f176fce9fee80

基于关键词筛选的通常是研究者自行选取一些关键词,然后通过标题、摘要等文本内容进行筛选,例如平台上给大家分享的金融科技相关专利:

1985~2022 年金融科技专利筛选结果:https://rstata.duanshu.com/#/brief/course/4473051372dd42d992c42fd79b107e73

也有同时根据分类号和关键词筛选的,例如国家知识产权局标准的绿色技术专利和绿色低碳技术专利:

使用 Stata 筛选绿色技术专利(国家知识产权局标准):https://rstata.duanshu.com/#/brief/course/66607ec05c3748699883f5e834682125

仅仅基于关键词筛选的话往往存在一个问题,就是所选的关键词词典不全,这会导致筛选的结果偏少,另外就是关键词选择错误,则会导致筛选错误。然而想要自行制定 IPC 分类号筛选标准又是一件非常困难且工作量巨大的事情。

为此「自动化能否导致企业生产率增长与分化——基于工作任务的差异替代视角」中使用了一种很有意思的方法:

  1. 根据关键词初步筛选自动化相关专利;
  2. 使用 IPC 的“组”作为类别,计算自动化专利数量占比作为该类别的自动化指数;
  3. 根据自动化指数从小到大的顺序对 IPC 专利类别排序,再设置某一百分位数作为阈值,高于这一阈值的专利类别即为自动化专利类别。

这就解决了上面所提出的问题。

关键词词典如下:

今天的课程我们将讲解如何在 Stata 中进行这一筛选过程。

初步筛选

专利数据使用的是我们之前分享的:

1985~2024 年专利申请与授权数据(版本 3,含申请人所处的省市区县):https://rstata.duanshu.com/#/brief/course/2397451274c546d3a36e156ffc865988

由于数据巨大,附件中并没有提供。

初步筛选:快速降低数据文件大小

首先我们进行一个初步的筛选:

cd "~/Desktop/自动化水平测度:使用 Stata 筛选自动化相关专利"

*- 循环所有年份
cap mkdir "初步筛选1"
forval y = 1985/2024 {
di "`y'"
qui {
use "/Volumes/rstata2t/newIP专利数据分年/`y'", clear
drop if 专利类型 == "外观设计"
keep newipzlid IPC 摘要 公开公告号
local regexplist1 = "自动化|自动|机器人|数控|CNC|计算机辅助|CAD|柔性化|柔性生产|柔性制造|可编程控制器|PLC|3D 打印|增材制造|劳动力|工人|人员|人力|人工|无人|人工智能|自然语言|机器学习|生产|制造|机器|设备|装置|仪器|器械|机械|无需|不需|避免|解放|减小|减少|减轻|节约|节省|降低|代替|替代|省力"
local regexplist2 = "生产|制造|机器|设备|装置|仪器|器械|机械"
local regexplist3 = "无需|不需|避免|解放|减小|减少|减轻|节约|节省|降低|代替|替代|省力"
keep if ustrregexm(摘要, "`regexplist1'") | (ustrregexm(摘要, "自动") & ustrregexm(摘要, "`regexplist2'")) | (ustrregexm(摘要, "自动") & ustrregexm(摘要, "`regexplist2'")) | (ustrregexm(摘要, "劳动力|工人|人员|人力|人工|无人") & ustrregexm(摘要, "`regexplist3'"))
save 初步筛选1/`y', replace
}
}

appendall 初步筛选1
save 初步筛选1, replace

经过初步筛选的 初步筛选1.dta 依然非常巨大(22GB),所以大家如果自己允许的话,还是不要直接合并所有年份的,而是循环处理各年的。

这里我选择了 2010~2012 三个年份的数据为例:

gen year = substr(newipzlid, 1, 4)
destring year, replace
keep if inlist(year, 2010, 2011, 2012)
save 初步筛选1a.dta, replace

数据概览如下:

精细筛选:根据自动化专利筛选标准进行逐步筛选

然后我们再根据上面的词典进行更为精细的筛选:

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

由于专利数据中同时包含了一些专利的申请和授权公告,所以还需要去除这种重复的:

use 自动化专利筛选结果, clear
*> (数据处理:微信公众号 RStata)
replace 公开公告号 = subinstr(公开公告号, "A", "", .)
*> (21,307 real changes made)
replace 公开公告号 = subinstr(公开公告号, "B", "", .)
*> (11,512 real changes made)
replace 公开公告号 = subinstr(公开公告号, "U", "", .)
*> (57,797 real changes made)
replace 公开公告号 = subinstr(公开公告号, "S", "", .)
*> (0 real changes made)
duplicates drop 公开公告号, force
*> Duplicates in terms of 公开公告号
*> (133,761 observations deleted)
drop 公开公告号
save 自动化专利筛选结果, replace
*> file 自动化专利筛选结果.dta saved

由于需要计算自动化专利数量的占比,所以我们还需要知道在总的专利数据中各类别的数量。专利数据sim.dta 文件是 2010~2012 年的专利数据,不过只有 newipzlid、公开公告号、IPC 三个变量。去除重复的:

use 专利数据sim, clear
*> (数据处理:微信公众号 RStata)
replace 公开公告号 = subinstr(公开公告号, "A", "", .)
*> (1,073,605 real changes made)
replace 公开公告号 = subinstr(公开公告号, "B", "", .)
*> (499,517 real changes made)
replace 公开公告号 = subinstr(公开公告号, "U", "", .)
*> (1,422,898 real changes made)
replace 公开公告号 = subinstr(公开公告号, "S", "", .)
*> (0 real changes made)
duplicates drop 公开公告号, force
*> Duplicates in terms of 公开公告号
*> (521,475 observations deleted)
keep newipzlid IPC
drop if mi(IPC)
*> (354,540 observations deleted)
save 全部专利IPC, replace
*> file 全部专利IPC.dta saved
export delimited using 全部专利IPC.csv, replace
*> file 全部专利IPC.csv saved
use 自动化专利筛选结果.dta, clear
*> (数据处理:微信公众号 RStata)
keep newipzlid
destring, replace
*> newipzlid: all characters numeric; replaced as double
save 自动化专利筛选结果newipzlid, replace
*> file 自动化专利筛选结果newipzlid.dta saved

为了分类别统计专利数据,我们需要把每个专利的 IPC 分类号拆分开,之前介绍过 Stata 中进行这一操作的方法,不过这个操作还是用 R 语言更高效:

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

计算各分类号类别的自动化指数

然后就可以分别统计各个类别的全部专利数量和自动化专利数量了:

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

专利 IPC 分类号的结构如下:

获取相应阈值标准下的所有专利

计算 80、85、90 分位数:

use 各IPC类别自动化专利数量, clear
_pctile ratio, p(80 85 90)
ret list
*> scalars:
*> r(r1) = .061643835157156
*> r(r2) = .0742358043789864
*> r(r3) = .091503269970417
hist ratio, xline(`=r(r1)' `=r(r2)' `=r(r3)')
*> (bin=36, start=0, width=.02777778)

以 85 为例,筛选该阈值分类下的自动化专利:

use 各IPC类别自动化专利数量, clear
_pctile ratio, p(80 85 90)
keep if ratio >= r(r2)
*> (4,220 observations deleted)
drop ratio
save class85, replace
*> file class85.dta saved
*- 匹配专利 newipzlid
use class85, clear
duplicates drop class, force
*> Duplicates in terms of class
*> (0 observations are duplicates)
merge 1:m class using newipzlid_class
*> Result Number of obs
*> -----------------------------------------
*> Not matched 3,944,197
*> from master 0 (_merge==1)
*> from using 3,944,197 (_merge==2)
*> Matched 429,572 (_merge==3)
*> -----------------------------------------
keep if _m == 3
*> (3,944,197 observations deleted)
keep newipzlid
duplicates drop newipzlid, force
*> Duplicates in terms of newipzlid
*> (103,847 observations deleted)
tostring newipzlid, format(%16.0f) replace
*> newipzlid was double now str11
save newipzlid_auto85, replace
*> file newipzlid_auto85.dta saved
list in 1/10
*> +-------------+
*> | newipzlid |
*> |-------------|
*> 1. | 2010931560 |
*> 2. | 2010833959 |
*> 3. | 20120852968 |
*> 4. | 20120863889 |
*> 5. | 20120628595 |
*> |-------------|
*> 6. | 20121062658 |
*> 7. | 20110140190 |
*> 8. | 2010686514 |
*> 9. | 20111080532 |
*> 10. | 2010785532 |
*> +-------------+

同样的方式生成 80 和 90 的:

*- 同样生成 80 和 90 的
use 各IPC类别自动化专利数量, clear
_pctile ratio, p(80 85 90)
keep if ratio >= r(r1)
*> (3,971 observations deleted)
drop ratio
duplicates drop class, force
*> Duplicates in terms of class
*> (0 observations are duplicates)
merge 1:m class using newipzlid_class
*> Result Number of obs
*> -----------------------------------------
*> Not matched 3,716,291
*> from master 0 (_merge==1)
*> from using 3,716,291 (_merge==2)
*> Matched 657,478 (_merge==3)
*> -----------------------------------------
keep if _m == 3
*> (3,716,291 observations deleted)
keep newipzlid
duplicates drop newipzlid, force
*> Duplicates in terms of newipzlid
*> (165,115 observations deleted)
tostring newipzlid, format(%16.0f) replace
*> newipzlid was double now str11
save newipzlid_auto80, replace
*> file newipzlid_auto80.dta saved
use 各IPC类别自动化专利数量, clear
_pctile ratio, p(80 85 90)
keep if ratio >= r(r3)
*> (4,467 observations deleted)
drop ratio
duplicates drop class, force
*> Duplicates in terms of class
*> (0 observations are duplicates)
merge 1:m class using newipzlid_class
*> Result Number of obs
*> -----------------------------------------
*> Not matched 4,098,275
*> from master 0 (_merge==1)
*> from using 4,098,275 (_merge==2)
*> Matched 275,494 (_merge==3)
*> -----------------------------------------
keep if _m == 3
*> (4,098,275 observations deleted)
keep newipzlid
duplicates drop newipzlid, force
*> Duplicates in terms of newipzlid
*> (58,984 observations deleted)
tostring newipzlid, format(%16.0f) replace
*> newipzlid was double now str11
save newipzlid_auto90, replace
*> file newipzlid_auto90.dta saved

从上面的筛选过程可以看出,使用不同年份的专利会得到不同的筛选结果。实际研究中需要结合自己的需要选择年份,或者,使用所有年份的数据进行统一筛选。

上市公司自动化专利筛选

以上市公司为例,其他的也都类似。

有了上面的 newipzlid_auto80.dta、newipzlid_auto85.dta、newipzlid_auto90.dta 就可以快速的从上市公司专利里面筛选自动化专利并统计数量了。

上市公司专利数据在这里:

1985~2024 年上市公司与专利数据匹配结果(版本3, 含申请、授权信息):https://rstata.duanshu.com/#/brief/course/04100321f88b411f90429be934934bff

上市公司专利数据sim.dta 是 2010~2012 年上市公司专利数据的简化版,只包含了:股票代码、newipzlid、年份、公开公告号、专利类型、IPC、授权公告日变量。

统计各公司各年的专利申请量:

use 上市公司专利数据sim, clear
replace 公开公告号 = subinstr(公开公告号, "A", "", .)
replace 公开公告号 = subinstr(公开公告号, "B", "", .)
replace 公开公告号 = subinstr(公开公告号, "U", "", .)
replace 公开公告号 = subinstr(公开公告号, "S", "", .)
replace 专利类型 = "发明" if index(专利类型, "发明")
duplicates drop 股票代码 公开公告号, force
contract 股票代码 专利类型 年份
spread 专利类型 _freq
foreach i of varlist 发明 实用新型 {
replace `i' = 0 if mi(`i')
}
gen 总专利申请量 = 发明 + 实用新型

foreach i of varlist 发明 实用新型 {
ren `i' `i'申请量
}
drop 外观设计
save tempdata1, replace

再统计申请并最终被授权的数量:

use 上市公司专利数据sim, clear
drop if mi(授权公告日)
replace 公开公告号 = subinstr(公开公告号, "A", "", .)
replace 公开公告号 = subinstr(公开公告号, "B", "", .)
replace 公开公告号 = subinstr(公开公告号, "U", "", .)
replace 公开公告号 = subinstr(公开公告号, "S", "", .)
replace 专利类型 = "发明" if index(专利类型, "发明")
duplicates drop 股票代码 公开公告号, force
contract 股票代码 专利类型 年份
spread 专利类型 _freq
foreach i of varlist 发明 实用新型 {
replace `i' = 0 if mi(`i')
}
gen 总专利授权量 = 发明 + 实用新型

foreach i of varlist 发明 实用新型 {
ren `i' `i'授权量
}
drop 外观设计
save tempdata2, replace

循环统计 80、85、90 阈值下自动化专利的申请与授权量:

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

匹配上面所有的结果数据就可以了:

use tempdata1.dta, clear
merge 1:1 股票代码 年份 using tempdata2.dta
drop _m
merge 1:1 股票代码 年份 using tempdata1_80.dta
drop _m
merge 1:1 股票代码 年份 using tempdata2_80.dta
drop _m
merge 1:1 股票代码 年份 using tempdata1_85.dta
drop _m
merge 1:1 股票代码 年份 using tempdata2_85.dta
drop _m
merge 1:1 股票代码 年份 using tempdata1_90.dta
drop _m
merge 1:1 股票代码 年份 using tempdata2_90.dta
drop _m

foreach i of varlist *量* {
replace `i' = 0 if mi(`i')
}
save 上市公司自动化专利申请与授权量, replace

点击这里跳转到 RStata 短书平台获取附件:名师讲堂|自动化水平测度:使用 Stata 筛选自动化相关专利

评论