2012-02-14 13 views
8

में ट्रेंडिंग एल्गोरिथ्म को लागू करने मैं एक Django आवेदन जिसमें मैं एक साधारण ट्रेंडिंग/रैंकिंग एल्गोरिथ्म लागू करने की आवश्यकता है। मैं बहुत एक के रूप में खो रहा हूँ:निर्णय लेना और Django

मैं दो मॉडल, Book और Reader है। हर रात, मेरे डेटाबेस में नई किताबें जोड़ दी जाती हैं। प्रत्येक पुस्तक के लिए पाठकों की संख्या भी हर रात अपडेट की जाती है यानी एक पुस्तक में एकाधिक पाठक आंकड़े रिकॉर्ड होंगे (प्रत्येक दिन के लिए एक रिकॉर्ड)।

एक निश्चित अवधि (पिछले सप्ताह, पिछले महीने या पिछले एक साल) के दौरान, मुझे सबसे लोकप्रिय पुस्तकों की सूची चाहते हैं, क्या एल्गोरिथ्म मैं इस के लिए इस्तेमाल करना चाहिए?

लोकप्रियता क्योंकि प्रत्येक पुस्तक के लिए पाठक संख्या केवल दैनिक अद्यतन किया जाता है किसी भी तरह से वास्तविक समय होने की जरूरत नहीं है।

मैं एक लेख जो एक और एसओ post that showed how they calculated trending Wikipedia articles संदर्भित किया गया है, लेकिन पोस्ट केवल दिखाया है कि कैसे मौजूदा रुझान गणना की गई पाई।

के रूप में किसी को इतने पर कहा, यह एक बहुत ही सरल आधारभूत प्रवृत्ति एल्गोरिथ्म है और केवल दो डेटा बिंदुओं के बीच ढलान की गणना करता है तो मैं यह कल और आज के बीच की प्रवृत्ति से पता चलता लगता है।

मैं पर हैकर समाचार, रेडिट इस्तेमाल किए जाने वाले की तरह एक uber जटिल ट्रेंडिंग एल्गोरिथ्म के लिए नहीं देख रहा हूँ, आदि

मैं केवल दो डेटा कुल्हाड़ियों, पाठक संख्या और तारीख की है।

किसी भी विचार पर मुझे क्या और कैसे लागू करना चाहिए। किसी ऐसे व्यक्ति के लिए जिसने कभी भी आंकड़े/एल्गोरिदम से संबंधित कुछ भी काम नहीं किया है, यह एक बहुत ही कठिन उपक्रम है।

अग्रिम में सभी को धन्यवाद।

उत्तर

5

शायद सबसे सरल संभव ट्रेंडिंग "एल्गोरिथ्म" मैं के एन दिन के औसत से बढ़ रहा है लगता है कर सकते हैं:

reader(date, book, total) 

तो यह रूप में सरल रूप में है।मुझे यकीन है कि कैसे अपने डेटा संरचित है नहीं कर रहा हूँ, लेकिन कहते हैं कि तुम कुछ इस तरह है:

books = {'Twilight': [500, 555, 580, 577, 523, 533, 556, 593], 
     'Harry Potter': [650, 647, 653, 642, 633, 621, 625, 613], 
     'Structure and Interpretation of Computer Programs': [1, 4, 15, 12, 7, 3, 8, 19] 
     } 

एक साधारण चलती औसत अभी पिछले n मूल्यों और औसत लेता है उन्हें:

def moving_av(l, n): 
    """Take a list, l, and return the average of its last n elements. 
    """ 
    observations = len(l[-n:]) 
    return sum(l[-n:])/float(observations) 

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

book_scores = {} 
for book, reader_list in books.iteritems(): 
    book_scores[book] = moving_av(reader_list, 5) 

आप दिनों की संख्या तुम पर औसत के साथ चारों ओर खेलने के लिए चाहता हूँ। और यदि आप हाल के रुझानों पर जोर देना चाहते हैं तो आप weighted moving average जैसे कुछ का उपयोग करने पर भी विचार कर सकते हैं।

आप कुछ है कि पूर्ण पाठक संख्या में कम लग रहा है और पाठकों की संख्या में बढ़ जाती है पर बजाय केंद्रित पर ध्यान केंद्रित करना चाहता था, तो बस 30 दिन की प्रतिशत में आया बदलाव को खोजने चलती औसत और 5 दिन का मूविंग औसत:

d5_moving_av = moving_av(reader_list, 5) 
d30_moving_av = moving_av(reader_list, 30) 
book_score = (d5_moving_av - d30_moving_av)/d30_moving_av 

इन सरल उपकरणों के साथ आप पिछले रुझानों पर कितना जोर देते हैं और आप कितनी आसानी से स्पाइक को बाहर करना चाहते हैं (या चिकनी नहीं) में लचीलापन की एक उचित मात्रा है।

+0

HI Wilduck, मैं आपके द्वारा निर्धारित ईडब्ल्यूएमए गणना में देख रहा हूं। यह मेरे मुद्दे के लिए एक अच्छा फिट लगता है। मैं उलझन में हूं कि अल्फा 'α' के मूल्य की गणना कैसे करें। क्या आपके पास कोई विचार है कि मैं इसकी गणना कैसे कर सकता हूं? –

+0

@MridangAgarwalla अच्छी खबर! आपको इसकी गणना करने की ज़रूरत नहीं है! आप शून्य और एक के बीच कोई भी संख्या चुन सकते हैं, जहां एक संख्या के करीब एक पुरानी अवलोकन तेजी से छूट जाती है। आपकी पसंद इस बात पर निर्भर करेगी कि आप पुराने मूल्यों को कितना छूट देना चाहते हैं, ताकि जब तक आपको कुछ पसंद न हो, तब तक आप इसके साथ खेल सकते हैं। – Wilduck

+0

कहा जा रहा है, मुझे लगता है कि एक साधारण चलती औसत (जो कि घातीय रूप से भारित नहीं है) आपके उद्देश्यों के लिए भी काम कर सकती है। मैं पहले सरल संस्करण को लागू करने का सुझाव दूंगा, और फिर यदि आप पाते हैं कि यह संतोषजनक नहीं है तो घातीय रूप से भारित संस्करण में स्वैपिंग करें। – Wilduck

0

लोकप्रियता आसान है; आप सिर्फ इतना है कि पाठकों और व्यवस्था पर एक गिनती चलाएँ: के रूप में इस अधिक एक लोकप्रियता डेल्टा है, यानी जो पुस्तकों लाभ अधिकांश पाठकों हाल ही में किया है

Book.objects.annotate(reader_count=Count('readers')).order_by('-reader_count') 

रुझान अधिक कठिन है। यदि आप ऐसा कुछ चाहते हैं, तो आपको तिथि के अनुसार पाठक संख्याओं का रिकॉर्ड रखने के लिए दृश्यों के पीछे कुछ चलाना होगा।

0

उदाहरण के तौर पर आप stackoverflow reputation ranking ले सकते हैं। , वार्षिक आधार पर, महीने के आधार ....

आपके मामले में: वर्ष तक माह से सबसे ज्यादा पढ़ा किताब,

उपयोगकर्ता दृश्य बदल सकते हैं।

इसे प्राप्त करने के लिए आपको प्रत्येक पुस्तक के लिए दिन-प्रतिदिन पाठकों की संख्या को बचाया जाना चाहिए।

Book.objects.filter( 
        boor__reader__date__gte = some_date 
        ).annotate(
          num_readers=Sum('book__reader__total') 
           ).order_by('-num_readers') 
+1

ऐसा कभी नहीं करें। एसक्यूएल सर्वर को मारने का यह सबसे आसान तरीका है। – iddqd

+0

@iddqd, आप थोड़ा अपोकैल्पिक हैं। कृपया, कुछ वाक्य को लिंक करें जो आपकी सजा को समझाता है। – danihp

+1

कुल कार्य बहुत धीमी हैं, पूर्ण स्कैन बहुत धीमी हैं। कुल कार्य प्लस पूर्ण स्कैन बहुत धीमी हैं। सभी समय रैंकिंग का उत्पादन करने के लिए आपको सभी डेटा पढ़ने की जरूरत है। – iddqd

0

मैं इसे प्रणालीबद्ध इस तरह करना होगा:

  1. सबसे आम सवाल है या डेटा बिंदुओं एक उपयोगकर्ता में दिलचस्पी होगी की एक सूची बनाएँ, उदाहरण के लिए: 1.1 शीर्ष 100 सबसे लोकप्रिय पुस्तकों इस सप्ताह 1.2 इस महीने 0 शीर्ष 30 सबसे लोकप्रिय किताबें

  2. आपके दैनिक पाठक/पुस्तक की जानकारी के बाद। अपडेट किया गया है, मैं इस जानकारी की एक तालिका को अद्यतन करने के लिए नौकरी (शायद रात में) चलाऊंगा। तालिका में शायद बुक और रीडर डेल्टा फ़ील्ड होंगे जहां रीडरडेल्टा एक हफ्ते, महीने या वर्ष में पाठक में परिवर्तन है।

  3. आप दैनिक रीडरडेल्टा को भी स्टोर कर सकते हैं और एक महीने के लायक डेटा की तलाश करते समय, गतिशील रूप से पिछले 30 दिनों की तारीख को बस समेकित कर सकते हैं।

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