那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

淺析基于圖數(shù)據(jù)庫NebulaGraph的ID Resolution方法與代碼示例

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

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

1 基于圖數(shù)據(jù)庫的用戶 ID 識別方法用戶

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

由于 ID 識別天然地是一個關(guān)聯(lián)關(guān)系問題,也是一個典型的圖、圖數(shù)據(jù)庫應(yīng)用場景。

1.1 建立圖譜

1.1.1 圖建模

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

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 數(shù)據(jù)

這份數(shù)據(jù)是開源的,地址在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 對應(yīng)的 NebulaGraph DDL 是:

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

#創(chuàng)建點的類型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`();

#創(chuàng)建邊的類型EdgeType

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

對于寫入數(shù)據(jù)的 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 根據(jù)確定規(guī)則獲取 ID 映射關(guān)系

最簡單、直接的方法,在特定的場景下也可能是有用的,試想像 email、IP 地址、上網(wǎng)設(shè)備這些有嚴(yán)格結(jié)構(gòu)的數(shù)據(jù),在它們成為圖譜中的點的時候,簡單的相等關(guān)系就足以找出這樣對應(yīng)關(guān)系,比如:

擁有相同的 email

使用過相同的 IP 地址

使用過相同的設(shè)備

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

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

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

注:

這個結(jié)果的數(shù)據(jù)源在https://github.com/wey-gu/identity-correlation-datagen/tree/main/sample/hand_crafted

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

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

根據(jù)確定規(guī)則獲取 ID 映射關(guān)系

顯然,在構(gòu)建 ID Mapping 系統(tǒng)的過程中,我們就是通過在圖數(shù)據(jù)庫中直接查詢,可視化渲染結(jié)果來看到等效的洞察,這個查詢可以寫成:

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

NebulaGraph 中的查詢結(jié)果

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

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

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

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

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

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,這兩個人的姓名不同,但是手機(jī)和地址卻是相同的。

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

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

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

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

如何表現(xiàn) 4kelly@yahoo.com 與 4kelly@hotmail.com 的相似性?

如何將多種匹配規(guī)則的信息都納入關(guān)聯(lián)系統(tǒng)?

1.3 非確定規(guī)則基于復(fù)合條件量化方法

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

需要多因素(規(guī)則)進(jìn)行綜合考慮與判定

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

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

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

a. 表現(xiàn)結(jié)構(gòu)化數(shù)據(jù)的相似性:Sharon91@gmail.com與Sharon91+001@gmail.com

b. 表現(xiàn)非結(jié)構(gòu)化數(shù)據(jù)的相似性:

直接判定子字符串

運算 Jaccard index 等類似的相似度

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

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

直接進(jìn)行兩個值的相似度

拆分為更細(xì)粒的多個屬性

然后就可以設(shè)計詳細(xì)的確定性規(guī)則:email.handle 相等、甚至再在此基礎(chǔ)上應(yīng)用其他非確定規(guī)則

有時候,比如對于 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. 的非結(jié)構(gòu)屬性相似性距離,處理方式可以根據(jù)具體的 domain knowledge 千差萬別:

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

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

對于600-192-2985x041與 (600)-192-2985這種字符串形式的電話號碼,則可以統(tǒng)一轉(zhuǎn)化為<國家碼>+<區(qū)域碼>+<本地號碼>+<分機(jī)號>這樣的結(jié)構(gòu)化數(shù)據(jù),進(jìn)一步按照結(jié)構(gòu)化數(shù)據(jù)的方式處理。

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

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

小結(jié)

總結(jié)來看,為了解決真實世界數(shù)據(jù)的復(fù)雜情形,基于復(fù)合條件的量化方法有:

通過細(xì)化結(jié)構(gòu)數(shù)據(jù)(比如郵箱字段拆分為子屬性或者點)、或者轉(zhuǎn)變?yōu)榻Y(jié)構(gòu)化數(shù)據(jù)(處理字符串形式的電話號碼)建立相似結(jié)構(gòu)化數(shù)據(jù)之間的確定關(guān)聯(lián);

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

為不同關(guān)系賦予加權(quán),計算相似度總分;

1.3.1 基于復(fù)合條件量化方法實操

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

細(xì)化結(jié)構(gòu)數(shù)據(jù)

通過細(xì)化結(jié)構(gòu)數(shù)據(jù)(比如郵箱字段拆分為子屬性或者點)、或者轉(zhuǎn)變?yōu)榻Y(jié)構(gòu)化數(shù)據(jù)(處理字符串形式的電話號碼)建立相似結(jié)構(gòu)化數(shù)據(jù)之間的確定關(guān)聯(lián);

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

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 是一個潛在的超級節(jié)點,并且,它的區(qū)分度在很多情況下是很小的,比如 gmail.com 這個公共郵箱后綴沒有很大的關(guān)聯(lián)性意義。我們可以只留下 email.handle 作為點,而對于 email_domain,把它留在邊中作為屬性:

email_domain

Prop:

email_domain

Prop:

has_email_with_handle (user -> email_handle)

with_handle (email -> email_handle)

對應(yīng)的新的點類型、邊類型的 NebulaGraph DDL 語句:

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

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

對應(yīng)新的點、邊的 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");

可以看到,經(jīng)過這個處理,我們已經(jīng)得到更多關(guān)聯(lián)的用戶了,它可以用這個圖查詢表達(dá):

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

基于復(fù)合條件量化方法實操

非確定性相似性

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

這里用地址的地理距離來做為例子,我們預(yù)先處理每一個地址,將它們的經(jīng)緯度導(dǎo)入圖譜。

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

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

對應(yīng)過來,它的 DDL 變化是:

address

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

在已經(jīng)建立了初始的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="""|
+-----------+------------------------------------+

對應(yīng)的點、邊的 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是地址的經(jīng)緯度
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));

有了經(jīng)緯度信息,結(jié)合 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|
+--------------------+

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

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;

這里,為了展現(xiàn)出針對 ”非確定性“ 條件之間的 ”相似性”,我們可以把地址中字符串完全相同的結(jié)果過濾掉,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

它的結(jié)果是:

+-------------------+-------------------+--------------------+--------------------------------------------+--------------------------------------------+
|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 米,因為他們的地址就在一個街區(qū)

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

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

加權(quán)評分

為不同關(guān)系賦予加權(quán),計算相似度總分;

下邊是一個在實際應(yīng)用中,可以綜合考量的多種關(guān)聯(lián)關(guān)系,包括但不限于:

確定性關(guān)系

同名(精確匹配)

相同電話(格式化處理)

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

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

非確定性

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

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

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

本例中,為求簡潔,我們只給出考慮“同郵件前綴”、“同名”與“地理距離小于 10KM”的綜合加權(quán),并且認(rèn)為兩個因素的權(quán)重都是 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

結(jié)果是

+-----------+-----------+---------------------+-------------+-----------------+
|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|
+-----------+-----------+---------------------+-------------+-----------------+

然后,我們計算加權(quán)分?jǐn)?shù):

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

結(jié)果是

+-----------+-----------+-------+
|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 的方法交互式學(xué)習(xí)評分權(quán)重

實際應(yīng)用中,不同因素的加權(quán)關(guān)系也不是那么容易輕易給出的,我們可以利用有限的人力判斷進(jìn)行 Active Learning 的交互訓(xùn)練來習(xí)得權(quán)重。

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

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

進(jìn)一步,對于這些確定(是否二元的)或非確定(量化的)關(guān)系,利用圖庫與外部系統(tǒng)獲得了關(guān)聯(lián)關(guān)系之后,常??梢灾苯影阉鼈兌x為圖譜中直連的邊,寫回圖庫,提供給其他算法、系統(tǒng)作為輸入,做進(jìn)一步迭代、計算。

1.4.1 創(chuàng)建單獨的直連邊

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

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 創(chuàng)建復(fù)合評分之后的邊

比如,我們查詢綜合分?jǐn)?shù)大于 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

然后根據(jù)返回結(jié)果建立新的邊:

#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 基于圖算法的方法

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

1.5.1 圖相似性算法

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

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

1.5.2 社區(qū)發(fā)現(xiàn)算法

自然地,還可以用社區(qū)發(fā)現(xiàn)的算法全圖找出給定的基于邊之下的社區(qū)劃分,調(diào)試算法,使得目標(biāo)劃分社區(qū)內(nèi)部點為估計的相同用戶。

1.5.3 基于圖算法的方法

1.5.3.1 基于圖查詢的 Jaccard 實現(xiàn)

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

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

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

我們可以看到結(jié)果里:

+-----------+-----------+---------------------+
|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 的系數(shù)是最大的的,讓我們看看他們之間的連接?

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 前面方法的局限

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

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

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

1.5.3.2.2 更 Scale 的方法

為了能處理更大規(guī)模,我們可以利用 Spark 等并行計算平臺進(jìn)行算法執(zhí)行;

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

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

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

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

獲取每一個點的鄰居集合

對點的鄰居進(jìn)行 MinHash 運算,獲得 Jaccard 系數(shù)

慶幸的是,開源的 NebulaGraph Algorithm 已經(jīng)提供了這個算法的實現(xiàn),而我們只需要調(diào)用 NebulaGraph Algorithm 就可以了,使用方法參考 NebulaGraph Algorithm 文檔。

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

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

讀者到這里應(yīng)該會注意到,這個方法顯然是假設(shè)所有的點都是用戶實體,邊是他們之間的直連關(guān)系的。所以再應(yīng)用這個方法之前,我們需要創(chuàng)建經(jīng)過預(yù)處理的直連邊,這個步驟正是前邊章節(jié)“利用新的邊連接不同方法”中的內(nèi)容。

1.5.3.3 基于 NebulaGraph Algorithm 圖計算平臺社區(qū)發(fā)現(xiàn)算法

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

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

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

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

Nebula-Up 部署命令:

curl-fsSLnebula-up.siwei.io/all-in-one.sh|bash-s--v3spark
1.6 基于圖神經(jīng)網(wǎng)絡(luò)的方法

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

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

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

1.6.1 基于 GNN 的實操

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

1.6.1.1 HDE[ICDM2021]

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

注:OpenHGNN 是由北郵 GAMMA Lab 開發(fā)的基于 PyTorch 和 DGL 的開源異質(zhì)圖神經(jīng)網(wǎng)絡(luò)工具包。

1.6.1.2 數(shù)據(jù)集

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

注:

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

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

1.6.1.3 數(shù)據(jù)處理

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

我們看下現(xiàn)在的圖中有哪些點、邊類型:

(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 中的這張圖構(gòu)造為 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')

模型訓(xùn)練

參考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() 可以接受的數(shù)據(jù),篇幅所限、略。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 神經(jīng)網(wǎng)絡(luò)

    關(guān)注

    42

    文章

    4781

    瀏覽量

    101176
  • URL
    URL
    +關(guān)注

    關(guān)注

    0

    文章

    139

    瀏覽量

    15482
  • DDL
    DDL
    +關(guān)注

    關(guān)注

    0

    文章

    13

    瀏覽量

    6345
  • DML模型
    +關(guān)注

    關(guān)注

    0

    文章

    4

    瀏覽量

    6053

原文標(biāo)題:基于圖數(shù)據(jù)庫NebulaGraph的ID Resolution方法與代碼示例

文章出處:【微信號:OSC開源社區(qū),微信公眾號:OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    SQL存儲過程在.NET數(shù)據(jù)庫中的應(yīng)用

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

    簡單的Access數(shù)據(jù)庫查詢示例

    一個簡單的Access數(shù)據(jù)庫查詢示例,可用作登陸系統(tǒng)
    發(fā)表于 08-23 16:17

    labview連接MS SQL數(shù)據(jù)庫示例

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

    淺析對象數(shù)據(jù)庫和NoSQL

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

    基于Data Ability的關(guān)系型數(shù)據(jù)庫數(shù)據(jù)管理能力,實現(xiàn)數(shù)據(jù)庫相關(guān)應(yīng)用服務(wù)的快速開發(fā)

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

    HarmonyOS關(guān)系型數(shù)據(jù)庫和對象關(guān)系數(shù)據(jù)庫的使用方法

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

    數(shù)據(jù)庫設(shè)計方法、規(guī)范、技巧

    數(shù)據(jù)庫設(shè)計方法、規(guī)范、技巧
    發(fā)表于 09-08 08:50 ?18次下載
    <b class='flag-5'>數(shù)據(jù)庫</b>設(shè)計<b class='flag-5'>方法</b>、規(guī)范、技巧

    各種數(shù)據(jù)庫的連接方法詳細(xì)資料說明

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

    MACSV數(shù)據(jù)庫導(dǎo)出、導(dǎo)入的方法

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

    Spring嵌入式數(shù)據(jù)庫示例

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

    用于完整的數(shù)據(jù)庫加密使用教程

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

    數(shù)據(jù)庫的特性及其優(yōu)勢

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

    數(shù)據(jù)庫建立|數(shù)據(jù)庫創(chuàng)建的方法?

    數(shù)據(jù)庫是一個存儲關(guān)鍵數(shù)據(jù)的文件系統(tǒng)。利用數(shù)據(jù)庫管理系統(tǒng)建立每個人的數(shù)據(jù)庫可以更好地提供安全。 數(shù)據(jù)庫建立|
    的頭像 發(fā)表于 07-14 11:15 ?1324次閱讀

    sql怎么用代碼創(chuàng)建數(shù)據(jù)庫

    sql怎么用代碼創(chuàng)建數(shù)據(jù)庫 SQL是一種結(jié)構(gòu)化查詢語言,用于通過編程語言與數(shù)據(jù)庫進(jìn)行通信。它允許用戶從數(shù)據(jù)庫中檢索、修改和刪除數(shù)據(jù)。在本文中
    的頭像 發(fā)表于 08-28 17:09 ?2806次閱讀

    oracle數(shù)據(jù)庫的使用方法

    數(shù)據(jù)庫的使用方法,包括安裝和配置、基本操作、高級功能等方面。 一、安裝和配置 安裝Oracle數(shù)據(jù)庫前,您需要先下載合適的安裝包,根據(jù)操作系統(tǒng)的要求選擇相應(yīng)的版本。安裝Oracle數(shù)據(jù)庫
    的頭像 發(fā)表于 12-06 10:10 ?1294次閱讀
    百家乐官网偷吗| 百家乐21点游戏| 百家乐技巧论坛| 金赞娱乐城真人娱乐| 百家乐官网专用台布| 澳门百家乐路单| 富易堂百家乐官网娱乐城| 誉博百家乐开户导航| 百家乐官网玩法百科| 百家乐赌博牌路分析| 介绍百家乐官网赌博技巧| 威尼斯人娱乐场官网是多少 | 百家乐官网视频游戏聊天| 大发888 赌场娱乐网规则| 定做百家乐官网桌子| 全讯网跑狗图| 属狗与属龙做生意好吗| 娱乐城开户送白菜| 百家乐园棋牌| 百家乐官网下载游戏| 真人游戏网| 荷规则百家乐官网的玩法技巧和规则| 大发888官网网址| 百家乐官网博赌场娱乐网规则| 百家乐官网7scs| 百家乐官网技巧-澳门百家乐官网官方网址 | 扶沟县| 玩百家乐犯法| 百家乐官网娱乐分析软件v4.0| 云顶国际网站| 百家乐斗视频游戏| 米林县| 伯爵百家乐的玩法技巧和规则| 至尊百家乐官网娱乐场开户注册| 平顶山市| 大发888大发娱乐城| 百家乐投住系统| 百家乐官网园有限公司| 百家乐官网统计概率| 大发888游戏平台dafa 888 gw| 百家乐官网筹码币套装|