久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    如何將任何文本語料轉換為知識圖譜?

     漢無為 2024-06-07 發布于湖北

    背景

    幾個月前,基于知識的問答系統(Knowledge Base Question Answering,KBQA)還是個新概念。

    現在,隨著大型語言模型(LLMs)的發展,帶有檢索增強生成(RAG)的KBQA對我們來說變得越來越容易了。

    知識圖譜

    知識圖譜(Knowledge Graph)是用來表示現實世界中的實體及其關系的一種數據結構。

    它通過節點(表示實體)和(表示實體間的關系)來構建一個連通的網絡。

    圖片

    知識圖譜的主要目的是將分散的數據組織成有結構的信息,使得機器能夠理解和處理這些信息,從而在搜索、問答、推薦等應用中提供更智能的服務。

    知識圖譜的基本組成部分

    1、實體(Entity):知識圖譜中的基本單元,代表現實世界中的對象,比如人、地點、事物等。

    2、屬性(Attribute):描述實體的特征,比如人的姓名、年齡,地點的名稱、坐標等。

    3、關系(Relation):表示實體之間的連接,比如“Tom 是 Mary 的朋友”這類描述實體間的關系。

    舉個例子

    Mary had a little lamb,

    You’ve heard this tale before;

    But did you know she passed her plate,

    And had a little more!

    繪制成KG,如下:

    圖片

    為什么要使用知識圖譜?

    知識圖譜在很多方面都很有用。

    1、可以運行圖算法并計算任何節點的中心性,以了解一個概念(節點)在整個工作體系中的重要性。

    2、可以分析連接和斷開的概念集合,或者計算概念群體,以深入理解主題內容。

    3、還能理解看似不相關的概念之間的聯系。

    舉例來說,僅僅依靠簡單的語義相似性搜索來找到與查詢最相關的上下文并不總是有效的,尤其是當查詢沒有提供足夠的上下文來明確其真實意圖,或者當上下文分散在大量文本中時。

    比如,考慮這個查詢:

    告訴我《百年孤獨》中何塞·阿爾卡迪奧·布恩迪亞的家譜。

    這本書中記錄了七代的何塞·阿爾卡迪奧·布恩迪亞,而且一半的人物都叫何塞·阿爾卡迪奧·布恩迪亞。

    如果使用簡單的 RAG 流程來回答這個查詢,可能會非常具有挑戰性,甚至可能無法實現。

    另外,RAG 的另一個缺點是它無法引導你提出正確的問題在很多情況下,提出正確的問題比獲取答案更為關鍵。

    圖增強生成(Graph Augmented generation,GAG)在一定程度上可以解決 RAG 的這些缺點。

    更好的是,我們可以靈活組合,構建一個圖增強檢索增強生成流水線,以融合兩者的優點,達到事半功倍的效果。

    將任何文本語料庫創建一個知識圖譜

    項目地址:https://rahulnyk./knowledge_graph/

    實現流程圖:

    圖片

    1、將文本語料庫分割成塊。為每個塊分配一個 chunk_id。

    2、針對每個文本塊,使用大型語言模型提取概念及其語義關系。我們將這種關系賦予權重 W1。同一對概念之間可能存在多種關系。每種關系都是一對概念之間的邊。

    3、考慮到在同一文本塊中出現的概念也會由于其上下文接近性而相關。我們將這種關系賦予權重 W2。請注意,同一對概念可能會在多個塊中出現。

    4、將相似的對組合起來,求其權重之和,并串聯它們的關系?,F在,對于任意不同的概念對之間只有一條邊。該邊具有一定的權重和一系列關系作為其名稱。

    5、它還計算每個節點的度數和節點的社區,分別用于調整圖中節點的大小和著色。

    技術棧

    1、Mistral 7B

    使用 Mistral 7B Openorca 從文本塊中提取概念。它可以很好地遵循系統提示指令。

    2、Ollama

    Ollama 可以輕松在本地托管任何模型。Mistral 7B OpenOrca 版本已可與 Ollama 一起使用,開箱即用。

    3、Pandas

    4、NetworkX

    這是一個 Python 庫,可以讓處理圖表變得超級簡單

    5、Pyvis

    Pyvis 用于可視化的 Python 庫。Pyvis 使用 python 生成 Javascript 圖形可視化。

    完整代碼

    1、初始化

    import pandas as pd
    import numpy as np
    import os
    from langchain.document_loaders import PyPDFLoader, UnstructuredPDFLoader, PyPDFium2Loader
    from langchain.document_loaders import PyPDFDirectoryLoader, DirectoryLoader
    from langchain.text_splitter import RecursiveCharacterTextSplitter
    from pathlib import Path
    import random

    ## 輸入數據目錄
    data_dir = 'cureus'
    inputdirectory = Path(f'./data_input/{data_dir}')

    print(inputdirectory.absolute().as_uri())
    ## 生成的結果文件(以CSV格式)存儲的位置
    out_dir = data_dir
    outputdirectory = Path(f'./data_output/{out_dir}')

    2、加載文檔

    loader = DirectoryLoader(inputdirectory, show_progress=True)

    documents = loader.load()

    splitter = RecursiveCharacterTextSplitter(
        chunk_size=1500,
        chunk_overlap=150,
        length_function=len,
        is_separator_regex=False,
    )

    pages = splitter.split_documents(documents)
    print('chunks數量 = ', len(pages))
    print(pages[3].page_content)

    圖片

    3、創建包含所有分塊的數據框

    from helpers.df_helpers import documents2Dataframe
    df = documents2Dataframe(pages)
    print(df.shape)
    df.head()

    圖片

    4、提取概念

    # 使用helpers/prompt函數從文本中提取概念
    from helpers.df_helpers import df2Graph
    from helpers.df_helpers import graph2Df

    如果regenerate設置為True,則會重新生成數據框,并將它們以CSV格式寫入,這樣就無需再次計算。數據框分為兩類:

    dfne 是邊的數據框(dataframe of edges)。

    df 是塊的數據框(dataframe of chunks)。

    如果regenerate為False,則數據框將從輸出目錄讀取,而不是重新計算。這意味著如果數據已經存在,程序將直接使用現有數據,無需再次處理。

    # 要使用大語言模型(LLM)重新生成圖,將此設置為True。
    regenerate = False

    if regenerate:
        concepts_list = df2Graph(df, model='zephyr:latest')
        dfg1 = graph2Df(concepts_list)
        if not os.path.exists(outputdirectory):
            os.makedirs(outputdirectory)
        
        dfg1.to_csv(outputdirectory/'graph.csv', sep='|', index=False)
        df.to_csv(outputdirectory/'chunks.csv', sep='|', index=False)
    else:
        dfg1 = pd.read_csv(outputdirectory/'graph.csv', sep='|')

    dfg1.replace('', np.nan, inplace=True)
    dfg1.dropna(subset=['node_1', 'node_2', 'edge'], inplace=True)
    dfg1['count'] = 4 
    # 將關系的權重增加到 4。
    # 當計算上下文 proximity 時,將分配權重 1。
    print(dfg1.shape)
    dfg1.head()

    文章的每個文本塊運行此操作并將 json 轉換為 Pandas 數據幀:

    圖片

    5、計算上下文 proximity(上下文相關性)

    def contextual_proximity(df: pd.DataFrame) -> pd.DataFrame:
        # 將數據框 melt(融化)為節點列表
        dfg_long = pd.melt(
            df, id_vars=['chunk_id'], value_vars=['node_1', 'node_2'], value_name='node'
        )
        dfg_long.drop(columns=['variable'], inplace=True)

        # 用塊ID作為鍵進行自連接,會在同一個文本塊中出現的詞之間創建關聯。
        # 使用塊ID作為鍵進行自連接將會創建一個在同一文本塊中出現的術語之間的關聯。
        dfg_wide = pd.merge(dfg_long, dfg_long, on='chunk_id', suffixes=('_1', '_2'))

        self_loops_drop = dfg_wide[dfg_wide['node_1'] == dfg_wide['node_2']].index
        dfg2 = dfg_wide.drop(index=self_loops_drop).reset_index(drop=True)

        dfg2 = (
            dfg2.groupby(['node_1', 'node_2'])
            .agg({'chunk_id': [','.join, 'count']})
            .reset_index()
        )
        dfg2.columns = ['node_1', 'node_2', 'chunk_id', 'count']
        dfg2.replace('', np.nan, inplace=True)
        dfg2.dropna(subset=['node_1', 'node_2'], inplace=True)

        dfg2 = dfg2[dfg2['count'] != 1]
        dfg2['edge'] = 'contextual proximity'
        return dfg2

    dfg2 = contextual_proximity(dfg1)
    dfg2.tail()

    得到一個與原始數據框非常相似的數據框。

    圖片

    6、數據合并這2個Dataframe

    dfg = pd.concat([dfg1, dfg2], axis=0)
    dfg = (
        dfg.groupby(['node_1', 'node_2'])
        .agg({'chunk_id': ','.join, 'edge': ','.join, 'count': 'sum'})
        .reset_index()
    )

    圖片

    7、計算 NetworkX 圖

    nodes = pd.concat([dfg['node_1'], dfg['node_2']], axis=0).unique()
    nodes.shape

    輸出:(215,)

    import networkx as nx
    G = nx.Graph()

    ## 添加節點
    for node in nodes:
        G.add_node(
            str(node)
        )

    ## 添加邊
    for index, row in dfg.iterrows():
        G.add_edge(
            str(row['node_1']),
            str(row['node_2']),
            title=row['edge'],
            weight=row['count']/4
        )

    8、對節點進行著色

    communities_generator = nx.community.girvan_newman(G)
    top_level_communities = next(communities_generator)
    next_level_communities = next(communities_generator)
    communities = sorted(map(sorted, next_level_communities))
    # 社區是指圖中的一組節點
    print('社區數量 = ', len(communities))
    print(communities)

    9、創建一個數據表(dataframe)來記錄每個社區的顏色

    import seaborn as sns
    palette = 'hls'

    ## Now add these colors to communities and make another dataframe
    # 在上一個問題中,我們已經創建了一個數據表 community\_colors,用于存儲每個社區的唯一顏色。
    # 現在,我們需要將這些顏色添加到社區檢測算法的輸出 results 中,并創建一個新的數據表 community\_info,其中包含每個節點的社區 ID 和社區顏色信息。
    def colors2Community(communities) -> pd.DataFrame:
        ## Define a color palette
        p = sns.color_palette(palette, len(communities)).as_hex()
        random.shuffle(p)
        rows = []
        group = 0
        for community in communities:
            color = p.pop()
            group += 1
            for node in community:
                rows += [{'node': node, 'color': color, 'group': group}]
        df_colors = pd.DataFrame(rows)
        return df_colors


    colors = colors2Community(communities)
    colors

    圖片

    10、給圖添加顏色

    for index, row in colors.iterrows():
        G.nodes[row['node']]['group'] = row['group']
        G.nodes[row['node']]['color'] = row['color']
        G.nodes[row['node']]['size'] = G.degree[row['node']]
    # 將一個 NetworkX 圖形 G 轉換為一個交互式的網絡可視化,并將其保存為 HTML 文件。
    from pyvis.network import Network

    graph_output_directory = './docs/index.html'

    net = Network(
        notebook=False,
        # bgcolor='#1a1a1a',
        cdn_resources='remote',
        height='900px',
        width='100%',
        select_menu=True,
        # font_color='#cccccc',
        filter_menu=False,
    )

    net.from_nx(G)
    # net.repulsion(node_distance=150, spring_length=400)
    net.force_atlas_2based(central_gravity=0.015, gravity=-31)
    # net.barnes_hut(gravity=-18100, central_gravity=5.05, spring_length=380)
    net.show_buttons(filter_=['physics'])

    net.show(graph_output_directory, notebook=False)

    輸出:./docs/index.html。

    全部節點

    圖片

    選擇需要查詢的節點:

    圖片

      本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 国产午夜精品理论大片| 亚洲高清WWW色好看美女| 国产av不卡一区二区| 国产成人精选视频在线观看不卡| 久久五十路丰满熟女中出| 少妇人妻AV无码专区| 久久亚洲国产精品久久| 精品人妻无码专区在中文字幕| 玩弄放荡人妻少妇系列| A毛片毛片看免费| 亚洲美免无码中文字幕在线| 丰满人妻被黑人连续中出| 久久精品国产www456c0m| 成年视频人免费网站动漫在线| 狠狠综合久久综合88亚洲| 精品 日韩 国产 欧美 视频| 日韩加勒比一本无码精品| 日韩国产亚洲一区二区三区| 亚洲国产精品日韩在线| 狠狠色丁香婷婷综合潮喷| 日本一区不卡高清更新二区| 国产成人无码A区在线观看视频| 成人3D动漫一区二区三区| JIZZJIZZ亚洲日本少妇| 国产按头口爆吞精在线视频| aaa少妇高潮大片免费看| 色妞色综合久久夜夜| 日韩国产中文字幕精品| 亚洲熟妇无码AV在线播放| 国产欧美综合在线观看第十页| 久久精品国产亚洲AV忘忧草18| 国产普通话刺激视频在线播放| 国产丰满乱子伦无码专区| 久久婷婷五月综合色国产免费观看 | 国产成人亚洲综合图区| 精品人妻中文无码AV在线| 亚洲日韩久热中文字幕| 亚洲欧洲日韩国内高清 | 欧美人与禽2O2O性论交| 国产重口老太和小伙| 日本一区二区不卡精品|