我一般都是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)
我的主要方法如下:
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-MODEL-CREATED:140184763844800
1。样品
self 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。样品
self 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。样本
self 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。样本
self 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。样品
self 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]
我的问题:
为什么self_ids会发生变化,但同时有时会保持不变?我认为这是w
仍为零向量的原因。但是__init__
只被调用一次。
我对Spark有什么误解,有什么方法可以解决这个问题,以便我有一个迭代操作的全局模型?
非常感谢。
修改:将tuples.foreachRDD(model.processRDD)
更改为tuples.map(model.prequential)
没有帮助,输出类似(出现相同问题)。
答案 0 :(得分:0)
尝试在单核上运行spark。问题在于与不同的工作人员共享模型(在您的案例核心中)。
以下是您为每批产品进行分布式处理的方法:
为每个其他记录(示例/示例)广播它可能会导致大量网络流量延迟。您可以将每个批次视为样本数据(来自整个群体),并找到该数据最小的权重。然后使用该值更新模型。您可以更详细地阅读In Docker, how can I share files between containers and then save them to an image?。
您可以进一步探索here。