Banda Ancha EU

Comunidad de usuarios
de fibra, móvil y ADSL

Bugs/Devel

Moderación de comentarios

Josh

En un foro, los tópicos reciben puntuaciones de los lectores. Vamos a suponer que tenemos 10 tópicos, con unas puntuaciones entre -18 el que menos y 125 el que más. Si saco la media de puntuación de los 10 tópicos me da 22.
Es decir, tengo tres puntos de referencia: mínimo -18, medio 22 y máximo 125.
Lo que quiero es transportar proporcionalmente estos puntos a una escala compensada donde el mínimo es -3, medio 0 y máximo 6.
Se que -18 = -3, 22 = 0 y 125 = 6. Ahora necesito saber la puntuación compensada de un comentario con puntuación 46.
En principio tiro de regla de tres:
125 - 22 = 103
46 - 22 = 24
Si 103 es 6
24 sera x
x = 24 * 6 / 103 = 1,39
Es decir el comentario con puntuación 46 en realidad tiene una puntuación compensada de 1,39.
Ahora quiero calcular un negativo: - 12 y pasarlo a compensada.
Las matemáticas no son mi fuerte. ¿alguien me puede echar un cable con una formula eficaz para calcular esto?

Este tema está cerrado a nuevas respuestas. Abre un nuevo tema para retomar la conversación.
quilloquepasa

No pillo muy bien lo del "medio", pero estas operaciones se realizan con un sistema de ecuaciones de dos incógnitas. ;-)

quilloquepasa

Te quedaría así:

aX + b = 6........ (x)=125
aX + b = -3....... (x)=-18

🗨️ 7
Josh

¿Y como se resuelve eso? Explicado para tontos ... :-?

🗨️ 6
POC

La formula a emplear siempre será 6x=106

Esa es la proporcion que quieres emplear. Una puntuación de -12 te dará una compensada de -0.67.

Si el -12 es el valor inicial, entonces sería -12-22=-34
Y eso daría una compensada de -34*6/106=-1,92

no?

🗨️ 5
Josh

Os pongo mis variables y me escribis la formula en Ruby que es lo que yo entiendo ;P

min, avg, max = -18, 22, 125
scale_min, scale_avg, scale_max = -3, 0, 6

punt_del_comentario = -12

punt_comp_del_comentario = ????

Por ejemplo con la regla de 3 sería:

punt_comp_del_comentario = ((punt_del_comentario - avg) * 6 / (max - avg))

🗨️ 4
POC
🗨️ 3
Josh
🗨️ 2
POC
🗨️ 1
Josh
MaX

Básicamente lo que quieres es una recta que pase por los puntos:
(-3, -18), (0, 22), (6, 125), y haciendo los cálculos así deprisa no existe esa recta.

Lo puedes comprobar con este applet.

Yo me saltaría la restricción de (0, 22) y haría lo siguiente:
[-18, 125] es un rango de 144 números.
[-3, 6] es un rango de 10 números.

Con un X en [-18, 125], queremos moverlo a [-3, 6]:
X + 18: ahora todos son positivos. Es decir: rango [0, 271]
(X + 18) * 10/144 : lo "comprimimos" en la escala [-3, 6], pero empezando en 0, es decir, rango [0, 9]
((X + 18) * 10/144) - 3: rango [-3, 6]

En java:
public class Prueba {
public static double R0_MIN = -18;
public static double R0_MAX = 125;
public static double R0_RANGO = (R0_MAX - R0_MIN);

public static double R1_MIN = -3;
public static double R1_MAX = 6;
public static double R1_RANGO = (R1_MAX - R1_MIN);

public static void main(String args[]) {
for(double i = R0_MIN; i <= R0_MAX; ++i) {
System.out.println(i + " -> " + escala(i));
}
}

public static double escala(double x) {
return ((x - R0_MIN) * (R1_RANGO / R0_RANGO)) + R1_MIN;
}
}

Probablemente me haya equivocado en algún cálculo por hacerlo demasiado deprisa... pero esa es la idea.
A la tarde lo repaso.

Si pruebas con números fuera del rango R0 también debería funcionar... porque la idea es se está calculando la recta que pasa por esos puntos.
Si la restricción (0, 22) es muy importante, divide el rango inicial en 2 partes (> 22 y <=22).

Editado: ¡Previsualización ya! xD

🗨️ 8
Josh

Muy bueno. EL tema es que no es una recta. Osea que para que 22 = 0 tendre que hacer dos calculos dependiendo de si esta por debajo de avg o no.
Gracias MAX ;) veo que le pegas a java

🗨️ 7
MaX

Sí, demasiado java en vena xD

El nombre de lo que quieres hacer realmente es interpolación.
La sencilla es la lineal, pero en tu caso no puede hacerse linealmente del tirón porque no es una recta.
Como en este caso no es importante que sea suave la interpolación [es como si tuvieras un piquito en el punto (0, 22)], lo más fácil es dividir el rango.

Si fuera importante habría que pasar a interpolaciones más complicadas (polinómicas, splines, ...).

;)

🗨️ 2
Josh

La razón de dividirlo es destacar más los buenos comentarios que esconder los malos: más premio y menos castigo.
Ya te abriré el svn para que me eches un cable cuando cuelgue la beta... :-D

🗨️ 1
POC
quilloquepasa

En ese caso para los positivos te quedaría así:

aX + b = 6....... (x)=125
aX + b = 0....... (x)=22

Primero despejamos:

b = 6 - 125a
b = -22a

Reducimos:

0 = 6 - 103a

a = 6 / 103

a = 0.058

Sustituimos a:

b = 6 - (0.058*125)

b = -1.25

Resultado de la ecuación:

a = 0.058
b = -1.25

Luego ya sólo tienes que sustituir los valores de X.

Para el ejemplo de 46:

ax + b = ?

(0.058*46) - 1,25 = 1.418

quilloquepasa

Para los negativos:

aX + b = 0....... (x)=22
aX + b = -3....... (x)=-18

Primero despejamos:

b = -22a
b = -3 + 18a

Reducimos:

0 = +3 - 40a

a = 6 / 40

a = 0.075

Sustituimos a:

b = - 0.075 * 22

b = -1.65

Resultado de la ecuación:

a = 0.075
b = -1.65

Luego ya sólo tienes que sustituir los valores de X.

Para el ejemplo de -10:

ax + b = ?

0,075 * (-10) + (-1.65) = -2.4

----------------------------------------

En programación para ambos sistemas empleas sentencias condicionales con bucle para sustituir los valores de la x. Fácil, fácil.

🗨️ 2
Josh

Gracias quillo. Al final lo he solucionado con vuestras ideas.

🗨️ 1
Bodescu

Dado que es tema resuelto, no tiene demasiada importancia, pero...

Por que no te sirve la escala actual? Es de verdad necesario hacer la conversion?

EDITO: Vale, releyendo el hilo ya he visto el fin. No es mala idea ;)

Un saludo