基于Neo4j的NBA球员知识图谱构建

基于Neo4j的NBA球员知识图谱构建

作为一个老JR,老早就像弄一个关于NBA的图谱了。最近尝试使用Neo4j,一直苦于没有大规模的感兴趣的数据,所以就决定自己动手丰衣足食。最后构建出来的东西,为了逼格高一点还是叫“知识图谱”,其实离真正牛逼的图谱还差很远。

由于数据直接爬取的虎扑,所以省去了大量的信息抽取的时间。不得不说一句虎扑还是很程序员友好的,根本没有什么反爬机制,直接上代码,弄到所有球队的名字以及URL,球队详细的信息手懒没爬。每一个球队的所有球员信息都用excel存起来。

# 获取所有球队以及信息
def getTeamUrl():
    root = 'https://nba.hupu.com/teams'  # 获取所有球队的信息
    response = requests.get(root)
    text = response.text
    soup = BS(text)
    h2s = soup.find_all('h2')
    teams = []
    teamUrls = []
    for h2 in h2s:
        teams.append(h2.string)
    print(teams)
    urls = soup.find_all(name='a', attrs={'class':'a_teamlink'})
    for url in urls:
        teamUrls.append(url.get('href'))
    print(teamUrls)
    frame = pd.DataFrame(columns=['team','urls'])
    frame['team'] = teams
    frame['urls'] = teamUrls
    frame.to_excel('./data/teamUrls.xlsx')

基于Neo4j的NBA球员知识图谱构建_第1张图片
有了数据就该定义知识图谱的schema了,为了简单就定义了两个entity:球队和球员,一种关系:效力于,球员的属性可以参照虎扑。
之后就将excel中的数据导入neo4j,这部分用了py2neo,直接pip安装就可以。

##连接neo4j数据库,输入地址、用户名、密码
graph = Graph('http://localhost:7474', username='neo4j', password='123456')

# 导入球队的数据
def importTeam():
    for root, dirs, files in os.walk('./data'):
        for file in files:
            team = file.split('.')[0]
            node = Node('球队', name=team)
            graph.create(node)
    print(graph)

py2neo中操作数据库需要三个类就差不多了:

from py2neo import Graph, Node, Relationship

都可以通过Graph.create()直接创建结点或者关系。
导入关系的时候需要考虑NBA是一个商业联盟,球员老被交易,每个人可能会效力几只不同的球队,所以“效力于”这个关系需要添加个时间属性,表示这个球员在某个时间段效力于这支球队。整个过程也就导入球员关系复杂一些。

def importRelation():
    for root, dirs, files in os.walk('./data'):
        for file in files:
            frame = pd.read_excel('./data/'+file)
            team = file.split('.')[0]
            for i in frame.index:
                player = frame.get_value(i,'players')
                career = str(frame.get_value(i,'生涯球队')).split()
                career_dict = {}
                for j in range(int(len(career)/2)):
                    year = career[j*2]
                    teamBefore = career[j*2+1]
                    if teamBefore in career_dict.keys():
                        career_dict[teamBefore] += (year+' ')
                    else:
                        career_dict[teamBefore] = year + ' '
                # 最后加入当前效力的球队
                if team in career_dict.keys():
                    career_dict[team] += '2019'
                else:
                    career_dict[team] = '2019'
                # 最后创建关系
                a = graph.nodes.match('球员', name=player).first()
                for key in career_dict.keys():
                    b = graph.nodes.match('球队',name=key).first()
                    relat = Relationship(a,'效力于',b)
                    relat['year'] = career_dict[key].strip()
                    try:
                        graph.create(relat)
                    except:
                        continue

最后得到497位球员,当然是30支球队,1099条关系。
基于Neo4j的NBA球员知识图谱构建_第2张图片
为了规整做了一个LIMIT,只显示100条关系
基于Neo4j的NBA球员知识图谱构建_第3张图片
至于各种条件查询以后再练习吧,吃饭去咯。

你可能感兴趣的:(知识图谱,Neo4j,NBA)