2012-07-25 11 views
22

मैं पढ़ रहा हूं + वर्तमान में गर्म/प्रवृत्त वस्तुओं को सूची में प्रदर्शित करने के लिए मेरे उपयोगकर्ता द्वारा सबमिट की गई सामग्री के लिए स्कोर तैयार करने के लिए एल्गोरिदम और सूत्रों पर शोध करना पढ़ रहा है, हालांकि मैं स्वीकार करूंगा कि मैं ' मेरे सिर पर थोड़ा सा यहाँ हूँ।हॉट कंटेंट एल्गोरिदम/समय क्षय के साथ स्कोर

मैं मैं क्या करने के बाद ... उपयोगकर्ता मेरी साइट के लिए ऑडियो अपलोड कर रहा हूँ पर कुछ पृष्ठभूमि दे देंगे, ऑडियो है कई कार्यों:

  • खेला गया
  • डाउनलोड किया
  • पसंद आया
  • पसंदीदा

आदर्श रूप से मैं एक एल्गोरिदम चाहता हूं जहां हर बार एक नई गतिविधि लॉग (खेली, डाउनलोड आदि ...) के दौरान मैं ऑडीओ स्कोर अपडेट कर सकता हूं, एक डाउनलोड एक्शन एक नाटक से अधिक मूल्यवान है, जैसे डाउनलोड से अधिक और एक पसंदीदा से अधिक पसंदीदा।

यदि संभव हो तो मैं नई सामग्री को प्रवृत्त करने का मौका देने के लिए सूची से काफी तेजी से बंद होने के लिए 1 सप्ताह से अधिक पुराने ऑडियो के लिए चाहूंगा।

मैंने लाल रंग के एल्गोरिदम के बारे में पढ़ा है जो अच्छा लग रहा था, लेकिन मैं अपने सिर पर हूं कि इसे अपने एकाधिक चर के उपयोग के लिए कैसे ट्विक करें, और लगभग 7 दिनों के बाद पुराने लेखों को छोड़ दें।

कुछ लेख है कि हम दिलचस्प कर रहे हैं:

किसी भी मदद की सराहना की है!

पॉल

+0

तो सवाल क्या है? –

+0

समय क्षय के साथ गर्म सामग्री? क्या आप [गर्मी समीकरण] (http://en.wikipedia.org/wiki/Heat_equation) के बारे में बात कर रहे हैं? नहीं, गंभीरता से, आपको इसके बारे में सोचना होगा - हालांकि गर्मी समीकरण आपको कुछ विचार दे सकता है। – Zeta

+0

अच्छी तरह से सवाल यह है कि वास्तव में मैं किस तरह का समीकरण ढूंढ रहा हूं, मुझे लगता है कि जेता ने इसका उत्तर दिया। मैं इस स्तर पर गणित और समीकरणों पर बिल्कुल गर्म नहीं हूं, मैं उम्मीद कर रहा था कि किसी के पास इससे पहले कोई अनुभव हो और कुछ उपयोगी ब्लॉग आदि मिले। –

उत्तर

49

reddits वर्ष सूत्र और बंद

एक छोटे से ड्रॉप मूल रूप से आप रेडिट के सूत्र का उपयोग कर सकते हैं। के बाद से अपने सिस्टम केवल upvotes का समर्थन करता है तो आप उन्हें वजन सकता है, कुछ इस तरह है, जिसके परिणामस्वरूप: पीछे

Exponential drop off

मूल बातें:

def hotness(track) 
    s = track.playedCount 
    s = s + 2*track.downloadCount 
    s = s + 3*track.likeCount 
    s = s + 4*track.favCount 
    baseScore = log(max(s,1)) 

    timeDiff = (now - track.uploaded).toWeeks 

    if(timeDiff > 1) 
     x = timeDiff - 1 
     baseScore = baseScore * exp(-8*x*x) 

    return baseScore 

कारक exp(-8*x*x) आप बंद अपने वांछित बूंद दे देंगे

आप किसी भी फ़ंक्शन का उपयोग कर सकते हैं जो आपके स्कोर की तुलना में शून्य पर तेज़ी से जाता है। चूंकि हम अपने स्कोर पर log का उपयोग करते हैं, यहां तक ​​कि एक रैखिक फ़ंक्शन गुणा हो सकता है (जब तक आपका स्कोर तेजी से बढ़ता नहीं है)।

तो आपको केवल एक ऐसा फ़ंक्शन है जो 1 देता है जब तक कि आप स्कोर को संशोधित नहीं करना चाहते हैं, और बाद में बूंदें। फॉर्म के ऊपर हमारा उदाहरण जो कार्य करता है:

multiplier(x) = x > 1 ? exp(-8*x*x) : 1 

यदि आप कम खड़े वक्र चाहते हैं तो आप गुणक को बदल सकते हैं।C++

varying multiplier

उदाहरण का कहना है कि किसी दिए गए ट्रैक के लिए संभावना एक दिया घंटे में खेला जा रहा है 50%, 10% डाउनलोड, 1% और पसंदीदा 0.1% की तरह देता है। उसके बाद निम्न सी ++ प्रोग्राम अपने स्कोर व्यवहार के लिए आप एक अनुमान दे देंगे:

#include <iostream> 
#include <fstream> 
#include <random> 
#include <ctime> 
#include <cmath> 

struct track{ 
    track() : uploadTime(0),playCount(0),downCount(0),likeCount(0),faveCount(0){} 
    std::time_t uploadTime;  
    unsigned int playCount; 
    unsigned int downCount; 
    unsigned int likeCount; 
    unsigned int faveCount;  
    void addPlay(unsigned int n = 1){ playCount += n;} 
    void addDown(unsigned int n = 1){ downCount += n;} 
    void addLike(unsigned int n = 1){ likeCount += n;} 
    void addFave(unsigned int n = 1){ faveCount += n;} 
    unsigned int baseScore(){ 
     return playCount + 
      2 * downCount + 
      3 * likeCount + 
      4 * faveCount; 
    } 
}; 

int main(){ 
    track test; 
    const unsigned int dayLength = 24 * 3600; 
    const unsigned int weekLength = dayLength * 7;  

    std::mt19937 gen(std::time(0)); 
    std::bernoulli_distribution playProb(0.5); 
    std::bernoulli_distribution downProb(0.1); 
    std::bernoulli_distribution likeProb(0.01); 
    std::bernoulli_distribution faveProb(0.001); 

    std::ofstream fakeRecord("fakeRecord.dat"); 
    std::ofstream fakeRecordDecay("fakeRecordDecay.dat"); 
    for(unsigned int i = 0; i < weekLength * 3; i += 3600){ 
     test.addPlay(playProb(gen)); 
     test.addDown(downProb(gen)); 
     test.addLike(likeProb(gen)); 
     test.addFave(faveProb(gen));  

     double baseScore = std::log(std::max<unsigned int>(1,test.baseScore())); 
     double timePoint = static_cast<double>(i)/weekLength;   

     fakeRecord << timePoint << " " << baseScore << std::endl; 
     if(timePoint > 1){ 
      double x = timePoint - 1; 
      fakeRecordDecay << timePoint << " " << (baseScore * std::exp(-8*x*x)) << std::endl; 
     } 
     else 
      fakeRecordDecay << timePoint << " " << baseScore << std::endl; 
    } 
    return 0; 
} 

परिणाम:

Decay

यह आप के लिए पर्याप्त होना चाहिए।

+2

इस स्पष्ट रूप से व्याख्या करने के लिए समय निकालने के लिए धन्यवाद ... इसे जांच लेंगे मेरे डेटा के साथ शाम। –

+0

@Zeta आप exp (-8 * x * x) के साथ कैसे आए? मुझे इसे 'made_at' और' update_at' टाइमस्टैम्प से जुड़ी एक ही समस्या पर लागू करने की आवश्यकता है, जहां मैं 'update_at' द्वारा सॉर्ट करता हूं लेकिन मुझे इसे 'create_at' से 6 घंटे के अंतर के बाद छोड़ने की आवश्यकता है और मुझे यकीन नहीं है कि कैसे ट्विक करें इसके लिए सूत्र। – paulkon

+3

@ पॉककॉन जो उत्तर देने में थोड़ा देर हो सकता है ... जेता के उत्तर में पहला ग्राफ (लाल एक) देखें: यह एक्स (-8 * x * x) के लिए ग्राफ है, जो आधार को एक बार बेसकोर पर लागू होता है ट्रैक एक सप्ताह से अधिक पुराना है। 6 घंटे के बाद अपना ड्रॉपऑफ प्राप्त करने के लिए, आप 'timeDiff = (now - track.created_at) .toHours' और फिर कुछ ऐसा करेंगे:' if timefiff> 6; एक्स = टाइमडिफ - 6; बेसस्कोर * = एक्सपी (-8 * एक्स * एक्स) '। एक्सपोनेंशियल फ़ंक्शन में 8 को ट्विक करें: मूल्य जितना अधिक होगा, ड्रॉपऑफ को खड़ा कर देगा :) साथ -8: http://fooplot.com/plot/h0nfqukrj8 -50 के साथ: http://fooplot.com/plot/e57bc1osnv –

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