2012-07-25 11 views
22

He estado leyendo + investigando sobre algoritmos y fórmulas para calcular un puntaje para el contenido enviado por el usuario para mostrar los artículos actualmente más populares en la lista, sin embargo, admitiré que ' Estoy un poco sobre mi cabeza aquí.Algoritmo/puntaje de contenido caliente con decaimiento de tiempo

Voy a dar algunos antecedentes sobre lo que busco ... los usuarios subir audio a mi sitio, audios tienen varias acciones:

  • jugadas
  • Transferido
  • gustó
  • Favorito

Idealmente quiero un algoritmo en el que pueda actualizar una puntuación de audición cada vez que se registra una nueva actividad (reproducida, descargada, etc.), también una acción de descarga vale más que una jugada, como más que una descarga y un favorito más que un me gusta.

De ser posible, me gustaría que los audios de más de 1 semana caigan de forma brusca de la lista para dar más posibilidades al contenido nuevo.

He leído sobre el algoritmo de reddits, que se veía bien, pero estoy en mi cabeza sobre cómo modificarlo para hacer uso de mis múltiples variables, y para dejar los artículos más antiguos después de aproximadamente 7 días.

Algunos artículos que son interesantes:

cualquier ayuda se agradece!

Paul

+0

¿Cuál es la pregunta? –

+0

¿Contenido caliente con decaimiento de tiempo? ¿Estás hablando de la [ecuación de calor] (http://en.wikipedia.org/wiki/Heat_equation)? Nah, en serio, tienes que pensar en esto tú mismo, aunque la ecuación de calor podría darte algunas ideas. – Zeta

+0

Bueno, la pregunta es realmente qué tipo de ecuación estoy buscando, supongo que Zeta respondió esto. No estoy muy entusiasmado con las matemáticas y las ecuaciones en este nivel, esperaba que alguien haya tenido alguna experiencia con esto antes y encontré algunos blogs útiles, etc. –

Respuesta

49

reddits vieja fórmula y una pequeña gota de

Básicamente se puede utilizar la fórmula de Reddit. Debido a que su sistema sólo admite upvotes se podía ponderar ellos, lo que resulta en algo como esto:

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 

El factor exp(-8*x*x) que le dará a su colocación deseada apagado:

Exponential drop off

los fundamentos detrás de

Puede usar cualquier función que llegue a cero más rápido que su puntaje. Dado que usamos log en nuestra puntuación, incluso una función lineal puede multiplicarse (siempre que su puntaje no crezca exponencialmente).

Así que todo lo que necesita es una función que devuelva 1 mientras no desee modificar el puntaje, y luego caiga. Nuestro ejemplo anterior forma esa función:

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

Puede variar el multiplicador si desea curvas menos empinadas. varying multiplier

Ejemplo en C++

permite decir que la probabilidad de una pista dada a ser jugado en una hora dada es 50%, descargar 10%, como 1% y preferida 0,1%. A continuación, el siguiente programa en C++ le dará una estimación de su comportamiento puntuaciones:

#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; 
} 

Resultado:

Decay

Esto debería ser suficiente para usted.

+2

Gracias por tomarse el tiempo para explicar esto claramente ... lo probaré tarde con mis datos. –

+0

@Zeta ¿Cómo se llegó a exp (-8 * x * x)? Necesito aplicar esto a un problema similar que involucre las marcas de tiempo 'created_at' y' updated_at' donde ordeno por 'updated_at' pero necesito que caiga después de 6 horas de diferencia de' created_at' y no estoy seguro de cómo ajustar la fórmula para eso. – paulkon

+3

@paulon que podría ser un poco tarde para responder ... mire el primer gráfico (el rojo) en la respuesta de Zeta: este es el gráfico para exp (-8 * x * x), mostrando el dropoff aplicado a baseScore una vez la pista tiene más de una semana de antigüedad. Para obtener su dropoff después de 6 horas, haría algo como 'timeDiff = (now - track.created_at) .toHours' y luego:' if timeDiff> 6; x = timeDiff - 6; baseScore * = exp (-8 * x * x) '. Ajustar el 8 en la función exponencial: cuanto mayor sea el valor, más pronunciada será la caída :) Con -8: http://fooplot.com/plot/h0nfqukrj8 Con -50: http://fooplot.com/plot/e57bc1osnv –

Cuestiones relacionadas