वेक्टर और वेक्टर खोज बड़े भाषा मॉडल (एलएलएम) के प्रमुख घटक हैं, लेकिन वे कई अन्य अनुप्रयोगों में कई उपयोग मामलों में उपयोगी होते हैं जिन पर आपने विचार नहीं किया होगा। खुदरा सामान वितरित करने का सबसे प्रभावी तरीका क्या है?
इस श्रृंखला के दो पूर्व लेखों में, मैंने एक काल्पनिक ठेकेदार की कहानी बताई थी, जिसे एक बड़े-बॉक्स रिटेलर पर एआई/एमएल समाधान लागू करने में मदद करने के लिए काम पर रखा गया था और फिर पता लगाया कि कैसे इस वितरित सिस्टम और एआई विशेषज्ञ ने ग्राहक के साथ परिणाम प्राप्त करने के लिए वेक्टर खोज का उपयोग किया। कंपनी में पदोन्नति. अब, मैं आपको बताऊंगा कि यह ठेकेदार ट्रकिंग मार्गों को अनुकूलित करने के लिए वेक्टर खोज का उपयोग कैसे करता है।
जब हम इस श्रृंखला की पहली कहानी से अनुशंसा बैच कार्य को छोटा करने (और अंततः अक्षम करने) के लिए अपने विकल्पों पर विचार कर रहे थे, हमें परिवहन सेवा टीम के साथ एक बैठक में आमंत्रित किया गया था। उन्होंने सुना था कि हमने प्रमोशन टीम की कैसे सहायता की और वे सोच रहे थे कि क्या हम उनकी एक समस्या पर नज़र डाल सकते हैं।
BigBoxCo के उत्पाद हवाई अड्डों और शिपिंग बंदरगाहों से ट्रक में लाए जाते हैं। एक बार वितरण केंद्र (डीसी) पर, उन्हें टैग किया जाता है और अलग-अलग ईंट-और-मोर्टार स्टोरों के लिए छोटे शिपमेंट में अलग किया जाता है। हालाँकि उत्पाद यात्रा के इस भाग के लिए हमारे पास अपने स्वयं के अर्ध ट्रेलर हैं, लेकिन बेड़ा कुशलता से व्यवस्थित नहीं है।
वर्तमान में, ड्राइवरों को ट्रक के डिजिटल डिवाइस पर दुकानों की एक सूची दी जाती है, और पर्यवेक्षक एक मार्ग सुझाता है। हालाँकि, ड्राइवर अक्सर स्टोर स्टॉप के आदेश से कतराते हैं, और वे अक्सर अपने पर्यवेक्षकों के मार्ग सुझावों की उपेक्षा करते हैं। यह, निश्चित रूप से, अपेक्षित शिपमेंट और रीस्टॉक समय के साथ-साथ कुल लगने वाले समय में भी भिन्नता पैदा करता है।
यह जानते हुए भी, डीसी कर्मचारी प्रत्येक ट्रक कंटेनर को पूरी तरह से भरने में असमर्थ हैं, क्योंकि उन्हें प्रत्येक स्टोर के लिए उत्पाद पैलेट तक पहुंच के लिए ट्रक में जगह छोड़नी पड़ती है। आदर्श रूप से, उत्पाद पैलेट को ट्रेलर में सबसे सुलभ स्थिति में पहले स्टोर के पैलेट के साथ ऑर्डर किया जाएगा।
परिवहन सेवा टीम चाहेगी कि हम उपलब्ध डेटा की जांच करें और देखें कि क्या इस समस्या से निपटने का कोई बेहतर तरीका है। उदाहरण के लिए, क्या होगा यदि कोई ऐसा तरीका हो कि हम ड्राइवर को दुकानों पर जाने के क्रम को निर्धारित करके सर्वोत्तम संभावित मार्ग को पूर्व-निर्धारित कर सकें?
यह "ट्रैवलिंग सेल्समैन समस्या" (टीएसपी) के समान है, एक काल्पनिक समस्या जिसमें एक सेल्समैन को यात्रा करने के लिए शहरों की एक सूची दी जाती है, और उनके बीच सबसे कुशल मार्ग का पता लगाने की आवश्यकता होती है। जबकि टीएसपी का कोडित कार्यान्वयन काफी जटिल हो सकता है, हम इसे हल करने के लिए वेक्टर खोज क्षमता के लिए अपाचे कैसेंड्रा जैसे वेक्टर डेटाबेस का उपयोग करने में सक्षम हो सकते हैं।
स्पष्ट दृष्टिकोण प्रत्येक गंतव्य शहर के प्रत्येक जियोलोकेशन निर्देशांक को प्लॉट करना है। हालाँकि, शहर केवल स्थानीय, महानगरीय क्षेत्र में फैले हुए हैं, जिसका अर्थ है कि अक्षांश और देशांतर की पूर्ण संख्याएँ अधिकतर समान होंगी। इससे बहुत अधिक आसानी से पता लगाने योग्य भिन्नता नहीं होने वाली है, इसलिए हमें जियो यूआरआई योजना के दशमलव बिंदु के दाईं ओर की संख्याओं पर विचार करके उस डेटा पर फिर से ध्यान केंद्रित करना चाहिए।
उदाहरण के लिए, रोजर्सविले शहर (हमारे बिगबॉक्सको स्टोर्स में से एक का स्थान) का जियो यूआरआई 45.200,-93.567 है। यदि हम अपने निर्देशांक के प्रत्येक दशमलव बिंदु के दाईं ओर देखते हैं, तो 200,-567 (45.200,-93.567 के बजाय) के समायोजित निर्देशांक पर पहुंचते हुए, हम इस और अन्य वैक्टर से भिन्नता का अधिक आसानी से पता लगाने में सक्षम होंगे।
अपने स्टोरों के साथ स्थानीय मेट्रो शहरों के साथ इस दृष्टिकोण को अपनाने से हमें निम्नलिखित डेटा मिलता है:
अब जब हमारे पास डेटा है, तो हम अपने कैसेंड्रा क्लस्टर में दो-आयामी वेक्टर के साथ एक तालिका बना सकते हैं। हमें वेक्टर कॉलम पर एक SSTable अटैच्ड सेकेंडरी इंडेक्स (SASI) भी बनाने की आवश्यकता होगी:
CREATE TABLE bigbox.location_vectors ( location_id text PRIMARY KEY, location_name text, location_vector vector<float, 2>); CREATE CUSTOM INDEX ON bigbox.location_vectors (location_vector) USING 'StorageAttachedIndex';
यह हमें प्रत्येक शहर का दौरा करने के क्रम को निर्धारित करने के लिए वेक्टर खोज का उपयोग करने में सक्षम करेगा। हालाँकि, यह ध्यान रखना महत्वपूर्ण है कि वेक्टर खोजें दूरी के लिए कोसाइन-आधारित गणनाओं पर आधारित होती हैं, यह मानते हुए कि बिंदु एक समतल तल पर हैं। जैसा कि हम जानते हैं, पृथ्वी कोई समतल समतल नहीं है। एक बड़े भौगोलिक क्षेत्र पर दूरियों की गणना हेवरसाइन सूत्र जैसे किसी अन्य दृष्टिकोण का उपयोग करके की जानी चाहिए, जो एक गोले की विशेषताओं को ध्यान में रखता है। लेकिन एक छोटे, स्थानीय मेट्रो क्षेत्र में हमारे उद्देश्यों के लिए, अनुमानित निकटतम पड़ोसी (एएनएन) की गणना करना ठीक काम करना चाहिए।
अब हम अपने शहर के वैक्टर को तालिका में लोड करते हैं, और हमें इसे क्वेरी करने में सक्षम होना चाहिए:
INSERT INTO bigbox.location_vectors (location_id, location_name, location_vector) VALUES ('B1643','Farley',[86, -263]); INSERT INTO bigbox.location_vectors (location_id, location_name, location_vector) VALUES (B9787,'Zarconia',[37, -359]); INSERT INTO bigbox.location_vectors (location_id, location_name, location_vector) VALUES (B2346,'Parktown',[-52, -348]); INSERT INTO bigbox.location_vectors (location_id, location_name, location_vector) VALUES ('B1643','Victoriaville',[94, -356]); INSERT INTO bigbox.location_vectors (location_id, location_name, location_vector) VALUES ('B6789','Rockton',[11, -456]); INSERT INTO bigbox.location_vectors (location_id, location_name, location_vector) VALUES ('B2345','Maplewood',[73, -456]); INSERT INTO bigbox.location_vectors (location_id, location_name, location_vector) VALUES ('B5243','Rogersville',[200, -567]);
मार्ग शुरू करने के लिए, हम पहले फ़ार्ले में गोदाम वितरण केंद्र पर विचार करेंगे, जिसे हमने 86, -263 के वेक्टर के साथ संग्रहीत किया है। हम फ़ार्ले के वेक्टर के ANN के लिए ` location_vectors
तालिका को क्वेरी करके शुरू कर सकते हैं:
SELECT location_id, location_name, location_vector, similarity_cosine(location_vector,[86, -263]) AS similarity FROM location_vectors ORDER BY location_vector ANN OF [86, -263] LIMIT 7;
क्वेरी के परिणाम इस तरह दिखते हैं:
location_id | location_name | location_vector | similarity -------------+---------------+-----------------+------------ B1643 | Farley | [86, -263] | 1 B5243 | Rogersville | [200, -567] | 0.999867 B1566 | Victoriaville | [94, -356] | 0.999163 B2345 | Maplewood | [73, -456] | 0.993827 B9787 | Zarconia | [37, -359] | 0.988665 B6789 | Rockton | [11, -456] | 0.978847 B2346 | Parktown | [-52, -348] | 0.947053 (7 rows)
ध्यान दें कि हमने ' similarity_cosine
' फ़ंक्शन के परिणामों को भी शामिल किया है, ताकि एएनएन परिणामों की समानता हमें दिखाई दे। जैसा कि हम देख सकते हैं, शीर्ष पर फ़ार्ले (हमारे शुरुआती बिंदु के लिए 100% मेल) की उपेक्षा करने के बाद, रोजर्सविले शहर लगभग निकटतम पड़ोसी के रूप में वापस आ रहा है।
इसके बाद, आइए एक माइक्रोसर्विस एंडपॉइंट बनाएं जो अनिवार्य रूप से शुरुआती बिंदु और शीर्ष एएनएन के आधार पर शहरों को पार करता है। इसे उन शहरों की भी उपेक्षा करने की आवश्यकता होगी जहां यह पहले ही जा चुका है। इसलिए, हम एक ऐसी विधि बनाते हैं जिस पर हम पोस्ट कर सकते हैं, ताकि हम प्रारंभिक शहर की आईडी, साथ ही अनुरोध के मुख्य भाग में प्रस्तावित मार्ग के लिए शहरों की सूची प्रदान कर सकें:
curl -s -XPOST http://127.0.0.1:8080/transportsvc/citylist/B1643 \ -d'["Rockton","Parktown","Rogersville","Victoriaville","Maplewood","Za rconia"]' -H 'Content-Type: application/json'
इस सेवा को ` location_id
' ''बी1643'' (फ़ार्ले) के साथ कॉल करने पर निम्नलिखित आउटपुट मिलता है:
["Rogersville","Victoriaville","Maplewood","Zarconia","Rockton","Parktown"]
तो यह इस अर्थ में बहुत अच्छा काम करता है कि यह हमारे ट्रकिंग मार्गों के लिए कुछ व्यवस्थित मार्गदर्शन प्रदान कर रहा है। हालाँकि, हमारी सेवा समापन बिंदु और (प्रॉक्सी द्वारा) हमारी एएनएन क्वेरी में राजमार्ग प्रणाली की समझ नहीं है जो इनमें से प्रत्येक शहर को जोड़ती है। अभी के लिए, यह केवल यह मान लिया गया है कि हमारे ट्रक "कौवा के उड़ने की तरह" सीधे प्रत्येक शहर की यात्रा कर सकते हैं।
वास्तविक रूप से, हम जानते हैं कि ऐसा नहीं है। वास्तव में, आइए हमारे मेट्रो क्षेत्र के मानचित्र को देखें, जिसमें इनमें से प्रत्येक शहर और कनेक्टिंग राजमार्ग चिह्नित हैं (चित्र 1)।
यहां सटीकता बढ़ाने का एक तरीका राजमार्गों के खंडों के लिए वेक्टर बनाना होगा। हम एक राजमार्ग तालिका बना सकते हैं और प्रत्येक के लिए उनके शुरुआती और अंतिम निर्देशांक के आधार पर वेक्टर उत्पन्न कर सकते हैं, जो इस बात पर आधारित है कि वे एक-दूसरे और हमारे शहरों के साथ कैसे प्रतिच्छेद करते हैं।
CREATE TABLE highway_vectors ( highway_name TEXT PRIMARY KEY, highway_vector vector<float,4>); CREATE CUSTOM INDEX ON highway_vectors(highway_vector) USING 'StorageAttachedIndex';
फिर हम प्रत्येक राजमार्ग के लिए वेक्टर सम्मिलित कर सकते हैं। हम राजमार्ग खंडों की दोनों दिशाओं के लिए प्रविष्टियाँ भी बनाएंगे ताकि हमारी एएनएन क्वेरी किसी भी शहर को शुरुआती या अंतिम बिंदु के रूप में उपयोग कर सके। उदाहरण के लिए:
INSERT INTO highway_vectors(highway_name,highway_vector) VALUES('610-E2',[94,-356,86,-263]); INSERT INTO highway_vectors(highway_name,highway_vector) VALUES('610-W2',[86,-263,94,-356]);
अपनी मूल क्वेरी से परिणाम को हटाकर, हम फ़ार्ले (86,-263) में डीसी और रोजर्सविले (200,-567) में हमारे स्टोर के लिए निर्देशांक के एएनएन के साथ राजमार्ग वैक्टर को वापस खींचने के लिए एक और क्वेरी चला सकते हैं:
SELECT * FROM highway_vectors ORDER BY highway_vector ANN OF [86,-263,200,-567] LIMIT 4; highway_name | highway_vector --------------+----------------------- 610-W2 | [86, -263, 94, -356] 54NW | [73, -456, 200, -567] 610-W | [94, -356, 73, -456] 81-NW | [37, -359, 94, -356] (4 rows)
चित्र 1 में दिखाए गए मानचित्र को देखकर, हम देख सकते हैं कि फ़ार्ले और रोजर्सविले राजमार्ग 610 और 54 से जुड़े हुए हैं। अब हम कुछ पर हैं!
हम शुरुआती और अंतिम शहरों के निर्देशांक के आधार पर एक शहर से दूसरे शहर तक राजमार्ग मार्ग बनाने के लिए एक और सेवा समापन बिंदु बना सकते हैं। इस सेवा को पूर्ण बनाने के लिए, हम चाहेंगे कि यह वापस आने वाले किसी भी "अनाथ" राजमार्गों (वे राजमार्ग जो हमारे अपेक्षित मार्ग पर नहीं हैं) को समाप्त कर दे और स्टोर वाले किसी भी शहर को इसमें शामिल कर दे जहां हम रास्ते में रुकना चाहें।
यदि हमने फ़ार्ले (बी1643) और रोजर्सविले (बी5243) के ' location_ids
' का उपयोग किया है, तो हमें एक आउटपुट मिलना चाहिए जो इस तरह दिखता है:
curl -s -XGET http://127.0.0.1:8080/transportsvc/highways/from/B1643/to/B5243 \ -H 'Content-Type: application/json' {"highways":[ {"highway_name":"610-W2", "Highway_vector":{"values":[86.0,-263.0,94.0,-356.0]}}, {"highway_name":"54NW", "highway_vector":{"values":[73.0,-456.0,200.0,-567.0]}}, {"highway_name":"610-W", "highway_vector":{"values":[94.0,-356.0,73.0,-456.0]}}], "citiesOnRoute":["Maplewood","Victoriaville"]}
इन नई परिवहन सेवाओं से हमारे ड्राइवरों और डीसी प्रबंधन को काफी मदद मिलेगी। अब उन्हें दुकानों के बीच मार्ग निर्धारण के लिए गणितीय रूप से महत्वपूर्ण परिणाम मिलने चाहिए।
एक अच्छा अतिरिक्त लाभ यह है कि डीसी कर्मचारी ट्रक को अधिक कुशलता से भर सकते हैं। समय से पहले मार्ग तक पहुंच के साथ, वे उपलब्ध स्थान का अधिक उपयोग करते हुए, फर्स्ट-इन-लास्ट-आउट (LIFO) दृष्टिकोण में ट्रक में पैलेट लोड कर सकते हैं।
हालाँकि यह एक अच्छा पहला कदम है, इस पहल के सफल होने पर हम भविष्य में कुछ सुधार कर सकते हैं। यातायात सेवा की सदस्यता से मार्ग नियोजन और संवर्द्धन में मदद मिलेगी। यह एक या अधिक राजमार्गों पर महत्वपूर्ण स्थानीय यातायात घटनाओं के आधार पर मार्ग पुनर्गणना की अनुमति देगा।
हम संक्षिप्त अक्षांश और अनुदैर्ध्य निर्देशांक का उपयोग करने के बजाय समन्वय स्थिति के लिए एन-वेक्टर दृष्टिकोण का भी उपयोग कर सकते हैं। यहां लाभ यह है कि हमारे निर्देशांक पहले से ही वैक्टर में परिवर्तित हो जाएंगे, जिससे संभवतः अधिक सटीक निकटतम-पड़ोसी अनुमान प्राप्त होंगे।
ऊपर वर्णित उदाहरण परिवहन सेवा समापन बिंदुओं के लिए कोड के लिए इस GitHub रिपॉजिटरी को देखें, और इस बारे में अधिक जानें कि डेटास्टैक्स वेक्टर खोज के साथ जेनरेटिव एआई को कैसे सक्षम करता है ।
एरोन प्लोएट्ज़, डेटास्टैक्स द्वारा