提取学术论文中的KEYWORDS

由于不同期刊和不同作者对学术论文中keywords部分要求不同,直接写程序提取很难做到普适性(也可能是我太菜了),然后就尝试了一下直接使用大模型进行提取,发现效果还不错,顺便就搞一下本地大模型。目前找了IEEE、ACM、springer这三个期刊的几篇文章,效果很好,应该只要标准点的都行。

这里使用ollama,安装方便且拉取模型也很方便。具体安装方法我就不说了,很简单,网上教程也很多了,主要就是修改存储路径啥的,这里就帖一下我的环境变量。注意,想要IP调用需要设置OLLAMA_HOST。

我这里找的模型是qwen2.5:14b,其他模型没有尝试ollama pull qwen2.5:14b

之后在命令上输入ollama serve,启动ollama服务,后面程序将调用本地接口。

下面是python代码(结合GPT),首先处理论文的PDF格式,这里使用PyMuPDF(fitz)pip install PyMuPDF这个库来处理,感觉效果比较好,然后处理出第一页(大部分论文的关键词应该都在第一页),处理成文本数据,发给ollama的API接口,选择模型,自己调了一下提示词,然后等待输出(平均10s)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import argparse
import fitz
import requests
# 提取PDF文本并去除页眉和页脚
def extract_text_without_headers_footers(pdf_path, header_height=50, footer_height=50):
doc = fitz.open(pdf_path) # 打开PDF文件
remaining_text = ""
for page in doc:
blocks = page.get_text("dict")["blocks"]
for block in blocks:
if block['type'] == 0: # 只处理文本块
for line in block['lines']:
for span in line['spans']:
text = span['text']
span_rect = fitz.Rect(span['bbox'])
remaining_text += (text+'\n')
break # 只处理第一页
return remaining_text

def ollama_extract_keywords(url,text):
api=url
data={
"model": "qwen2.5:14b",
"stream": False,
"messages": [
{
"role": "user",
"content": f"On the first page of a paper, please extract all the keywords that come with it, only the keywords written by the author in the keyword section, and only tell me the results. Remember to remove all symbols, do not reply to other messages, and use commas to separate each keyword:\n{text}"
}
],
"options":{
"temperature": 0
}
}
res=requests.post(url,json=data)
if res.status_code==200:
keywords=res.json()
return keywords['message']['content'].strip()
else:
return NULL
# 处理文件夹中的所有PDF文件
def process_pdfs_in_folder(url, file_path):

# 提取PDF文本
text = extract_text_without_headers_footers(file_path)

results = []

# 调用 Ollama 模型获取关键词

# 解析返回的结果并提取关键词
keywords_str = ollama_extract_keywords(url, text)
while not keywords_str:
keywords_str = ollama_extract_keywords(url, text)
keywords_list = process_keywords(keywords_str) # 处理关键词字符串,返回列表
results = []
for i in keywords_list:
results.append(i.lower().replace('-',' '))


return results

# 处理返回的关键词字符串并将其转换为列表
def process_keywords(keywords_str):
# 假设关键词以逗号分隔
keywords = [keyword.strip() for keyword in keywords_str.split(',')]
return keywords

def main():
parser = argparse.ArgumentParser()
parser.add_argument("-f", "--file", required=True, help="Path of the PDF files")
parser.add_argument("-u", "--url", required=True, help="OLLAMA API URL")
args = parser.parse_args()

file_path = args.file
api_url = args.url

results = process_pdfs_in_folder(api_url, file_path)

for i in results:
print(i)

if __name__ == "__main__":
main()
# python3 1.py -f <filename> -u <api_url>

由于我毕设是要用C写的,然后这里贴一份C调用命令获取python输出的代码。

(我不会写,都是靠GPT的,难绷的地方轻喷)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
int extract_keywords_from_pdf_by_ollama(const char *directoryPath, const char *filename, const char *url, char file_keywords[MAX_FILE_KEYWORDS][MAX_KEYWORD_LENGTH])
{
// 定义调用 Python 脚本的命令
char command[1024];
snprintf(command, sizeof(command), "python3 1.py -f %s/%s -u %s", directoryPath, filename, url);

FILE *fp;
char result[128];

// 打开管道,调用Python脚本并获取输出
fp = popen(command, "r");
if (fp == NULL)
{
perror("popen");
return 0;
}

int count = 0;

// 读取Python脚本的输出

while (fgets(result, sizeof(result), fp) != NULL)
{
int len = strlen(result);
while (len > 0 && isspace((unsigned char)result[len - 1]))
{
len--;
}
result[len] = '\0';
strcpy(file_keywords[count++], result);
if (count >= MAX_FILE_KEYWORDS)
{
break;
}
}

// 关闭管道
fclose(fp);
return count;
}

提取学术论文中的KEYWORDS
http://example.com/2025/01/08/expdfkey/
作者
Naby
发布于
2025年1月8日
许可协议