Skip to content

Commit

Permalink
Merge pull request #39 from aliyun/feature/behavior
Browse files Browse the repository at this point in the history
feat: add GetBehaviorFeatures support
  • Loading branch information
bruceding authored Dec 24, 2024
2 parents 771e8ce + f4c7bd6 commit ec8eeff
Show file tree
Hide file tree
Showing 13 changed files with 977 additions and 46 deletions.
61 changes: 60 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ go get github.com/aliyun/aliyun-pai-featurestore-go-sdk/v2

# 使用方式

## 初始化 client

- 初始化 client

```go
Expand Down Expand Up @@ -44,6 +46,10 @@ client, err := featurestore.NewFeatureStoreClient(regionId, accessId, accessKey,

**注意:** 当使用 WithTestMode() 初始化 client 时,需要确认在线数据源是否已开启公网。通过公网访问onlinestore会有对应数据源的流量开销,可能会产生下行流量费用。因此建议在此模式下只进行测试,生产环境请勿添加 WithTestMode()。

## 获取特征数据

### 获取 FeatureView 的特征数据

- 获取 (离线/实时) FeatureView 的特征数据

```go
Expand Down Expand Up @@ -84,7 +90,7 @@ features, err := user_feature_view.GetOnlineFeatures([]interface{}{"100043186",
]
```

- 获取 序列特征 FeatureView 的特征数据
- 获取 行为序列 FeatureView 的序列特征数据
```go
// get project by name
project, err := client.GetProject("holo_p1")
Expand Down Expand Up @@ -150,6 +156,59 @@ features, err := seq_feature_view.GetOnlineFeatures([]interface{}{"186569075", "
]
```

- 获取 行为序列 FeatureView 的行为表数据

```go
// get project by name
project, err := client.GetProject("fs_test_ots")
if err != nil {
// t.Fatal(err)
}

// get featureview by name
user_feature_view := project.GetFeatureView("seq_fea")
if user_feature_view == nil {
// t.Fatal("feature view not exist")
}

// get online features
features, err := feature_view.GetBehaviorFeatures([]interface{}{"142688703"}, []interface{}{"click", "praise"}, []string{"*"})
```
行为(event)字段信息可以填写0至多个。

[]string{"*"} 代表获取 featureview 下的所有行为特征字段, 也可以指定部分字段名称。

返回的数据示例如下

```json
[
{
"event":"praise",
"event_time":1733040792,
"exp_id":"ER2_L2#EG2#E3",
"item_id":"284794190",
"net_type":"wifi",
"page":"home",
"playtime":0,
"request_id":994994441,
"user_id":142688703
},
{
"event":"click",
"event_time":1732990248,
"exp_id":"ER2_L2#EG2#E3",
"item_id":"296088863",
"net_type":"wifi",
"page":"detail",
"playtime":15.499447802946065,
"request_id":966793253,
"user_id":142688703
}
]
```


### 获取模型特征

- 获取 ModelFeature 里的特征数据

Expand Down
2 changes: 2 additions & 0 deletions api/api_feature_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ func (a *FeatureViewApiService) ListFeatureViews(pagesize, pagenumber int32, pro
request.SetPageSize(pagesize)
request.SetPageNumber(pagenumber)
request.SetProjectId(projectId)
request.SetSortBy("GmtCreateTime")
request.SetOrder("ASC")

response, err := a.client.ListFeatureViews(&a.client.instanceId, &request)
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions api/model_feature_view_seq_config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package api

type FeatureViewSeqConfig struct {
RegistrationMode string `json:"registration_mode"`
ReferencedFeatureViewId int `json:"referenced_feature_view_id,omitempty"`
ReferencedFeatureViewName string `json:"referenced_feature_view_name,omitempty"`
ItemIdField string `json:"item_id_field"`
EventField string `json:"event_field"`
TimestampField string `json:"timestamp_field"`
Expand Down
5 changes: 5 additions & 0 deletions constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,8 @@ const (
Feature_View_Type_Stream = "Stream"
Feature_View_Type_Sequence = "Sequence"
)

const (
Seq_Registration_Mode_Full_Sequence = "full_sequence"
Seq_Registration_Mode_Only_Behavior = "only_behavior"
)
28 changes: 25 additions & 3 deletions dao/feature_view_dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import (

"github.com/aliyun/aliyun-pai-featurestore-go-sdk/v2/api"
"github.com/aliyun/aliyun-pai-featurestore-go-sdk/v2/constants"
"github.com/aliyun/aliyun-pai-featurestore-go-sdk/v2/utils"
)

type FeatureViewDao interface {
GetFeatures(keys []interface{}, selectFields []string) ([]map[string]interface{}, error)
GetUserSequenceFeature(keys []interface{}, userIdField string, sequenceConfig api.FeatureViewSeqConfig, onlineConfig []*api.SeqConfig) ([]map[string]interface{}, error)
GetUserBehaviorFeature(userIds []interface{}, events []interface{}, selectFields []string, sequenceConfig api.FeatureViewSeqConfig) ([]map[string]interface{}, error)
RowCount(string) int
}

Expand All @@ -24,6 +26,9 @@ func (d *UnimplementedFeatureViewDao) GetFeatures(keys []interface{}, selectFiel
func (d *UnimplementedFeatureViewDao) GetUserSequenceFeature(keys []interface{}, userIdField string, sequenceConfig api.FeatureViewSeqConfig, onlineConfig []*api.SeqConfig) ([]map[string]interface{}, error) {
return nil, nil
}
func (d *UnimplementedFeatureViewDao) GetUserBehaviorFeature(userIds []interface{}, events []interface{}, selectFields []string, sequenceConfig api.FeatureViewSeqConfig) ([]map[string]interface{}, error) {
return nil, nil
}
func (d *UnimplementedFeatureViewDao) RowCount(string) int {
return 0
}
Expand All @@ -46,10 +51,10 @@ func NewFeatureViewDao(config DaoConfig) FeatureViewDao {
panic("not found FeatureViewDao implement")
}

func makePlayTimeMap(sequenceConfig api.FeatureViewSeqConfig) map[string]float64 {
func makePlayTimeMap(playTimeFilter string) map[string]float64 {
sequencePlayTimeMap := make(map[string]float64)
if sequenceConfig.PlayTimeFilter != "" {
playTimes := strings.Split(sequenceConfig.PlayTimeFilter, ";")
if playTimeFilter != "" {
playTimes := strings.Split(playTimeFilter, ";")
for _, eventTime := range playTimes {
strs := strings.Split(eventTime, ":")
if len(strs) == 2 {
Expand Down Expand Up @@ -109,3 +114,20 @@ func makeSequenceFeatures(offlineSequences, onlineSequences []*sequenceInfo, seq
return properties

}

func combineBehaviorFeatures(offlineBehaviorInfo, onlineBehaviorInfo []map[string]interface{}, timestampField string) []map[string]interface{} {
// combine offline and online features
if len(offlineBehaviorInfo) > 0 {
index := 0
for index < len(onlineBehaviorInfo) {
if utils.ToInt64(onlineBehaviorInfo[index][timestampField], 0) < utils.ToInt64(offlineBehaviorInfo[0][timestampField], 0) {
break
}
index++
}

onlineBehaviorInfo = onlineBehaviorInfo[:index]
onlineBehaviorInfo = append(onlineBehaviorInfo, offlineBehaviorInfo...)
}
return onlineBehaviorInfo
}
Loading

0 comments on commit ec8eeff

Please sign in to comment.