簡體   English   中英

Spark Streaming:如何實現自定義流算法?

[英]Spark Streaming: How to implement a custom streaming algorithm?

我通常是Spark的新手,所以我想測試一下Spark Streaming的某些功能,這對於另一個更大的項目可能是必需的。

我的玩具問題是我想處理流並學習帶有隨機梯度下降的線性回歸(我知道已經提供了StreamingLinearRegression,但是我想自己實現):

class OnlineLinearRegression:
    def __init__(self, eta=0.1, nr_features=8):
        self.w = np.zeros(nr_features)
        self.nr_features = nr_features
        self.eta = eta

    def evaluate(self, x):
        return np.dot(self.w, x)

    def loss(self, pred, true_value):
        loss = (pred-true_value)*(pred-true_value)
        return loss

    def update_model(self, x, pred, y):
        bef_update = self.w
        self.w = self.w - self.eta * (pred - y) * np.array(x)
        print "=========================="
        print "UPDATE MODEL"
        print "self id " + str(id(self))
        print "w_before_update " + str(bef_update)
        print "w_after_update " + str(self.w)
        print "=========================="

    def prequential(self, e):
        y_hat = self.evaluate(e[0])
        ell = self.loss(y_hat, e[1])
        self.update_model(e[0], y_hat, e[1])
        return ell

    def processRDD(self, time, RDD):
        RDD.foreach(self.prequential)

我的Main方法如下所示:

if __name__ == "__main__":
    model = OnlineLinearRegression(eta=0.1,nr_features=8)
    print "ID-MODEL-CREATED: " + str(id(model))

    sc = SparkContext("local[*]", "Test Scenario")
    ssc = StreamingContext(sc, 0.5)

    text = ssc.socketTextStream("localhost", 9997)
    tuples = text.map(parser)
    tuples.foreachRDD(model.processRDD)

    ssc.start()
    ssc.awaitTermination() 

每秒生成一次數據,Spark Streaming的間隔為一秒(因此,僅處理一個樣本/批次)。 這是OnlineLinearRegression update_model函數中生成的一些輸出:

一旦開始:

ID模型創建:140184763844800

1.樣品

  • 自我ID 140411103203200

  • w_before_update [0. 0. 0. 0. 0. 0. 0. 0.]

  • w_after_update [0. 0.6825 0.5475 0.1425 0.771 0.33675 ​​0.1515 0.225]

2.樣品

  • 自我ID 140411106740920

  • w_before_update [0. 0. 0. 0. 0. 0. 0. 0.]

  • w_after_update [0. 0.245 0.1855 0.063 0.15785 0.06965 0.03395 0.049]

3.樣品

  • 自我ID 140411106740704

  • w_before_update [0. 0. 0. 0. 0. 0. 0. 0.]

  • w_after_update [1.8 0.477 0.378 0.1215 0.6093 0.23085 0.12735 0.189]

4.樣品

  • 自我ID 140411106738904

  • w_before_update [0. 0. 0. 0. 0. 0. 0. 0.]

  • w_after_update [0. 0.44 0.365 0.125 0.516 0.2155 0.114 0.155]

5.樣品

  • 自我ID 140411106738904(注釋:與4中相同的ID,但w仍然沒有改變)

  • w_before_update [0. 0. 0. 0. 0. 0. 0. 0.]

  • w_after_update [0.7 0.231 0.1785 0.056 0.1435 0.06265 0.02765 0.0385]

我的問題:

  1. 為什么self_ids會更改,但有時卻保持不變? 我將其識別為w仍為零向量的原因。 但是__init__僅被調用一次。

  2. 我對Spark的誤解是什么?有什么可能以某種方式修復它,以使我擁有可以迭代操縱的全局模型?

非常感謝。

編輯:tuples.foreachRDD(model.processRDD)更改為tuples.map(model.prequential)並沒有幫助,輸出是相似的(具有相同的問題)。

嘗試在單核上運行spark。 問題在於與不同工作人員(在您的情況下為核心)共享模型。

這是您可以為每個批次進行分布式處理的方法:

  • 使模型成為廣播變量。
  • 取消持續(blocking = true)每次更新。
  • 轉播它。

廣播其他每條記錄(示例/示例)可能會導致大量網絡流量延遲。 您可以將每一批都當作樣本數據(來自總體),並找到對該數據最小的權重。 然后使用該值更新模型。 您可以在此處詳細閱讀。

您可以在這里進一步探索。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM