閱讀473 返回首頁    go 小米淨水器


在線算法開發手冊__算法規範_開發者指南_推薦引擎-阿裏雲

先決條件

您需要熟悉基於NodeJS的開發模式,主要包括JS的基本語法+異步編程+函數回調(後兩項為高級進階要求,依您所需要開發的算法複雜度選擇具備即可)。

在線自定義算法代碼可在推薦引擎提供的界麵中進行編輯修改,並運行在推薦引擎內置的NodeJS環境中,您不需要在本地搭建NodeJS的環境。

推薦引擎提供了適用於個性化推薦的多種算法和模板,了解詳情請訪問係統內置算法和模板說明

基本知識

在線流程中,您要編寫的算法體現為流程圖中的一個個節點,如https://dtboost.aliyun.com/re/onlineflow?tp=tpl&id=45 所示:其中節點表現為函數,函數體基本結構如下

  1. 0 // 下麵這部分是流程節點運行時真正的執行代碼,要求您提交的在線代碼嚴格按照以下格式。為方便講解起見,我們給他起個代號叫做MAIN_ENTRY
  2. 1 function() {
  3. 2 // 函數體內您可以定義一些公用的變量或函數
  4. 3 var test_variable = 0;
  5. 4 var test_function = function() {
  6. 5 console.log('i am test_function');
  7. 6 }
  8. 7 var callback = this; // NodeJS裏的回調函數習慣用callback表示,這裏直接賦值,符合程序員習慣
  9. 8 var reclist = arguments[0][0]; //arguments[0][0]表示上遊節點的輸出數據,典型的情況下就是一個推薦列表
  10. 9 ... // 在這裏完成您的處理邏輯
  11. 10 return callback(null, reclist); // 值得注意的是,這裏必須寫成callback的形式(由於是最後一個語句,因此有沒有return無區別,但對於需要提前回調的情況,請注意使用return callback),而不能直接return一個變量,否則下遊節點獲取不到本節點的輸出,程序也會hang住,框架會一直等待該函數回調事件
  12. 11 }

注意事項

  1. 第2-6行,定義的內層公用變量和函數,您可以在MAIN_ENTRY中調用,後文會提及公用變量和方法的一種高級用法(請移步“高級用法-使用共享緩存”)。
  2. 第8行,arguments代表的是上遊輸出給下遊節點的數據列表,是一個二維數組,但由於流程中限製了每個節點隻能有一個直接上遊,因此arguments的第一維長度也就固定為<=1(=0對應的情況是callback的時候無第二個參數)。第二維的長度由上遊節點callback時的參數長度決定,假設上遊callback(null, ‘a’, ‘b’),那麼arguments[0] = [‘a’,’b’]
  3. 第10行,關於callback函數的第一個參數,在“NodeJS最佳實踐”中,callback的第一個參數固定表示是否遇到錯誤,如果callback的第一個參數不為null,框架會認為程序遇到異常退出,後續流程不會再繼續流程。我們在這裏編寫代碼的時候,也請遵循這一實踐規範。
  4. 第10行,return callback(null, reclist),這裏的reclist就是本節點輸出給下遊節點的數據,對應注釋第2)條,下遊可以通過arguments[0][0]獲取。
  5. 代碼中如何獲取算法啟動參數?對於同一算法,在線SDK允許您定義不同的函數參數取值,以完成不同的操作,這部分請參見https://dtboost.aliyun.com/re#/alg/editAlg?id=29, 這個算法裏定義了一個topn參數,您可以在MAIN_ENTRY中通過topn = parseInt(topn);獲取。需要注意的是,所有算法啟動參數均以string類型傳入,由您自己決定是否需要進行類型轉換。

初級用法

下麵展示了一個對推薦列表按item_id進行去重的簡單方法

  1. function() {
  2. var callback = this;
  3. var reclist = arguments[0][0];
  4. var occupy = {}, mergedList = [];
  5. reclist.forEach(function(item) {
  6. var item_id = item.item_id === undefined ? item[0] : item.item_id;
  7. if (typeof(occupy[item_id]) === 'undefined') {
  8. occupy[item_id] = 1;
  9. mergedList.push(item);
  10. }
  11. });
  12. return callback(null, mergedList);
  13. }

這個代碼很簡單,這裏不做進一步的詳細分析。

高級用法

使用共享緩存

值得注意的是,所有您定義的函數,在執行時共享同一個this引用,舉例來說,如果您定義了一個函數A和函數B(流程中B在A之後調用),假設兩段函數分別為:

  1. function() { // 函數A
  2. this.cache_A = 'cache_A ';
  3. ...
  4. }
  1. function() { // 函數B
  2. console.log(tihs.cache_A); // 將輸出cache_A
  3. ...
  4. }

這種機製使您可以將一些下遊節點反複引用的數據緩存起來,避免重複調用相同函數造成的資源浪費。

同理,共享緩存機製可以方便您提前注冊一些您自定義的功能性函數,以下給出一個示例:

  1. function() { // 我們假設這個函數的名稱叫setup
  2. var add = function(a,b) { return a+b; }
  3. var sub = function(a,b) { return a-b; }
  4. var callback = this;
  5. this.func_add = add;
  6. this.func_sub = sub;
  7. var c = this.func_add(1,2); // c=3
  8. return callback(null, c);
  9. }

您可以在在線流程的初始節點執行該函數,那麼該節點的所有下遊節點都可以引用this.func_add和this.func_sub函數。具體來說,假設在線流程執行順序為setup->A->B,那麼A和B節點的函數體內均可調用this.func_add和this.func_sub函數。

注意:盡管提供了共享緩存機製,但不建議對所有節點都執行該操作,基於以下理由:

1)所有節點輸出都緩存在內存中,無疑會增加內存占用量。

2)對於一些結構比較簡單的節點上下遊關係,建議直接采用callback的方式傳遞數據給下遊,因為這種情況下下遊節點完全不需要關注上遊節點的實現細節,隻要采用arguments[0][0]的方式接收上遊輸出即可,否則下遊節點還需要查看上遊節點將產出緩存在了哪個變量裏。

SDK內置屬性

CTX:SDK內置變量

請求上下文變量,包含以下一些屬性:

  • REC_REQ:格式化後的API請求參數假設您的請求參數為:biz_code=biz&scn_code=scn&user_id=uid&item_id=iid&city_id=cid,那麼您得到的CTX.REC_REQ變量是一個JSON對象{biz_code:biz,scn_code:scn,user_id:uid,item_id:iid,city_id:cid},您可以通過訪問CTX.REC_REQ的各個屬性來獲得本次API請求的所有請求參數

  • REC_IS:推薦候選集,包含以下子屬性:

屬性名 屬性說明 取值類型 訪問方法
RD_UBRC 獲取以當次請求參數中的user_id作為查詢條件的推薦列表 二維數組,每一維表示一個推薦項,表示為[item_id, score],item_id表示推薦的item標示,score表示離線為該item計算得到的推薦打分。示例:[[i1,s1],…,[in,sn]] CTX.REC_IS.RD_UBRC
RD_IBRC 獲取以當次請求參數中的item_id作為查詢條件的推薦列表 同上 CTX.REC_IS.RD_IBRC
RD_UA 獲取用戶的離線資產表,即用戶最近有行為記錄的item列表 同上 CTX.REC_IS.RD_UA
RD_DFLT 獲取離線計算好的默認推薦列表。 同上 CTX.REC_IS.RD_DFLT
  • REC_UF:獲取離線計算得到的user特征向量,包含以下子屬性:
屬性名 屬性說明 取值類型 訪問方法
RD_UF user特征向量,字符串表示 string CTX.REC_UF.RD_UF
  • REC_IF:獲取離線計算得到的item特征向量,包含以下子屬性:
屬性名 屬性說明 取值類型 訪問方法
RD_IF item特征向量,字符串表示 string CTX.REC_IF.RD_IF
  • REC_MODEL:獲取離線計算得到的推薦模型,包含以下子屬性:
屬性名 屬性說明 取值類型 訪問方法
RD_MODEL 推薦模型,該數據取值類型依不同模型而定 string CTX.REC_IF.RD_IF

TOOLBOX:SDK內置方法

這部分方法以係統內置函數的形式提供,您可以通過TOOLBOX.func_name調用(func_name為具體的方法名稱)。

TOOLBOX主要包含以下一些方法:

方法名稱 方法說明 參數列表 返回參數 注意事項
getRecItemInfo 獲取item列表對應的rec_item_info表的item_info信息 CTX,即請求上下文變量
itemids:itemid數組,每一個元素對應一個item_id
與itemids元素一一對應的item_info信息 這是一個異步方法,需要使用回調形式使用,請參考https://dtboost.aliyun.com/re#/alg/editAlg?id=102
getTagReclist 獲取自定義tag(可以為城市、性別等任意可作為生成推薦結果對象,比如對分城市的推薦結果做個性化,需要離線開發相應算法在線方能獲取)的推薦列表 CTX,即請求上下文變量
tags:tag數組,每一個元素對應一個tag
與tags元素一一對應的推薦列表信息 異步方法
getTagValues 與getTagReclist同義,區別在於getTagValues獲取的結果是裸數據(即原始字符串),getTagReclist對裸數據進行了一次解析為推薦列表 同getTagReclist 與tags元素一一對應的推薦列表裸字符串,用0203分隔 異步方法
getKeyValues 獲取一組自定義鍵值 CTX,即請求上下文變量
keys:自定義鍵數組,每一個元素對應一個自定義鍵
與鍵keys一一對應的值數組 自定義鍵值的寫入需要進行離線開發並導入在線,請參考離線算法開發手冊
getValuesByDataform 獲取在線存儲中一組指定dataform的查詢key的對應值 dataform:對應離線算法的輸出類別,keys:一組查詢主鍵,類型為數組 與keys一一對應的字符串 注意事項 假設需要在線獲取物品特征向量,可以這樣用
TOOLBOX.getValuesByDataform(‘ITEM_FEATURE’, [item_id1, item_id2], function(err, features) {
if (err) return callback(err);
//features[0]是item_id1的feature,features[1]是item_id2的feature字符串
});

Tips:關於默認推薦結果,SDK不提供get方法,原因在於大部分情況下都需要有一個全局默認結果,推薦引擎從API效率角度考慮,在處理流程前一並並行獲取,隻需要您在在線流程“選擇離線數據中”勾選“RD_DFLT”即可,然後通過CTX.REC_IS.RD_DFLT獲得

Tips:如果您確實需要係統提供其他方法,請在阿裏雲工單係統中詳細描述您的需求,我們評估後會酌情進行添加。

關於require方法的使用

SDK提供了沙箱機製,您所能require到的NodeJS模塊列出如下(包括NodeJS自帶和第三方NPM包):

  • util
  • utility
  • lodash

嚐試require其他模塊將直接報錯。有關模塊的具體使用方法,請參考 https://npm.taobao.org 中的文檔。

Tips:如果您確實需要require其他模塊,請在阿裏雲工單係統中詳細描述您的需求和所要引用的模塊名稱,我們評估後會酌情進行添加。

最後更新:2016-11-23 17:31:34

  上一篇:go 離線算法開發手冊__算法規範_開發者指南_推薦引擎-阿裏雲
  下一篇:go 實時修正算法開發手冊__算法規範_開發者指南_推薦引擎-阿裏雲