圖機器學習(17)——基于文檔語料庫構建知識圖譜

圖機器學習(17)——基于文檔語料庫構建知識圖譜

    • 0. 前言
    • 1. 基于文檔語料庫構建知識圖譜
    • 2. 知識圖譜
    • 3. 文檔-實體二分圖

0. 前言

文本數據的爆炸性增長,直接推動了自然語言處理 (Natural Language Processing, NLP) 領域的快速發展。在本節中,通過從文檔語料庫中提取的信息,基于文檔語料庫提取的信息,介紹如何利用這些信息構建知識圖譜。

1. 基于文檔語料庫構建知識圖譜

在本節中,我們將使用自然語言處理一節中提取的信息,構建關聯不同知識要素的網絡圖譜。我們將重點探討兩種圖結構:

  • 知識圖譜 (Knowledge-based graph):通過句子的語義推斷實體間關系
  • 二分圖 (Bipartite graph):建立文檔與文本實體間的連接,后可投影為僅含文檔節點或實體節點的同質圖

2. 知識圖譜

知識圖譜的價值在于不僅能關聯實體,更能賦予關系方向與語義內涵。例如比較以下兩種關系:

I (->) buy (->) a book  
I (->) sell (->) a book

除 “buy/sell” 的動作差異外,關系方向性同樣關鍵——需區分動作執行者(主語)與承受者(賓語)的非對稱關系。
構建知識圖譜需要實現主謂賓 (Subject-Verb-Object, SVO) 三元組提取函數,該函數將應用于語料所有句子,聚合三元組后即可生成對應圖譜。
SVO 提取器可基于 spaCy 模型提供的依存句法分析實現:依存樹標注既能區分主從句子結構,又可輔助識別 SVO 三元組。實際業務邏輯需處理若干特殊情況(如連詞、否定結構、介詞短語等),這些均可通過規則集編碼實現,且規則可根據具體用例調整優化。使用這個輔助函數,可以計算語料庫中的所有三元組,并將它們存儲在語料庫 DataFrame 中。

from subject_object_extraction import findSVOs
corpus["triplets"] = corpus["parsed"].apply(lambda x: findSVOs(x, output="obj"))

連接類型(由句子核心謂語決定)存儲在 edge 列中。查看出現頻率最高的 10 種關系:

edges["edge"].value_counts().head(10)

最常見的邊類型對應基礎謂詞結構。除通用動詞(如 be、have、tell、give )外,我們還發現更多金融語境相關的謂詞(如 buy、sell、make)。利用這些邊數據,可以通過 networkx 工具函數構建知識圖譜:

G=nx.from_pandas_edgelist(edges, "source", "target", edge_attr=True, create_using=nx.MultiDiGraph())

通過篩選邊數據表并創建子網絡,可分析特定關系類型,如 “lend” 邊:

G=nx.from_pandas_edgelist(edges[edges["edge"]=="lend"], "source", "target",edge_attr=True, create_using=nx.MultiDiGraph()
)

下圖顯示了基于 “lend” 關系的子圖。

子圖

我們也可以通過篩選其他關系類型來靈活調整上述代碼進行探索。接下來,我們將介紹另一種將文本信息編碼為圖結構的方法,該方法將運用特殊圖結構——二分圖。

3. 文檔-實體二分圖

雖然知識圖譜能有效揭示實體間的聚合關系,但在某些場景下其他圖表示法可能更具優勢。例如當需要進行文檔語義聚類時,知識圖譜并非最優數據結構;同樣,對于識別未共現于同一句子但頻繁出現在同一文檔中的間接關聯(如競品分析、相似產品發現等),知識圖譜也存在局限性。
為解決這些問題,我們將采用二分圖對文檔信息進行編碼:為每篇文檔提取最具代表性的實體,建立文檔節點與對應實體節點的連接。這種結構中,單個文檔節點會關聯多個實體節點,而實體節點也可被多篇文檔引用(形成交叉引用網絡)。這種交叉引用關系可衍生出實體間、文檔間的相似度度量,進而支持將二分圖投影為純文檔節點或純實體節點的同質圖。
為了構建二分圖,需要提取文檔中的相關實體。“相關實體”在當前的上下文中,可以視為命名實體(例如,由命名實體識別引擎識別的組織、人物或地點)或關鍵詞;即,能夠識別并通常描述文檔及其內容的詞(或詞的組合)。
關鍵詞提取算法眾多,其中基于 TF-IDF 評分的方法較為經典:該算法通過計算詞元(或詞元組合 n-gram )的得分進行篩選,得分與文檔內詞頻 (Term Frequency) 成正比,與語料庫中出現該詞的文檔頻率 (Inverse Document Frequency) 成反比:
ci,j∑ci,j?logN1+Di\frac{c_{i,j}}{\sum c_{i,j}}\cdot log\frac N{1+D_i} ci,j?ci,j???log1+Di?N?
其中,ci,jc_{i,j}ci,j? 表示文檔 jjj 中詞語 iii 的計數,NNN 表示語料庫中的文檔數量,DiD_iDi? 表示詞 iii 出現的文檔。因此,TF-IDF 評分機制會提升文檔中高頻出現的詞匯權重,同時降低常見詞匯(往往缺乏代表性)的得分。
TextRank 算法同樣基于文檔的圖結構表示。TextRank 算法構建的網絡中,節點是單個詞元,邊則由特定滑動窗口內共現的詞元對形成。網絡構建完成后,通過 PageRank 算法計算各詞元的中心度得分,據此對文檔內詞匯進行重要性排序。最終選取中心度最高的節點(通常占文檔總詞量的 5%-20% )作為候選關鍵詞。當多個候選關鍵詞相鄰出現時,它們會被合并為多詞復合關鍵詞。

(1) 利用 gensim 庫可以直接使用 TextRank 算法:

from gensim.summarization import keywords
text = corpus["clean_text"][0]
keywords(text, words=10, split=True, scores=True, pos_filter=('NN', 'JJ'), lemmatize=True)

輸出結果如下所示:

[('trading', 0.4615130639538529),('said', 0.3159855693494515),('export', 0.2691553824958079),('import', 0.17462010006456888),('japanese electronics', 0.1360932626379031),('industry', 0.1286043740379779),('minister', 0.12229815662000462),('japan', 0.11434500812642447),('year', 0.10483992409352465)]

這里的評分代表中心度 (centrality),反映了特定詞元的重要性。可以看到,算法還可能生成復合詞元。我們可以實現關鍵詞提取功能來計算整個語料庫的關鍵詞,并將結果存儲到語料 DataFrame 中:

corpus["keywords"] = corpus["clean_text"].apply(lambda text: keywords(text, words=10, split=True, scores=True, pos_filter=('NN', 'JJ'), lemmatize=True)
)

(2) 除了關鍵詞,構建二分圖還需要解析 NER 引擎提取的命名實體,并以與關鍵詞相似的數據格式進行編碼:

def extractEntities(ents, minValue=1, typeFilters=["GPE", "ORG", "PERSON"]):entities = pd.DataFrame([{"lemma": e.lemma_, "lower": e.lemma_.lower(), "type": e.label_}for e in ents if hasattr(e, "label_")])if len(entities)==0:return pd.DataFrame()g = entities.groupby(["type", "lower"])summary = pd.concat({"alias": g.apply(lambda x: x["lemma"].unique()), "count": g["lower"].count()}, axis=1)return summary[summary["count"]>1].loc[pd.IndexSlice[typeFilters, :, :]]def getOrEmpty(parsed, _type):try:return list(parsed.loc[_type]["count"].sort_values(ascending=False).to_dict().items())except:return []def toField(ents):typeFilters=["GPE", "ORG", "PERSON"]parsed = extractEntities(ents, 1, typeFilters)
return pd.Series({_type: getOrEmpty(parsed, _type) for _type in typeFilters})

(3) 解析 spacy 標簽:

entities = corpus["parsed"].apply(lambda x: toField(x.ents))

(4) 通過 pd.concat 函數可以將實體 DataFrame 與語料 DataFrame 合并,從而將所有信息整合到單一數據結構中:

merged = pd.concat([corpus, entities], axis=1)

(5) 現在我們已經具備構建二分圖的所有要素,可以通過循環遍歷所有文檔-實體或文檔-關鍵詞對來創建邊列表:

edges = pd.DataFrame([{"source": _id, "target": keyword, "weight": score, "type": _type}for _id, row in merged.iterrows()for _type in ["keywords", "GPE", "ORG", "PERSON"] for (keyword, score) in row[_type]
])

(6) 邊列表創建完成后,即可使用 networkx API 生成二分圖:

G = nx.Graph()
G.add_nodes_from(edges["source"].unique(), bipartite=0)
G.add_nodes_from(edges["target"].unique(), bipartite=1)
G.add_edges_from([(row["source"], row["target"])for _, row in edges.iterrows()
])

接下來,我們將把這個二分圖投影到任意一組節點(實體或文檔)上。使我們能夠探索兩種圖之間的差異,并使用無監督技術對術語和文檔進行聚類。然后,我們將回到二分圖,通過利用網絡信息進行監督分類任務。

2.2.1 實體-實體圖

我們首先將圖投影到實體節點集合上。NetworkX 提供了一個專門處理二分圖的子模塊 networkx.algorithms.bipartite,其中已實現了多種算法,networkx.algorithms.bipartite.projection 子模塊提供了若干實用函數,可將二分圖投影到特定節點子集上。在執行投影之前,我們需要利用創建圖時設置的 “bipartite” 屬性來提取特定集合(文檔或實體)的節點:

document_nodes = {n for n, d in G.nodes(data=True) if d["bipartite"] == 0}
entity_nodes = {n for n, d in G.nodes(data=True) if d["bipartite"] == 1}

圖投影本質上會創建一個由選定節點組成的新圖。節點之間邊的建立取決于它們是否擁有共同鄰居節點。基礎的 projected_graph 函數會生成一個邊未加權的網絡。但通常更具信息量的做法是根據共同鄰居的數量為邊賦予權重,投影模塊提供了基于不同權重計算方式的多種函數。在下一節中,我們將使用 overlap_weighted_projected_graph 函數,該函數基于共同鄰居采用 Jaccard 相似度計算邊權重。我們也可以探索其它函數,根據具體應用場景選擇最適合的方案。

2.2.2 維度問題

在進行圖投影時還需特別注意一個問題:投影后圖的維度。在某些情況下,投影可能會產生數量龐大的邊,導致圖難以分析。在我們的使用場景中,按照我們用來創建網絡的邏輯,一個文檔節點至少連接到 10 個關鍵詞和若干實體節點。在最終的實體-實體圖中,這些實體之間都會因為至少擁有一個共同鄰居(包含它們的文檔)而相互連接。因此單文檔就會生成約 15×142≈100\frac {15×14}2\approx 100215×14?100 條邊。如果我們將這個數字乘以文檔的數量 (~105\sim 10^5105),即便在本節的簡單場景中也會產生數百萬條邊,幾乎無法處理。雖然這顯然是個保守上限(因為某些實體共現關系會出現在多個文檔中而不會重復計算),但已能反映可能面臨的復雜度量級。因此建議,根據底層網絡的拓撲結構和圖規模,實施二分圖投影前務必謹慎。
為了降低復雜度使投影可行,可以僅保留達到特定度數的實體節點。大多數復雜性來自于那些僅出現一次或少數次、卻仍在圖中形成團結構的實體節點。這類實體對模式捕捉和洞見發現的貢獻度很低,且可能受到統計波動性的強烈干擾。相反,我們應聚焦于那些高頻出現、能提供更可靠統計結果的強相關性實體。
為此,我們將僅保留度數 ≥5 的實體節點,具體方法是生成經過過濾的二分子圖:

nodes_with_low_degree = {n for n, d in nx.degree(G, nbunch=entity_nodes) if d<5}

對該子圖進行投影,而不會生成邊數過多的圖:

entityGraph = overlap_weighted_projected_graph(subGraph, {n for n, d in subGraph.nodes(data=True) if d["bipartite"] == 1}
)

盡管我們已應用過濾條件,但圖的邊數和平均節點度數仍然相當大。下圖展示了節點度數和邊權重的分布情況,可以觀察到,度數分布在較低值處出現一個峰值,但向高值方向呈現長尾分布;邊權重也表現出類似趨勢,峰值出現在較低值區間,但右側同樣具有長尾特征。這些分布特征表明圖中存在多個小型社區(即團結構),它們通過某些中心節點相互連接。

節點度數和邊權重的分布

邊權重的分布情況也表明可以應用第二個過濾器。在二分圖上實施的實體度數過濾,幫助我們篩除了僅出現在少數文檔中的低頻實體。但由此得到的圖結構可能會面臨相反的問題:高頻實體之間可能僅僅因為共同出現在多個文檔中就產生連接,即便它們之間并不存在有意義的因果關系。以江蘇和蘇州為例,這兩個實體幾乎必然存在連接,因為極有可能存在至少一個或多個文檔同時提及它們。但若二者之間缺乏強因果關聯,它們的Jaccard相似度就不太可能達到較高值。僅保留權重最高的邊,能讓我們聚焦于最相關且可能穩定的關系。邊權重分布表明,將閾值設定為 0.05 較為合適:

filteredEntityGraph = entityGraph.edge_subgraph([edge for edge in entityGraph.edges if entityGraph.edges[edge]["weight"]>0.05]
)

該閾值能顯著減少邊的數量,使網絡分析具備可操作性。

過濾后圖的節點度數與邊權重的分布

上圖展示了過濾后圖的節點度數與邊權重的分布情況,可以看到當前分布顯示節點度數在 10 左右出現峰值。

2.2.3 圖分析

通過 Gephi 生成的網絡全景如下所示:

網絡全景圖

(1) 為深入理解網絡拓撲特性,我們計算了平均最短路徑長度、聚類系數和全局效率等宏觀指標。雖然該圖包含五個連通分量,但最大分量幾乎涵蓋整個網絡——在 2265 個節點中占據了 2254 個:

components = nx.connected_components(filteredEntityGraph)
pd.Series([len(c) for c in components])

(2) 獲取最大連通分量的全局屬性:

comp = components[0]
global_metrics = pd.Series({"shortest_path": nx.average_shortest_path_length(comp),"clustering_coefficient": nx.average_clustering(comp),"global_efficiency": nx.global_efficiency(comp)
})

輸出結果如下所示:

{'shortest_path': 4.715073779178782,'clustering_coefficient': 0.21156314975836915,'global_efficiency': 0.22735551077454275
}

從這些指標的數值(最短路徑約 5,聚類系數約 0.2) 結合度數分布可以看出,該網絡由多個規模有限的社區組成。局部屬性(如度數、PageRank 和中介中心性分布)如下圖所示,這些指標之間往往存在相互關聯性:

局部屬性

在完成網絡局部/全局指標的描述及整體可視化后,我們將應用無監督學習技術來挖掘網絡中的深層信息。

(3) 首先使用 Louvain 社區檢測算法,該算法通過模塊度優化,旨在將節點劃分至互不重疊的最佳社區結構中:

import community
communities = community.best_partition(filteredEntityGraph)

大約可以得到 30 個社區,其成員數量分布與下圖所示,其中較大規模的社區一般包含 130-150 篇文檔。

成員分布

下圖展示了其中一個社區的細節視圖,從中可識別特定主題。左側除實體節點外,還可看到文檔節點,由此揭示了關聯二分圖的結構:

社區視圖

(4) 通過節點嵌入技術可以提取關于實體間拓撲關系與相似性的深層信息。我們可以采用 Node2Vec 方法——該方法通過將隨機生成的游走序列輸入 skip-gram 模型,將節點映射至向量空間,使拓撲相近的節點在嵌入空間中位置鄰近:

from node2vec import Node2Vec
node2vec = Node2Vec(filteredEntityGraph, dimensions=5)
model = node2vec.fit(window=10)
embeddings = model.wv

在嵌入向量空間中,我們可以應用傳統聚類算法(如高斯混合模型、K-MeansDBSCAN)。我們還能通過 t-SNE 將嵌入向量投影至二維平面,實現聚類與社區的可視化。Node2Vec 不僅為圖中社區識別提供了另一種解決方案,還能像經典 Word2Vec 那樣計算詞語相似度。例如,我們可以查詢 Node2Vec 嵌入模型,找出與 “turkey” 最相似的詞語,從而獲取語義關聯詞:

[('turkish', 0.9975333213806152),
('lira', 0.9903393983840942),
('rubber', 0.9884852170944214),
('statoil', 0.9871745109558105),
('greek', 0.9846569299697876),
('xuto', 0.9830175042152405),
('stanley', 0.9809650182723999),
('conference', 0.9799597263336182),
('released', 0.9793018102645874),
('inra', 0.9775203466415405)]

盡管 Node2VecWord2Vec 在方法上存在相似性,但兩種嵌入方案的信息來源截然不同:Word2Vec 直接基于文本構建,捕捉句子層面的詞語關系;而 Node2Vec 源自實體-文檔二分圖,其編碼的特征更傾向于文檔層面的描述。

2.2.4 文檔-文檔圖

接下來,我們將二分圖投影至文檔節點集,構建可分析的文檔關聯網絡。與創建實體關聯網絡類似,這里采用 overlap_weighted_projected_graph 函數生成帶權圖,并通過過濾保留顯著性邊。需要注意的是,網絡的拓撲結構以及構建二分圖時使用的業務邏輯并不鼓勵形成團(即完全圖),正如在實體-實體圖中看到的那樣:只有當兩個節點至少共享一個關鍵詞、組織、地點或人時,它們才會連接。在 10-15 個節點組成的群組中(如實體節點群組),這種情況雖可能發生,但概率較低。

(1) 接下來,快速構建網絡:

documentGraph = overlap_weighted_projected_graph(G,document_nodes
)

下圖展示了節點度數與邊權重的分布情況,這有助于我們確定過濾邊時所采用的閾值。值得注意的是,與實體-實體圖的度數分布相比,當前節點度數分布明顯向高值區域偏移,表明存在多個具有超高連接度的"超級節點"。同時,邊權重分布顯示杰卡德指數傾向于接近1的數值,遠高于實體-實體圖中的觀測值。這兩項發現揭示了兩個網絡的本質差異:實體-實體圖以大量緊密連接的社區(即完全子圖)為特征,而文檔-文檔圖則呈現"核心-邊緣"結構——高度連接的大度數節點構成網絡核心,外圍則分布著弱連接或孤立節點:

節點度數與邊權重的分布

(2) 將所有邊存儲至 DataFrame 中,這樣既能實現可視化呈現,又可基于該數據集進行過濾以生成子圖:

allEdgesWeights = pd.Series({(d[0], d[1]): d[2]["weight"]for d in documentGraph.edges(data=True)
})

觀察上圖可知,將邊權重閾值設定為 0.6 較為合理,這樣可通過 networkxedge_subgraph 函數生成更易處理的網絡:

filteredDocumentGraph = documentGraph.edge_subgraph(allEdgesWeights[(allEdgesWeights>0.6)].index.tolist()
)

下圖展示了精簡后的網絡在節點度數與邊權重上的分布情況:

節點度數與邊權重上的分布

文檔-文檔圖與實體-實體圖在拓撲結構上的本質差異,在下文完整的網絡可視化圖中更為明顯。文檔-文檔網絡呈現"核心-衛星"結構——由緊密連接的核心網絡與多個弱連接的衛星節點構成。這些衛星節點代表那些未共享或僅共享少量關鍵詞/實體的文檔,其中完全孤立的文檔數量相當龐大,約占總量的 50%

網絡可視化

(3) 提取該網絡的連通分量:

components = pd.Series({ith: componentfor ith, component in enumerate(nx.connected_components(filteredDocumentGraph))
})

下圖展示了連通分量的規模分布情況。可以清晰觀察到若干超大聚類(核心集群)與大量孤立或極小分量(邊緣衛星集群)并存的現象。這種結構與我們在實體-實體圖中觀察到的結構截然不同,在實體-實體圖中,所有節點歸屬于單一超大連通集群:

連通分量的規模分布

(4) 從完整圖中提取由最大連通分量構成的子圖:

coreDocumentGraph = nx.subgraph(filteredDocumentGraph,[nodefor nodes in components[components.apply(len)>8].valuesfor node in nodes]
)

觀察核心網絡的 Gephi 可視化結果(下圖右側),可以發現,該核心網絡由若干社區組成,其中包含多個彼此緊密連接的高度數節點。

網絡可視化

與處理實體-實體網絡時類似,我們可以處理網絡以識別嵌入在圖中的社區。然而,不同之處在于,文檔-文檔圖現在提供了一個使用文檔標簽來判斷聚類的手段。實際上,屬于同一主題的文檔應當彼此鄰近且相互連接。此外,這種方法還能幫助我們識別不同主題之間的相似性。

(5) 首先,提取候選社區:

import community
communities = pd.Series(community.best_partition(filteredDocumentGraph)
)

(6) 隨后分析各社區內的主題分布,檢測是否存在同質性(所有文檔屬于同一類別)或主題間的相關性:

from collections import Counter
def getTopicRatio(df):return Counter([labelfor labels in df["label"]for label in labels])
communityTopics = pd.DataFrame.from_dict({cid: getTopicRatio(corpus.loc[comm.index])for cid, comm in communities.groupby(communities)
}, orient="index")
normalizedCommunityTopics = (communityTopics.T / communityTopics.sum(axis=1)
).T

normalizedCommunityTopics 是一個 DataFrame 結構,其中每一行代表一個社區 (community),每一列對應不同主題的分布比例(以百分比形式呈現)。為了量化這些社區/集群內部主題混合的異質性,我們需要計算每個社區的香農熵 (Shannon entropy):
Ic=?∑ilogtciIc=?∑_ilogt_{ci} Ic=?i?logtci?
其中,IcIcIc 表示社區 ccc 的熵值,$t_{ci} 表示社區 ccc 中主題 iii 的占比。接下來,我們需要為所有社區計算經驗香農熵:

normalizedCommunityTopics.apply(lambda x: np.sum(-np.log(x)), axis=1)

下圖展示了所有社區的熵值分布情況。大多數社區的熵值為零或接近零,這表明相同類別(標簽)的文檔傾向于聚集在一起:

社區熵分布

盡管大多數社區在主題分布上呈現零變異或低變異,但當某些社區表現出異質性時,探究主題間的關聯仍具有意義。為此,我們計算主題分布之間的相關性

topicsCorrelation = normalizedCommunityTopics.corr().fillna(0)

然后,使用主題-主題網絡表示和可視化這些相關性:

topicsCorrelation[topicsCorrelation<0.8] = 0
topicsGraph = nx.from_pandas_adjacency(topicsCorrelation)

下圖左側展示了主題網絡的完整圖表示。與文檔-文檔網絡類似,主題網絡呈現出"核心-邊緣"結構——邊緣由孤立節點構成,核心則是高度連通的節點集群。右圖聚焦展示了核心網絡的細節,其中商品類主題之間的強相關性反映出明確的語義關聯:

網絡可視化

本節我們分析了文檔及文本源分析中產生的各類網絡結構,通過全局與局部屬性統計描述網絡特征,并運用無監督算法揭示了圖中的潛在結構。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/916060.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/916060.shtml
英文地址,請注明出處:http://en.pswp.cn/news/916060.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【實時Linux實戰系列】實時文件系統的特性與優化

在實時系統中&#xff0c;文件系統的性能和可靠性對于系統的整體表現至關重要。實時文件系統需要在嚴格的時間約束內完成文件的讀寫操作&#xff0c;以確保系統的實時性。本文將介紹實時文件系統的基本特性和應用場景&#xff0c;并提供相關的實施和優化建議&#xff0c;以滿足…

Clickhouse源碼分析-副本數據同步

1 總體流程上圖說明了一條insert語句最后如何被副本同步到的流程&#xff08;圖中ck集群為單shard&#xff0c;雙副本&#xff09;。&#xff08;1&#xff09;從客戶端發出&#xff0c;寫入ck&#xff08;2&#xff09;ck提交LogEntry到Keeper&#xff08;3&#xff09;另外一…

Spring AI 系列之二十四 - ModerationModel

之前做個幾個大模型的應用&#xff0c;都是使用Python語言&#xff0c;后來有一個項目使用了Java&#xff0c;并使用了Spring AI框架。隨著Spring AI不斷地完善&#xff0c;最近它發布了1.0正式版&#xff0c;意味著它已經能很好的作為企業級生產環境的使用。對于Java開發者來說…

在 macOS 上 安裝最新 Python 和 pip

文章目錄方法一&#xff1a;使用 Homebrew&#xff08;推薦&#xff09;方法二&#xff1a;使用 pyenv&#xff08;管理多個 Python 版本&#xff09;方法三&#xff1a;從官網下載安裝包升級 pip驗證安裝方法一&#xff1a;使用 Homebrew&#xff08;推薦&#xff09; 1. 安裝…

新能源電池廠自動化應用:Modbus TCP轉DeviceNet實踐

一、項目背景在新能源電池廠的生產過程中&#xff0c;提升自動化水平對提高生產效率和產品質量至關重要。我們的生產線上&#xff0c;施耐德PLC負責整體的生產流程控制&#xff0c;采用Modbus TCP協議進行數據傳輸&#xff0c;它基于以太網&#xff0c;傳輸速度快、穩定性高&am…

Java進階3:Java集合框架、ArrayList、LinkedList、HashSet、HashMap和他們的迭代器

Java集合框架 集合框架被設計成的目標&#xff1a;高性能、高效 允許不同類型的結合&#xff0c;以類似的方式進行工作&#xff0c;有高度的互操作性 對一個集合的擴展和適應必須是簡單的兩種容器&#xff1a;集合Collection、圖Map 集合接口被分為了三種子類型&#xff1a;Lis…

筆記/使用Excel進行財務預測

文章目錄金融預測的決策與數據收集決定財務問題收集財務數據清理與合并財務數據解釋與應用預測結果使用excel進行財務回歸分析回歸預測的步驟解釋回歸結果在 Excel 中執行預測財務分析指標財務分析常用指標一覽表財務指標的相關性對競爭對手進行基準測試財務指標的趨勢分析持續…

力扣1287:有序數組中出現次數超過25%的元素

力扣1287:有序數組中出現次數超過25%的元素題目思路代碼題目 給你一個非遞減的 有序 整數數組&#xff0c;已知這個數組中恰好有一個整數&#xff0c;它的出現次數超過數組元素總數的 25%。 請你找到并返回這個整數 思路 哈希表秒了 代碼 class Solution { public:int fi…

如何用 Z.ai 生成PPT,一句話生成整套演示文檔

大家好&#xff0c;這里是K姐。 一個幫你追蹤最新AI應用的女子。 最近朋友給我分享了一個好玩的頁面截圖。 一眼看過去&#xff0c;就感覺這PPT的文字排版很有人工味。 我立馬就去試了一下&#xff0c;才發現它根本不是傳統的 PPT&#xff0c;而是一種網頁式的 Slides 。 做…

C/C++ 編程:掌握靜態庫與動態庫的編譯

在 C/C 項目開發中&#xff0c;理解并掌握如何編譯和使用庫文件是至關重要的一環。庫允許你將常用的函數和代碼模塊化&#xff0c;從而提高代碼重用性、簡化項目管理并縮短編譯時間。最常見的兩種庫類型是靜態庫 (.a) 和動態庫 (.so)。它們各有優缺點&#xff0c;適用于不同的開…

汽車安全 | 汽車安全入門

引言 汽車安全不僅僅是對汽車/車輛進行物理入侵。這只是很小且簡單的一部分。當你以攻擊者/對手的思維去看待一輛聯網汽車時&#xff0c;你關注的是整個車輛生態系統。這不僅包括它如何與外部實體通信&#xff0c;也包括它在車內如何運作。 汽車是主要的交通工具&#xff0c;…

CLIP與SIGLIP對比淺析

CLIP 和 SIGLIP 的核心區別在于損失函數的設計&#xff1a;CLIP 使用基于 softmax 的對比損失&#xff08;InfoNCE&#xff09;&#xff0c;強制正樣本在全局對比中壓倒所有負樣本&#xff0c;計算成本高且受限于負樣本數量&#xff1b;SIGLIP 改用基于 sigmoid 的二元分類損失…

移動管家手機控車便捷性如何

移動管家4G手機控車-全面升級一鍵啟動、無鑰匙進入、手機啟動、手機開關鎖、手機開尾箱、手機尋車、車輛診斷、GPS北斗定位、電子圍欄、車輛授權、車輛防盜搶、胎壓檢測、預約啟動、車窗控制、車況提醒等功&#xff1b;移動管家手機控車系統&#xff08;以“移動管家控車APP”為…

MySQL 8.4.4詳細下載安裝配置

1、下載mysql8.4.4文件&#xff0c;取zip文件 mysql8.4.4下載路徑 MySQL 5.7.31詳細下載安裝配置 2、配置環境變量 1.系統—>高級系統設置—>環境變量—>系統變量 在系統變量中點擊新建&#xff0c;變量名為量名為&#xff1a;MYSQL_HOME&#xff0c;添加你的mys…

在 Linux 上安裝 `pgvector`(這是一個 PostgreSQL 的向量類型擴展,常用于處理嵌入向量,便于進行向量相似度搜索)

全文 4000 字&#xff0c;配圖配碼&#xff0c;已在多家企業落地驗證。閱讀完如有收獲&#xff0c;文末投票告訴我你最關注的方向&#xff0c;我會在下一篇文章里繼續深入。 0. pgvector 簡介 pgvector 是一款 PostgreSQL 原生向量數據類型擴展&#xff0c;核心能力&#xff1…

【項目實戰】——深度學習.全連接神經網絡

目錄 1.使用全連接網絡訓練和驗證MNIST數據集 2.使用全連接網絡訓練和驗證CIFAR10數據集 1.使用全連接網絡訓練和驗證MNIST數據集 import torch from torch import nn from torchvision import datasets, transforms from torch.utils.data import DataLoader from torch im…

嵌入式學習的第三十四天-進程間通信-TCP

一、TCPTCP : 傳輸控制協議 傳輸層1. TCP特點(1).面向連接,避免部分數據丟失 (2).安全、可靠 (3).面向字節流 (4).占用資源開銷大2.TCP安全可靠機制三次握手:指建立tcp連接時&#xff0c;需要客戶端和服務端總共發送三次報文確認連接。確保雙方均已做好 收發…

【爬蟲】06 - 自動化爬蟲selenium

自動化爬蟲selenium 文章目錄自動化爬蟲selenium一&#xff1a;Selenium簡介1&#xff1a;什么是selenium2&#xff1a;安裝準備二&#xff1a;元素定位1&#xff1a;id 定位2&#xff1a;name 定位3&#xff1a;class 定位4&#xff1a;tag 定位5&#xff1a;xpath 定位(最常用…

2025年中國移動鴻鵠大數據實訓營(大數據方向)kafka講解及實踐-第2次作業指導

書接上回&#xff0c;第二次作業比較容易解決&#xff0c;我問了ai&#xff0c;讓他對我進行指導&#xff0c;按照它提供的步驟&#xff0c;我完成了本次實驗&#xff0c;接下來我會標注出需要注意的細節&#xff0c;指導大家完成此次任務。 &#x1f3af; 一、作業目標 ??…

三十七、【高級特性篇】定時任務:基于 APScheduler 實現測試計劃的靈活調度

三十七、【高級特性篇】定時任務:基于 APScheduler 實現測試計劃的靈活調度 前言 準備工作 第一部分:后端實現 - `APScheduler` 集成與任務調度 1. 安裝 `django-apscheduler` 2. 配置 `django-apscheduler` 3. 數據庫遷移 4. 創建調度觸發函數 5. 啟動 APScheduler 調度器 6…