名师讲堂|使用 R 语言调用 deepseek-r1 模型判断上市公司高管的政治背景

AI 摘要:本课程主要介绍了如何借助 R 语言调用 DeepSeek-R1 模型来判断上市公司高管的政治背景:先介绍了前期需参考的课程、模型安装方法及所用的样本数据,接着详细说明了通过 DeepSeek API 和本地部署的离线模型两种方式调用模型的具体操作,包括相关代码和不同系统下的注意事项,然后阐述了对单条及批量简历信息的处理过程,包括循环与多线程处理、结果合并清洗,最后呈现了处理结果,即 139 条有效记录中 124 人无相关经历、15 人有相关经历,还提及可进一步获取具体政治层级但结果可靠性待确认。

最近给大家分享了上市公司高管简历数据:

历年上市公司高管、董事和监事简历、持股情况、任职情况变动数据(2025年8月初爬取):https://rstata.duanshu.com/#/brief/course/b75a97992e6e4e63a50ef8c79d3a47b7

使用该数据可以做一些很意思的研究,例如今天就给大家分享的这个课程,根据简历信息判断高管是否具有从政经历或政治背景。传统的数据处理方法中,我们需要人工一条条的查看和判断。不过现在我们可以借助 LLM 模型完成这种工作。

在之前的课程中我已经给大家介绍了使用本地部署的 LLM 模型进行经济增长目标提取:

使用 Stata 调用本地部署的大语言模型进行文本主要内容提取——历年政府工作报告中的经济增长目标提取:https://rstata.duanshu.com/#/brief/course/42f4af4244df4e26b1f8b625ab5e321d

在学习本课程之前,大家可以参考该课程安装 ollama 等预置项目。

类似 llama3.1,安装 deepseek-r1 模型可以使用下面的代码(在终端(Mac)或 DOS 窗口(Windows)运行):

ollama run deepseek-r1:1.5b

使用 1.5b 参数的模型会更快速点。

sampledata.dta 是我从高管简历数据里随机抽取的样本:

haven::read_dta("sampledata.dta") %>%
mutate(id = row_number()) -> df
df
#> # A tibble: 140 × 13
#> 股票代码 姓名 职务 起始日期 终止日期 名目 链接 出生日期 国籍 简历
#> <chr> <chr> <chr> <date> <chr> <chr> <chr> <dbl> <chr> <chr>
#> 1 002128 周舜华 监事 2018-05-07 "2019-0… 第6届监… http… 1958 "" 周舜华先…
#> 2 600179 许文祥 副董事长 2004-12-27 "2008-0… 第3届董… http… 1952 "中国"… 许文祥先…
#> 3 601808 赵璧 职工代表监事…… 2019-07-30 "" 第2届监… http… 198106 "中国"… 赵璧先生…
#> 4 002239 王艳妍 董事 2012-11-16 "2015-1… 第3届董… http… 198212 "中国"… 王艳妍:…
#> 5 600203 李震 监事会主席…… 2013-02-01 "2015-1… 第5届监… http… 196307 "" 李震,男…
#> 6 000737 韩长纯 监事会主席…… 2009-05-15 "2012-1… 第5届监… http… 196512 "" 韩长纯:…
#> 7 002576 姜煜峰 董事长 2014-09-15 "2017-0… 第3届董… http… 1969 "中国"… 姜煜峰:…
#> 8 300473 李毅 董事 2015-03-25 "2018-0… 第2届董… http… 1966 "中国"… 李毅先生…
#> 9 002107 王炯 财务总监 2010-11-29 "--" 历届高管… http… 197309 "中国"… 王炯,男…
#> 10 002501 王建新 副董事长 2018-10-12 "2019-0… 第4届董… http… 1983 "中国"… 王建新,…
#> # ℹ 130 more rows
#> # ℹ 3 more variables: 性别 <chr>, 学历 <chr>, id <int>

例如郑钟焕的简历:

郑钟焕先生:1962年出生,大学本科,工程师职称。曾在深圳市轻纺工业公司、深圳市轻工业公司就职;自1985年10月起进入深圳中华自行车集团(股份)有限公司工作,历任计划部副经理、经理,资材部经理、制造部经理等职;现为本公司监事、深圳市阿米尼实业有限公司采购物管部经理。

我们按照下面的提示词进行提问:

根据下面的简历信息判断该主体是否有从政经历或者政治背景,仅返回是或者否即可:“郑钟焕先生:1962年出生,大学本科,工程师职称。曾在深圳市轻纺工业公司、深圳市轻工业公司就职;自1985年10月起进入深圳中华自行车集团(股份)有限公司工作,历任计划部副经理、经理,资材部经理、制造部经理等职;现为本公司监事、深圳市阿米尼实业有限公司采购物管部经理。”

在使用本地部署的离线模型之前,我们先介绍下如何使用 Deeseek 的 API 进行请求。

首先我们需要在 deepseek 的网站上充值和申请 API key:https://platform.deepseek.com/

需要注意这个密钥只有在创建的时候是可以看到的,记得及时复制保存下来。

在终端(Mac)或 DOS 窗口(Windows)运行:

curl https://api.deepseek.com/chat/completions -H "Content-Type: application/json" -H "Authorization: Bearer sk-1c6ee***********************54a1" -d '{"model": "deepseek-chat","messages": [{"role": "system", "content": "根据下面的简历信息判断该主体是否有从政经历或者政治背景,仅返回是或者否即可:“郑钟焕先生:1962年出生,大学本科,工程师职称。曾在深圳市轻纺工业公司、深圳市轻工业公司就职;自1985年10月起进入深圳中华自行车集团(股份)有限公司工作,历任计划部副经理、经理,资材部经理、制造部经理等职;现为本公司监事、深圳市阿米尼实业有限公司采购物管部经理。”"}, {"role": "user", "content": "Hello!"}], "stream": false}' -o temp1.json

sk-1c6ee***********************54a1 替换成大家自己的即可(注意是创建时候的那串不带星号的字符串,不是现在看到的这个)。

temp1.json 里面存储的就是保存的结果。主要内容如下:

否

另外需要注意,在 Windows 电脑上,上述的 curl 语句需要进行如下调整:

  1. 单引号都要替换成双引号;
  2. 双引号都替换成 "。
curl "https://api.deepseek.com/chat/completions" -H "Content-Type: application/json" -H "Authorization: Bearer sk-1c6ee***********************54a1" -d "{\"model\": \"deepseek-chat\",\"messages\": [{\"role\": \"system\", \"content\": \"根据下面的简历信息判断该主体是否有从政经历或者政治背景,仅返回是或者否即可\"}, {\"role\": \"user\", \"content\": \"郑钟焕先生:1962年出生,大学本科,工程师职称。曾在深圳市轻纺工业公司、深圳市轻工业公司就职;自1985年10月起进入深圳中华自行车集团(股份)有限公司工作,历任计划部副经理、经理,资材部经理、制造部经理等职;现为本公司监事、深圳市阿米尼实业有限公司采购物管部经理。\"}], \"stream\": false}" -o temp1.json

使用 Windows 小伙伴记得把后面代码里面的单引号和双引号都做出这样的调整。

关于 deepseek api 的使用可以阅读官方文档:https://api-docs.deepseek.com/zh-cn/

考虑到这个 api 的调用是需要付费的,所以我们还是转而使用本地部署的离线模型:

这个请求也可以使用 curl 语句(在终端(Mac)或 DOS 窗口(Windows)运行):

记得先退出 ollama 聊天窗口再运行!

curl http://localhost:11434/api/generate -d '{"model": "deepseek-r1:1.5b", "prompt": "根据下面的简历信息判断该主体是否有从政经历或者政治背景,仅返回是或者否即可:“郑钟焕先生:1962年出生,大学本科,工程师职称。曾在深圳市轻纺工业公司、深圳市轻工业公司就职;自1985年10月起进入深圳中华自行车集团(股份)有限公司工作,历任计划部副经理、经理,资材部经理、制造部经理等职;现为本公司监事、深圳市阿米尼实业有限公司采购物管部经理。”", "stream": false}' -o temp2.json

返回的结果会被保存到 temp0.json 文件中。

R 语言中可以使用 system() 函数调用 shell 语句,不过不如使用 httr 构造 curl 请求。使用这个网站应用可以非常容易把 curl 语句转换成 R 语言代码:https://curlconverter.com/r/

library(tidyverse)
library(httr)

headers = c(
`Content-Type` = "application/x-www-form-urlencoded"
)

data = '{"model": "deepseek-r1:1.5b", "prompt": "根据下面的简历信息判断该主体是否有从政经历或者政治背景,仅返回是或者否即可:“郑钟焕先生:1962年出生,大学本科,工程师职称。曾在深圳市轻纺工业公司、深圳市轻工业公司就职;自1985年10月起进入深圳中华自行车集团(股份)有限公司工作,历任计划部副经理、经理,资材部经理、制造部经理等职;现为本公司监事、深圳市阿米尼实业有限公司采购物管部经理。”", "stream": false}'

res <- httr::POST(url = "http://localhost:11434/api/generate", httr::add_headers(.headers=headers), body = data)

提取 res 的内容:

content(res) -> lst

lst$response
#> [1] "<think>\n好的,我现在需要判断郑钟焕先生是否有从政经历或者政治背景。首先,我得仔细阅读他的简历信息。\n\n他出生在1962年,大学本科,工程师职称。在职位方面,他曾在深圳市轻纺工业公司、深圳市轻工业公司工作,之后进入了深圳中华自行车集团(股份)有限公司,并担任了多个部门的经理。现在是该公司的监事和阿米尼实业有限公司采购物管部经理。\n\n接下来,我要分析他的政治背景。从简历中没有提到任何与政治相关的成就或职位,也没有提到政治行为或参与的政治活动。因此,可以推断他没有从政经历或者政治背景。\n\n再者,我需要确认是否有其他可能的关联,比如担任过公司领导职务或者其他专业职务,但这并没有显示出任何政治背景。此外,他的主要职责是商业管理,而非政治活动。\n\n综上所述,根据提供的信息,郑钟焕先生没有表现出从政的经历或政治背景。\n</think>\n\n否"

下面我们再循环处理所有的简历:

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

多线程可以提升速度,不过对于这种任务提升不是很大,比较 LLM 模型比较考验电脑性能:

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

合并处理结果:

fs::dir_ls("res") %>%
lapply(readr::read_rds) %>%
bind_rows() -> dfres

dfres
#> # A tibble: 140 × 2
#> id response
#> <int> <chr>
#> 1 1 "<think>\n好吧,我现在要回答关于周舜华先生是否有从政的经历的问题。首先,我要仔细阅读他的简历信息。他的姓名是周舜华先生,出生于19…
#> 2 10 "<think>\n好,我现在要判断这个主体是否有从政经历或政治背景。首先看简历信息:王建新是男,1983年出生,本科毕业。他历任了技术员、…
#> 3 100 "<think>\n好的,我现在要判断邵瑞泽是否有从政经历或者政治背景。\n\n首先,他有多个职位:副总工程师、副总裁、投资总监、董事总经理…
#> 4 101 "<think>\n嗯,用户给了一个关于宋利国先生的简历信息,然后让我判断他是否有从政经历或者政治背景。首先,我需要仔细阅读简历内容,找出是…
#> 5 102 "<think>\n好的,我现在需要判断杨坤平是否有从政经历或者政治背景。首先,他的简历里提到了他是“高级经济师”,这可能表明他在金融或商业…
#> 6 103 "<think>\n好的,我现在要判断这个主体“方培琦”是否有从政经历或者政治背景。首先,我需要仔细阅读他的简历信息。\n\n根据信息,他是…
#> 7 104 "<think>\n嗯,用户给了一个简历信息,让我判断主体是否有从政经历或者政治背景,只需要返回是或否。\n\n首先,我需要仔细看看简历中的…
#> 8 105 "<think>\n嗯,我现在要判断这个主体是否具备从政经历或者政治背景。让我先仔细看看简历里的信息。\n\n首先,这个人是曲为民,男,19…
#> 9 106 "<think>\n嗯,我现在需要判断赵西卜是否有从政经历或者政治背景。首先,他的教育背景包括经济学博士和管理学博士后,还有中国注册会计师和…
#> 10 107 "<think>\n嗯,我现在需要判断眭世荣有没有从政的经历或者政治背景。首先,我得仔细阅读他的简历信息。\n\n他出生在1962年,中国国…
#> # ℹ 130 more rows

继续处理:

dfres %>%
filter(!is.na(response)) %>%
mutate(response = str_remove_all(response, "\\n"),
response = str_remove_all(response, "<think>(.*)</think>")) %>%
mutate(response = if_else(str_detect(response, "\\*\\*否\\*\\*"), "否", response),
response = if_else(response == "否。", "否", response),
response = if_else(response == "No", "否", response),
response = if_else(response == "Yes", "是", response),
response = if_else(response == "没有", "是", response)) %>%
mutate(len = str_length(response),
len = if_else(is.na(len), 0, len)) %>%
group_by(id) %>%
filter(len == min(len, na.rm = T)) %>%
ungroup() %>%
distinct(id, .keep_all = T) %>%
select(-len) %>%
left_join(df) %>%
rename(是否有从政经历或政治背景 = response) -> dfres

dfres
#> # A tibble: 139 × 14
#> id 是否有从政经历或政治背景 股票代码 姓名 职务 起始日期 终止日期 名目
#> <int> <chr> <chr> <chr> <chr> <date> <chr> <chr>
#> 1 1 否 002128 周舜华…… 监事 2018-05-07 2019-01… 第6届监…
#> 2 10 否 002501 王建新…… 副董事长… 2018-10-12 2019-04… 第4届董…
#> 3 100 否 002427 邵瑞泽…… 董事 2018-12-17 2019-12… 第4届董…
#> 4 101 否 600268 宋利国…… 独立董事… 2005-12-28 2008-12… 第3届董…
#> 5 102 否 600505 杨坤平…… 董事 2006-04-05 2007-05… 第5届董…
#> 6 103 否 600848 方培琦…… 独立董事… 2003-06-23 2005-06… 第4届董…
#> 7 104 否 600022 孙成玉…… 监事会主… 2018-04-19 2019-11… 第6届监…
#> 8 105 否 000869 曲为民…… 董事 2006-12-07 2010-05… 第4届董…
#> 9 106 否 000807 赵西卜…… 独立董事… 2020-01-22 2020-09… 第7届董…
#> 10 107 否 300647 眭世荣…… 独立董事… 2014-12-19 2017-12… 第1届董…
#> # ℹ 129 more rows
#> # ℹ 6 more variables: 链接 <chr>, 出生日期 <dbl>, 国籍 <chr>, 简历 <chr>,
#> # 性别 <chr>, 学历 <chr>
dfres %>%
count(是否有从政经历或政治背景)
#> # A tibble: 2 × 2
#> 是否有从政经历或政治背景 n
#> <chr> <int>
#> 1 否 124
#> 2 是 15

可以看出有从政经历或政治背景的有 15 人,还有一个解析失败的,也可以继续再重新解析一次。

另外如果想要得到具体政治层级,可以在上面结果的基础上对那些具有政治背景的高管简历再使用下面的提示词提问:

res <- httr::POST(url = "http://localhost:11434/api/generate", httr::add_headers(.headers = c(`Content-Type` = "application/x-www-form-urlencoded")), body = paste0('{"model": "deepseek-r1:1.5b", "prompt": "根据下面的简历信息判断该主体是否有从政经历或者政治背景(对应下面级别的均是“有”),仅返回行政级别编号即可,如果有多个级别编号的,使用分号分隔。其中行政级别编号为:政治背景行政层级:1=国家级正职,2=国家级副职,3=省部级正职,4=省部级副职,5=厅局级正职,6=厅局级副职,7=县处级正职,8=县处级副职,9=乡科级正职,10=乡科级副职,11=巡视员,12=副巡视员,13=调研员,14=副调研员,15=主任科员,16=副主任科员,17=科员,18=办事员,98=无法确定行政级别,99=无政府背景。若为人大代表、党代表等、则1=国家级,3=省级,5=市级,7=县级,9=乡级:“冀光恒先生,执行董事、行长。1968年出生,北京大学经济地理学本科、人文地理学硕士、区域经济学博士,高级经济师。冀光恒先生于2020年4月加入中国平安,历任上海总部党委书记、总经理,陆金所控股有限公司党委书记、董事长,中国平安副总经理,2022年7月至今,任中国平安党委副书记。2023年6月至今,任平安银行党委书记,2023年11月至今,任平安银行执行董事、行长。在加入中国平安前,冀先生曾出任宝能集团副董事长、联席总裁;上海农商银行党委书记、董事长;上海浦东发展银行党委委员、副行长、北京分行党委书记、行长;中国工商银行北京市分行党委委员、副行长,北京市分行办公室主任兼党办主任,长安支行党委书记、行长,总行副行长专职秘书,总行住房信贷部市场开发处副处长;上海银工房地产开发公司董事、副总经理。”", "stream": false}'))

content(res)$response

不过这个感觉就不是那么靠谱了。

点击这里跳转到 RStata 短书平台获取附件:名师讲堂|使用 R 语言调用 deepseek-r1 模型判断上市公司高管的政治背景

评论