概述
FeatureStore Go SDK 是人工智慧平台(PAI)下特徵平台(FeatureStore)的 Go 用戶端 SDK,提供特徵資料的高效能讀取和寫入。
適用情境
線上推理情境快速擷取特徵資料
即時特徵寫入與更新
支援行為資料讀取和序列特徵拼接
模型特徵批量擷取
前提條件
在使用 FeatureStore Go SDK 之前,請確保已完成以下準備工作:
* 已建立 FeatureStore 專案(Project)、特徵實體(FeatureEntity)、特徵視圖(FeatureView)和模型特徵(ModelFeature),並完成資料同步操作。具體操作,請參見 配置FeatureStore專案。
* 已擷取阿里雲賬戶的 AccessKey ID 和 AccessKey Secret。具體操作,請參見 建立AccessKey。
快速開始
FeatureStore Go SDK地址見:https://github.com/aliyun/aliyun-pai-featurestore-go-sdk
執行以下命令安裝 SDK:
go get github.com/aliyun/aliyun-pai-featurestore-go-sdk/v2
import (
"os"
featurestore "github.com/aliyun/aliyun-pai-featurestore-go-sdk/v2/featurestore"
)
accessId := os.Getenv("AccessId")
accessKey := os.Getenv("AccessKey")
regionId := "cn-hangzhou"
projectName := "fs_test_ots"
client, err := featurestore.NewFeatureStoreClient(regionId, accessId, accessKey, projectName)
如若從 FeatureDB 讀寫資料,需配置 FeatureDB 使用者名稱和密碼:
username := os.Getenv("FEATUREDB_USERNAME")
password := os.Getenv("FEATUREDB_PASSWORD")
client, err := featurestore.NewFeatureStoreClient(
regionId, accessId, accessKey, projectName,
featurestore.WithFeatureDBLogin(username, password),
)
參數介紹
參數名 | 類型 | 必填 | 說明 | 樣本 |
regionId | String | 是 | 地區ID | cn-hangzhou |
accessId | String | 否 | 阿里雲帳號 AccessKey ID | 從環境變數擷取 |
accessKey | String | 否 | 阿里雲帳號 AccessKey Secret | 從環境變數擷取 |
projectName | String | 是 | FeatureStore 專案名稱 | my_project |
username | String | FeatureDB 必填 | FeatureDB 使用者名稱,僅線上資料來源為 FeatureDB 時需配置 | featuredb_user |
password | String | FeatureDB 必填 | FeatureDB 密碼,僅線上資料來源為 FeatureDB 時需配置 | featuredb_password |
SDK 預設直連線上資料來源(如 FeatureDB),用戶端需要在 VPC 環境運行才能串連。本地調試時可使用 WithTestMode() 啟用公網訪問,但生產環境請勿啟用。
// 本地調試使用公網地址
client, err := featurestore.NewFeatureStoreClient(
regionId, accessId, accessKey, projectName,
featurestore.WithTestMode(),
featurestore.WithFeatureDBLogin(username, password),
)
可選配置項
配置項 | 用途 | 樣本 |
WithFeatureDBLogin() | FeatureDB 認證資訊 | featurestore.WithFeatureDBLogin("admin", "pwd") |
WithTestMode() | 本地調試,使用公網地址 | featurestore.WithTestMode() |
讀取功能
擷取 FeatureView 特徵資料
通過 FeatureView 擷取線上特徵資料,支援離線特徵、即時特徵和序列特徵的讀取。
介面說明
GetOnlineFeatures(joinIds []interface{}, features []string, alias map[string]string) ([]map[string]interface{}, error)
參數說明
參數名 | 類型 | 必填 | 說明 |
joinIds | []interface{} | 是 | join_id 值列表,用於查詢特徵資料 |
features | []string | 否 | 需要返回的特徵欄位列表, |
alias | map[string]string | 否 | 特徵欄位別名映射,返回資料時顯示別名 |
樣本
project, err := client.GetProject("fs_test_ots")
if err != nil {
log.Fatal(err)
}
userFeatureView := project.GetFeatureView("user_fea")
if userFeatureView == nil {
log.Fatal("feature view not exist")
}
features, err := userFeatureView.GetOnlineFeatures(
[]interface{}{"100043186", "100060369"},
[]string{"*"},
nil,
)
離線/即時FeatureView特徵資料樣本結果
[ { "city":"合肥市", "follow_cnt":1, "gender":"male", "user_id":"100043186" }, { "city":"", "follow_cnt":5, "gender":"male", "user_id":"100060369" } ]序列特徵FeatureView特徵資料樣本結果
假設序列特徵讀取配置如下
離線序列特徵欄位
事件名稱
序列長度
線上序列特徵名稱
click_seq_50_seq
click
50
click_seq_50_seq
expr_seq_100_seq
expr
100
expr_seq_100
返回樣本結果
[ { "click_seq_50_seq": "216751275;228787053;220852269;242884721", "click_seq_50_seq__event": "click;click;click;click", "click_seq_50_seq__event_time": "1699128398;1699128398;1699118623;1699118623", "click_seq_50_seq__item_id": "216751275;228787053;220852269;242884721", "click_seq_50_seq__playtime": "65.40;72.06;104.69;62.74", "click_seq_50_seq__ts": "389018;389018;398793;398793", "expr_seq_100": "207474427;216751275;228787053;247136848;270584471;299485479;220852269;242884721;245999124;265863707", "expr_seq_100__event": "expr;expr;expr;expr;expr;expr;expr;expr;expr;expr", "expr_seq_100__event_time": "1699128398;1699128398;1699128398;1699128398;1699128398;1699128398;1699118623;1699118623;1699118623;1699118623", "expr_seq_100__item_id": "207474427;216751275;228787053;247136848;270584471;299485479;220852269;242884721;245999124;265863707", "expr_seq_100__playtime": "0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00", "expr_seq_100__ts": "389018;389018;389018;389018;389018;389018;398793;398793;398793;398793", "user_id": "186569075" }, { "click_seq_50_seq": "201741544;236327912;293320498", "click_seq_50_seq__event": "click;click;click", "click_seq_50_seq__event_time": "1699178245;1699178245;1699178245", "click_seq_50_seq__item_id": "201741544;236327912;293320498", "click_seq_50_seq__playtime": "97.41;70.32;135.21", "click_seq_50_seq__ts": "339171;339171;339171", "expr_seq_100": "201741544;224940066;236327912;240253906;247562151;293320498", "expr_seq_100__event": "expr;expr;expr;expr;expr;expr", "expr_seq_100__event_time": "1699178245;1699178245;1699178245;1699178245;1699178245;1699178245", "expr_seq_100__item_id": "201741544;224940066;236327912;240253906;247562151;293320498", "expr_seq_100__playtime": "0.00;0.00;0.00;0.00;0.00;0.00", "expr_seq_100__ts": "339171;339171;339171;339171;339171;339171", "user_id": "186569870" } ]
擷取 ModelFeature 關聯特徵
通過 Model 擷取關聯的所有 FeatureEntity 特徵資料,支援上級-下級 Entity 層級關係。
介面說明
// 擷取所有根實體及其關聯的下級實體特徵
GetOnlineFeatures(joinIds map[string][]interface{}) ([]map[string]interface{}, error)
// 擷取指定 Entity 及其下級 Entity 特徵
GetOnlineFeaturesWithEntity(joinIds map[string][]interface{}, featureEntityName string) ([]map[string]interface{}, error)
參數說明
參數名 | 類型 | 必填 | 說明 |
joinIds | map[string][]interface{} | 是 | join_id 映射,key 為 join_id 名稱,value 為值列表 |
featureEntityName | string | 否 | 指定擷取某個 FeatureEntity 的特徵資料 |
Entity 層級關係
ModelFeature 可關聯多個 FeatureEntity,存在上下級嵌套關係:
* 上級 Entity:包含主特徵欄位 + 關聯下級 Entity 的欄位
* 下級 Entity:被上級 Entity 引用,包含獨立的特徵欄位
擷取特徵時,只需傳入根實體的 join_id,SDK 會自動根據上級實體的特徵值擷取下級實體的特徵。
不同情境樣本
情境1:擷取 Model 關聯的全部特徵
調用 GetOnlineFeatures 傳入所有根實體的 join_id,SDK 自動擷取 Model 關聯的全部特徵(包括下級實體)。
model := project.GetModelFeature("model_fv1")
if model == nil {
t.Fatal("model feature not exist")
}
// 傳入所有根實體的 join_id
joinIds := map[string][]interface{}{
"user_id": {"U001", "U002", "U003"},
"item_id": {"1001", "1002", "1003"},
}
// 會一併擷取所有根實體及其關聯下級實體的特徵
features, err := model.GetOnlineFeatures(joinIds)
返回樣本:
{
"item_id": "1001",
"item_title": "智能手錶",
"item_price": 299.00,
"author_id": "A001",
"author_name": "張三",
"author_fans_count": 10000,
"category_id": "C001",
"category_name": "電子產品",
"category_level": 1,
"user_id": "U001",
"user_age": 28,
"user_gender": "male"
}
情境2:擷取指定 Entity 側特徵(含下級實體)
調用 GetOnlineFeaturesWithEntity 指定 Entity 名稱,擷取該 Entity 及其下級實體特徵。樣本中 item Entity 關聯 author、category 兩個下級實體,返回 item 側全部特徵。
joinIds := map[string][]interface{}{
"item_id": {"1001", "1002", "1003"},
}
// 指定擷取 item Entity 的特徵
// item側關聯下級實體 author、category,一併返回
features, err := model.GetOnlineFeaturesWithEntity(joinIds, "item")
返回樣本:
{
"item_id": "1001",
"item_title": "智能手錶",
"item_price": 299.00,
"author_id": "A001",
"author_name": "張三",
"author_fans_count": 10000,
"category_id": "C001",
"category_name": "電子產品",
"category_level": 1
}
情境3:擷取指定 Entity 側特徵(無下級實體)
調用 GetOnlineFeaturesWithEntity 指定實體名稱,擷取該實體特徵。樣本中 author 實體無下級實體,只返回 author 本身的特徵欄位。
joinIds := map[string][]interface{}{
"author_id": {"A001", "A002", "A003"},
}
// 指定擷取 author Entity 的特徵
// author側無下級實體,只返回 author側特徵
features, err := model.GetOnlineFeaturesWithEntity(joinIds, "author")
返回樣本:
{
"author_id": "A001",
"author_name": "張三",
"author_fans_count": 10000
}
ModelFeature 包含序列特徵樣本
當 ModelFeature 關聯序列特徵 FeatureView 時,返回資料中會包含序列特徵欄位:
序列特徵對應FeatureEntity一般為user,樣本中有兩個join_id、user_id和item_id。擷取特徵的時候需要設定相同的ID數量。
假設序列特徵讀取配置如下:
離線序列特徵欄位
事件名稱
序列長度
線上序列特徵名稱
click_seq_50_seq
click
50
click_seq_50_seq
// get ModelFeature by name model := project.GetModelFeature("model_with_seq") if model == nil { t.Fatal("model feature not exist") } joinIds := map[string][]interface{}{ "user_id": {"186569075", "186569870"}, "item_id": {"299485479", "207474427"}, } // get online features features, err := model.GetOnlineFeatures(joinIds)返回樣本結果
[ { "age": 51, "author": 147848300, "category": "7", "city": "", "click_count": 0, "click_seq_50_seq": "216751275;228787053;220852269;242884721", "click_seq_50_seq__event": "click;click;click;click", "click_seq_50_seq__event_time": "1699128398;1699128398;1699118623;1699118623", "click_seq_50_seq__item_id": "216751275;228787053;220852269;242884721", "click_seq_50_seq__playtime": "65.40;72.06;104.69;62.74", "click_seq_50_seq__ts": "391447;391447;401222;401222", "duration": 48, "follow_cnt": 2, "follower_cnt": 0, "gender": "female", "item_cnt": 0, "item_id": 299485479, "praise_count": 2, "pub_time": 1697885713, "register_time": 1696582012, "tags": "0", "title": "#健身打卡", "user_id": "186569075" }, { "age": 28, "author": 119734983, "category": "18", "city": "", "click_count": 0, "click_seq_50_seq": "201741544;236327912;293320498", "click_seq_50_seq__event": "click;click;click", "click_seq_50_seq__event_time": "1699178245;1699178245;1699178245", "click_seq_50_seq__item_id": "201741544;236327912;293320498", "click_seq_50_seq__playtime": "97.41;70.32;135.21", "click_seq_50_seq__ts": "341600;341600;341600", "duration": 15, "follow_cnt": 0, "follower_cnt": 2, "gender": "male", "item_cnt": 0, "item_id": 207474427, "praise_count": 79, "pub_time": 1697731285, "register_time": 1699135393, "tags": "1", "title": "#成語故事", "user_id": "186569870" } ]
寫入功能
將特徵資料即時寫入 FeatureDB 資料來源,支援即時特徵和序列特徵的寫入。
適用情境
即時更新使用者特徵(如線上特徵更新)
寫入使用者行為序列資料(點擊、播放等事件)
即時特徵資料的部分欄位更新(不影響其他欄位)
目前寫入介面僅支援線上資料來源為 FeatureDB 的即時特徵視圖和行為序列特徵視圖,需配置 FeatureDB 使用者名稱和密碼。
即時特徵寫入
整行更新
project, err := client.GetProject("test_pro1")
if err != nil {
log.Fatal(err)
}
featureView := project.GetFeatureView("user_feature_view")
if featureView == nil {
t.Fatal("feature view not exist")
}
// 構造寫入資料
writeData := make([]map[string]interface{}, 0)
record := map[string]interface{}{
"user_id": "user_001",
"name": "張三",
"age": 28,
"city": "北京",
}
writeData := append(writeData, record)
// 寫入資料
featureView.WriteFeatures(writeData)
// 強制重新整理(確保資料完成寫入)
featureView.WriteFlush()
方法 | 參數 | 必填 | 說明 |
WriteFeatures | []map[string]interface{} | 是 | 批量寫入資料 |
WriteFlush | 無 | - | 確保資料完成寫入(調用後不能再寫入) |
部分欄位更新
預設整行替換,部分欄位更新需指定 InsertMode:
import "github.com/aliyun/aliyun-pai-featurestore-go-sdk/v2/constants"
record = map[string]interface{}{
"user_id": "user_001",
"name": "李四",
}
writeData := append(writeData, record)
featureView.WriteFeaturesWithInsertMode(writeData, constants.Partial_Field_Write)
// 強制重新整理(確保資料完成寫入)
featureView.WriteFlush()
序列特徵寫入
序列特徵寫入用於即時記錄使用者行為事件(點擊、播放、購買等),支援線上推理情境的行為序列特徵構建。
樣本
sequenceFeatureView := project.GetFeatureView("sequence")
if sequenceFeatureView == nil {
t.Fatal("sequence featureview not found")
}
// 構造序列資料
sequenceWriteData := make([]map[string]interface{}, 0)
for i := 0; i < 10; i++ {
data := make(map[string]interface{})
data["request_id"] = int64(901850344 + i)
data["user_id"] = fmt.Sprintf("%d", 1000+i+1)
data["page"] = "home"
data["net_type"] = "wifi"
data["day_h"] = 17
data["week_day"] = 6
data["event_unix_time"] = time.Now().Unix()
data["item_id"] = fmt.Sprintf("22346678%d", i)
data["event"] = "click"
data["playtime"] = 54.7296554003366 + float64(i)
sequenceWriteData = append(sequenceWriteData, data)
}
err = sequenceFeatureView.WriteFeatures(sequenceWriteData)
if err != nil {
t.Fatal(err)
}
sequenceFeatureView.WriteFlush()