本文檔適用人員:研發
在語義的世界裏,可以近似地說:萬事萬物都是特徵提取。 你只要找到特徵,事情就好辦。…………你期望畢其功於一役嗎?自然語言處理的真實應用裏是很難有什麼場景找到一個通吃特徵的。都是一層一層特徵疊加的。一層特徵去掉一部分垃圾數據。如此反覆,終成正果。注意方法論。
統計粗且糙,乃大錘。規則細而精,乃小錘。先大場後細棋。
- 推薦位展示次數、商品投放次數;
- 推薦位展示點擊率、商品投放點擊率;
- 最重要的是下單轉化率和成單轉化率(或叫支付轉化率)這兩個硬指標。
- 實時(至少是近乎實時)統計幾個展示性指標
- 區分網站端和移動客戶端的推薦展示效果
- 進一步區分不同客戶端,如 iOS 和 Android
- 圖
- 圖
- 看了又看
- 瀏覽過該商品的用戶購買了
- 您可能對以下商品感興趣(猜你喜歡)
- 商品周邊商品(注:只能是本地生活服務類商品)
- 簽到彈窗推薦
- 商品附近門店
- 門店周邊美食
- 附近吃喝玩樂
- 圖
- ……
- 離線試驗:
- 做法:從日誌系統中取得用戶的行爲數據,然後將數據集分成訓練數據和測試數據,比如80%的訓練數據和20%的測試數據(還可以交叉驗證),然後在訓練數據集上訓練用戶的興趣模型,在測試集上進行測試
- 優點:它不需要實際用戶的交互
- 缺點:離線實驗只能評測一個很狹窄的數據集切面,主要是關於算法預測或者評估的準確性
- 目的:提前過濾掉性能較差的算法
- 做法:通過一定的規則把用戶隨機分成幾組,並對不同組的用戶採用不同的推薦算法,這樣的話能夠比較公平地獲得不同算法在實際在線時的一些性能指標
- 圖
- 暴露出來,讓我們手工就可以提交,看看效果
- 數據上報:——Piwik
- 主站本身部署了 開源流量統計系統 Piwik,所以在網頁的各種推薦位上按規則埋點即可
- 實例:“瀏覽過該商品的用戶還購買了”推薦欄第一位商品的a元素增加了wwe屬性:wwe="t:goods,w:rec,id:ae45c145d1045c9d51c270c066018685,rec:101_01_103"
- Piwik 集羣的每一臺服務器上都部署了 Flume Agent
- agent 會向 推薦數據收集 Flume 集羣 推送日誌,譬如配置爲每增加一行日誌就推送,或每5分鐘推送一次
- 手機客戶端的埋點日誌則存放在無線服務器端的 MySQL 中,所以我們用腳本每分鐘讀取一次數據,放到 flume 的監控目錄下
- 由於數據採集速度和數據處理速度不一定匹配,因此添加一個消息中間件 Linkedin Kafka 作爲緩衝
- 數據流轉方式爲 Flume Source-->Flume Channel-->Flume Sink,那麼我們寫一個 Kafka Sink 作爲消息生產者,將 sink 從 channel 裏接收到的日誌數據發送給消息消費者
- 圖
- Storm 負責對採集到的數據進行實時計算
- Storm Spout 負責從外部系統不間斷地讀取數據,並組裝成 tuple 發射出去,tuple 被髮射後在 Topology 中傳播
- 所以我們要寫一個 Kafka Spout 作爲消息消費者拉日誌數據
- 再寫些 Storm Bolt 處理數據
- ,一個Topology的結構示意圖
- Storm Bolt 實時分析數據之後,將統計結果寫入 Redis
- 評測系統實時數據直接從 Redis 中讀取,並查詢主站數據庫追蹤成單情況,同步到 MySQL 中,作爲報表展示數據源
- piwik javascript
- piwik servers
- flume agent
- 自定義 kafka sink
- 自定義 kafka spout
- 自定義 storm bolt
- redis
- 評測系統計算
- mysql
- 評測系統報表展示
- 如 果配置爲每新增一條日誌就採集,那麼 flume 到 kafka 的實時數據可能會由於單條過快,造成 storm spout 消費 kafka 消息速率跟不上。延時可以是數據發射到 stream 中後進行 hbase 的計算操作引起的(注:hbase 的性能確實堪憂,不適合這種實時數據處理,尤其是加了較多索引之後);
- 可參考的一個數據:storm 單條流水線的處理能力大約爲 20000 tupe/s (每個tuple大小爲1000字節);
- tuple 過多,會由於 kafka 的 message 需要 new String() 進行獲取,會報 gc 的異常;
- tuple 在 stream 中的大量堆積,造成超時自動回調 fail() 的函數;
- 可以進行多 tuple 結構的優化,把多個 log 打包成一個 tuple
- 就一般情況而言,單條發射能扛得住
KafkaSink.java
|
import kafka.javaapi.producer.Producer;
……
public class KafkaSink extends AbstractSink implements Configurable {
……
private Producer<String, byte[]> producer;
……
@Override
public Status process() throws EventDeliveryException {
Channel channel = getChannel();
Transaction tx = channel.getTransaction();
try {
tx.begin();
Event e = channel.take();
if (e == null) {
tx.rollback();
return Status.BACKOFF;
}
producer.send(new KeyedMessage<String, byte[]>(topic, e.getBody()));
tx.commit();
return Status.READY;
} catch (Exception e) {
|
KafkaSpout.java
|
public abstract class KafkaSpout implements IRichSpout {
……
@Override
public void activate() {
……
for (final KafkaStream<byte[], byte[]> stream : streamList) {
executor.submit(new Runnable() {
@Override
public void run() {
ConsumerIterator<byte[], byte[]> iterator = stream.iterator();
while (iterator.hasNext()) {
if (spoutPending.get() <= 0) {
sleep(1000);
continue;
}
MessageAndMetadata<byte[], byte[]> next = iterator.next();
byte[] message = next.message();
List<Object> tuple = null;
try {
tuple = generateTuple(message);
} catch (Exception e) {
e.printStackTrace();
}
if (tuple == null || tuple.size() != outputFieldsLength) {
continue;
}
collector.emit(tuple);
spoutPending.decrementAndGet();
}
}
|
EvaluateBolt.java
|
public class EvaluateBolt extends BaseBasicBolt {
……
@Override
public void execute(Tuple input, BasicOutputCollector collector) {
……
if (LogWebsiteSpout.PAGE_EVENT_BROWSE.equals(event)) {
if (LogWebsiteSpout.PAGE_TYPE_GOODS.equals(pageType)) {
incrBaseStatistics(baseKeyMap, BROWSE_ALL, 1);
} else if (LogWebsiteSpout.PAGE_TYPE_PAY1.equals(pageType)) {
incrBaseStatistics(baseKeyMap, ORDER_ALL, 1);
}
String recDisplay = input.getStringByField(LogWebsiteSpout.FIELD_REC_DISPLAY);
recDisplayStatistics(recDisplay, time, pageType, baseKeyMap);
} else if (LogWebsiteSpout.PAGE_EVENT_CLICK.equals(event)) {
String recType = input.getStringByField(LogWebsiteSpout.FIELD_REC_TYPE);
|
- 投放點擊率:推薦瀏覽量/推薦商品投放量
- 展現點擊率:推薦瀏覽量/推薦位展現次數
- 推薦展示率::推薦位展示次數/總瀏覽量
- 推薦瀏覽量:經由推薦產生的瀏覽量
- 推薦商品投放量:推薦位投放的推薦商品數量(如:用戶瀏覽A商品,那在瀏覽或購買推薦位產生的推薦商品爲5個,則推薦商品投放量+5)
- 推薦位展現次數:如果推薦位有推薦商品並展示,計數+1