छोटा जवाब: हाल में साझा की गई 250 होमब्रू रेसिपी एक अच्छा छोटा डेटा इंजीनियरिंग प्रोजेक्ट बनाती हैं, और ज़्यादातर मेहनत स्क्रेपिंग में नहीं है। मेहनत पार्सिंग में है: एक लाइन में दो-दो आँकड़े, ‘7 lbs 14.00 oz’ जैसी मात्राएँ, तारांकन से चिह्नित कस्टम इंग्रीडिएंट, और तीन तरह से लिखा गया एक ही हॉप। संरचित फ़ील्ड सादे कोड से पार्स कीजिए, सब कुछ बेस यूनिट में नॉर्मलाइज़ कीजिए, LLM को सिर्फ़ गड़बड़ नाम सुलझाने के लिए इस्तेमाल कीजिए, और डेटा को ख़ुद उसी से जाँचिए (12 रेसिपी का ABV उनकी अपनी ग्रैविटी से मेल नहीं खाता था)। नतीजा: American IPA आगे है, Citra और Cascade बराबरी पर हैं, और hazy IPA वह ट्रेंड है जो सच में आगे बढ़ रहा है।
कोड लिखने वाला हर ब्रूअर देर-सबेर जानना चाहता है कि बाकी सब क्या ब्रू कर रहे हैं। रेसिपी साझा करने वाली साइटें हज़ारों रेसिपी खुले में प्रकाशित करती हैं, और सब कुछ खींचकर लैंग्वेज मॉडल से ट्रेंड पूछने का लालच होता है। मैंने एक छोटा, ज़्यादा सावधान संस्करण किया: एक सार्वजनिक साइट पर हाल में साझा की गई 250 रेसिपी। यह एक साफ़-सुथरा, पूरा डेटा इंजीनियरिंग अभ्यास निकला, जिसमें एक जगह LLM सच में मदद करता है और कई जगह वह हालात बिगाड़ देता।
शालीनता से स्क्रेप कीजिए, वरना बिल्कुल नहीं
कोई भी कोड लिखने से पहले, तीन जाँच:
- robots.txt और उपयोग की शर्तें पढ़िए। अगर साइट मना करती है, तो प्रोजेक्ट वहीं रुक जाता है।
- सिर्फ़ सार्वजनिक पेज। दूसरों की सामग्री स्क्रेप करने के लिए लॉग इन नहीं, पेवॉल से बचने का कोई जुगाड़ नहीं।
- विश्लेषण, दोबारा प्रकाशन नहीं। लोगों ने ये रेसिपी अपने समुदाय के साथ साझा कीं। कुल गिनती प्रकाशित करना उचित है। उनकी रेसिपी थोक में दोबारा पोस्ट करना नहीं।
फिर अपने निशान छोटे रखिए: संपर्क पते वाला असली यूज़र एजेंट, हर दो-एक सेकंड में एक रिक्वेस्ट, और एक लोकल कैश ताकि हर पेज ठीक एक बार फ़ेच हो। सबसे नई पहले वाले लिस्टिंग पेजों में लगभग 20-20 रेसिपी थीं, तो 250 रेसिपी यानी दर्जन भर लिस्टिंग पेज और 250 डिटेल पेज। धीमी रफ़्तार पर यह एक घंटा है। किसी के सर्वर को आपका पता भी नहीं चलना चाहिए।
पार्सिंग के जाल
समय यहीं गया। रेसिपी पेज इंसानों के लिए लिखे जाते हैं, और इंसानों को एक जैसी फ़ॉर्मैटिंग की ज़रूरत नहीं होती।
एक लाइन में दो आँकड़े। पेज ‘Batch Size: 5.00 gal’ और ‘Style: American IPA’ को बिना किसी सेपरेटर के एक ही लाइन पर छापता था। लाइनों पर तोड़ने से बकवास मिलती है। इलाज है ख़ुद लेबल पर एंकर करना और अगले ज्ञात लेबल तक पढ़ना।
मिली-जुली यूनिट वाली मात्राएँ। ग्रेन की मात्रा ‘7 lbs 14.00 oz’, ‘12.00 oz’ या ‘3 lbs’ के रूप में आती थी। 250 रेसिपी में, 529 ग्रेन लाइनों में पाउंड और औंस साथ थे, 276 में सिर्फ़ औंस और 189 में सिर्फ़ पाउंड। जो पार्सर पहली संख्या और पहली यूनिट पढ़ता है, उसे 7 पाउंड मिलते हैं और 14 औंस चुपचाप खो जाते हैं।
कस्टम इंग्रीडिएंट। जो ब्रूअर अपना इंग्रीडिएंट ख़ुद परिभाषित करते हैं, उसके आगे तारांकन लग जाता है। तारांकन रहने दीजिए तो ‘*Safale US-05’ और ‘Safale US-05’ दो यीस्ट गिने जाते हैं।
फ़ालतू व्हाइटस्पेस। नामों के अंदर के डबल स्पेस किसी भी गिनती में एक हॉप को दो बना देते हैं। कुछ भी एकत्र करने से पहले व्हाइटस्पेस समेट दीजिए।
टाइप टाइटल में है। रेसिपी all-grain है या extract, यह टाइटल लाइन का आख़िरी शब्द था, कोई फ़ील्ड नहीं। रिकॉर्ड के लिए, 250 में से 243 all-grain थीं।
बेस यूनिट में नॉर्मलाइज़ कीजिए, एक बार
हर मात्रा अंदर आते ही बदली गई: ग्रेन किलोग्राम में, हॉप्स ग्राम में, आयतन लीटर में, और हॉप दरें ग्राम प्रति लीटर में ताकि 5 गैलन और 20 लीटर की होमब्रू की तुलना हो सके। ग्रैविटी वैसी ही रही जैसी साइट ने दी (स्पेसिफ़िक ग्रैविटी), और टेस्ट किए गए कन्वर्ज़न से एक प्लेटो कॉलम निकाला गया।
यह वही नियम है जो भाग 2 के कैलकुलेशन टूल में था: अंदर बेस यूनिट, किनारे पर डिस्प्ले यूनिट। एक ही जगह, टेस्ट वाले कोड में कन्वर्ट करने का मतलब है कि कोई ट्रेंड चार्ट कभी चुपचाप औंस और ग्राम नहीं मिलाता।
जहाँ हो सके regex, जहाँ ज़रूरी हो LLM
आज हर पेज को लैंग्वेज मॉडल पर फेंककर JSON माँगना आसान है। इस काम के लिए ज़्यादातर फ़ील्ड पर वह धीमा, महँगा और कम सटीक होता।
संरचित फ़ील्ड: सादा कोड। ओरिजिनल ग्रैविटी, फ़ाइनल ग्रैविटी, ABV, IBU, रंग, मात्राएँ और बॉयल टाइम तय लेबल के बगल में होते हैं। Regular expressions उन्हें बिल्कुल सटीक, मुफ़्त में, मिलीसेकंड में निकाल लेते हैं। LLM कभी-कभार कोई संख्या राउंड कर देता, दशमलव गिरा देता या ‘मदद के लिए’ यूनिट बदल देता।
नाम: यहाँ LLM अपनी जगह कमाता है। हॉप और यीस्ट के नाम गड़बड़ हैं। इस सैंपल में ‘Amarillo Gold’ (49 बार) और ‘Amarillo’ (27) एक ही हॉप है जो दो नामों से बिकता है, और ‘Fuggle’ और ‘Fuggles’ 16 और 16 में बँटे हैं। यीस्ट लैब कोड, ब्रांड नाम या उपनाम से आते हैं। इन्हें सुलझाना डोमेन ज्ञान के साथ फ़ज़ी मैचिंग है, जो लैंग्वेज मॉडल अच्छा करते हैं।
इसे सुरक्षित इस्तेमाल करने का तरीका: मॉडल को रॉ नाम और ज्ञात वैरायटी की सूची दीजिए, उससे एक चुनने या ‘unknown’ कहने को कहिए, और कभी ऐसा नाम स्वीकार मत कीजिए जो सूची में नहीं है। मॉडल मैप करता है। फ़ैसला सूची करती है।
प्रकाशित गिनती में मैंने असल में Amarillo और Amarillo Gold को अलग छोड़ा और यह साफ़ बताया, क्योंकि उन्हें मिलाना एक फ़ैसला है और पाठक को वह दिखना चाहिए। ऐसा चुनाव पाइपलाइन में दबाने के बजाय दिखाने लायक है।
डेटा को ख़ुद उसी से जाँचिए
स्क्रेप किए डेटा में अपनी त्रुटियाँ होती हैं, और ब्रूइंग डेटा में एक अंतर्निहित जाँच है: ABV ओरिजिनल और फ़ाइनल ग्रैविटी से निकलना चाहिए। आम होमब्रू सन्निकटन (ग्रैविटी की गिरावट गुणा 131.25) से, 250 में से 12 रेसिपी का ABV उनकी अपनी ग्रैविटी से निकलने वाले मान से 0.3 पॉइंट से ज़्यादा दूर था।
इसका मतलब यह नहीं कि 12 ब्रूअर ने गलती की। रेसिपी सॉफ़्टवेयर एक से ज़्यादा ABV फ़ॉर्मूला देता है, कुछ ब्रूअर आँकड़ा हाथ से बदलते हैं, और कुछ रेसिपी पुरानी संख्याओं वाले टेम्पलेट हैं। इसका मतलब यह है कि ABV कॉलम पर आँख मूँदकर भरोसा नहीं करना चाहिए, और ABV का ट्रेंड चार्ट ग्रैविटी से, एक बताए गए फ़ॉर्मूले के साथ बनना चाहिए।
250 रेसिपी ने क्या कहा
इस शर्त के साथ कि यह एक साइट की हाल की फ़ीड है:
- स्टाइल: American IPA 26 रेसिपी के साथ आगे रहा, फिर American Pale Ale 18 के साथ। Saison, Blonde Ale, Witbier और Session IPA 10-10 पर बराबर रहे। समुदाय IPA की अगुवाई में है, पर सिर्फ़ IPA से बहुत दूर।
- हॉप्स: Citra (84 बार) और Cascade (83) लगभग बराबर हैं। Centennial, Amarillo, Magnum, Saaz और Simcoe पीछे हैं। नई वैरायटी के मुकाबले क्लासिक American C-hops अब भी हावी हैं।
- यीस्ट: दो साफ़ American ale स्ट्रेन मिलकर 58 रेसिपी में थे, सैंपल का लगभग एक-चौथाई।
- क्या बढ़ रहा है: hazy और New England IPA, नाम या स्टाइल से 13 रेसिपी, किसी भी दूसरे नए स्टाइल से काफ़ी आगे। नए hazy स्ट्रेन दिखने लगे हैं पर अब भी कम हैं।
- आम बीयर: मीडियन ओरिजिनल ग्रैविटी 1.055, मीडियन ABV 5.6%, मीडियन कड़वाहट लगभग 33 IBU।
होमब्रू कॉम्पिटिशन में जज करने वाले किसी को इसमें से कुछ भी चौंकाएगा नहीं। कोई बात नहीं। इसकी कीमत किसी खुलासे में नहीं है, बल्कि इसे ऐसे डेटा के रूप में रखने में है जिसे आप अगली तिमाही फिर चलाकर तुलना कर सकें।
यह कहाँ टूटता है
एक साइट यानी एक समुदाय। जो लोग सार्वजनिक रूप से रेसिपी साझा करते हैं, वे सारे ब्रूअर नहीं हैं। कमर्शियल ब्रूअरी गायब हैं, और कुछ स्टाइल ज़रूरत से ज़्यादा दिखते हैं क्योंकि उनके ब्रूअर को साझा करना पसंद है।
हाल का मतलब प्रतिनिधि नहीं। कुछ महीनों की नई-पहले फ़ीड मौसमी ब्रूइंग पकड़ती है। इसे सर्दियों में फिर चलाइए और stouts ऊपर आ जाएँगे।
नाम अब भी फ़ैसले हैं। स्पेलिंग मिलाना, hazy और NEIPA को एक समूह में रखना, यह तय करना कि ‘Session IPA’ अलग स्टाइल है या नहीं: इनमें से हर फ़ैसला एक गिनती बदल देता है। नतीजों के साथ नियम भी प्रकाशित कीजिए।
शर्तें बदलती हैं। जो साइट आज शालीन क्रॉलिंग की अनुमति देती है, हो सकता है कल न दे। हर बार दोबारा चलाने से पहले फिर जाँचिए।
निचोड़
स्क्रेपिंग आसान वाला एक घंटा था। वीकेंड गया एक लाइन में दो-दो छपे आँकड़ों, पाउंड-और-औंस वाली मात्राओं, तारांकनों और तीन नाम वाले एक हॉप पर, और किसी भी असली डेटा इंजीनियरिंग काम में यह सामान्य है। संरचित फ़ील्ड सादे कोड से पार्स कीजिए, टेस्ट किए फ़ंक्शन में एक बार नॉर्मलाइज़ कीजिए, फ़ज़ी नामों के लिए LLM इस्तेमाल कीजिए पर एक सूची के साथ जिसमें से उसे चुनना ही हो, और डेटा को उसकी अपनी भौतिकी से जाँचिए। तब ट्रेंड चार्ट देखने लायक होता है।
इस ब्लॉग पर पहले: क्या AI बीयर रेसिपी डिज़ाइन कर सकता है? में जनरेशन देखा गया था। यह पोस्ट उस डेटा के बारे में थी जिसकी एक जनरेटर को ज़रूरत होगी। सीरीज़ में आगे: ब्रूइंग असिस्टेंट के लिए evals। पूरी सूची The Brewer’s Agent सीरीज़ पेज पर है।
अक्सर पूछे जाने वाले सवाल
क्या सार्वजनिक होमब्रू रेसिपी साइटों को स्क्रेप करना ठीक है? सिर्फ़ साइट की शर्तों और robots.txt के दायरे में, धीमी रिक्वेस्ट दर पर, और दोबारा प्रकाशित करने के लिए नहीं बल्कि विश्लेषण के लिए। वही पेज स्क्रेप कीजिए जो बिना लॉग इन के सार्वजनिक हैं, अपनी पहचान बताइए, जो फ़ेच करें उसे कैश कीजिए ताकि कोई पेज दो बार न खुले, और लोगों की रेसिपी कॉपी करने के बजाय कुल निष्कर्ष प्रकाशित कीजिए।
रेसिपी डेटा पार्स करने के लिए LLM इस्तेमाल करूँ या regular expressions? ग्रैविटी, कड़वाहट और मात्रा जैसे संरचित फ़ील्ड के लिए regular expressions और सादी पार्सिंग इस्तेमाल कीजिए, क्योंकि वे तेज़, मुफ़्त और सटीक हैं। गड़बड़ हिस्सों के लिए LLM इस्तेमाल कीजिए, जैसे कई तरह से लिखे गए हॉप और यीस्ट के नाम सुलझाना, और उसके आउटपुट को ज्ञात वैरायटी की सूची से जाँचिए।
हाल की 250 होमब्रू रेसिपी ने ट्रेंड के बारे में क्या दिखाया? American IPA 26 रेसिपी के साथ सबसे ज़्यादा साझा किया गया स्टाइल था, Citra और Cascade 84 और 83 बार इस्तेमाल के साथ सबसे ज़्यादा इस्तेमाल होने वाले हॉप के रूप में लगभग बराबर थे, और दो साफ़ American ale यीस्ट लगभग एक-चौथाई रेसिपी में थे। Hazy और New England IPA 13 रेसिपी के साथ सबसे साफ़ आधुनिक ट्रेंड था। यह एक साइट की हाल की फ़ीड है, इसलिए इसे संकेत मानिए, जनगणना नहीं।