8

मैं हाल ही में साइकेट सीखने के प्रतिस्थापन के रूप में अपाचे स्पार्क को जानने की कोशिश कर रहा हूं, हालांकि मुझे लगता है कि सरल मामलों में भी, विज्ञान स्पार्क की तुलना में कहीं अधिक सटीक मॉडल तक पहुंच जाता है।क्या अपाचे स्पार्क साइकिट से कम सटीक है?

import sklearn 
from sklearn import linear_model 

import numpy as np 

data = [] 
target = [] 
with open("data_yequalsx.csv") as inFile: 
    for row in inFile: 
     vals = row.split(",") 
     data.append([float(x) for x in vals[:-1]]) 
     target.append(float(vals[-1])) 

test_samples= len(data)/10 

train_data = [0]*(len(data) - test_samples) 
train_target = [0]*(len(data) - test_samples) 
test_data = [0]*(test_samples) 
test_target = [0]*(test_samples) 
train_index = 0 
test_index = 0 
for j in range(len(data)): 
    if j >= test_samples: 
     train_data[train_index] = data[j] 
     train_target[train_index] = target[j] 
     train_index += 1 
    else: 
     test_data[test_index] = data[j] 
     test_target[test_index] = target[j] 
     test_index += 1 

model = linear_model.SGDRegressor(n_iter=100, learning_rate="invscaling", eta0=0.0001, power_t=0.5, penalty="l2", alpha=0.0001, loss="squared_loss") 
model.fit(train_data, train_target) 
print(model.coef_) 
print(model.intercept_) 

result = model.predict(test_data) 
mse = np.mean((result - test_target) ** 2) 
print("Mean Squared Error = %s" % str(mse)) 

और फिर:

from random import random 

def func(in_vals): 
    '''result = x (+y+z+w....)''' 
    result = 0 
    for v in in_vals: 
     result += v 
    return result 

if __name__ == "__main__": 
    entry_count = 1000 
    dim_count = 2 
    in_vals = [0]*dim_count 
    with open("data_yequalsx.csv", "w") as out_file: 
     for entry in range(entry_count): 
      for i in range(dim_count): 
       in_vals[i] = random() 
      out_val = func(in_vals) 
      out_file.write(','.join([str(x) for x in in_vals])) 
      out_file.write(",%s\n" % str(out_val)) 

मैं उसके बाद निम्न Scikit स्क्रिप्ट चलाने: उदाहरण के लिए मैं निम्नलिखित स्क्रिप्ट के साथ एक बहुत ही सरल रेखीय कार्य (z = x + y) के लिए 1000 डेटा बिंदुओं उत्पन्न इस स्पार्क स्क्रिप्ट: (साथ चिंगारी से जमा कर सकते हैं, कोई अन्य तर्कों)

from pyspark.mllib.regression import LinearRegressionWithSGD, LabeledPoint 
from pyspark import SparkContext 

sc = SparkContext (appName="mllib_simple_accuracy") 

raw_data = sc.textFile ("data_yequalsx.csv", minPartitions=10) #MinPartitions doesnt guarantee that you get that many partitions, just that you wont have fewer than that many partitions 
data = raw_data.map(lambda line: [float(x) for x in line.split (",")]).map(lambda entry: LabeledPoint (entry[-1], entry[:-1])).zipWithIndex() 
test_samples= data.count()/10 

training_data = data.filter(lambda (entry, index): index >= test_samples).map(lambda (lp,index): lp) 
test_data = data.filter(lambda (entry, index): index < test_samples).map(lambda (lp,index): lp) 

model = LinearRegressionWithSGD.train(training_data, step=0.01, iterations=100, regType="l2", regParam=0.0001, intercept=True) 
print(model._coeff) 
print(model._intercept) 

mse = (test_data.map(lambda lp: (lp.label - model.predict(lp.features))**2).reduce(lambda x,y: x+y))/test_samples; 
print("Mean Squared Error: %s" % str(mse)) 

sc.stop() 

अजीब हालांकि, चिंगारी द्वारा दिए गए त्रुटि परिमाण द्वारा दिए गए कि से बड़ा का एक आदेश है लगभग दो समान मॉडल (जहां तक ​​मैं कह सकता हूं) के बावजूद विज्ञान (0.185 और 0.045 क्रमशः) मैं समझता हूं कि यह बहुत कम पुनरावृत्तियों के साथ एसजीडी का उपयोग कर रहा है और इसलिए परिणाम भिन्न हो सकते हैं लेकिन मैंने सोचा नहीं होगा यह इतने बड़े अंतर या इतनी बड़ी त्रुटि के पास कहीं भी होगा, विशेष रूप से असाधारण सरल डेटा दिया गया है।


क्या स्पार्क में मुझे कुछ गलतफहमी है? क्या यह सही ढंग से कॉन्फ़िगर नहीं किया गया है? निश्चित रूप से मुझे उससे छोटी त्रुटि मिलनी चाहिए?

+1

का अनुकूलन मैं सुझाव है कि आप प्रयोग को दोहराते हुए त्रुटि सीमाएं प्रदान अलग-अलग यादृच्छिक बीज के साथ कई बार जांचें और जांचें कि क्या आपको एक ही परिणाम मिल रहा है; 1000 डेटा पॉइंट्स और 100 पुनरावृत्तियों बहुत कुछ नहीं हैं। इसके अलावा, स्लेलेर्न और एमएलआईबी एसजीडी के लिए एक ही सीखने की दर अनुसूची का उपयोग करते हैं? आप स्केलेर्न के लिए आक्रमण का उपयोग करते हैं लेकिन मल्टीब का उपयोग कर वही? –

उत्तर

2

क्योंकि स्पार्क समानांतर है, प्रत्येक नोड को अन्य नोड्स से स्वतंत्र रूप से काम करने में सक्षम होने की आवश्यकता होती है जब गणना नोड्स के बीच [समय-] महंगी शफल से बचने के लिए होती है। नतीजतन, यह न्यूनतम पहुंचने के लिए स्टोकास्टिक ग्रेडियेंट वंश नामक एक प्रक्रिया का उपयोग करता है, जो नीचे स्थानीय ग्रेडियेंट का पालन करता है।

[सरल, कम-वर्ग] प्रतिगमन समस्या को हल करने के 'सटीक' तरीके में मैट्रिक्स समीकरण को हल करना शामिल है। यह संभवतः विज्ञान-सीख क्या कर रहा है, इसलिए इस मामले में यह अधिक सटीक होगा।

व्यापार-बंद यह है कि मैट्रिक्स समीकरणों को हल करना आम तौर पर आकार-एन वर्ग मैट्रिक्स के लिए एन^3 के रूप में स्केल करता है, जो तेजी से बड़े डेटासेट के लिए असुरक्षित हो जाता है। कम्प्यूटेशनल पावर के लिए स्पार्क स्वैप सटीकता। किसी भी मशीन-लर्निंग प्रक्रिया के साथ, आपको यह सुनिश्चित करने के लिए अपने पिछले एल्गोरिदम में स्वच्छता जांच के बहुत सारे में निर्माण करना चाहिए कि पिछले चरण के परिणाम किसी भी समझ में आते हैं।

आशा है कि इससे मदद मिलती है!

3

एसजीडी, जो स्टोकास्टिक ग्रेडियेंट डेसेंट के लिए खड़ा है, एक ऑनलाइन उत्तल अनुकूलन एल्गोरिदम है, और इसलिए समानांतर करना बहुत मुश्किल है, क्योंकि यह प्रति पुनरावृत्ति को एक अद्यतन बनाता है (मिनी बैचों के साथ एसजीडी जैसे स्मार्ट वैरिएंट हैं, लेकिन अभी भी नहीं समानांतर पर्यावरण के लिए बहुत अच्छा है।

दूसरी ओर, बैच एल्गोरिदम, जैसे कि एल-बीएफजीएस, हैविच मैं आपको स्पार्क (लॉजिजिस्टिक रेग्रेशन विथलबीएफजीएस) के साथ उपयोग करने की सलाह देता हूं, आसानी से समांतर किया जा सकता है, क्योंकि यह प्रति युग (सभी डेटापॉइंट्स देखने की आवश्यकता है, प्रत्येक बिंदु के हानि फ़ंक्शन के मान और ढाल की गणना करें, फिर पूर्ण ढाल की गणना करने के लिए एकत्रीकरण निष्पादित करें)

पायथन एक मशीन में भाग गया है, इसलिए एसजीडी अच्छी तरह से प्रदर्शन करता है।

वैसे, अगर आप MLlib कोड में देखो, scikit के बराबर जानने के लैम्ब्डा डेटासेट के लैम्ब्डा/आकार (mllib 1/n*sum(l_i(x_i,f(y_i)) + lambda का अनुकूलन जबकि scikit जानने sum(l_i(x_i,f(y_i)) + lambda

संबंधित मुद्दे