2012-07-25 3 views
22

나는 + 사용자가 제출 한 콘텐츠에 대한 점수를 계산하여 더 높은 인기/인기 항목을 표시하는 알고리즘 및 수식에 대해 연구하고 있지만, 내 머릿속에 조금있다.뜨거운 콘텐츠 알고리즘/시간이 지남에 따라 점수가

나는 사용자가 내 사이트에 오디오를 업로드 후 ...이야 무엇에 대한 몇 가지 배경을주지

, 오디오가있는 몇 가지 행동 :

  • 플레이는
  • 좋아 다운로드
  • 즐겨 찾기

이상적으로는 새로운 활동이 기록 될 때마다 오디오 스코어를 업데이트 할 수있는 알고리즘이 필요합니다 (재생, 다운로드 등 ...) 또한 다운로드 액션은 연극보다 더 가치가 있습니다. 다운로드 및 좋아하는 것 이상입니다.

가능하면 1 주일 이상 지난 음향 기기가 목록에서 상당히 급락하여 최신 콘텐츠에 더 많은 트렌드를 줄 수 있기를 바랍니다.

나는 잘 어울리는 reddits 알고리즘을 읽었지만, 필자는 여러 변수를 사용하고 약 7 일 후에 이전 기사를 삭제하는 방법을 고민해 본다. 우리가 재미있어

일부 기사 :

어떤 도움에 감사드립니다!

+0

그럼 뭐가 문제입니까? –

+0

시간이 지남에 따라 뜨거운 콘텐츠가 표시 되나요? [열기 방정식] (http://en.wikipedia.org/wiki/Heat_equation)에 대해 이야기하고 있습니까? 나, 진지하게, 당신 자신에 대해 생각해야만합니다. 열 방정식이 당신에게 아이디어를 줄 수는 있습니다. – Zeta

+0

그럼 질문은 정말로 내가 찾는 방정식의 종류입니다. 나는 Zeta가 이것을 대답했다고 생각합니다. 나는 정확히이 수준의 수학과 방정식에 열정이 없다. 나는 누군가가 전에 이것에 대한 경험이 있었으면하고 유용한 블로그를 찾았 으면한다. –

답변

49

Reddits 된 공식과

조금 떨어져 하락은 기본적으로 당신은 레딧의 공식을 사용할 수 있습니다. 뒤에

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) 당신에게 떨어져 원하는 드롭을 줄 것이다 : 시스템은 upvotes을 지원하기 때문에이 같은 결과를 체중 수

점수가 올라가는 것보다 빠르게 0이되는 기능을 사용할 수 있습니다. 우리의 점수에 log을 사용했기 때문에 심지어 선형 함수도 곱해질 수 있습니다 (점수가 기하 급수적으로 증가하지 않는 한).

그래서 점수를 수정하고 싶지 않은 경우에만 1을 반환하는 함수가 필요합니다. 위의 예는 다음과 같은 기능을합니다.

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

가파른 곡선이 덜 필요하면 승수를 변경할 수 있습니다.

++ C에서 varying multiplier

예는 소정의 트랙에 대한 확률은 주어진 시간에서 50 %이다 재생할 수 있다고 1 % 좋아하는 0.1 %와 같이 10 %를 다운로드 할 수 있습니다. 그런 다음 C++ 프로그램 점수 동작 당신에게 견적을 줄 것이다 :

#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)를 만들었습니까? 나는'created_at'와'updated_at' 타임 스탬프와 관련된 유사한 문제에 이것을 적용 할 필요가 있습니다.'updated_at'에 의해 정렬하지만'created_at'와의 차이가 6 시간 후에는 떨어질 필요가 있습니다. 그리고 나는 조정할 방법이 확실하지 않습니다. 그 공식. – paulkon

+3

@paulkon 대답하는 데 조금 늦을 수도 있습니다 ... 제타의 답변에서 첫 번째 그래프 (빨간색)를 봅니다.이 그래프는 exp (-8 * x * x)의 그래프로 baseScore에 한 번 적용된 드롭 오프를 보여줍니다 트랙은 1 주 이상 지났습니다. 6 시간 후에 드롭 오프를 얻으려면'timeDiff = (now - track.created_at) .toHours'와 같은 일을하고'if timeDiff> 6; x = timeDiff - 6; baseScore * = exp (-8 * x * x)'. 비틀기는 8 지수 함수에서 : 값이 높을수록 가파른 하락 : -8 : http://fooplot.com/plot/h0nfqukrj8 -50 : http://fooplot.com/plot/e57bc1osnv –

관련 문제