色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

淺析基于圖數據庫NebulaGraph的ID Resolution方法與代碼示例

OSC開源社區 ? 來源:NebulaGraph ? 2023-03-14 17:33 ? 次閱讀

本文是一個基于 NebulaGraph 上的圖算法、圖數據庫、圖神經網絡的 ID-Mapping 方法綜述,除了基本方法思想的介紹之外,我還給大家提供了可以跑的 Playground。

1 基于圖數據庫的用戶 ID 識別方法用戶

ID 識別,是一個很常見的圖技術應用場景,在不同的語境下它可能還被叫做 Entity Correlation(實體關聯)、Entity Linking(實體鏈接)、ID Mapping(身份映射)等等。ID 識別解決的問題是找出相同的用戶在同一個系統或者不同系統中的不同賬號。

由于 ID 識別天然地是一個關聯關系問題,也是一個典型的圖、圖數據庫應用場景。

1.1 建立圖譜

1.1.1 圖建模

我們從一個最簡單、直接的圖譜開始,如下邊的圖結構示意顯示,我們定義了點:

Prop: [name, email, birthday, address, phone_num]

user

phone

email

device

ip

address

在他們之間有很自然的邊:

Prop: time

Prop: time

used_device

logged_in_from

has_phone

has_address

has_email

42c0f120-bfa5-11ed-bfe3-dac502259ad0.png

建立圖譜

1.1.2 數據

這份數據是開源的,地址在https://github.com/wey-gu/identity-correlation-datagen

1.1.3 寫入NebulaGraph

利用 Nebula Up,一行部署 NebulaGraph地址:https://github.com/wey-gu/nebula-up/

curl-fsSLnebula-up.siwei.io/install.sh|bash

圖建模的 Schema 對應的 NebulaGraph DDL 是:

#創建一個叫做entity_resolution的圖空間
CREATESPACEentity_resolution(vid_type=FIXED_STRING(30));
USEentity_resolution;

#創建點的類型TAG

CREATETAG`user`(`name`stringNOTNULL,`email`stringNOTNULL,`phone_num`stringNOTNULL,`birthday`dateNOTNULL,`address`stringNOTNULL);

CREATETAG`address`(`address`stringNOTNULL);
CREATETAG`device`(`uuid`stringNOTNULL);
CREATETAG`email`();
CREATETAG`ip`();
CREATETAG`phone`();

#創建邊的類型EdgeType

CREATEEDGE`used_device`(`time`timestampNOTNULL);
CREATEEDGE`logged_in_from`(`time`timestampNOTNULL);
CREATEEDGE`has_phone`();
CREATEEDGE`has_address`();
CREATEEDGE`has_email`();

對于寫入數據的 DML,這里只給出user,email類型點、has_email類型邊的例子

INSERTVERTEX`user`(`email`,`name`,`birthday`,`address`,`phone_num`)VALUES
"user_1":("heathermoore@johnson.com","MirandaMiller",date("1957-08-27"),"BrittanyForgeApt.718EastEricWV97881","+1-652-450-5443x00562"),
"user_2":("holly@welch.org","HollyPollard",date("1990-10-19"),"1AmandaFreewayLisalandNJ94933","600-192-2985x041"),
"user_3":("julia.h.24@gmail.com","JuliaHall",date("1927-08-24"),"RodriguezTrackEastConnorfortNC63144","1248361783"),
"user_4":("franklin.b@gibson.biz","FranklinBarnett",date("2020-03-01"),"RichardCurveKingstadAZ05660","(224)497-9312"),
"user_5":("4kelly@yahoo.com","AprilKelly",date("1967-12-01"),"SchmidtKeyLakeCharlesAL36174","410.138.1816x98702"),
"user_6":("steven.web@johnson.com","StevenWebb",date("1955-04-24"),"5JoannaKeySuite704FrankshireOK03035","3666519376"),
"user_7":("Jessica_Torres@morris.com","JessicaTorres",date("1958-09-03"),"1PayneCircleMitchellfortLA73053","535-357-3112x4903"),
"user_8":("brettglenn@gmail.com","BrettGlenn",date("1992-09-03"),"WeberUnionsEddielandMT64619","660.391.3730"),
"user_9":("veronica.j@yahoo.com","VeronicaJordan",date("1947-06-08"),"2KleinMissionNewAnnettetonHI05775","810-252-6218"),
"user_10":("steven@phelps-craig.info","StevenBrooks",date("1954-06-14"),"1VanessaStravenueSuite184BaileyvilleNY46381","+1-665-328-8103x3448"),
"user_11":("ReginaldTheMan@hotmail.com","ReginaldMccullough",date("1915-04-12"),"JohnGardenPortJohnLA54602","030.088.4523x94511"),
"user_12":("Jennifer.f@carroll-acosta.com","JenniferFoster",date("1988-04-30"),"11WebbGrovesTiffanysideMN14566","(489)306-8558x98227"),
"user_13":("Philip66@yahoo.com","PhilipGarcia",date("1955-12-01"),"70RobinsonLocksSuite113EastVeronicaND87845","490-088-7610x9437"),
"user_14":("Ann@hernandez.com","AnnWilliams",date("1947-05-28"),"24McknightPortApt.028SarahboroughMD38195","868.057.4056x4814"),
"user_15":("Jessica@turner.com","JessicaStewart",date("1951-11-28"),"0337MasonCornerApt.900ToddmouthFL61464","(335)408-3835x883"),
"user_16":("Sandra311@hotmail.com","SandraDougherty",date("1908-06-03"),"7DavisStationApt.691PittmanfortHI29746","+1-189-827-0744x27614"),
"user_17":("Sharon91@gmail.com","SharonMccoy",date("1958-09-01"),"1SouthportStreetApt.098WestportKY85907","(814)898-9079x898"),
"user_18":("Sharon91+001@gmail.com","KathrynMiller",date("1958-09-01"),"1SouthportStreetApt.098WestportKY85907","(814)898-9079x898"),
"user_19":("brettglenn@googlemail.com","BrettyGlenn",date("1991-09-03"),"WeberUnionsEddielandMT64619","660-391-3730"),
"user_20":("julia.h.24@yahoo.com","JuliaH.",date("1927-08-24"),"RodriguezTrackEastConnorfortNC63144","1248361783"),
"user_21":("holly@welch.org","Holly",date("0000-10-19"),"1AmandaFreewayLisalandNJ94933","(600)-192-2985"),
"user_22":("veronica.j@yahoo.com","VeronicaJordan",date("0000-06-08"),"2KleinHI05775","(810)-252-6218"),
"user_23":("4kelly@hotmail.com","KellyApril",date("2010-01-01"),"SchmidtKeyLakeCharlesAL13617","410-138-1816");

INSERTVERTEX`email`()VALUES
"heathermoore@johnson.com":(),
"holly@welch.org":(),
"julia.h.24@gmail.com":(),
"franklin.b@gibson.biz":(),
"4kelly@yahoo.com":(),
"steven.web@johnson.com":(),
"Jessica_Torres@morris.com":(),
"brettglenn@gmail.com":(),
"veronica.j@yahoo.com":(),
"steven@phelps-craig.info":(),
"ReginaldTheMan@hotmail.com":(),
"Jennifer.f@carroll-acosta.com":(),
"Philip66@yahoo.com":(),
"Ann@hernandez.com":(),
"Jessica@turner.com":(),
"Sandra311@hotmail.com":(),
"Sharon91@gmail.com":(),
"Sharon91+001@gmail.com":(),
"brettglenn@googlemail.com":(),
"julia.h.24@yahoo.com":(),
"holly@welch.org":(),
"veronica.j@yahoo.com":(),
"4kelly@hotmail.com":();

INSERTVERTEX`ip`()VALUES
"202.123.513.12":(),
"202.41.23.11":(),
"143.1.23.4":(),
"143.1.23.12":(),
"153.42.2.8":(),
"9.1.4.1":();

INSERTVERTEX`device`(`uuid`)VALUES
"device_0":("2a8e791d-0183-4df2-aa36-5ac82151be93"),
"device_1":("f9be6a11-f74b-45f5-a9ea-bb3af5a868a2"),
"device_2":("ae083379-91f5-4cd3-b2b3-273960979dab"),
"device_3":("c0981d43-1e59-4cd5-a1e1-e88cd9e792a5"),
"device_4":("e730dd8a-fcd3-47b4-be4a-0190610e6f02");


INSERTEDGE`has_email`()VALUES
"user_1"->"heathermoore@johnson.com":(),
"user_2"->"holly@welch.org":(),
"user_3"->"julia.h.24@gmail.com":(),
"user_4"->"franklin.b@gibson.biz":(),
"user_5"->"4kelly@yahoo.com":(),
"user_6"->"steven.web@johnson.com":(),
"user_7"->"Jessica_Torres@morris.com":(),
"user_8"->"brettglenn@gmail.com":(),
"user_9"->"veronica.j@yahoo.com":(),
"user_10"->"steven@phelps-craig.info":(),
"user_11"->"ReginaldTheMan@hotmail.com":(),
"user_12"->"Jennifer.f@carroll-acosta.com":(),
"user_13"->"Philip66@yahoo.com":(),
"user_14"->"Ann@hernandez.com":(),
"user_15"->"Jessica@turner.com":(),
"user_16"->"Sandra311@hotmail.com":(),
"user_17"->"Sharon91@gmail.com":(),
"user_18"->"Sharon91+001@gmail.com":(),
"user_19"->"brettglenn@googlemail.com":(),
"user_20"->"julia.h.24@yahoo.com":(),
"user_21"->"holly@welch.org":(),
"user_22"->"veronica.j@yahoo.com":(),
"user_23"->"4kelly@hotmail.com":();

INSERTEDGE`used_device`(`time`)VALUES
"user_2"->"device_0":(timestamp("2021-03-01T0800")),
"user_21"->"device_0":(timestamp("2021-03-01T0800")),
"user_18"->"device_1":(timestamp("2021-03-01T0800")),
"user_17"->"device_1":(timestamp("2021-03-01T0800")),
"user_22"->"device_2":(timestamp("2021-03-01T0800")),
"user_9"->"device_3":(timestamp("2021-03-01T0800")),
"user_9"->"device_2":(timestamp("2021-03-01T0800")),
"user_23"->"device_4":(timestamp("2021-03-01T0800"));

INSERTEDGE`logged_in_from`(`time`)VALUES
"user_2"->"202.123.513.12":(timestamp("2021-03-01T0800")),
"user_21"->"202.41.23.11":(timestamp("2021-03-01T0800")),
"user_18"->"143.1.23.4":(timestamp("2021-03-01T0800")),
"user_17"->"143.1.23.12":(timestamp("2021-03-01T0800")),
"user_22"->"153.42.2.8":(timestamp("2021-03-01T0800")),
"user_9"->"153.42.2.8":(timestamp("2021-03-01T0800")),
"user_9"->"153.42.2.8":(timestamp("2021-03-01T0800")),
"user_23"->"9.1.4.1":(timestamp("2021-03-01T0800"));
1.2 根據確定規則獲取 ID 映射關系

最簡單、直接的方法,在特定的場景下也可能是有用的,試想像 email、IP 地址、上網設備這些有嚴格結構的數據,在它們成為圖譜中的點的時候,簡單的相等關系就足以找出這樣對應關系,比如:

擁有相同的 email

使用過相同的 IP 地址

使用過相同的設備

在前邊的圖譜、圖數據庫中,擁有相同的 email 可以直接表達為如下的圖模式(Graph Pattern)。

(:user)-[:has_email]->(:email)<-[:has_email]-[:user]

下圖為頂點:user 與邊:has_email 的一個圖的可視化結果,可以看到這其中有兩個三個點相連的串正是符合擁有相同 email 的模式的點。

注:

這個結果的數據源在https://github.com/wey-gu/identity-correlation-datagen/tree/main/sample/hand_crafted

如果通過線上訪問本文,你可以鼠標懸停(獲取點上的屬性)和框選放大每一個點和子圖哦。

42d8d36c-bfa5-11ed-bfe3-dac502259ad0.png

根據確定規則獲取 ID 映射關系

顯然,在構建 ID Mapping 系統的過程中,我們就是通過在圖數據庫中直接查詢,可視化渲染結果來看到等效的洞察,這個查詢可以寫成:

MATCHp=(:user)-[:has_email]->(:email)<-[:has_email]-(:user)
RETURN?p?limit?10

NebulaGraph 中的查詢結果

42edb0d4-bfa5-11ed-bfe3-dac502259ad0.png

同樣,在上邊交互圖中可以放大看到這兩對擁有相同 email 關聯起來的賬號:

4311156a-bfa5-11ed-bfe3-dac502259ad0.png

然而,在更多真實世界中,這樣的模式匹配往往不能解決更多稍微復雜一點的情形:

比如從上邊的圖中我們可以看到這兩個匹配了的映射中,holly@welch.org關聯下的兩個用戶的姓名是不同的,而veronica.j@yahoo.com關聯下的兩個用戶姓名是完全相同的。

user_2,holly@welch.org,HollyPollard,1990-10-19,1AmandaFreewayLisalandNJ94933,600-192-2985x041
user_21,holly@welch.org,Holly,0000-10-19,1AmandaFreewayLisalandNJ94933,(600)-192-2985

再比如Sharon91@gmail.com和Sharon91+001@gmail.com,這兩個人的姓名不同,但是手機和地址卻是相同的。

user_17,Sharon91@gmail.com,SharonMccoy,1958-09-01,1SouthportStreetApt.098WestportKY85907,(814)898-9079x898
user_18,Sharon91+001@gmail.com,KathrynMiller,1958-09-01,1SouthportStreetApt.098WestportKY85907,(814)898-9079x898

比較慶幸的是我們只需要增加類似于"擁有相同郵箱"、“擁有相同地址”、“擁有相同電話"等其他條件就可以把這種情況考慮進來了,而隨之而來的問題是:

不是所有的數據都至少存在某一個確定條件的相等(二元的是與否),所以不存在一條確定的邊去連接它們,比如這兩個賬戶中:

user_5,4kelly@yahoo.com,AprilKelly,1967-12-01,SchmidtKeyLakeCharlesAL36174,410.138.1816x98702
user_23,4kelly@hotmail.com,KellyApril,2010-01-01,SchmidtKeyLakeCharlesAL13617,410-138-1816

如何表現 4kelly@yahoo.com 與 4kelly@hotmail.com 的相似性?

如何將多種匹配規則的信息都納入關聯系統?

1.3 非確定規則基于復合條件量化方法

前邊提到了幾種確定規則無法處理的情況,它們可以歸結為這兩點:

需要多因素(規則)進行綜合考慮與判定

需要對非確定條件(屬性)進行處理,挖掘隱含相等、相似的關聯關系(邊)

對于 1. ,很自然可以想到對多種關聯條件進行量化評分(score),按照多種條件的重要程度進行加權,給出認定為關聯的總分的閾值。

有了多因素評分的機制,我們只需要考慮如何在確定的多因素基礎之上,增加對不確定因素的處理,從而解決 2. 的情況。這里,非確定的條件可能是:

a. 表現結構化數據的相似性:Sharon91@gmail.com與Sharon91+001@gmail.com

b. 表現非結構化數據的相似性:

直接判定子字符串

運算 Jaccard index 等類似的相似度

Schmidt Key Lake Charles AL 36174與Schmidt Key Lake Charles AL 13617

600-192-2985x041與 (600)-192-2985對于 a. 的結構化數據中的相似性,有兩個思路是可以考慮的:

直接進行兩個值的相似度

拆分為更細粒的多個屬性

然后就可以設計詳細的確定性規則:email.handle 相等、甚至再在此基礎上應用其他非確定規則

有時候,比如對于 email_domain 字段,我們還知道 gmail.com 和 googlemail.com 是等價的,這里的處理也是可以考慮的(像是user_19,brettglenn@googlemail.com與user_8,brettglenn@gmail.com,但從郵箱判斷背后就是同一個持有者)

將 emailfoo+num@bar.com拆分成三個子屬性 email_handle:foo, email_alias:num, email_domain:bar.com

而對于 b. 的非結構屬性相似性距離,處理方式可以根據具體的 domain knowledge 千差萬別:

像Schmidt Key Lake Charles AL 36174與Schmidt Key Lake Charles AL 13617的地址信息,除了可以用值的相似度之外,還可以把它轉換成地理類型的屬性,比如一個經緯度組成的點,從而計算兩個點之間的地理距離,根據給定的距離值來打分。

注,你知道嗎?NebulaGraph 圖數據庫中原生支持地理類型的屬性與索引,可以直接創建 Point 類型的地理屬性,并計算兩個 Point 之間的距離。

對于600-192-2985x041與 (600)-192-2985這種字符串形式的電話號碼,則可以統一轉化為<國家碼>+<區域碼>+<本地號碼>+<分機號>這樣的結構化數據,進一步按照結構化數據的方式處理。

如果賬號存在圖片對象 URL,可以對比其文件相似度。

另外,對于非結構屬性的相似性計算我們要盡量避免兩兩窮舉運算的方式(笛卡爾積),因為這是一個指數增長的量級,一個可行的方法是只比較建立了確定性關系(比如相同郵件前綴:email_handle,地址在相同街區,IP 在同一個網段等)的實體。

小結

總結來看,為了解決真實世界數據的復雜情形,基于復合條件的量化方法有:

通過細化結構數據(比如郵箱字段拆分為子屬性或者點)、或者轉變為結構化數據(處理字符串形式的電話號碼)建立相似結構化數據之間的確定關聯;

在有限存在確定性關聯的點之間(避免兩兩窮舉),運算其他量化、非確定相似性(字符距離、地理距離等、圖片文件相似度);

為不同關系賦予加權,計算相似度總分;

1.3.1 基于復合條件量化方法實操

下邊,我們來給出這系列方法的實操案例。

細化結構數據

通過細化結構數據(比如郵箱字段拆分為子屬性或者點)、或者轉變為結構化數據(處理字符串形式的電話號碼)建立相似結構化數據之間的確定關聯;

首先,我們把 email 的點拆成前綴 email_handle 與后綴 email_domain,自然地,會產生這樣的邊:

has_email_with_handle (user -> email_handle)

has_email_with_domain (user -> email_domain)

with_handle (email -> email_handle)

with_domain (email -> email_domain)

然而,可以想見 email_domain 是一個潛在的超級節點,并且,它的區分度在很多情況下是很小的,比如 gmail.com 這個公共郵箱后綴沒有很大的關聯性意義。我們可以只留下 email.handle 作為點,而對于 email_domain,把它留在邊中作為屬性:

email_domain

Prop:

email_domain

Prop:

has_email_with_handle (user -> email_handle)

with_handle (email -> email_handle)

對應的新的點類型、邊類型的 NebulaGraph DDL 語句:

#新的點類型
CREATETAG`email_handle`();

#新的邊類型
CREATEEDGE`has_email_with_handle`(`email_domain`stringNOTNULL);
CREATEEDGE`with_handle`(`email_domain`stringNOTNULL);

對應新的點、邊的 DML 語句:

INSERTVERTEX`email_handle`()VALUES
"4kelly":(),
"Ann":(),
"brettglenn":(),
"franklin.b":(),
"heathermoore":(),
"holly":(),
"Jennifer.f":(),
"Jessica":(),
"Jessica_Torres":(),
"julia.h.24":(),
"Philip66":(),
"ReginaldTheMan":(),
"Sandra311":(),
"Sharon91":(),
"steven":(),
"steven.web":(),
"veronica.j":();

INSERTEDGE`has_email_with_handle`(`email_domain`)VALUES
"user_1"->"heathermoore":("johnson.com"),
"user_2"->"holly":("welch.org"),
"user_3"->"julia.h.24":("gmail.com"),
"user_4"->"franklin.b":("gibson.biz"),
"user_5"->"4kelly":("yahoo.com"),
"user_6"->"steven.web":("johnson.com"),
"user_7"->"Jessica_Torres":("morris.com"),
"user_8"->"brettglenn":("gmail.com"),
"user_9"->"veronica.j":("yahoo.com"),
"user_10"->"steven":("phelps-craig.info"),
"user_11"->"ReginaldTheMan":("hotmail.com"),
"user_12"->"Jennifer.f":("carroll-acosta.com"),
"user_13"->"Philip66":("yahoo.com"),
"user_14"->"Ann":("hernandez.com"),
"user_15"->"Jessica":("turner.com"),
"user_16"->"Sandra311":("hotmail.com"),
"user_17"->"Sharon91":("gmail.com"),
"user_18"->"Sharon91":("gmail.com"),
"user_19"->"brettglenn":("googlemail.com"),
"user_20"->"julia.h.24":("yahoo.com"),
"user_21"->"holly":("welch.org"),
"user_22"->"veronica.j":("yahoo.com"),
"user_23"->"4kelly":("hotmail.com");

INSERTEDGE`with_handle`(`email_domain`)VALUES
"heathermoore@johnson.com"->"heathermoore":("johnson.com"),
"holly@welch.org"->"holly":("welch.org"),
"julia.h.24@gmail.com"->"julia.h.24":("gmail.com"),
"franklin.b@gibson.biz"->"franklin.b":("gibson.biz"),
"4kelly@yahoo.com"->"4kelly":("yahoo.com"),
"steven.web@johnson.com"->"steven.web":("johnson.com"),
"Jessica_Torres@morris.com"->"Jessica_Torres":("morris.com"),
"brettglenn@gmail.com"->"brettglenn":("gmail.com"),
"veronica.j@yahoo.com"->"veronica.j":("yahoo.com"),
"steven@phelps-craig.info"->"steven":("phelps-craig.info"),
"ReginaldTheMan@hotmail.com"->"ReginaldTheMan":("hotmail.com"),
"Jennifer.f@carroll-acosta.com"->"Jennifer.f":("carroll-acosta.com"),
"Philip66@yahoo.com"->"Philip66":("yahoo.com"),
"Ann@hernandez.com"->"Ann":("hernandez.com"),
"Jessica@turner.com"->"Jessica":("turner.com"),
"Sandra311@hotmail.com"->"Sandra311":("hotmail.com"),
"Sharon91@gmail.com"->"Sharon91":("gmail.com"),
"Sharon91+001@gmail.com"->"Sharon91":("gmail.com"),
"brettglenn@googlemail.com"->"brettglenn":("googlemail.com"),
"julia.h.24@yahoo.com"->"julia.h.24":("yahoo.com"),
"holly@welch.org"->"holly":("welch.org"),
"veronica.j@yahoo.com"->"veronica.j":("yahoo.com"),
"4kelly@hotmail.com"->"4kelly":("hotmail.com");

可以看到,經過這個處理,我們已經得到更多關聯的用戶了,它可以用這個圖查詢表達:

MATCHp=(:user)-[:has_email_with_handle]->(:email_handle)<-[:has_email_with_handle]-(:user)
RETURN?p?limit?10
432923da-bfa5-11ed-bfe3-dac502259ad0.png

基于復合條件量化方法實操

非確定性相似性

在有限存在確定性關聯的點之間(避免兩兩窮舉),運算其他量化、非確定相似性(字符距離、地理距離等、圖片文件相似度);

這里用地址的地理距離來做為例子,我們預先處理每一個地址,將它們的經緯度導入圖譜。

這樣,我們更改地址這個點的類型 address 的 schema:

Prop: geo_point(geography(point) 經緯度類型)

對應過來,它的 DDL 變化是:

address

-CREATETAG`address`()
+CREATETAG`address`(`geo_point`geography(point));

在已經建立了初始的addressTAG 之上,可以用ALTER TAG的 DDL 去修改address的定義:

ALTERTAG`address`ADD(`geo_point`geography(point));

可以用SHOW CREATE TAG查看修改之后的 Schema

(root@nebula)[entity_resolution]>SHOWCREATETAG`address`
+-----------+------------------------------------+
|Tag|CreateTag|
+-----------+------------------------------------+
|"address"|"CREATETAG`address`(|
||`address`stringNOTNULL,|
||`geo_point`geography(point)NULL|
||)ttl_duration=0,ttl_col="""|
+-----------+------------------------------------+

對應的點、邊的 DML:

#插入邊
INSERTEDGE`has_address`()VALUES
"user_1"->"addr_0":(),
"user_2"->"addr_15":(),
"user_3"->"addr_18":(),
"user_4"->"addr_1":(),
"user_5"->"addr_2":(),
"user_6"->"addr_3":(),
"user_7"->"addr_4":(),
"user_8"->"addr_14":(),
"user_9"->"addr_5":(),
"user_10"->"addr_6":(),
"user_11"->"addr_7":(),
"user_12"->"addr_8":(),
"user_13"->"addr_9":(),
"user_14"->"addr_10":(),
"user_15"->"addr_11":(),
"user_16"->"addr_12":(),
"user_17"->"addr_13":(),
"user_18"->"addr_13":(),
"user_19"->"addr_14":(),
"user_20"->"addr_18":(),
"user_21"->"addr_15":(),
"user_22"->"addr_16":(),
"user_23"->"addr_17":();

#插入點,geo_point是地址的經緯度
INSERTVERTEX`address`(`address`,`geo_point`)VALUES
"addr_0":("BrittanyForgeApt.718EastEricWV97881",ST_Point(1,2)),
"addr_1":("RichardCurveKingstadAZ05660",ST_Point(3,4)),
"addr_2":("SchmidtKeyLakeCharlesAL36174",ST_Point(13.13,-87.65)),
"addr_3":("5JoannaKeySuite704FrankshireOK03035",ST_Point(5,6)),
"addr_4":("1PayneCircleMitchellfortLA73053",ST_Point(7,8)),
"addr_5":("2KleinMissionNewAnnettetonHI05775",ST_Point(9,10)),
"addr_6":("1VanessaStravenueSuite184BaileyvilleNY46381",ST_Point(11,12)),
"addr_7":("JohnGardenPortJohnLA54602",ST_Point(13,14)),
"addr_8":("11WebbGrovesTiffanysideMN14566",ST_Point(15,16)),
"addr_9":("70RobinsonLocksSuite113EastVeronicaND87845",ST_Point(17,18)),
"addr_10":("24McknightPortApt.028SarahboroughMD38195",ST_Point(19,20)),
"addr_11":("0337MasonCornerApt.900ToddmouthFL61464",ST_Point(21,22)),
"addr_12":("7DavisStationApt.691PittmanfortHI29746",ST_Point(23,24)),
"addr_13":("1SouthportStreetApt.098WestportKY85907",ST_Point(120.12,30.16)),
"addr_14":("WeberUnionsEddielandMT64619",ST_Point(25,26)),
"addr_15":("1AmandaFreewayLisalandNJ94933",ST_Point(27,28)),
"addr_16":("2KleinHI05775",ST_Point(9,10)),
"addr_17":("SchmidtKeyLakeCharlesAL13617",ST_Point(13.12,-87.60)),
"addr_18":("RodriguezTrackEastConnorfortNC63144",ST_Point(29,30));

有了經緯度信息,結合 NebulaGraph 原生對于 Geo Spatial 空間地理屬性的處理能力,我們可以輕松獲得兩個點之間的距離(單位:米)

如下,ST_Distance(ST_Point(13.13, -87.65),ST_Point(13.12, -87.60) 表示兩個地球上的點 ST_Point(13.13, -87.65)和ST_Point(13.12, -87.60)之間的距離是5559.9459840993895米。

RETURNST_Distance(ST_Point(13.13,-87.65),ST_Point(13.12,-87.60))ASdistance;
+--------------------+
|distance|
+--------------------+
|5559.9459840993895|
+--------------------+

那么,我們可以用查詢語句來表達”所有擁有相同郵箱前綴用戶之間的距離“:

MATCH(v_start:user)-[:has_email_with_handle]->(:email_handle)<-[:has_email_with_handle]-(v_end:user)
MATCH?(v_start:user)-[:has_address]->(a_start:address)
MATCH(v_end:user)-[:has_address]->(a_end:address)
RETURNv_start,v_end,ST_Distance(a_start.address.geo_point,a_end.address.geo_point)ASdistance,a_start,a_end;

這里,為了展現出針對 ”非確定性“ 條件之間的 ”相似性”,我們可以把地址中字符串完全相同的結果過濾掉,WHERE a_start.address.address != a_end.address.address,如此:

MATCH(v_start:user)-[:has_email_with_handle]->(:email_handle)<-[:has_email_with_handle]-(v_end:user)
MATCH?(v_start:user)-[:has_address]->(a_start:address)
MATCH(v_end:user)-[:has_address]->(a_end:address)
WHEREa_start.address.address!=a_end.address.address
RETURNv_start.`user`.name,v_end.`user`.name,ST_Distance(a_start.address.geo_point,a_end.address.geo_point)ASdistance,a_start.address.address,a_end.address.address

它的結果是:

+-------------------+-------------------+--------------------+--------------------------------------------+--------------------------------------------+
|v_start.user.name|v_end.user.name|distance|a_start.address.address|a_end.address.address|
+-------------------+-------------------+--------------------+--------------------------------------------+--------------------------------------------+
|"AprilKelly"|"KellyApril"|5559.9459840993895|"SchmidtKeyLakeCharlesAL36174"|"SchmidtKeyLakeCharlesAL13617"|
|"VeronicaJordan"|"VeronicaJordan"|0.0|"2KleinMissionNewAnnettetonHI05775"|"2KleinHI05775"|
|"KellyApril"|"AprilKelly"|5559.9459840993895|"SchmidtKeyLakeCharlesAL13617"|"SchmidtKeyLakeCharlesAL36174"|
|"VeronicaJordan"|"VeronicaJordan"|0.0|"2KleinHI05775"|"2KleinMissionNewAnnettetonHI05775"|
+-------------------+-------------------+--------------------+--------------------------------------------+--------------------------------------------+

可以看出:

user_5與user_23之間的地址距離只相差 5559 米,因為他們的地址就在一個街區

而user_9與user_13之間距離相差 0 米,因為它們(“2 Klein Mission New Annetteton HI 05775” 與 “2 Klein HI 05775”)實際上是完全相同的地址。

這就是利用屬性的具體含義(domain knowledge)計算的實質距離的一個最好的詮釋,大家可以借助于圖數據庫中查詢語句描述能力或者利用其他系統去運算用戶間非確定性特征的量化距離/相似度。

加權評分

為不同關系賦予加權,計算相似度總分;

下邊是一個在實際應用中,可以綜合考量的多種關聯關系,包括但不限于:

確定性關系

同名(精確匹配)

相同電話(格式化處理)

使用過相同設備(精確匹配)

同郵件前綴(精細化處理)

非確定性

地址距離(處理成經緯度,計算地球球面距離)

頭像圖片背景相似度(訓練模型計算圖像距離)

一個很直覺的方法就是將多種條件按照不同的權重加權,獲得兩點間的總“疑似相同賬號”的評分。

本例中,為求簡潔,我們只給出考慮“同郵件前綴”、“同名”與“地理距離小于 10KM”的綜合加權,并且認為兩個因素的權重都是 1。

注,為了防止兩兩全匹配,我們從相同郵件前綴條件作為初始匹配條件。

MATCH(v_start:user)-[:has_email_with_handle]->(:email_handle)<-[:has_email_with_handle]-(v_end:user)
MATCH?(v_start:user)-[:has_address]->(a_start:address)
MATCH(v_end:user)-[:has_address]->(a_end:address)
WITHid(v_start)ASs,id(v_end)ASe,v_start.`user`.nameASs_name,v_end.`user`.nameASe_name,ST_Distance(a_start.address.geo_point,a_end.address.geo_point)ASdistance
RETURNs,e,1ASshared_email_handle,s_name==e_nameASshared_name,distance

結果是

+-----------+-----------+---------------------+-------------+-----------------+
|s|e|shared_email_handle|shared_name|shared_location|
+-----------+-----------+---------------------+-------------+-----------------+
|"user_5"|"user_23"|1|false|true|
|"user_9"|"user_22"|1|true|true|
|"user_21"|"user_2"|1|false|true|
|"user_2"|"user_21"|1|false|true|
|"user_22"|"user_9"|1|true|true|
|"user_20"|"user_3"|1|false|true|
|"user_3"|"user_20"|1|false|true|
|"user_18"|"user_17"|1|false|true|
|"user_17"|"user_18"|1|false|true|
|"user_19"|"user_8"|1|false|true|
|"user_8"|"user_19"|1|false|true|
|"user_23"|"user_5"|1|false|true|
+-----------+-----------+---------------------+-------------+-----------------+

然后,我們計算加權分數:

MATCH(v_start:user)-[:has_email_with_handle]->(:email_handle)<-[:has_email_with_handle]-(v_end:user)
MATCH?(v_start:user)-[:has_address]->(a_start:address)
MATCH(v_end:user)-[:has_address]->(a_end:address)
WITHid(v_start)ASs,id(v_end)ASe,v_start.`user`.nameASs_name,v_end.`user`.nameASe_name,ST_Distance(a_start.address.geo_point,a_end.address.geo_point)ASdistance
WITHs,e,1ASshared_email_handle,CASEWHENs_name==e_nameTHEN1ELSE0ENDASshared_name,CASEWHENdistance

結果是

+-----------+-----------+-------+
|s|e|score|
+-----------+-----------+-------+
|"user_9"|"user_22"|3|
|"user_22"|"user_9"|3|
|"user_5"|"user_23"|2|
|"user_21"|"user_2"|2|
|"user_2"|"user_21"|2|
|"user_20"|"user_3"|2|
|"user_3"|"user_20"|2|
|"user_18"|"user_17"|2|
|"user_17"|"user_18"|2|
|"user_19"|"user_8"|2|
|"user_8"|"user_19"|2|
|"user_23"|"user_5"|2|
+-----------+-----------+-------+

1.3.2 利用 Active Learning 的方法交互式學習評分權重

實際應用中,不同因素的加權關系也不是那么容易輕易給出的,我們可以利用有限的人力判斷進行 Active Learning 的交互訓練來習得權重。

注:篇幅所限,本文中略掉具體的方法實操。

1.4 利用新的邊連接不同方法

進一步,對于這些確定(是否二元的)或非確定(量化的)關系,利用圖庫與外部系統獲得了關聯關系之后,常常可以直接把它們定義為圖譜中直連的邊,寫回圖庫,提供給其他算法、系統作為輸入,做進一步迭代、計算。

1.4.1 創建單獨的直連邊

假設之前對郵件、地址、姓名的處理之后,把結果作為用戶實體之前的直連邊插入圖譜,這些種邊叫做:

shared_similar_email

shared_similar_location

shared_name

#DDL
CREATEEDGE`shared_similar_email`();
CREATEEDGE`shared_similar_location`();
CREATEEDGE`shared_name`();
#DML

INSERTEDGE`shared_similar_email`()VALUES
"user_5"->"user_23":(),
"user_9"->"user_22":(),
"user_21"->"user_2":(),
"user_2"->"user_21":(),
"user_22"->"user_9":(),
"user_20"->"user_3":(),
"user_3"->"user_20":(),
"user_18"->"user_17":(),
"user_17"->"user_18":(),
"user_19"->"user_8":(),
"user_8"->"user_19":(),
"user_23"->"user_5":();

INSERTEDGE`shared_name`()VALUES
"user_9"->"user_22":(),
"user_22"->"user_9":();

INSERTEDGE`shared_similar_location`()VALUES
"user_5"->"user_23":(),
"user_9"->"user_22":(),
"user_21"->"user_2":(),
"user_2"->"user_21":(),
"user_22"->"user_9":(),
"user_20"->"user_3":(),
"user_3"->"user_20":(),
"user_18"->"user_17":(),
"user_17"->"user_18":(),
"user_19"->"user_8":(),
"user_8"->"user_19":(),
"user_23"->"user_5":();

1.4.2 創建復合評分之后的邊

比如,我們查詢綜合分數大于 2 的點:

MATCH(v_start:user)-[:has_email_with_handle]->(:email_handle)<-[:has_email_with_handle]-(v_end:user)
MATCH?(v_start:user)-[:has_address]->(a_start:address)
MATCH(v_end:user)-[:has_address]->(a_end:address)
WITHid(v_start)ASs,id(v_end)ASe,v_start.`user`.nameASs_name,v_end.`user`.nameASe_name,ST_Distance(a_start.address.geo_point,a_end.address.geo_point)ASdistance
WITHs,e,1ASshared_email_handle,CASEWHENs_name==e_nameTHEN1ELSE0ENDASshared_name,CASEWHENdistance2
RETURNs,e,score
ORDERBYscoreDESC

然后根據返回結果建立新的邊:

#DDL
CREATEEDGE`is_similar_to`(scoreintNOTNULL);

#DML
INSERTEDGE`is_similar_to`(`score`)VALUES
"user_22"->"user_9":(3),
"user_9"->"user_22":(3);
1.5 基于圖算法的方法

前邊的方法中我們直接利用了用戶的各項屬性、行為事件中產生的關系,并利用各種屬性、值相似度的方法建立了基于概率或者帶有評分的關聯關系。而在通過其他方法增加了新的邊之后的圖上,我們也可以利用圖算法的方法來映射潛在的相同用戶 ID。

1.5.1 圖相似性算法

利用節點相似性圖算法,比如 Jaccard Index、余弦相似度等,我們可以或者 a. 利用圖庫之上的圖計算平臺全量計算相似度,或者 b. 用圖查詢語句實現全圖/給定的點之間的相似度,最后給相似度一定的閾值來幫助建立新的(考慮了涉及邊的)映射關系。

注,這里的 Jaccard index 和我們前邊提到的比較兩個字符串的方法本質是一樣的,不過我們現在提及的是應用在圖上的點之間存在相連點作為算法中的“交集”的實現。

1.5.2 社區發現算法

自然地,還可以用社區發現的算法全圖找出給定的基于邊之下的社區劃分,調試算法,使得目標劃分社區內部點為估計的相同用戶。

1.5.3 基于圖算法的方法

1.5.3.1 基于圖查詢的 Jaccard 實現

Jaccard Index 是一個描述兩個集合距離的定義公式,非常簡單、符合直覺,它的定義為:

這里,我們把交集理解為 A 與 B 共同連接的點(設備、IP、郵箱前綴、地址),而并集理解為這幾種關系下與 A 或者 B 直連的所有點,于是,我們用這樣的 NebulaGraph OpenCypher 查詢就可以算出至少包含一跳關系的點和它相關的點、以及 Jaccard Index 值,越大代表關聯度越大。

MATCH(v_start:user)-[:used_device|logged_in_from|has_email_with_handle|has_address]->(shared_components)<-[:used_device|logged_in_from|has_email_with_handle|has_address]-(v_end:user)
WITH?v_start,?v_end,?count(shared_components)?AS?intersection_size
MATCH?(v_start:user)-[:used_device|logged_in_from|has_email_with_handle|has_address]->(shared_components)
WITHid(v_start)ASv_start,v_end,intersection_size,COLLECT(id(shared_components))ASset_a
MATCH(v_end:user)-[:used_device|logged_in_from|has_email_with_handle|has_address]->(shared_components)
WITHv_start,id(v_end)ASv_end,intersection_size,set_a,COLLECT(id(shared_components))ASset_b
WITHv_start,v_end,toFloat(intersection_size)ASintersection_size,toSet(set_a+set_b)ASA_U_B
RETURNv_start,v_end,intersection_size/size(A_U_B)ASjaccard_index
ORDERBYjaccard_indexDESC

我們可以看到結果里:

+-----------+-----------+---------------------+
|v_start|v_end|jaccard_index|
+-----------+-----------+---------------------+
|"user_8"|"user_19"|1.0|
|"user_19"|"user_8"|1.0|
|"user_20"|"user_3"|0.6666666666666666|
|"user_3"|"user_20"|0.6666666666666666|
|"user_21"|"user_2"|0.6|
|"user_18"|"user_17"|0.6|
|"user_17"|"user_18"|0.6|
|"user_2"|"user_21"|0.6|
|"user_22"|"user_9"|0.5|
|"user_9"|"user_22"|0.5|
|"user_23"|"user_5"|0.2|
|"user_5"|"user_23"|0.2|
|"user_21"|"user_20"|0.16666666666666666|
|"user_20"|"user_21"|0.16666666666666666|
+-----------+-----------+---------------------+

user_8 與 user_19 的系數是最大的的,讓我們看看他們之間的連接?

FINDALLPATHFROM"user_8"TO"user_19"OVER*BIDIRECTYIELDpathASp;

果然,他們之間的相似度很大:

4356123c-bfa5-11ed-bfe3-dac502259ad0.png

基于圖算法的方法

1.5.3.2 基于 NebulaGraph Algorithm 圖計算平臺的 Jaccard 方法

1.5.3.2.1 前面方法的局限

利用圖數據庫查詢計算 Jaccard 系數的方法有兩方面局限。

首先,為了防止兩兩運算,我們假設了所有值得被運算的點之間已經存在某種確定鏈接(對應 MATCH 第一行),雖然這樣的假設在大部分情況下是可以粗略被接受的,但是它是一種壓縮和妥協。

其次,在數據量很大的情形里,這樣的查詢將不具有可操作性。

1.5.3.2.2 更 Scale 的方法

為了能處理更大規模,我們可以利用 Spark 等并行計算平臺進行算法執行;

在全圖運算時,我們可以利用局部敏感哈希 MinHash 來對兩兩比對降維,慶幸的是,Spark 中提供了 MinHash 的實現供我們使用!

MinHash 的思想:這個方法是用概率去有損估計 Jaccard 系數,這里的降維體現在它用 bit map 去數字化每一個集合,隨機定義不同的集合上的 shuffle(亂序)變換,取變換之后 hash 的最小值。

這里,兩個集合的隨機變換后最小值 相等的概率是等于 Jaccard 系數的。所以,這樣偷梁換柱,就把需要兩兩集合運算比較的算法變成只需要對每一個集合做常數次隨機變換取最小的降維近似運算了。

在圖上,對于每一個點,我們認為它的鄰居就是這個點的集合,那么在 Spark 中運算 Jaccard 系數的過程就是:

獲取每一個點的鄰居集合

對點的鄰居進行 MinHash 運算,獲得 Jaccard 系數

慶幸的是,開源的 NebulaGraph Algorithm 已經提供了這個算法的實現,而我們只需要調用 NebulaGraph Algorithm 就可以了,使用方法參考 NebulaGraph Algorithm 文檔。

注,配置中 jaccard.tol 的意涵是 approxSimilarityJoin 中的 threshold :

defapproxSimilarityJoin(
datasetA:Dataset[_],
datasetB:Dataset[_],
threshold:Double,
distCol:String):Dataset[_]={
...
//Filterthejoineddatasetswherethedistancearesmallerthanthethreshold.
joinedDatasetWithDist.filter(col(distCol)

讀者到這里應該會注意到,這個方法顯然是假設所有的點都是用戶實體,邊是他們之間的直連關系的。所以再應用這個方法之前,我們需要創建經過預處理的直連邊,這個步驟正是前邊章節“利用新的邊連接不同方法”中的內容。

1.5.3.3 基于 NebulaGraph Algorithm 圖計算平臺社區發現算法

提到基于全圖的算法,我們自然可以想到可以利用社區發現的手段去幫助識別相同用戶的不同賬號,弱聯通分量(WCC)、Louvain 算法都是常見的手段。

同樣,NebulaGraph Algorithm 開箱即用地提供了這兩種算法,我們可以很容易在 NebulaGraph 得出社區劃分,并在此基礎上做復合方法的識別。

1.5.3.4 上手基于 NebulaGraph Algorithm 圖計算方法

因為篇幅關系,這里不展示 NebulaGraph Algorithm 方法的上手環節,類似于在之前 Fraud Detection 方法文章中的對應章節,你可以利用 Nebula-Up 的 all-in-one 模式,一行命令搭建這樣的環境并親自體驗。

Nebula-Up 部署命令:

curl-fsSLnebula-up.siwei.io/all-in-one.sh|bash-s--v3spark
1.6 基于圖神經網絡的方法

我們注意到,在講以上不同的方法相結合的時候,會把前導方法的結果作為圖上的邊,進而作為后邊的方法的輸入,而相同用戶 ID 的識別本質上就是在圖上去預測用戶之間鏈接、邊。

在 GNN 的方法中,除了我們在欺詐檢測中利用到的節點分類(屬性預測)之外,鏈接預測(Link Prediction)也是另一個常見的算法目標和應用場景。自然地,可以想到用 GNN 的方法結合 1. 非 GNN 方法獲得的、 2. 已經有的人為標注的鏈接,來學習、預測圖上的 ID 映射。

值得注意的是,GNN 的方法只能利用數字型的 feature、屬性,我們沒辦法把非數字型的屬性像在分類情況里那樣枚舉為數值,相反,我們在真正的 GNN 之前,可以用其他的圖方法去建立基于打分、或者相似度的邊建立。這時候,這些前邊的方法成為了 GNN 鏈路預測的特征工程。

1.6.1 基于 GNN 的實操

和在 “基于 NebulaGraph 圖數據庫的欺詐檢測方法與代碼示例” 的欺詐檢測類似,我將給出的例子也是 GNN 結合圖數據庫做實時預測的例子。

1.6.1.1 HDE[ICDM2021]

我們利用 Heterogeneous Graph Neural Network with Distance Encoding 給出的方法來做 Inductive Learning 的異構 GNN 上的鏈路預測,同時,我們將用一個更方便的 GNN 工具,OpenHGNN,有了它,本例中的代碼量也會大大下降。

注:OpenHGNN 是由北郵 GAMMA Lab 開發的基于 PyTorch 和 DGL 的開源異質圖神經網絡工具包。

1.6.1.2 數據集

本利的數據集是前邊方法中建立在 NebulaGraph 中的圖譜,借助于 Nebula-DGL,我們可以一行代碼把 NebulaGraph 中的圖加載到 DGL 之中。

注:

這里,我們使用的的工具為 Deep Graph library(DGL),NebulaGraph 圖數據庫和他們之間的橋梁,Nebula-DGL。

你可以直接 load 這個 .ngql 文件到 NebulaGraph。

1.6.1.3 數據處理

為了將 NebulaGraph 圖譜進行工程處理,序列化成為 DGL 的圖對象,我們要通過 Nebula-DGL 的 YAML 配置文件 API 描述所需的點、邊類型以及關心的屬性(特征)。

我們看下現在的圖中有哪些點、邊類型:

(root@nebula)[entity_resolution]>SHOWTAGS
+----------------+
|Name|
+----------------+
|"address"|
|"device"|
|"email"|
|"email_handle"|
|"ip"|
|"phone"|
|"user"|
+----------------+
Got7rows(timespent1335/7357us)

(root@nebula)[entity_resolution]>SHOWEDGES
+---------------------------+
|Name|
+---------------------------+
|"has_address"|
|"has_email"|
|"has_email_with_handle"|
|"has_phone"|
|"is_similar_to"|
|"logged_in_from"|
|"shared_name"|
|"shared_similar_email"|
|"shared_similar_location"|
|"used_device"|
|"with_handle"|
+---------------------------+
Got11rows(timespent1439/30418us)

在本例中,我們不考慮屬性(特征)。

nebulagraph_entity_resolution_dgl_mapper.yaml
---
#Ifvertexidisstring-typed,remap_vertex_idmustbetrue.
remap_vertex_id:True
space:entity_resolution
#strorint
vertex_id_type:int
vertex_tags:
-name:user
-name:address
-name:device
-name:email_handle
-name:ip
edge_types:
-name:has_email_with_handle
start_vertex_tag:user
end_vertex_tag:email_handle
-name:is_similar_to
start_vertex_tag:user
end_vertex_tag:user
-name:shared_similar_location
start_vertex_tag:user
end_vertex_tag:user
-name:has_address
start_vertex_tag:user
end_vertex_tag:address
-name:logged_in_from
start_vertex_tag:user
end_vertex_tag:ip
-name:used_device
start_vertex_tag:user
end_vertex_tag:device

然后,我們在安裝好 Nebula-DGL 之后只需要這幾行代碼就可以將 NebulaGraph 中的這張圖構造為 DGL 的 DGLHeteroGraph 圖對象:

fromnebula_dglimportNebulaLoader


nebula_config={
"graph_hosts":[
('graphd',9669),
('graphd1',9669),
('graphd2',9669)
],
"nebula_user":"root",
"nebula_password":"nebula",
}

#loadfeature_mapperfromyamlfile
withopen('nebulagraph_entity_resolution_dgl_mapper.yaml','r')asf:
feature_mapper=yaml.safe_load(f)

nebula_loader=NebulaLoader(nebula_config,feature_mapper)
g=nebula_loader.load()

g=g.to('cpu')
device=torch.device('cpu')

模型訓練

參考custom_link_prediction_dataset.py

HDE_link_predict.py
importtorchasth
fromopenhgnnimportExperiment
fromopenhgnn.datasetimportAsLinkPredictionDataset,generate_random_hg
fromdglimporttransformsasT
fromdglimportDGLHeteroGraph
fromdgl.dataimportDGLDataset
fromdgl.dataloading.negative_samplerimportGlobalUniform

meta_paths_dict={'APA':[('user','has_email_with_handle','email_handle'),('user','is_similar_to','user'),('user','shared_similar_location','user'),('user','has_address','address'),('user','logged_in_from','ip'),('user','used_device','device')]}
target_link=[('user','is_similar_to','user')]
target_link_r=[('user','is_similar_to','user')]


classMyLPDataset(DGLDataset):
def__init__(self,g):
super().__init__(name='entity_resolution',force_reload=True)
self.g=g

defprocess(self):
#Generatearandomheterogeneousgraphwithlabelsontargetnodetype.
self._g=transform_hg(self.g)

#Somemodelsrequiremetapaths,youcansetmetapathdictforthisdataset.
@property
defmeta_paths_dict(self):
returnmeta_paths_dict

def__getitem__(self,idx):
returnself._g

def__len__(self):
return1


deftransform_hg(g:DGLHeteroGraph)->DGLHeteroGraph:
transform=T.Compose([T.ToSimple(),T.AddReverse()])
hg=transform(g)
returnhg


deftrain_with_custom_lp_dataset(dataset):
experiment=Experiment(model='HDE',dataset=dataset,task='link_prediction',gpu=-1)
experiment.run()


myLPDataset=AsLinkPredictionDataset(
MyLPDataset(g),
target_link=target_link,
target_link_r=target_link_r,
split_ratio=[0.8,0.1,0.1],
force_reload=True)

train_with_custom_lp_dataset(myLPDataset)

注,這里尚需把 g 處理成為 MyLPDataset() 可以接受的數據,篇幅所限、略。





審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 神經網絡
    +關注

    關注

    42

    文章

    4779

    瀏覽量

    101044
  • URL
    URL
    +關注

    關注

    0

    文章

    139

    瀏覽量

    15421
  • DDL
    DDL
    +關注

    關注

    0

    文章

    13

    瀏覽量

    6342
  • DML模型
    +關注

    關注

    0

    文章

    4

    瀏覽量

    6043

原文標題:基于圖數據庫NebulaGraph的ID Resolution方法與代碼示例

文章出處:【微信號:OSC開源社區,微信公眾號:OSC開源社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    SQL存儲過程在.NET數據庫中的應用

    :Visual Studio.NET 數據庫管理系統:SQL Server 2000(其中包含了示例程序所用到的Pubs數據庫) 三.創建一個簡單的存儲過程: 這里我將向大家介紹如何運用Visual
    發表于 12-31 16:54

    簡單的Access數據庫查詢示例

    一個簡單的Access數據庫查詢示例,可用作登陸系統
    發表于 08-23 16:17

    labview連接MS SQL數據庫示例

    網絡上的連接數據庫示例多少都有點問題,因此參照C#的操作方法,封裝了一個VI,來操作數據庫。亮點:可以讀取二進制格式字段。
    發表于 10-12 15:41

    淺析對象數據庫和NoSQL

    (阻抗不匹配)”。于是嗎,關系型數據庫對于程序員的設計始終有相當大的限制,有的人擅長從領域模型去設計程序,有的人喜好從數據存儲層面去設計代碼。在對象數據庫中,可以顯式避免了一些傳統關系
    發表于 05-27 06:36

    基于Data Ability的關系型數據庫數據管理能力,實現數據庫相關應用服務的快速開發

    數據庫的增/刪/改/查API方法),示例代碼如下:public class PersonDataAbility extends Ability { private static fi
    發表于 09-26 16:43

    HarmonyOS關系型數據庫和對象關系數據庫的使用方法

    容易就上手的知識。本篇速成教程直接使用最精準和簡短的文字,再配上講解代碼,讓我們能在10分鐘左右就能掌握最基本的數據庫使用方法數據庫的三大要素:
    發表于 03-29 14:10

    數據庫設計方法、規范、技巧

    數據庫設計方法、規范、技巧
    發表于 09-08 08:50 ?18次下載
    <b class='flag-5'>數據庫</b>設計<b class='flag-5'>方法</b>、規范、技巧

    各種數據庫的連接方法詳細資料說明

    本文檔的主要內容詳細介紹的是各種數據庫的連接方法詳細資料說明包括了:一、JDBC連接各種數據庫,二、ASP連接各種數據庫方法,三、PDO對
    發表于 06-26 15:39 ?3次下載

    MACSV數據庫導出、導入的方法

    MACSV數據庫導出、導入的方法(現代電源技術期末考試)-文檔為MACSV數據庫導出、導入的方法詳解文檔,是一份不錯的參考資料,感興趣的可以下載看看,,,,,,,,,,,,,
    發表于 09-17 15:41 ?2次下載
    MACSV<b class='flag-5'>數據庫</b>導出、導入的<b class='flag-5'>方法</b>

    Spring嵌入式數據庫示例

    在本教程中,我們將向您展示一些示例,以在Spring框架中配置嵌入式數據庫引擎,例如HSQL,H2和Derby。 使用的技術: 春天4.1.6.RELEASE jUnit 4.1.2
    發表于 10-20 19:35 ?1次下載
    Spring嵌入式<b class='flag-5'>數據庫</b><b class='flag-5'>示例</b>

    用于完整的數據庫加密使用教程

    ohos-database-sqlcipher 用于完整的數據庫加密。 使用說明 sample/ 文件夾中提供了一個示例項目,該示例項目提供了可運行的代碼
    發表于 04-13 10:18 ?1次下載

    數據庫的特性及其優勢

    本文介紹了數據庫的歷史由來、特性及其優勢,并說明了數據庫解決的是什么樣的問題,闡述了數據庫
    的頭像 發表于 03-29 13:35 ?2078次閱讀
    <b class='flag-5'>圖</b><b class='flag-5'>數據庫</b>的特性及其優勢

    數據庫建立|數據庫創建的方法

    數據庫是一個存儲關鍵數據的文件系統。利用數據庫管理系統建立每個人的數據庫可以更好地提供安全。 數據庫建立|
    的頭像 發表于 07-14 11:15 ?1301次閱讀

    sql怎么用代碼創建數據庫

    sql怎么用代碼創建數據庫 SQL是一種結構化查詢語言,用于通過編程語言與數據庫進行通信。它允許用戶從數據庫中檢索、修改和刪除數據。在本文中
    的頭像 發表于 08-28 17:09 ?2785次閱讀

    oracle數據庫的使用方法

    數據庫的使用方法,包括安裝和配置、基本操作、高級功能等方面。 一、安裝和配置 安裝Oracle數據庫前,您需要先下載合適的安裝包,根據操作系統的要求選擇相應的版本。安裝Oracle數據庫
    的頭像 發表于 12-06 10:10 ?1276次閱讀
    主站蜘蛛池模板: 伊人久久大香线蕉资源 | 男女车车的车车网站W98免费 | 一二三四韩国免费观看 | 色欲国产麻豆一精品一AV一免费 | 苍井空教师BD在线观看全集 | 美女逼逼毛茸茸 | 45分钟做受片免费观看 | 邪恶肉肉全彩色无遮琉璃神社 | 国产精品亚洲AV色欲在线观看 | 中文字幕乱码一区AV久久 | 亚洲高清在线mv | 快播最新电影网站 | 成人免费观看在线视频 | 久久精品国产亚洲AV久五月天 | 秋霞网韩国理伦片免费看 | 永久免费看A片无码网站四虎 | 久久久久久91香蕉国产 | 欧美三级不卡在线观线看 | 青柠在线电影高清免费观看 | 狠狠躁天天躁小说 | 97午夜伦伦电影理论片 | 国产精品嫩草影视在线观看 | 久久精品国产午夜伦班片 | 在线视频 国产精品 中文字幕 | 性派对xxxhd| av狼新人开放注册区 | 欧美另类jizzhd | 国产在线精彩视频 | 无套内射在线观看THEPORN | 国语自产一区第二页 | 亚洲色噜噜狠狠站欲八 | 么公一夜要了我一八次视频HD | 久久青草免费91线频观看站街 | 热久久免费频精品99热 | 最近日本MV字幕免费观看视频 | 亚洲这里只有精品 | 国产毛A片久久久久久无码 国产毛A片啊久久久久久A | 亚洲色欲国产AV精品综合 | 国产AV无码一二三区视频 | 扒开美女的内衣亲吻漫画 | 噜噜噜狠狠夜夜躁 |