依据CCS分类建树(简单方案)

本文介绍ACM计算分类系统(CCS)的树状结构及其在论文分类中的应用,通过分析CCS分类文件,实现论文间的相似度计算。文章详细阐述了如何预处理分类数据,构建树形结构,以及根据树的层级计算论文之间的距离和相似度。

依据CCS分类建树(简单方案)

CCS分类

ACM Computing Classification System(CCS)
2012 ACM计算分类系统已开发为一种多层次的本体,可以在语义Web应用程序中使用。它替代了1998年的ACM计算分类系统(CCS)的传统版本,该版本已成为计算领域的事实上的标准分类系统。
它已集成到ACM数字图书馆的搜索功能和可视主题显示中。它依赖于语义词汇作为类别和概念的唯一来源,它反映了计算机科学的最新水平,并且随着未来的发展而接受结构性变化。 ACM在可视显示格式内提供了一种工具,以促进将2012 CCS类别应用到即将发表的论文中,并提供确保CCS与时俱进的过程。新的分类系统将在ACM数字图书馆的人员搜索界面的开发中起到关键作用,以补充其当前的传统书目搜索。
完整的CCS分类树可以HTML格式免费用于教育和研究目的。在ACM数字图书馆中,CCS以可视化显示格式显示,有助于导航和反馈。完整的CCS分类树也可以在数字图书馆中以平面文件形式查看。
CCS
来源:https://dl.acm.org/ccs

即,CCS分类是一种树结构的分类标准。接下来看一下给出的CCS分类文件:
IndexTerms.txt文件
由这个文件可以很显然的看出每篇论文的所属的类别。
例如:

  • h. information systems h.3 information storage and retrieval h.3.3 information search and retrieval subjects: search process
  • H.信息系统 h.3信息存储和检索 h.3.3信息搜索和检索主题:搜索过程
    由此可见,该文件属于h.3.3类。

文件的每一行对应一个类,空行是空数据,作特殊处理。
在查询的过程中也发现了中国标准文献分类法(CCS),在这里也可以记录一下。
中标分类CCS

建树求距离
方案一:借助文件求

观察文件IndexTerms.txt,我们可以知道一篇论文可能会有三种情况:

  • 论文属于a(假设)
  • 论文属于a.1
  • 论文属于a.1.1
    (以后都以a,a.1,a.1.1为例)

因此,树结构最多有三层。那么,我们可以通过分类讨论列举所有情况并进行处理的方式来解决这个问题。

数据预处理

对于文件IndexTerms.txt来说,我们需要的是能够表达论文所属类型的关键词(a,a.1,a.1.1等),而不需要冗长的介绍,因此我们需要对文件进行预处理。
对于这种,我们选择提取k.3.1
a.1.1
但是并不是每个论文都能精确的分类到第三级,因此会有:
j.5
这种情况出现,对于这样的我们选择提取j.5。
而有的论文只能划分到大类,例如
在这里插入图片描述
对于这种情况,我们选择提取a。

对于这种提取我们有一个很好用的工具:正则表达式。能想到这个问题就很简单了,代码如下

s=""
for i in range(len(lis)):
    if(len(lis[i])==0):
        #print(i)
        s+=str(i)
        s+=','
        s+='\n'
    else:
        s+=str(i)
        s+=','
        ret = re.findall(r'\w.\d.\d',lis[i])
        if(len(ret)==0):
            print(i)
            ret = re.findall(r'\w.\d',lis[i])
            if(len(ret)==0):
                ret = re.findall(r'\w',lis[i])
                s+=ret[0]
            else:
                s+=ret[0]
        else:
            for j in range(len(ret)):
                s+=ret[j]
                if(j<len(ret)-1):
                    s+=","
        s+='\n'

        
print(s)

需要注意的是,还有一种特殊情况需要单独考虑:
特殊情况
图中展示的论文分类表示,该论文可以被分到多个类中,这种情况我们需要把它所属的类都统计下来,因此在匹配的时候选择的函数是re.findall()re.findall()re.findall()

为了方便之后的计算,我们把处理后的数据存到一个文件中。存储的形式为“论文id,分类”,因此在构造字符串的时候也进行了相应的处理。写入文件:

fh = open('E:\\创新实训\\资料整理\\code+data\\treenode.txt', 'w', encoding='utf-8')
fh.write(s)
fh.close()

文件如下:
预处理文件

计算距离

因为树的结构是规则的,因此距离也是有规律可循的,接下来我们对每种情况进行分类讨论。
假设论文为X和Y,并且,我们把 “* . * . *” 部分记为该论文的分类属性。

  • 其中有论文没有所属类:
    • 相似度为0
  • 两篇论文不属于同一个大类:
    • 相似度为0(该相似度仍有待商榷)
  • 两篇论文的分类属性字符串完全相同
    • 相似度为1
  • 两篇论文的分类属性字符串不同
    • 两篇论文分类属性长度lll相同(字符串长度)
      • l==3l==3l==3:同为二级节点,没有多种情况,边数为2,设边权为2(*),相似度记为距离的倒数,因此相似度为1/4。
      • l==5l==5l==5
        • 两篇论文属于同一个二级结点:边数为2,距离为4,相似度为1/4。
        • 两篇论文不同属于一个二级结点,那么它们的最近公共父节点就是根节点,因此边数为4,距离为8,相似度为1/8.
      • 注:l!=1l!=1l=1,因为当属性分类字符串长度为1时,说明是“a”这种情况,这种情况已经由上一步的“分类属性字符串完全相同”处理了,因此这里没有。
    • 两篇论文分类属性长度lll不同(字符串长度)
      • 声明: 我们保证lx<lyl_x<l_ylx<ly,如正好相反,则交换x,yx,yx,y
      • lx==1l_x==1lx==1 and ly==3l_y==3ly==3:边长为1,距离为2,相似度为1/2。
      • lx==1l_x==1lx==1 and ly==5l_y==5ly==5:边长为2,距离为4,相似度为1/4。
      • lx==3l_x==3lx==3 and ly==5l_y==5ly==5
        • 两篇论文是父子关系: 边长为1,距离为2,相似度为1/2。
        • 两篇论文不是父子关系:边长为3,距离为6,相似度为1/6。

至此,所以的情况我们已经都讨论完了,只要按照这个编写代码即可完成。

def fun():
    X,Y=input().split()
    X=int(X)
    Y=int(Y)##ID i
    tx=listid[X].split(",")
    ty=listid[Y].split(",")
    if(tx[1]==ty[1]):
        return 1
    XT=tx[1][0]
    YT=ty[1][0]
    #print(XT,YT)
    if(XT!=YT):
        return 0##直接返回相似度,不是距离,距离算无穷大
    else :
        lx=len(tx[1])
        ly=len(ty[1])
        if(lx>ly):##保证lx<ly
            tt=lx
            lx=ly
            ly=tt
            tt=tx
            tx=ty
            ty=tt##数值和字符串都换回来
        if(lx==ly):
            if(lx==1):
                return 1/1
            elif(lx==3):
                return 1/4
            else:
                #print(lx)
                xx=tx[1]
                yy=ty[1]
                mx=xx.split(".")[1]
                my=yy.split(".")[1]##找出第二位
                if(mx==my):
                    return 1/4
                else:
                     return 1/8
        else:##lx<ly
            if(lx==1)&(ly==3):
                return 1/2
            elif(lx==1)&(ly==5):
                return 1/4
            else:
                xx=tx[1]
                yy=ty[1]
                mx=xx.split(".")[1]
                my=yy.split(".")[1]##找出第二位
                if(mx==my):
                    return 1/4
                else:
                     return 1/6

调用该函数,输入需要计算的论文id,即可得到结果。
调用样例

全部代码如下:

# -*- coding: utf-8 -*-
"""
Created on Tue Jun 23 10:33:22 2020

@author: nyy
"""
#import re 
def Load():
    listid = []
    for line in open("treenode.txt","r"): #设置文件对象并读取每一行文件
        listid.append(line.replace("\n","")) 
    #print(listid)
    return listid

def fun(listid):
    print("请输入论文id:")
    X,Y=input().split()
    X=int(X)
    Y=int(Y)##ID i
    tx=listid[X].split(",")
    ty=listid[Y].split(",")
    if(len(tx[1])==0) or (len(ty[1])==0):
        return 0
    if(tx[1]==ty[1]):
        return 1
    XT=tx[1][0]
    YT=ty[1][0]
    #print(XT,YT)
    if(XT!=YT):
        return 0##直接返回相似度,不是距离,距离算无穷大
    else :
        lx=len(tx[1])
        ly=len(ty[1])
        if(lx>ly):##保证lx<ly
            tt=lx
            lx=ly
            ly=tt
            tt=tx
            tx=ty
            ty=tt##数值和字符串都换回来
        if(lx==ly):
            if(lx==1):
                return 1/1
            elif(lx==3):
                return 1/4
            else:
                #print(lx)
                xx=tx[1]
                yy=ty[1]
                mx=xx.split(".")[1]
                my=yy.split(".")[1]##找出第二位
                if(mx==my):
                    return 1/4
                else:
                     return 1/8
        else:##lx<ly
            if(lx==1)&(ly==3):
                return 1/2
            elif(lx==1)&(ly==5):
                return 1/4
            else:
                xx=tx[1]
                yy=ty[1]
                mx=xx.split(".")[1]
                my=yy.split(".")[1]##找出第二位
                if(mx==my):
                    return 1/4
                else:
                     return 1/6

def main():
    lis=Load()
    #print(lis)
    rere=fun(lis)
    print(rere)
    
main()
ACM CCSACM Computing Classification System分类代码在学术研究和文献管理中较为重要,以下是几种可能导出其代码的方法: ### 利用ACM数字图书馆 如果是在ACM数字图书馆中浏览相关文献,部分文献页面会直接显示该文献对应的ACM CCS分类代码。可以手动复制这些代码。若需要批量获取,可以使用ACM数字图书馆提供的导出功能,在导出文献列表时,有些格式(如BibTeX等)可能会包含ACM CCS分类代码。以BibTeX为例,在导出选项中选择BibTeX格式,下载文件后打开,文件中可能会有相关代码记录。 ```bibtex @article{example, title = {Example Article}, author = {Author, A.}, journal = {Journal of Examples}, year = {2023}, ccs = {12.34.56} # 这里可能就是ACM CCS分类代码 } ``` ### 借助文献管理软件 像EndNote、Mendeley等文献管理软件,当导入ACM相关文献时,软件可能会识别并提取ACM CCS分类代码。在EndNote中,导入文献后,可以通过编辑文献信息查看和导出这些代码。选择文献后,在编辑界面中可能会有ACM CCS分类的字段,复制相应代码即可。如果需要批量导出,可以使用软件的导出功能,选择合适的格式(如CSV等),确保导出文件包含ACM CCS分类代码列。 ### 编程爬虫获取 若有大量文献需要处理,可以编写爬虫程序。使用Python的`requests`和`BeautifulSoup`库,通过向ACM相关网页发送请求,解析HTML页面获取ACM CCS分类代码。以下是一个简单示例: ```python import requests from bs4 import BeautifulSoup url = 'https://dl.acm.org/doi/10.1145/xxxxxx' # 替换为具体文献URL response = requests.get(url) soup = BeautifulSoup(response.text, 'html.parser') # 查找ACM CCS分类代码元素,这里需要根据实际页面结构调整 ccs_code = soup.find('span', class_='ccs-code').text print(ccs_code) ``` ### 数据库API 一些学术数据库可能提供API接口,通过调用这些API可以获取文献的ACM CCS分类代码。例如,部分数据库的API可能支持根据文献DOI查询相关信息,其中就包括ACM CCS分类代码。需要先注册获取API密钥,然后按照API文档的要求进行请求。以下是一个简单的API请求示例(假设API支持): ```python import requests api_url = 'https://example-database-api.com/search' params = { 'doi': '10.1145/xxxxxx', # 替换为具体文献DOI 'api_key': 'your_api_key' } response = requests.get(api_url, params=params) data = response.json() ccs_code = data.get('ccs_code') print(ccs_code) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值