譯者介紹:張冬洪,Redis中國用戶組主席
剛剛結束的RedisConf2017大會,在國外是比較大型的Redis盛會了,而且已經舉辦多年,每次都會在全球邀請業界知名公司的技術大咖分享他們在企業應用中的典型案例和踩過的坑,以及他們正在積極探索的新的技術實現或擴展。
今年就有許多好玩的新玩意比較吸引我,比如Redisearch、Redis-ML和Amazon ElastiCache for Redis等。我們都知道,如今CI/CD和AI非常火爆,前段時間亞馬遜發表了一篇關於用機器學習自動優化數據庫的博客轟動一時(詳情戳此看社群文章《DBA要失業了?看ML如何自動優化數據庫》),我們感嘆的不僅僅是DBA要失業(joke),還是技術更新太快,日新月異。那麼在Redis領域是否也能用機器學習來幫助做一些更高級的事情呢?答案不言而喻,是肯定的。在本次大會上來自Redislabs的Shay Nativ大神就分享了“用Redis-ML模塊來實現實時機器學習”的案例, 主要內容如下:
Redis主要區別
(1)高性能
(2)簡單-多種數據結構
(3)可擴展-Redis Modules
Redis主要的數據結構概括
Redis Modules:一種革命的方式
任何C/C++程序現在都可以運行在Redis上
Modules是用一種本地的方式來擴展Redis的新用例和功能
使用現有的或者添加新的數據結構
享受簡單,無限可擴展性和高可用性的同時保持著redis的本機的速度
可以由任何人創建
Adapt your database to your data, not the other way around
Redis-ML:機器學習模型服務器
(1)機器學習的世界
(2)傳統的基於Spark-ML機器學習的生命週期
(3)基於ML模型的服務挑戰
ML變得非常流行,但是Models卻變得很大,很複雜
需要以更快的速度去分發/部署它們
速度和大小方面不能很好的擴展,需要保持他們在集群中的一致性以及使得他們持久化
可靠的服務很難做到 – 需要確保服務的可靠性
比較昂貴 – 需要投入更多的硬件資源和人力成本
一個簡單的基於Redis-ML的機器學習生命週期
Redis-ML:ML服務引擎
以“熱模式”存儲機器訓練輸出
直接在Redis中進行評估
輕鬆整合現有的C/C++ ML lib庫
可以在運行過程中進行調整
享有Redis的高性能,可擴展性和HA
ML Modules
隨機森林模型
一個決策樹集合
支持分類和迴歸
分離節點
按類別(例如:day == “sunday”)
按數值(例如:age < 43)
決策是由大多數決策樹所決定的
Gini impurity:基尼不純度準則
【充電】在實際訓練中, 需要根據不同的需求選擇適當的損失函數是必須的,損失函數的形式即是我們選擇最優分支函數的優化目標。損失函數形式設定分為兩類:分類樹損失函數和迴歸樹損失函數,其中分類樹損失函數又分為4種準測:基尼不純度準則、信息熵準則、對數價值準則和經過Kass調整的對數價值準則;迴歸樹損失函數分為方差的最大似然估計準則、絕對偏差準則和分支規則的F檢驗準則。
公式
按其定義式所表達的,它的含義是“任意取兩個觀測其屬於不同類的概率”。
在分支時的基尼不純度公式改進為:
分別為當前節點與其分支節點的觀測數;基尼不純度改進越大,說明分支後各個子節點任取兩個觀測數與不同類的概率越低。
在一個決策樹上的泰坦尼克號的生存預測
在一個隨機森林上的泰坦尼克號的生存預測
舉一個例子:John的特徵是:
{male, 34, married + 2, US, CA, 1.78m, 78kg, 110iq, blue eyes}
那麼根據上面的隨機森林的計算,John會生存下來嗎?
Tree#1 - Survived
Tree#2 - Died
Tree#3 - Survived
結果:根據隨機森林決策是Survived。
真實世界的挑戰
廣告服務的公司需要在數據中心50ms的延遲的條件下完成每秒20000次廣告服務。運行1000次活動需要1000個隨機森林,每一個森林有15000棵決策樹,平均每一棵樹的深度有7層。可以想象計算量是很龐大的。針對這個案例,廣告模型服務在基於Homegrown和Redis-ML的機器學習計算中的比較:
真實世界的一個案例:電影推薦系統
(1)概述
(2)用到的工具集
(3)Docker中運行Redis-ML 和spark-redis-ml
# docker pull shaynativ/redis-ml
# docker run --net=host shaynativ/redis-ml
# docker pull shaynativ/spark-redis-ml
# docker run --net=host shaynativ/spark-redis-ml
(4)一棵森林對應一個電影
數據處理的過程分為以下幾步:
(1)獲取數據
下載和提取數據:MovieLens 100K Dataset,數據內容格式大致如下:
Ratings: user id | item id | rating (1-5) | timestamp
Item (movie) info: movie id | genre info fields (1/0)
User info: user id | age | gender | occupation
我們的分類器應該返回用戶給出的一個考慮之中的電影的期望等級(從1到5)。
(2)轉換格式
對每部電影的訓練數據應該包含每個用戶一行數據,如:
class (rating from 1 to 5 the user gave to this movie)
user info (age, gender, occupation)
user ratings of other movies (movie_id:rating ...)
user genre rating averages (genre:avg_score ...)
運行gen_data.py來轉換文件所需要的格式。
(3)訓練和加載數據到Redis中
// Create a new forest instance
val rf = new
RandomForestClassifier().setFeatureSubsetStrategy("auto").setLabelCol("indexedLabel").setFeaturesCol("indexedFeatures").setNumTrees(500)
…..
// Train model
val model = pipeline.fit(trainingData)
…..
val rfModel =
model.stages(2).asInstanceOf[RandomForestClassificationModel]
// Load the model to redis
val f = new Forest(rfModel.trees)
f.loadToRedis(”movie-10", "127.0.0.1")
(4)在Redis中執行運算
Python例子:
>> import redis
>> config = {"host":"localhost", "port":6379}
>> r = redis.StrictRedis(**config)
>> user_profile = r.get("user_shay_profile")
>> print(user_profile)
12:1.0,13:1.0,14:3.0,15:1.0,17:1.0,18:1.0,19:1.0,20:1.0,23:1.0,24:5.0,1.0,115:1.0,116:2.0,117:2.0,119:1.0,120:4.0,121:2.0,122:2.0,
........
1360:1.0,1361:1.0,1362:1.0, 1701:6.0,1799:435.0,1801:0.2,1802:0.11,1803:0.04,1812:0.04,1813:0.07,1814:0.24,1815:0.09,1816:0.32,1817:0.06
>> r.execute_command("ML.FOREST.RUN", "movie-10", user_profile)
'3'
Redis cli例子:
>> KEYS *
1) "movie-5"
2) "movie-1"
........
8) "movie-6"
9) "movie-4"
10) "movie-10"
11) "user_1_profile”
>> ML.FOREST.RUN movie-10
12:1.0,13:1.0,,332:3.0,333:1.0,334:1.0,335:2.0,336:1.0,357:2.0,358:1.0,359:1.0,362:1.0,367:1.0,368:3.0,369:2.0,404:4.0,405:1.0,406:2.0,407:1.0,408:1.0,409:1.0
........
,410:3.0,411:2.0,412:2.0,423:1.0,454:1.0,455:1.0,456:1.0,457:3.0,458:1.0,459:1.0,470:1”
"3”
性能
Redis time: 0.635129ms, res=3
Spark time: 46.657662ms, res=3.0
---------------------------------------
Redis time: 0.644444ms, res=3
Spark time: 49.028983ms, res=3.0
---------------------------------------
Classification averages:
redis: 0.9401250000000001 ms
spark: 58.01970206666667 ms
ratio: 61.71488053893542
diffs: 0.0
獲取實際的推薦的完整腳本classify_user.py
總結
參考資料:
Redis-ML:
https://github.com/RedisLabsModules/redis-ml
Spark-Redis-ML:
https://github.com/RedisLabs/spark-redis-ml
Databricks Notebook:
http://bit.ly/sparkredisml
Dockers:
https://hub.docker.com/r/shaynativ/redis-ml/
https://hub.docker.com/r/shaynativ/spark-redis-ml/
決策樹:
http://wiki.swarma.net/index.php/%E5%86%B3%E7%AD%96%E6%A0%91#.E5.9F.BA.E5.B0.BC.E4.B8.8D.E7.BA.AF.E5.BA.A6.28Gini_impurity.29.E5.87.86.E5.88.99
作者:redislabs Shay Nativ
原文:https://www.slideshare.net/RedisLabs/redisconf17-redis-labs-implementing-realtime-machine-learning-with-redisml
End.
來源:公眾號“DBAplus社群”
運行人員:中國統計網小編(微信號:itongjilove)
微博ID:中國統計網
中國統計網,是國內最早的大數據學習網站,公眾號:中國統計網
http://www.itongji.cn