Técnicas de aprendizaje automático para estimar la edad de los usuarios en función de los sitios de Facebook que les gustan


25

Tengo una base de datos de mi aplicación de Facebook y estoy tratando de usar el aprendizaje automático para estimar la edad de los usuarios en función de los sitios de Facebook que les gustan.

Hay tres características cruciales de mi base de datos:

  • la distribución de edad en mi conjunto de entrenamiento (12k de usuarios en total) está sesgada hacia los usuarios más jóvenes (es decir, tengo 1157 usuarios de 27 años y 23 usuarios de 65 años);

  • muchos sitios no tienen más de 5 me gusta (he filtrado los sitios de FB con menos de 5 me gusta).

  • Hay muchas más características que muestras.

Entonces, mis preguntas son: ¿qué estrategia sugeriría para preparar los datos para un análisis posterior? ¿Debo realizar algún tipo de reducción de dimensionalidad? ¿Qué método de ML sería el más apropiado para usar en este caso?

Principalmente uso Python, por lo que las sugerencias específicas de Python serían muy apreciadas.


1
Cuando dices "muchas más funciones que muestras", supongo que te refieres a que el número único de sitios favoritos es >> número de usuarios. ¿Es ese también el caso del dominio raíz de los sitios? es decir, ¿son un número de URL de youtube.com o cnn.com en los sitios o ya se derivan al dominio? Me inclino hacia la reducción de la dimensionalidad al contraer las URL a las raíces del dominio en lugar de páginas específicas si es posible.
cwharland

Gracias por responder. El número de características (sitios preferidos únicos) es de 32k, mientras que el número de muestras (usuarios) es de 12k. Las características son páginas de Facebook, por lo que no es necesario detener las URL. A un usuario le puede gustar facebook.com/cnn o no. Sin embargo, me gusta la idea de tratar de estimar la edad de los usuarios en función de los enlaces que comparten :)
Wojciech Walczak

Ahhh, leí mal la descripción de los sitios favoritos. Gracias por la aclaración.
cwharland

Respuestas:


16

Una cosa para comenzar sería k-NN. La idea aquí es que tiene una matriz de usuario / elemento y para algunos de los usuarios tiene una edad reportada. La edad de una persona en la matriz de elementos de usuario puede estar bien determinada por algo como la edad media o mediana de algunos vecinos más cercanos en el espacio de elementos.

Entonces, tiene cada usuario expresado como un vector en el espacio del elemento, encuentre los k vecinos más cercanos y asigne al vector en cuestión algunas estadísticas resumidas de las edades de los vecinos más cercanos. Puede elegir k en un límite de distancia o de manera más realista asignando iterativamente edades a una bodega de tren y eligiendo la k que minimiza el error en esa asignación.

Si la dimensionalidad es un problema, puede realizar fácilmente la reducción en esta configuración mediante la descomposición de un solo valor eligiendo los m vectores que capturan la mayor variación en todo el grupo.

En todos los casos, dado que cada característica es binaria, parece que la similitud del coseno sería su métrica de distancia.

Necesito pensar un poco más sobre otros enfoques (regresión, rf, etc.) dado el enfoque limitado de su espacio de características (todas las variantes de la misma acción, gusto) Creo que el enfoque de usuario / elemento podría ser el mejor.

Una nota de precaución, si las edades que tiene para el tren son autoinformadas, es posible que deba corregir algunas de ellas. Las personas en Facebook tienden a informar edades en la década en que nacieron. Trace un histograma de las fechas de nacimiento (derivadas de las edades) y vea si tiene picos en décadas como 70, 80, 90.


Hola, tu respuesta es bastante similar a mi estrategia real. Utilicé sklearn.neighbors.KNeighborsRegressorcon la métrica del coseno en el espacio reducido SVD (después de aplicar SVD, el error de estimación promedio bajó de ~ 6 años a ~ 4). Los usuarios de mi base de datos tienen entre 18 y 65 años (los usuarios mayores fueron filtrados), por lo que hay 48 clases posibles. Me pregunto si no son demasiadas clases para kNN y si debería tratarlo como una regresión o un problema de clasificación (creo que ambos son aplicables).
Wojciech Walczak

Puedo decir, anecdóticamente, que he usado Bosques aleatorios por clase para ajustar una cantidad de clases individualmente y luego combiné los resultados de cada uno de esos modelos de varias maneras. En este caso, incluso puede pensar en asignar probabilidades previas a la edad de cada usuario con el kNN, luego recorrer cada modelo basado en la clase, usar esos puntajes para actualizar las probabilidades anteriores para cada clase y elegir la clase más probable de esos posteriores. Parece demasiado complicado, pero en el peor de los casos tendría la precisión de kNN.
cwharland

7

Recientemente hice un proyecto similar en Python (prediciendo opiniones usando datos similares a FB), y obtuve buenos resultados con el siguiente proceso básico:

  1. Lea en el conjunto de entrenamiento (n = N) iterando sobre registros delimitados por comas línea por línea y use un contador para identificar las páginas más populares
  2. Para cada una de las K páginas más populares (usé alrededor de 5000, pero puedes jugar con diferentes valores), usa pandas.DataFrame.isin para probar si a cada individuo en el conjunto de entrenamiento le gusta cada página, luego haz un marco de datos N x K de los resultados (lo llamaré xdata_train)
  3. Cree una serie (la llamaré ydata_train) que contenga todas las variables de resultado (en mi caso opiniones, en su edad) con el mismo índice que xdata_train
  4. Configure un clasificador de bosque aleatorio a través de scikit-learn para predecir ydata_train basado en xdata_train
  5. Utilice las pruebas de validación cruzada de scikit-learn para ajustar los parámetros y refinar la precisión (ajuste del número de páginas populares, número de árboles, tamaño mínimo de hoja, etc.)
  6. Genere un clasificador de bosque aleatorio y una lista de las páginas más populares con pickle (o guárdelo si está haciendo todo a la vez)
  7. Cargue el resto de sus datos, cargue la lista de páginas populares (si es necesario) y repita el paso 2 para generar xdata_new
  8. Cargue el clasificador de bosque aleatorio (si es necesario) y úselo para predecir valores para los datos xdata_new
  9. Envíe los puntajes pronosticados a un nuevo CSV u otro formato de salida que elija

En su caso, necesitaría cambiar el clasificador por un regresor (así que vea aquí: http://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestRegressor.html ) pero de lo contrario el mismo proceso debería funcionar sin muchos problemas.

Además, debe tener en cuenta la característica más sorprendente de los bosques aleatorios en Python: la paralelización instantánea. Aquellos de nosotros que comenzamos a hacer esto en R y luego nos mudamos siempre estamos asombrados, especialmente cuando trabajas en una máquina con unas pocas docenas de núcleos (ver aquí: http://blog.yhathq.com/posts/comparing- random-forest-in-python-and-r.html ).

Finalmente, tenga en cuenta que esta sería una aplicación perfecta para el análisis de red si tiene los datos de amigos y de los propios individuos. Si puede analizar las edades de los amigos de un usuario, la edad del usuario seguramente será dentro de un año o dos de la mediana entre sus amigos, particularmente si los usuarios son lo suficientemente jóvenes como para haber construido sus redes de amigos mientras todavía están en escuela (ya que la mayoría serán compañeros de clase). Es probable que esa predicción supere a cualquiera que obtenga del modelado: este es un ejemplo de libro de texto de un problema en el que los datos correctos> el modelo correcto cada vez.

¡Buena suerte!


2
Un aspecto interesante del uso de los mejores 5000 sitios es el hecho de que pueden no ser buenos para segmentar a los usuarios por edad. Los mejores sitios, por construcción, son los que todos visitan. Por lo tanto, no son muy buenos para segmentar a sus usuarios ya que todas las clasificaciones posibles (edades) se han involucrado con esos sitios. Esta es una noción similar a la parte idf de tf-idf. idf ayuda a filtrar el ruido "todos tienen esta característica". ¿Cómo se clasifican los sitios más visitados como características en sus parcelas de importancia variable con su RF?
cwharland

1
Buen punto. Una solución fácil para esto sería estratificar el conjunto de datos de entrenamiento en contenedores J age (por ejemplo, 13-16, 17-20, 21-24, etc.) y tomar las páginas superiores (K / J) para cada grupo. Eso aseguraría que tenga una representación significativa para cada grupo. Ciertamente habrá cierta superposición entre los grupos, por lo que si fueras muy quisquilloso, quizás quieras tomar las páginas únicas (K / J) superiores para cada grupo, pero creo que eso podría ser excesivo.
Therriault

5

Otra sugerencia es probar la regresión logística . Como una ventaja adicional, los pesos (coeficientes) del modelo le darán una idea de qué sitios son distributivos por edad.

Sklearn ofrece el paquete sklearn.linear_model.LogisticRegression que también está diseñado para manejar datos dispersos.

Como se menciona en los comentarios, en el presente caso, con más variables de entrada que muestras, debe regularizar el modelo (con sklearn.linear_model.LogisticRegression use el penalty='l1'argumento).


1
Creo que con LR tendrías que hacer varios modelos para contenedores de edad. ¿Cómo compararía dos modelos para diferentes contenedores de edad que predicen el mismo problema de inclusión para un usuario?
cwharland

1
Tenga en cuenta que LR falla cuando hay más variables que observaciones y funciona mal si no se cumplen los supuestos del modelo. Para usarlo, la reducción de dimensionalidad debe ser un primer paso.
Christopher Louden

1
@cwharland no debe considerar que la variable de respuesta sea categórica, ya que es continua por naturaleza y discretizada por la definición del problema. Considerarlo categórico significaría decirle al algoritmo que predecir la edad de 16 años cuando en realidad tiene 17 años es un error tan grave como predecir 30 cuando en realidad tiene 17 años. Considerarlo de forma continua garantiza que los errores pequeños (16 vs 17) se consideren errores pequeños y grandes ( 30 vs 17) se consideran grandes. La regresión logística se utiliza en este caso para predecir el valor continuo y no estimar las probabilidades posteriores.
damienfrancois

@ChristopherLouden Tiene razón en que la versión vainilla de la regresión logística no es adecuada para el caso 'grande p pequeño n', debería haber mencionado que la regularización es importante en el presente caso. Actualizo mi respuesta. Pero el LR regularizado por L1 es una especie de selección de características, por lo que considero que no es necesario un paso FS preliminar.
damienfrancois

@damienfrancois: definitivamente estoy de acuerdo. Me preocupa un poco que en este caso LR penalice los valores intermedios con demasiada severidad. Parece que no hay motivación para mapear a una curva sigmoidea dado que no está particularmente interesado en los valores de edad extrema. Quizás estoy malinterpretando el uso sin embargo.
cwharland

4

Algunas investigaciones de D. Nguyen et al. intente predecir la edad del usuario de Twitter en función de sus tweets. Quizás los encuentres útiles. Utilizan regresión logística y lineal.


3

Además de los métodos más sofisticados, puedes probar la fórmula de Bayes

P (I | p1 ... pn) = P (p1 ... pn | I) P (I) / sum_i (P (p1 ... pn | i) P (i))

P (I | p1 ... pn) es la probabilidad de que un usuario pertenezca al grupo de edad I si le gustó p1, .., pn

P (i) es la probabilidad de que un usuario pertenezca al grupo de edad i

P (p1 .. pn | i) es la probabilidad de que a un usuario le haya gustado p1, .., pn si pertenece al grupo de edad i.

  • Ya tiene las estimaciones para P (i) de sus datos: esta es solo la proporción de usuarios en el grupo de edad I.
  • Para estimar P (p1 ... pn | i), para cada grupo de edad calculo la probabilidad (frecuencia) p_ij de que le guste una página j. Para que p_ij no sea cero para todos los j, puede mezclar la frecuencia para toda la población con un peso pequeño.

  • Luego, log P (p1 ... pn | i) = sum (log p_ij, i = p1, .., pn), la suma de todas las páginas que le gusta a un nuevo usuario. Esta fórmula sería aproximadamente cierta suponiendo que a un usuario le gusten las páginas de su grupo de edad de forma independiente.

  • Teóricamente, también debe agregar log (1-p_ij) para todo lo que no le ha gustado, pero en la práctica debe encontrar que la suma de log (1-p_ij) será irrelevantemente pequeña, por lo que no necesitará demasiado mucha memoria

Si usted u otra persona ha intentado esto, comente sobre el resultado.


2

Este es un problema muy interesante.

Me enfrenté a uno similar al analizar las imágenes que los usuarios suben a la red social. Hice el siguiente enfoque:

  • En lugar de asociar datos a edades (15 años, 27 años, ...) lo que hice fue establecer diferentes grupos de edades: menores de 18 años, de 18 a 30 y mayores de 30 (esto se debe al problema específico que teníamos) enfrentarse, pero puede elegir los intervalos que desee). Esta división ayuda mucho a resolver el problema.
  • Posteriormente, creé un agrupamiento jerárquico (divisivo o agregativo). Luego elijo aquellas ramas en las que tenía usuarios con edades conocidas (o edades de grupo) y luego para esa rama extendí la misma edad a ese grupo.

Este enfoque es el aprendizaje semi-supervisado y lo recomendé en caso de que solo tenga algunos datos etiquetados.

Tenga en cuenta que en una red social, las personas generalmente mienten sobre la edad (solo por diversión o, a veces, porque quieren camuflarse en la red social).

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.