क्यों बड़ा डेटा कार्यात्मक होने की आवश्यकता है?


9

मैंने अपनी इंटर्नशिप के लिए बिग डेटा से संबंधित एक नई परियोजना पर काम करना शुरू कर दिया है। मेरे प्रबंधकों ने कार्यात्मक प्रोग्रामिंग सीखना शुरू करने की सिफारिश की (वे अत्यधिक अनुशंसित स्काला)। मुझे F # का उपयोग करने का एक विनम्र अनुभव था, लेकिन मैं प्रोग्रामिंग के इस प्रतिमान का उपयोग करने के लिए महत्वपूर्ण नहीं देख सका क्योंकि यह कुछ मामलों में महंगा है।

डीन ने इस विषय पर एक दिलचस्प बात कही, और यहाँ "बिग डेटा" पर अपने विचार साझा किए: http://www.youtube.com/watch?v=DFAdLCqDbLQ लेकिन यह बहुत सुविधाजनक नहीं था क्योंकि बिग डेटा का मतलब यह नहीं है केवल Hadoop।

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

फैंसी उपकरणों से दूर, मैंने तीन दृष्टिकोणों का उपयोग करके एक विशिष्ट और लोकप्रिय समस्या के लिए एक समाधान बनाने की कोशिश की: इंपीरियल तरीका और कार्यात्मक तरीका (पुनरावृत्ति, संग्रह का उपयोग करके)। मैंने तीन दृष्टिकोणों के बीच तुलना करने के लिए समय और जटिलता की तुलना की।

मैंने इन कार्यों को लिखने के लिए स्काला का उपयोग किया क्योंकि यह तीन प्रतिमानों का उपयोग करके एल्गोरिथ्म लिखने का सबसे अच्छा उपकरण है

def main(args: Array[String]) {
    val start = System.currentTimeMillis()
    // Fibonacci_P
    val s = Fibonacci_P(400000000)
    val end = System.currentTimeMillis()
    println("Functional way: \n the Fibonacci sequence whose values do not exceed four million : %d \n Time : %d ".format(s, end - start))
    val start2 = System.currentTimeMillis()

    // Fibonacci_I
    val s2 = Fibonacci_I(40000000 0)
    val end2 = System.currentTimeMillis();
    println("Imperative way: \n the Fibonacci sequence whose values do not exceed four million : %d \n Time : %d ".format(s2, end2 - start2))
}

कार्यात्मक तरीका:

def Fibonacci_P(max: BigInt): BigInt = {
    //http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Stream
    //lazy val Fibonaccis: Stream[Long] = 0 #:: 1 #:: Fibonaccis.zip(Fibonaccis.tail).map { case (a, b) => a + b }
    lazy val fibs: Stream[BigInt] = BigInt(0)#::BigInt(1)#::fibs.zip(fibs.tail).map {
        n = > n._1 + n._2
    }
    // println(fibs.takeWhile(p => p < max).toList)
    fibs.takeWhile(p = > p < max).foldLeft(BigInt(0))(_ + _)
}

पुनरावर्ती तरीका:

def Fibonacci_R(n: Int): BigInt = n match {
    case 1 | 2 = > 1
    case _ = > Fibonacci_R(n - 1) + Fibonacci_R(n - 2)
}

शाही तरीका:

def Fibonacci_I(max: BigInt): BigInt = {
    var first_element: BigInt = 0
    var second_element: BigInt = 1
    var sum: BigInt = 0

    while (second_element < max) {
        sum += second_element

        second_element = first_element + second_element
        first_element = second_element - first_element
    }

    //Return 
    sum
}

मैंने देखा कि कार्यात्मक प्रोग्रामिंग भारी है! इसमें अधिक समय लगता है और मेमोरी में अधिक जगह की खपत होती है। मैं भ्रमित हूं, जब भी मैं एक लेख पढ़ता हूं या एक बात देखता हूं, तो वे कहते हैं कि हमें डेटा विज्ञान में कार्यात्मक प्रोग्रामिंग का उपयोग करना चाहिए। सच है, यह आसान और अधिक उत्पादक है, विशेष रूप से डेटा की दुनिया में। लेकिन इसमें अधिक समय और अधिक मेमोरी स्पेस लगता है।

तो, हमें बिग डेटा में फ़ंक्शनल प्रोग्रामिंग का उपयोग करने की आवश्यकता क्यों है? बिग डेटा के लिए कार्यात्मक प्रोग्रामिंग (स्काला) का उपयोग करने के लिए सबसे अच्छे अभ्यास क्या हैं?


5
फ़ंक्शनल प्रोग्रामिंग से आपके कोड को समानांतर करना आसान हो जाता है, इसलिए भले ही एक ही ऑपरेशन को एक थ्रेड में चलाने में अधिक समय लग सकता है, लेकिन समग्र प्रदर्शन समानांतरता के कारण बेहतर हो सकता है।
जियोर्जियो

@ जियोर्जियो: समानता के लिए सर्वश्रेष्ठ प्रदर्शन प्राप्त करने के लिए अभिनेता मॉडलिंग के रूप में अलग-अलग प्रतिमान हैं। ऐसा नहीं लगता?
user3047512

2
मैं इसका केवल अनुमान लगाता हूं क्योंकि हडूप से नक्शा / कम दृष्टिकोण कार्यात्मक प्रोग्रामिंग से एक विचार है।
डॉक ब्राउन

1
@ user3047512: उदाहरण के लिए, एर्लैंग अभिनेता मॉडल का उपयोग करता है और सबसे अधिक कार्यात्मक है।
जियोर्जियो

2
"बिग डेटा" सनक और एफपी के बीच का संबंध इतना सीधा नहीं है। "बिग डेटा" में, तथाकथित मैप-कम दृष्टिकोण फैशनेबल है, जो बदले में कार्यात्मक प्रोग्रामिंग लोकाचार से कुछ हद तक प्रेरित था। यह वह जगह है जहाँ समानता समाप्त होती है, मैं इन दोनों दुनिया के बीच कोई और संबंध नहीं देख सकता।
एसके-तर्क

जवाबों:


13

यहाँ मैं इसे कैसे देख रहा हूँ:

  • आइए कुछ समय के लिए "बड़े डेटा" शब्दों को अनदेखा करें, क्योंकि वे एक सुंदर अस्पष्ट धारणा हैं

  • आपने हडोप का उल्लेख किया। Hadoop 2 चीजें करता है: आपको एक प्रकार की "वर्चुअल" ड्राइव की अनुमति देता है, जिसे कई मशीनों पर वितरित किया जाता है, अतिरेक के साथ, जिसे Hadoop के API के माध्यम से एक्सेस किया जा सकता है जैसे कि यह एक एकल, एकात्मक, ड्राइव है। इसे HFSop डिस्ट्रीब्यूटेड फाइल सिस्टम के रूप में HDFS कहा जाता है । Hadoop की दूसरी बात आपको मैप-रिड्यूस जॉब्स को निष्पादित करने की अनुमति देती है (यह मैप-रिड्यूस के लिए एक फ्रेमवर्क है)। यदि हम MapReduce का विकिपीडिया पृष्ठ देखें, तो हम देखते हैं कि:

MapReduce एक प्रोग्रामिंग मॉडल है जो एक क्लस्टर पर समानांतर, वितरित एल्गोरिदम के साथ बड़े डेटा सेट को संसाधित करता है।

...

MapReduce प्रोग्राम एक मैप () प्रक्रिया से बना होता है, जो फ़िल्टरिंग और सॉर्टिंग (जैसे छात्रों को पहले नाम से कतारों में क्रमबद्ध करना, प्रत्येक नाम के लिए एक कतार) और एक Reduce () प्रक्रिया करता है जो सारांश ऑपरेशन करता है (जैसे कि संख्या गिनना। प्रत्येक कतार में छात्रों के नाम आवृत्तियों की पैदावार)

...

'MapReduce' बड़ी संख्या में कंप्यूटरों का उपयोग करके विशाल डेटासेट में समांतर समस्याओं को संसाधित करने के लिए एक रूपरेखा है

इस पृष्ठ पर भी, Hadoop के रूप में वर्णित है

Hadoop, Apache का मुफ्त और खुला स्रोत कार्यान्वयन MapReduce।

अब, Hadoop जावा में लिखा गया है, जो एक कार्यात्मक भाषा नहीं है। इसके अलावा, अगर हम Hadoop के पेज को देखते हैं, तो हम जावा में MapReduce की नौकरी कैसे बनाते हैं और इसे Hadoop क्लस्टर में कैसे तैनात करते हैं, इसका एक उदाहरण भी मिलता है ।

यहाँ Hadoop के लिए एक Fibonnaci MapReduce जॉब का जावा उदाहरण है।

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

निश्चित रूप से इसका मतलब यह नहीं है कि बिगडेटा को "ओओ-ओनली" होना चाहिए। आप बहुत अच्छी तरह से नौकरी की तरह एक MapReduce को लागू करने के लिए एक कार्यात्मक भाषा का उपयोग कर सकते हैं। उदाहरण के लिए, यदि आप चाहते हैं, तो स्कैड का उपयोग Hadoop के साथ करें, यदि आप स्केलिंग के माध्यम से करना चाहते हैं ।

मेरे विचार से अन्य बिंदु ध्यान देने योग्य हैं।

स्काला में पुनरावृत्ति करते समय, यदि आपका कोड इसके लिए अनुमति देता है, तो स्काला टेल-कॉल-ऑप्टिमाइज़ेशन करेगा । हालाँकि, चूंकि JVM टेल-कॉल-ऑप्टिमाइज़ेशन का समर्थन नहीं करता है , इसलिए स्केला ने इसे प्रतिस्थापित करके, संकलन समय पर, आपके पुनरावर्ती कॉल को लूप के बराबर कोड के साथ प्राप्त किया, जैसा कि यहां बताया गया है । मूल रूप से इसका मतलब यह है कि स्कैला का उपयोग करके पुनरावर्ती बनाम गैर-पुनरावर्ती कोड बेंचमार्क करना व्यर्थ है, क्योंकि वे दोनों एक ही समय में एक ही काम कर रहे हैं।


2
आप जेवीएम के बारे में एक उत्कृष्ट बिंदु बनाते हैं जो टेल कॉल ऑप्टिमाइज़ेशन का समर्थन नहीं करता है जो ओपी द्वारा प्रस्तावित बेंचमार्क को कमजोर करता है। यह बहुत जानकारीपूर्ण उत्तर है, धन्यवाद।
maple_shaft

1
आपके उत्तर के लिए धन्यवाद, हाँ! टेल-कॉल-ऑप्टिमाइज़ेशन छिपे हुए स्कैला सुविधाओं में से एक है। stackoverflow.com/questions/1025181/hidden-features-of-scala/… । "बिग डेटा" की समस्याओं में से एक यह है कि हर कंपनी अलग-अलग तरीके से एक नई तकनीक बनाने की कोशिश कर रही है। लेकिन मुख्य रूप से दो हैं: Hadoop तकनीक और अन्य। जैसा कि आपने कहा, यह व्यक्तिपरक है और यह स्वयं की समस्याओं से संबंधित है, हमें अपनी विशेषज्ञता के आधार पर सही प्रोग्रामिंग प्रतिमान चुनना चाहिए। उदाहरण के लिए: रियल-टाइम प्रेडिक्टिव मॉडल Hadoop प्लेटफार्मों पर बहुत अच्छी तरह से काम नहीं करता है।
user3047512

9

जब तक आप इसे एक मशीन पर चला सकते हैं, यह "बिग डेटा" नहीं है। आपके उदाहरण की समस्या इसके बारे में कुछ भी प्रदर्शित करने के लिए पूरी तरह से अनुचित है।

बिग डेटा का मतलब है कि समस्या के आकार इतने बड़े हैं कि प्रोसेसिंग को वितरित करना एक अनुकूलन नहीं बल्कि एक मूलभूत आवश्यकता है। और कार्यात्मक प्रोग्रामिंग अपरिवर्तनीय डेटा संरचनाओं और स्टेटलेसनेस के कारण सही और कुशल वितरित कोड लिखना बहुत आसान बनाता है।


"बिग डेटा का मतलब है कि समस्या के आकार इतने बड़े हैं कि प्रसंस्करण का वितरण एक अनुकूलन नहीं है बल्कि एक मूलभूत आवश्यकता है।" - मुझे समझ में नहीं आ रहा है कि एक मशीन का उपयोग करके सभी को किस तरह की समस्या का समाधान नहीं किया जा सकता है, और इसके लिए कम से कम एन की आवश्यकता होती है जहां एन> 1 ...
शिवन ड्रैगन

6
@ शिवनड्रगन: एक तरह की समस्या जिसमें प्रदर्शन आवश्यकताएं शामिल होती हैं जो किसी एक प्रणाली पर संतुष्ट करने के लिए पूरी तरह से असंभव हैं। या जहां डेटा का आकार इतना बड़ा है कि कोई एकल प्रणाली भी इसे संग्रहीत नहीं कर सकती है।
माइकल बोर्गवर्ड

मुझे क्षमा करें, मैं अब आपकी बात देखता हूं। क्या यह कहना सही है कि आप जिस चीज़ का जिक्र कर रहे हैं, वह और अधिक विशेष रूप से, MapReduce है जो बिगडाटा की छतरी के नीचे रहता है?
शिवन ड्रैगन

आपके इनपुट के लिए धन्यवाद, मैं सहमत हूं। शायद मुझे अपनी बात प्रदर्शित करने के लिए एक अच्छा सरल उदाहरण नहीं मिला। "बिग डेटा" अभी भी एक तरीका है जो डेवलपर्स 3Vs परिभाषा को ध्यान में रखते हुए हमारी दैनिक समस्याओं को हल करने के लिए डेटा का उपयोग करते हैं। मैं थोड़ी देर के लिए 3V को भूल जाऊंगा और डेटा के साथ काम करते हुए बहुत ही सरल पहलू के बारे में बात करूंगा। यदि हम देखते हैं कि कार्यात्मक तरीके से डेटा का विश्लेषण करना महंगा है, तो हम क्यों कहते हैं कि "बिग डेटा" को कार्यात्मक होने की आवश्यकता है? यह मेरी बात है।
user3047512

4
@ ShivanDragon, उदाहरण के लिए, LHC प्रति सेकंड कई गीगाबाइट डेटा का उत्पादन कर रहा है । यकीन नहीं है कि एक मशीन भी ऐसे थ्रूपुट को संभाल सकती है।
एसके-लॉजिक

4

मुझे स्काला का पता नहीं है और इसलिए मैं आपके कार्यात्मक दृष्टिकोण पर टिप्पणी नहीं कर सकता, लेकिन आपका कोड ओवरकिल जैसा लगता है।

दूसरी ओर आपका पुनरावर्ती कार्य अक्षम है। क्योंकि फ़ंक्शन स्वयं को दो बार कॉल करता है, यह क्रम 2 ^ n का है, जो अत्यधिक अक्षम है। यदि आप तीन दृष्टिकोणों की तुलना करना चाहते हैं, तो आपको तीन इष्टतम कार्यान्वयनों की तुलना करने की आवश्यकता है।

फिबोनाची फ़ंक्शन को केवल एक बार फ़ंक्शन को कॉल करने के साथ पुनरावर्ती रूप से लागू किया जा सकता है। आइए एक अधिक सामान्यीकृत परिभाषा लें:

F(0) = f0
F(1) = f1
F(n) = F(n-1) + F(n-2)

मानक विशेष मामला है:

f0 = 0
f1 = 1

सामान्य पुनरावर्ती कार्य है:

function fibonacci($f0, $f1, $n){
    if($n < 0 || !isInt($n)) return false;
    if($n = 0) return $f0;
    if($n = 1) return $f1;
    return fibonacci($f1, $f0 + $f1, $n - 1);
}

धन्यवाद! आपने एक अच्छा बिंदु उठाया, लेकिन इसे पुनरावृत्त तरीके से करने का कोई कुशल तरीका नहीं है। यह एक बहुत ही सामान्य संभावना है (फाइबोनैचि सूट)। और यह तीन तरीकों का उपयोग करके एक ही समस्या से निपटने का बिंदु है। क्या आप किसी भी प्रोग्रामिंग भाषा का उपयोग करके इस संभावना को हल करने का बेहतर तरीका सुझा सकते हैं, मैं फिर से लिख सकता हूं कि स्कैला का उपयोग करके और उसी परीक्षण को करें?
user3047512

@ user3047512 पूंछ पुनरावृत्ति का समर्थन करने वाली भाषा के लिए, आप इसे एक संचायक के साथ लिख सकते हैं। उदाहरण
toasted_flakes

स्काला भी टेल फ़ीचर का समर्थन छिपी हुई सुविधा के रूप में करता है oldfashionedsoftware.com/2008/09/27/…
user3047512

1
@ user3047512 क्योंकि पुनरावर्ती समाधान एक शुद्ध कार्य है (आउटपुट केवल फ़ंक्शन आर्ग पर निर्भर करता है और कुछ नहीं ), संस्मरण एक अच्छा समाधान है। सीधे शब्दों में कहें, हर बार जब यह एक मान लौटाता है, तो आर्गों को संग्रहीत करें और एक कुंजी / मान हैश में परिणाम करें, और हर बार जब फ़ंक्शन चलाया जाता है, तो पहले वहां देखें। यह शुद्ध कार्यों के फायदों में से एक है - इस फ़ंक्शन के लिए एक भविष्य की कॉल preexisting हैशेड मान प्राप्त करेगी और शून्य गणना करेगी, क्योंकि हम जानते हैं कि परिणाम बदल नहीं गया होगा।
इज़्काता

@ user3047512 पुनरावृत्त संस्करण भी इस मामले में एक शुद्ध कार्य की तरह दिखता है, लेकिन यह हमेशा सच नहीं होता है - एक कार्यात्मक भाषा में, मेरा मानना ​​है कि यह भाषा द्वारा बेहतर रूप से लागू किया गया है ...
इज़्काता

0

यदि कार्यात्मक प्रोग्रामिंग महंगा है और छोटे डेटा के लिए मेमोरी-खपत है, तो हमें बिग डेटा के लिए इसकी आवश्यकता क्यों है?

विशेष रूप से मैं पहले से ही कुछ एप्लिकेशन देख सकता हूं जहां यह अत्यंत उपयोगी है। पूर्व। सांख्यिकी, यानी विभिन्न मापदंडों या डेटा एनालिटिक्स के लिए मापदंडों के एक सेट के साथ मक्खी पर एक गाऊसी फ़ंक्शन की गणना। संख्यात्मक विश्लेषण आदि के लिए भी प्रक्षेप है।

बिग डेटा के लिए कार्यात्मक प्रोग्रामिंग (स्काला) का उपयोग करने के लिए सबसे अच्छे अभ्यास क्या हैं?

दक्षता पर जवाब देने के लिए अंतरिक्ष या समय में आपकी दक्षता बढ़ाने में मदद करने की तकनीकें भी हैं, विशेष रूप से पुनरावृत्ति, पूंछ पुनरावृत्ति , निरंतर गुजर शैली , उच्च-क्रम के कार्य , आदि। कुछ भाषाओं में उनके पेशेवरों और विपक्ष हैं (उदाहरण आलसी बनाम उत्सुक।) Fibonnacci अनुक्रम की तरह कुछ सरल मैं बस अनिवार्य तरीके का उपयोग कर सकता हूं क्योंकि मुझे लगता है कि कई बार मेरे कुछ सहकर्मी अनिच्छुक हैं और कार्यात्मक प्रोग्रामिंग के साथ सहज नहीं हो सकते हैं और इसलिए अधिक विकास का समय लगता है ... (मैं अभी भी पसंद करता हूं जब मैं इसे प्राप्त कर सकता हूं, तब से कार्यात्मक प्रोग्रामिंग का उपयोग कर सकता हूं]) क्योंकि मुझे यह जल्दी, साफ और "पढ़ने में आसान" लगता है (हालांकि मुझे यह व्यक्तिपरक लगता है) कोड।

विकिपीडिया में पोस्ट किए गए फ़ाइबोनैचि अनुक्रम का "तेज़" संस्करण है। https://en.wikipedia.org/wiki/Functional_programming#Scala

def fibTailRec(n: Int): Int = {
  @tailrec def f(a: Int, b: Int, c: Int): Int = if (a == 0) 0 else if(a < 2) c else f(a-1, c, b + c)
  f(n, 0, 1)
}

धाराओं / हॉफ का उपयोग करना

val fibStream:Stream[Int] = 0 #:: 1 #:: (fibStream zip fibStream.tail).map{ t => t._1 + t._2 }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.