AI开发: 知识图谱的初识,学会制作知识图谱- Python 机器学习

一、知识图谱的概念

知识图谱是一个通过图结构来表示和组织知识的工具,它将事物、概念和它们之间的关系以图的形式呈现出来,图中的节点代表实体(比如人物、地点、事件等),而边代表这些实体之间的各种关系(例如“某人是某地的居民”,“某人是某公司的员工”等)。简单来说,知识图谱就像是一个庞大的电子地图,通过它我们可以知道不同事物是如何相互联系的。

举个简单的例子:假设你有一个图谱,节点包括“马云”、“阿里巴巴”和“电商行业”。如果我们在“马云”和“阿里巴巴”之间连接一条边,标注为“创办了”,就说明“马云”与“阿里巴巴”之间有一个“创办了”的关系。如果再连接一条边,标注为“属于”,连接“阿里巴巴”和“电商行业”,那么就说明“阿里巴巴”属于“电商行业”。通过这样的关系连接,我们可以清晰地了解实体之间的联系。 

二、知识图谱的作用

  1. 增强搜索引擎:通过知识图谱,搜索引擎不仅能返回关键词匹配的页面,还能理解背后的意思,提供更准确、相关的结果。例如,你搜索“马云”,不仅能找到他的介绍,还能了解到他与阿里巴巴、电子商务等多个相关的信息。

  2. 语义理解:机器可以通过知识图谱来理解自然语言的深层含义,提升人工智能的理解能力。这对聊天机器人、语音助手等非常重要。

  3. 数据关联与推理:知识图谱能帮助系统发现不同数据之间的潜在关联,并进行推理。例如,通过分析知识图谱,系统能推测出某个人可能有某种职业,或者某个产品可能属于哪个类别。

三、知识图谱的应用场景:

  1. 搜索引擎:如Google、百度等,通过知识图谱提供更智能的搜索结果。
  2. 智能问答系统:例如智能客服、语音助手,通过知识图谱理解用户提问的背后意思,提供精准的回答。
  3. 推荐系统:比如电商平台,根据用户的历史行为和知识图谱中的关联关系,推荐用户可能喜欢的商品或服务。
  4. 医疗领域:在医学研究中,知识图谱可以帮助医生根据症状、疾病、药物之间的关系,进行疾病诊断、药物推荐等。
  5. 金融领域:通过构建公司、股东、债务等方面的知识图谱,帮助分析公司间的关系、风险等。

知识图谱的核心价值在于,它能让机器理解和推理人与人、人与物、物与物之间的复杂关

四、networkx在知识图谱中的应用

 接下来,我们一起准备用 一个Python库来演绎一个简单的知识图谱,以让我们直观地理解这个概念地内涵。

我们即将用到一个Python库:networkx,我们先来看看这个networkx是个什么东:

networkx 是一个用于创建、分析和可视化复杂网络的 Python 库。它支持多种图的表示方式,包括有向图、无向图、加权图、带标签的图等,广泛应用于图论、社交网络分析、推荐系统等领域。

A、networkx 主要功能

  1. 图的创建与操作

  2. networkx 提供了多种方法来创建图(如 Graph() 创建无向图、DiGraph() 创建有向图)和操作图中的节点和边。
  3. 可以添加或删除节点和边,并支持为节点和边附加属性(如权重、标签等)。
  4. 图算法

  5. 提供了丰富的图算法,包括最短路径计算、最大流、图的连通性分析、社区检测等。
  6. 还可以进行深度优先搜索(DFS)、广度优先搜索(BFS)等常见图遍历。
  7. 图的分析

  8. 提供了计算图的度数、中心性、聚类系数、图的直径等常用图分析指标。
  9. 可视化

  10. 使用 matplotlib 等库支持简单的图形可视化。可以通过 nx.draw() 等方法绘制图形,支持多种布局、节点颜色、边的标签等。

基本概念

  • 节点(Node):图中的基本元素,通常表示一个对象、个体或实体。
  • 边(Edge):连接节点的线,表示节点之间的关系。
  • 加权边(Weighted Edge):边可以有一个附加的权重值,表示节点之间关系的强度或其他性质。
  • 图(Graph):由一组节点和一组边构成的结构。
  • B、networkx 基本用法示例

    1. 创建图并添加节点和边

    import networkx as nx
    
    # 创建一个无向图
    G = nx.Graph()
    
    # 添加节点
    G.add_node("A")
    G.add_node("B")
    
    # 添加带权重的边
    G.add_edge("A", "B", weight=4)
    
    # 查看图的节点和边
    print(G.nodes())  # 输出 ['A', 'B']
    print(G.edges())  # 输出 [('A', 'B')]
    
  • G.nodes() 返回图中所有的节点,结果是一个列表或集合,表示图中存在的所有节点。
  • G.edges() 返回图中所有的边,结果是一个包含元组的列表,每个元组表示一条边,元组中的元素是边的两个端点(节点)。
  • 2. networkx 可视化图

    import networkx as nx
    import matplotlib.pyplot as plt
    # 创建一个无向图
    G = nx.Graph()
    # 添加节点
    G.add_node("A")
    G.add_node("B")
    # 添加带权重的边
    G.add_edge("A", "B", weight=4)
    # 查看图的节点和边
    print(G.nodes())  # 输出 ['A', 'B']
    print(G.edges())  # 输出 [('A', 'B')]
    # 绘制图
    nx.draw(G, with_labels=True, node_size=3000, node_color="skyblue", font_size=15)
    # 显示图形
    plt.show()
    

     

    上述代码生成了一张两个节点的关系图

    无向图

    无向图是图论中的一种图类型,其中的边没有方向,即边连接的两个节点之间是对称的。在无向图中,边 (A, B)(B, A) 是等效的,表示节点 A 和节点 B 之间存在一种双向的关系。

    networkx 中,无向图是通过 nx.Graph() 创建的。它表示的关系没有方向性,边 (A, B) 只是表示 AB 之间有某种联系,而不会区分是从 AB 还是从 BA

    权重的作用

    在图中,边的权重表示连接两个节点之间的强度、成本、距离或其他某种度量。边的权重是一个数值,用来量化节点之间的关系。在 networkx 中,边的权重是通过为边添加一个属性来实现的。

    通过设置权重,我们可以在图的算法中考虑不同边之间的差异。例如,在寻找最短路径时,算法会考虑权重较小的边优先,而不是简单地选择边数较少的路径。

    3. networkx 计算最短路径

    # 创建一个有向图
    G = nx.DiGraph()
    
    # 添加节点和边(带权重)
    G.add_edge("A", "B", weight=2)
    G.add_edge("B", "C", weight=3)
    G.add_edge("A", "C", weight=6)
    
    # 计算从 A 到 C 的最短路径
    shortest_path = nx.shortest_path(G, source="A", target="C", weight="weight")
    print(shortest_path)  # 输出 ['A', 'B', 'C']
    

    为什么要创建 有向图

    在图论中,有向图是指边有方向的图。每条边表示一个方向性的关系,比如从 AB,而不是从 BA。有向图适合描述单向的关系,比如道路、数据流、电路等。

    networkx 中,有向图是通过 nx.DiGraph() 创建的。它与无向图的主要区别在于边有方向性。例如:

  • ("A", "B") 表示从节点 A 到节点 B 的连接,而不能表示反向关系(BA)。
  • 如果需要双向关系,可以显式添加 ("B", "A") 的边。
  • 在上面的代码中,创建有向图是为了明确定义从 AB、从 BC 的单向路径,便于计算有方向限制的最短路径。

    为什么从 AC 的最短路径是 A -> B -> C 而不是 A -> C

    这是因为路径的选择是基于权重(weight)的最小值,而不是直接看节点之间是否有连接。

    图的结构和权重:

    你的有向图包含以下边和权重:

    1. ("A", "B") 的权重是 2
    2. ("B", "C") 的权重是 3
    3. ("A", "C") 的权重是 6
    最短路径计算过程:

    networkx.shortest_path() 函数根据 权重之和 来寻找从起点到终点的最短路径:

    1. A 直接到 C:路径是 ["A", "C"],权重为 6
    2. AB 再到 C:路径是 ["A", "B", "C"],总权重为 2 + 3 = 5

    显然,第二条路径的权重总和更小(5 < 6),因此从 AC 的最短路径是 ["A", "B", "C"]

    为什么“直线”不是最短路径?

    难道不是AC这个直线距离最短吗?

    从节点 A 到节点 C 的确有一条直接的边 (A, C),并且它是“直线”。但最短路径计算的关键并不是看边是否直接连接,而是基于权重的最小和。

    在图中,“直线”或“直接连接”指的是节点之间是否有一条直接的边,而最短路径算法关注的是路径的权重总和,而不是边的数量或是否是直接连接。

    4. networkx 计算节点的度数

    # 计算节点的度数(与该节点相连的边数)
    degree_A = G.degree("A")
    print(degree_A)  # 输出 2 (因为 A 与 B 和 C 都有连接)
    

    节点的度数的实际意义

    在图论中,**节点的度数(Degree)**是指与该节点相连的边的数量。

    对于无向图:
  • 节点的度数是所有直接连接到该节点的边的数量。
  • 例如,如果节点 A 有两条边分别连接到节点 BC,则节点 A 的度数为 2
  • 对于有向图(如 DiGraph):
  • 有向图的度数分为两种:
    1. 入度(In-degree):指指向该节点的边的数量。
    2. 出度(Out-degree):指从该节点出发的边的数量。
  • networkx 中,G.degree(node) 会返回该节点的 总度数,即入度和出度的总和。
  • 5、networkx 常见图类型

  • 无向图 (Graph):节点之间的关系没有方向性。
  • 有向图 (DiGraph):节点之间的关系是有方向的。
  • 多重图 (MultiGraphMultiDiGraph):允许多条边连接同一对节点。
  • 优势

  • 灵活性:支持多种类型的图结构,能够处理加权、无向、有向等多种情境。
  • 丰富的算法支持:提供了很多经典的图算法,适用于网络分析、社交网络分析等领域。
  • 易于使用:简洁的 API 使得用户可以快速构建和操作图。
  • networkx 是一个强大且易用的工具库,适用于各种图分析任务。无论是社交网络、推荐系统还是知识图谱的构建,都可以利用这个库来表示和分析图数据。如果你需要操作复杂网络或进行图论研究,networkx 是一个非常合适的选择。

    五、用PYTHON创建一个知识图谱

    (1)示例一,人物关系图

    一个简单的知识图谱可以包含几个人物和他们之间的关系,例如:“Alice”“Bob” 的朋友,“Bob” 住在 “New York”,等等。

    下面是一个用 Python 和 networkx 库来演绎一个简单知识图谱的例子:

    安装 networkx

    首先,如果没有安装 networkx 库,可以通过以下命令安装:

    pip install networkx
    

    Python代码示例

    import networkx as nx
    import matplotlib.pyplot as plt
    
    # 创建一个空的有向图
    G = nx.Graph()
    
    # 添加节点
    G.add_node("Alice")
    G.add_node("Bob")
    G.add_node("New York")
    G.add_node("Jane")
    
    # 添加边(关系)
    G.add_edge("Alice", "Bob", relationship="friend")
    G.add_edge("Bob", "New York", relationship="lives_in")
    G.add_edge("Bob", "Jane", relationship="colleague")
    
    # 可视化知识图谱
    pos = nx.spring_layout(G)  # 设置节点布局
    plt.figure(figsize=(8, 6))
    nx.draw(G, pos, with_labels=True, node_size=3000, node_color='skyblue', font_size=12, font_weight='bold')
    
    # 为每条边添加标签(表示关系)
    edge_labels = nx.get_edge_attributes(G, 'relationship')
    nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
    
    # 显示图形
    plt.title("Simple Knowledge Graph")
    plt.show()
    

    代码说明:

    1. networkx.Graph():创建一个无向图。
    2. add_node():添加节点(实体)。
    3. add_edge():添加边(实体之间的关系),可以通过 relationship 属性来指定关系的类型。
    4. nx.spring_layout():自动生成节点的布局方式。
    5. nx.draw():绘制图形。
    6. nx.draw_networkx_edge_labels():在边上添加标签,表示关系。

    结果:

    这段代码会生成一个简单的知识图谱,显示:

  • AliceBob 之间的关系是“朋友”。
  • BobNew York 之间的关系是“住在”。
  • BobJane 之间的关系是 “同事”
  • 扩展:

  • 可以添加更多的节点和边,表示更多的实体和关系。
  • 使用更复杂的图布局和样式来改善图的可视化效果。
  • 这只是一个基础示例,知识图谱的应用非常广泛,涉及的内容可以更加复杂和丰富。

    (2)示例2,从文本中构建知识图谱

    假设有一篇新闻,我们是否能让系统自动从文本中提取相应的信息来自动生成知识图谱呢? 

    这个想法完全可以实现的!完全可以从一篇新闻文本中提取信息并自动生成知识图谱。这个过程通常包括以下几个步骤:

    1. 文本预处理:对新闻文本进行清理、分词等处理,提取有意义的实体(如人物、地点、组织等)和关系(如“是”、“在”、“属于”等)。

    2. 命名实体识别(NER):从文本中识别出重要的实体,如人名、地名、机构名等。

    3. 关系抽取:确定实体之间的关系,通常通过自然语言处理(NLP)技术如依存句法分析、规则匹配、或基于机器学习的方法来实现。

    4. 构建知识图谱:使用 networkx 或其他图数据库,将识别出的实体作为节点,实体间的关系作为边,构建出知识图谱。

    一个简单的例子:

    假设我们有一篇新闻,内容如下:

    “Alice 是 Bob 的朋友。Bob 住在 New York。Alice 喜欢去 Central Park。”

    从这篇文本中,我们可以提取出如下信息:

  • AliceBob 是朋友。
  • Bob 住在 New York
  • Alice 喜欢 Central Park
  • 代码示例

    我们可以通过 NLP 库(如 spaCy)来进行实体识别和关系抽取,然后用 networkx 来生成知识图谱。

    安装所需库
    pip install spacy networkx matplotlib
    python -m spacy download en_core_web_sm
    
    Python 代码
    import spacy
    import networkx as nx
    import matplotlib.pyplot as plt
    
    # 加载spacy模型
    nlp = spacy.load("en_core_web_sm")
    
    # 输入的新闻文本
    text = "Alice is a friend of Bob. Bob lives in New York. Alice likes to visit Central Park."
    
    # 使用spaCy进行NER(命名实体识别)
    doc = nlp(text)
    
    # 创建一个图
    G = nx.Graph()
    
    # 存储实体及其关系
    entities = []
    relationships = []
    
    # 提取命名实体
    for ent in doc.ents:
        entities.append(ent.text)
    
    # 提取关系(这里假设我们通过简单的规则抽取关系)
    for sent in doc.sents:
        tokens = [token.text for token in sent]
        
        # 定义一些简单的规则来抽取关系
        if "friend" in tokens:
            G.add_edge("Alice", "Bob", relationship="friend")
        elif "lives in" in " ".join(tokens):
            G.add_edge("Bob", "New York", relationship="lives_in")
        elif "likes" in tokens:
            G.add_edge("Alice", "Central Park", relationship="likes_to_visit")
    
    # 可视化生成的知识图谱
    pos = nx.spring_layout(G)
    plt.figure(figsize=(8, 6))
    nx.draw(G, pos, with_labels=True, node_size=3000, node_color='skyblue', font_size=12, font_weight='bold')
    
    # 为边添加关系标签
    edge_labels = nx.get_edge_attributes(G, 'relationship')
    nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
    
    plt.title("Knowledge Graph Generated from News Text")
    plt.show()
    

    代码解释

    1. 使用 spaCy 提取实体

    2. nlp(text) 会将文本解析成一个 doc 对象,其中包含了每个词和命名实体的详细信息。
    3. 使用 doc.ents 来获取命名实体(如人物、地点等)。
    4. 关系抽取

    5. 在这个示例中,我们简单地通过检查特定关键词(如“friend”,“lives in”,“likes”)来构造关系。
    6. 在实际应用中,可以使用更复杂的技术,如依存句法分析或训练机器学习模型来自动抽取实体间的关系。
    7. 生成知识图谱

    8. 利用 networkx 来创建一个无向图,并用边表示实体之间的关系。
    9. nx.draw() 用于绘制图形,nx.draw_networkx_edge_labels() 用来为每条边添加关系标签。

    最后 系统自动地解析了文本中地关系,并自动生成了一张知识图谱: 

    扩展知识:

    这个示例中关系的抽取非常简单,实际应用中通常会采用更复杂的方法来处理,例如:

  • 依存句法分析:通过分析句子的语法结构,确定哪些词语是主谓宾关系。
  • 预训练模型:使用如 BERT 等预训练模型,通过细粒度的分类或关系提取来自动识别实体之间的关系。
  • 图数据库:构建一个更加复杂的知识图谱,并存储在图数据库(如 Neo4j)中,方便查询和推理。
  • 通过这些方法,可以将新闻文本中蕴含的知识自动转化为知识图谱,便于进一步分析和应用。

    在文末需要说明的一点是,我们在这里讲的 【知识图谱】, 实际应用中大多数情况下并不是以图片的形式来展示的,它的本质是一种数据的关系结构,这种关系结构将很多关联的信息联系在一起,组成了我们所说的【知识图谱】

    这就是AI的应用,入门后,逐步练习,逐步领悟,逐步融汇贯通,不久的将来,你的段位会越来越高的!

    作者:minstbe

    物联沃分享整理
    物联沃-IOTWORD物联网 » AI开发: 知识图谱的初识,学会制作知识图谱- Python 机器学习

    发表回复