Machine Learning - Project - Makeit / DataSource.ai

Daniel Morales
By Daniel Morales - Screencast # 6
Apr 24, 2020


Machine Learning - Project - Makeit / DataSource.ai

Este es un ejemplo de lo que veremos en las clases del bootcamp de Data Science de MakeitReal en asociación con DataSource.ai

Recursos:
  1. Dataset: https://drive.google.com/file/d/1cFC0m0fWDaPgNjUU8dlGU99I8CovyT7p/view?usp=sharing
  2. Ejercicio en Jupyter Notebook: https://drive.google.com/file/d/1ShoIKXPkY8Y9RcAs_6Ggup33LY75cU6I/view?usp=sharing
  3. Puedes encontrar este texto y código en Github para visualizarlo como un jupyter notebook aqui
  4. Solucion: La solucion la encontrarás en un link al final de este post. Recuerda retarte primero a ti mismo(a)!
La industria de la restauración esta más dura que nunca, con críticas en Internet desde el primer día de la apertura de un restaurante. Pero como amante de la comida, usted y su amigo deciden entrar en la industria y abrir su propio restaurante, Danielle's Delicious Delicacies. Dado que el éxito de un restaurante está altamente correlacionado con su reputación, usted quiere asegurarse de que Danielle's Delicious Delicacies tenga las mejores críticas en el sitio de reseñas de restaurantes más consultado: Yelp!

Aunque usted sabe que su comida será deliciosa, cree que hay otros factores que influyen en la calificación de Yelp y que, en última instancia, determinarán el éxito de su negocio. Con un conjunto de datos de diferentes características del restaurante y sus clasificaciones Yelp, usted decide usar un modelo de Regresión Lineal Múltiple para investigar qué factores afectan más la clasificación Yelp de un restaurante y predecir la clasificación Yelp para su restaurante.

En este proyecto trabajaremos con un conjunto de datos reales proporcionados por Yelp. Hemos proporcionado seis archivos, que se enumeran a continuación con una breve descripción:

yelp_business.json: datos del establecimiento relativos a la ubicación y los atributos de todas las empresas en el conjunto de datos yelp_review.json: metadatos de las calificaciones por empresa yelp_user.json: metadatos del perfil de usuario por empresa yelp_checkin.json: metadatos de facturación online por empresa yelp_tip.json: metadatos de consejos por empresa yelp_photo.json: metadatos de fotos por empresa

Nota: como puede ver los datos estan en .json, un formato diferente a .csv, pero no te preocupes, es lo mismo al momento de importarlos y trabajarlos, aqui te vamos a ir enseñando como, sigue adelante!


Cargar los datos y echar un vistazo

Para obtener una mejor comprensión del conjunto de datos podemos usar Pandas para explorar los datos en forma de DataFrame. En el siguiente bloque de código debes importar Pandas. El método read_json() lee los datos de un archivo json en un DataFrame, como se muestra a continuación:

df = pd.read_json('file_name.json', lines=True)

Cargue los datos de cada uno de los archivos json con las siguientes convenciones para fijar nombres:

yelp_business.json en un DataFrame llamado business
yelp_review.json en un DataFrame llamado reviews
yelp_user.json en un DataFrame nombrando users
yelp_checkin.json en un DataFrame llamado checkins
yelp_tip.json en un DataFrame llamado tips
yelp_photo.json en un DataFrame llamado photos

La importación de esos datos puede tardar de 10 a 20 segundos en ejecutarse dependiendo de su computadora, pero no se preocupe, una vez cargados, ¡ya está listo para empezar!

In [ ]:

Para poder ver más claramente la información en nuestro DataFrame, podemos ajustar el número de columnas mostradas (max_columns) y el número de caracteres mostrados en una columna (max_colwidth) con el siguiente código:

pd.options.display.max_columns = number_of_columns_to_display
pd.options.display.max_colwidth = number_of_characters_to_display

Ajuste max_columns a 60 y max_colwidth a 500. Estamos trabajando con algunos datos GRANDES aquí! (bienvenido al Big Data!)

In [ ]:

Inspeccione las primeras cinco filas de cada DataFrame usando el método .head() para obtener una visión general de los datos (asegúrese de revisar cada DataFrame en una celda separada para poder verlo correctamente).

In [ ]:

In [ ]:

In [ ]:

In [ ]:

In [ ]:

In [ ]:


¿Cuántos negocios diferentes hay en el conjunto de datos? ¿Cuáles son las diferentes características/features/columnas en el DataFrame reviews?

In [ ]:

¿Cuál es el rango de valores para las features del DataFrame users? Nota: puedes usar el metodo .describe() para hacer esto
In [ ]:

¿Cuál es la calificación Yelp, o estrellas, del establecimiento con business_id=5EvUIR4IzCWWUOOm0PsUZXjA Utilice la indexación booleana de Pandas para encontrar la clasificación de Yelp, usando la sintaxis de abajo:
df[df['column_we_know'] == 'value_we_know']['column_we_want']
In [ ]:


Fusionar los datos

Como estamos trabajando con datos de varios archivos, necesitamos combinar los datos en un solo DataFrame que nos permita analizar las diferentes características con respecto a nuestra variable objetivo, la clasificación Yelp.

Podemos hacer esto fusionando los múltiples DataFrames que tenemos juntos, uniéndolos en las columnas que tienen en común. En nuestro caso, esta columna de identificación única es el business_id.

Dados nuestros seis DataFrames, necesitaremos realizar 5 fusiones para combinar todos los datos en un solo DataFrame. Fusione primero business y reviews con un left join y asignelo a una variable llamada df

In [ ]:

Combine cada uno de los otros 4 DataFrames en nuestro nuevo DataFrame df para combinar todos los datos juntos. Asegúrese de que df es el DataFrame izquierdo en cada fusión y que hace left join en cada uno de ellos ya que no todos los DataFrame incluyen todos los negocios en el conjunto de datos (de esta manera no perderemos ningún dato durante las fusiones). Una vez combinada, imprima las columnas de df. ¿Qué características/features/columnas tiene este nuevo DataFrame
In [ ]:

In [ ]:

In [ ]:

In [ ]:

Limpieza de los datos

Nos estamos acercando mucho a la parte del análisis divertido! Sólo tenemos que limpiar un poco nuestros datos para que podamos centrarnos en las características que podrían tener poder predictivo para determinar la calificación Yelp de un establecimiento.

En un modelo de Regresión Lineal, nuestras características serán idealmente variables continuas que afectan a nuestra variable dependiente, o sea la clasificación de Yelp. Para este proyecto también se trabajará con algunas características que son binarias, en la escala [0,1]. Con esta información, podemos eliminar cualquier columna en el conjunto de datos que no sea continua o binaria, y sobre la que no queramos hacer predicciones. La siguiente celda contiene una lista de estas características innecesarias. Sáquelos de df con la sintaxis de drop de Pandas, basicamente necesitamos remover las siguientes columnas:

'address',
'attributes',
'business_id',
'categories',
'city',
'hours',
'is_open',
'latitude',
'longitude',
'name',
'neighborhood',
'postal_code',
'state',
'time'
In [ ]:

In [ ]:

In [ ]:

Ahora sólo tenemos que comprobar nuestros datos para asegurarnos de que no nos faltan valores, o NaNs, lo que impedirá que el modelo de Regresión Lineal funcione correctamente. Para ello podemos utilizar la sentencia df.isna().any(). Esto comprobará todas nuestras columnas y devolverá True si hay valores faltantes o NaNs, o False si no hay valores faltantes. Compruebe si a df le falta algún valor.

In [ ]:

Como puede ver, hay algunas columnas con valores que faltan. Dado que nuestro conjunto de datos no tiene información registrada para algunos negocios en estas columnas, asumiremos que las páginas de Yelp no muestran estas características. Por ejemplo, si hay un valor NaN para number_pics, significa que el negocio asociado no tenía ninguna imagen publicada en su página de Yelp. De esta manera podemos reemplazar todos nuestros NaNs con 0s. Para ello podemos utilizar el método .fillna().

Rellena los valores que faltan en df con 0. Después, confirme que los valores que faltan han sido rellenados con df.isna().any().

In [ ]:

In [ ]:

Análisis exploratorio

Ahora que nuestros datos están todos juntos, investiguemos algunas de las diferentes características para ver qué podría correlacionarse más con nuestra variable dependiente, la calificacion de Yelp (llamada stars en nuestro DataFrame). Las características con las mejores correlaciones podrían ser las más útiles para nuestro modelo de Regresión Lineal!

Los DataFrames de Pandas tienen un método realmente útil, .corr(), que nos permite ver los coeficientes de correlación para cada par de nuestras diferentes características. Recuerde, una correlación de 0 indica que dos características no tienen relación lineal, un coeficiente de correlación de 1 indica que dos características tienen una relación lineal positiva perfecta, y un coeficiente de correlación de -1 indica que dos características tienen una relación lineal negativa perfecta.

llame .corr() sobre df. Verás que number_funny_votes tiene un coeficiente de correlación de 0.001320 con respecto a stars o clasificación de Yelp. Esta es una correlación muy débil. ¿Qué características se correlacionan mejor, tanto positiva como negativamente, con la clasificación Yelp?

In [ ]:

Para visualizar mejor estas relaciones, podemos graficar ciertas características contra nuestra variable dependiente, la clasificación de Yelp. importe Matplotlib. Podemos usar el método .scatter() de Matplotlib para graficar cómo son estas correlaciones (añada como tercer parametro al scatter lo siguiente alpha=0.1)

Grafique las tres características que más se correlacionan con la clasificación Yelp (average_review_sentiment, average_review_length, average_review_age) contra stars, nuestra clasificación Yelp. Luego trace una característica de baja correlación, como por ejemplo, number_funny_votes, contra stars.

Nota: que es average_review_sentiment?, average_review_sentiment es la puntuación media de todos los comentarios en la página Yelp de un negocio. La puntuación de sentimiento para una revisión se calculó utilizando la herramienta de análisis de sentimiento VADER. VADER utiliza un conjunto de palabras positivas y negativas, junto con reglas gramaticales codificadas, para estimar qué tan positiva o negativa es una declaración. Las puntuaciones van de 1, más negativas, a +1, más positivas, con una puntuación de 0 que indica una declaración neutral. Aunque no es perfecto, VADER hace un buen trabajo adivinando el sentimiento de los datos de texto!

In [ ]:

In [ ]:

In [ ]:


Selección de datos

Para poner nuestros datos en un modelo de Regresión Lineal, necesitamos separar nuestras características/features/columnas para modelar las clasificaciones de Yelp.

De nuestro análisis de correlación vimos que las tres características con las correlaciones más fuertes para la calificación de Yelp son el average_review_sentiment, average_review_length, y average_review_age.

Ya que queremos profundizar un poco más que usar solo el average_review_sentiment, que comprensiblemente tiene una correlación muy alta con la clasificación Yelp, elijamos crear nuestro primer modelo con average_review_length y average_review_age como características.

Cree una nueva columna de DataFrame que contenga las columnas sobre las que queremos modelar y llamelo features con las columnas: average_review_length y average_review_age. Luego cree otro DataFrame llamado ratings que almacene el valor que queremos predecir, la clasificación Yelp o las stars en df.
In [ ]:

Dividir los datos en conjuntos de entrenamiento y pruebas

Estamos casi listos para modelar! Pero primero, necesitamos dividir nuestros datos en un conjunto de entrenamiento y un conjunto de pruebas para poder evaluar qué tan bien funciona nuestro modelo.

Usaremos la función train_test_split de scikit-learn para hacer esta división. Esta función toma dos parámetros requeridos: los datos, o nuestras características, seguidos por nuestra variable dependiente, en nuestro caso la clasificación Yelp. Ajuste el parámetro opcional test_size a 0,2. Finalmente, establezca el parámetro opcional random_state en 1. Esto hará que sus datos se dividan de la misma manera que los datos en nuestro código de solución.

In [ ]:


Crear y entrenar al modelo

Ahora que nuestros datos están divididos en conjuntos de entrenamiento y pruebas, ¡por fin podemos modelar! Importe LinearRegression desde el módulo linear_model de scikit-learn.

Cree un nuevo objeto LinearRegression llamado model. El método .fit() ajustará nuestro modelo de Regresión Lineal a nuestros datos de entrenamiento y calculará los coeficientes para nuestras características. Llamar al método .fit() en el modelo con X_train y y_train como parámetros. De esta manera, nuestro modelo ya ha sido entrenado en nuestros datos de entrenamiento!

In [ ]:


Evaluar y comprender el modelo

Ahora podemos evaluar nuestro modelo de varias maneras. La primera forma será usando el método .score(), que proporciona el valor R^2 para nuestro modelo. Recuerde, R^2 es el coeficiente de determinación, o una medida de cuánto de la varianza en nuestra variable dependiente, la clasificación Yelp predicha, se explica por nuestras variables independientes, nuestros datos de características.

Los valores de R^2 van de 0 a 1, con 0 indicando que el modelo creado no se ajusta a nuestros datos en absoluto, y con 1indicando que el modelo se ajusta perfectamente a nuestros datos de características.

Llame .score()en nuestro modelo con X_train y y_traincomo parámetros para calcular nuestra puntuación R^2 de entrenamiento. Luego llame de nuevo al score()en el modelo con X_test y y_test como parámetros para calcular R^2 para nuestros datos de prueba.

¿Qué dicen estos valores de R^2 sobre nuestro modelo? ¿Cree usted que estas características por sí solas son capaces de predecir eficazmente las clasificaciones de Yelp?

In [ ]:

In [ ]:

Después de tanto trabajo, por fin podemos echar un vistazo a los coeficientes de nuestras diferentes características!

El modelo tiene un atributo .coef_ que es una matriz de los coeficientes de característica determinados al ajustar nuestro modelo a los datos de entrenamiento. Para que sea más fácil ver qué característica corresponde a qué coeficiente, hemos proporcionado un código en la celda que une una lista de nuestras características con los coeficientes y las ordena en orden descendente desde la más predictiva a la menos predictiva.

sorted(list(zip(['average_review_length','average_review_age'],model.coef_)),key = lambda x: abs(x[1]),reverse=True)

Copiela y peguela en la siguiente celda

In [ ]:

Por último, podemos calcular las clasificaciones Yelp previstas para nuestros datos de pruebas y compararlas con sus clasificaciones Yelp reales.

Nuestro modelo tiene un método .predict() que utiliza los coeficientes del modelo para calcular el valor de Yelp predicho. Llamar a .predict() en X_test y asignar los valores a y_predicted.

Usa Matplotlib para trazar y_test vs y_predicted. Para un modelo de regresión lineal perfecto, esperaríamos ver los datos trazados a lo largo de la línea y = x, ¿Es éste el caso? Si no, ¿por qué no?

In [ ]:

In [ ]:

In [ ]:


Definir diferentes subconjuntos de datos

Después de evaluar el primer modelo, puede ver que average_review_length y average_review_age por sí solas no son los mejores predictores para la clasificación de Yelp.

Vamos a hacer un poco más de modelado con diferentes subconjuntos de características y ver si podemos lograr un modelo más preciso!

En las celdas de abajo hemos proporcionado diferentes listas de subconjuntos de características con las que modelaremos y evaluaremos. ¿Qué otros subconjuntos de características le gustaría probar? ¿Por qué crees que esos conjuntos de características son más predictivos de la clasificación Yelp que otros? Cree al menos un subconjunto más de características a partir de las cuales desea predecir las clasificaciones de Yelp. Copie y pegue los subconjuntos en la siguiente celda

# subset of only average review sentiment
sentiment = ['average_review_sentiment']

# subset of all features that have a response range [0,1]
binary_features = ['alcohol?','has_bike_parking','takes_credit_cards','good_for_kids','take_reservations','has_wifi']

# subset of all features that vary on a greater range than [0,1]
numeric_features = ['review_count','price_range','average_caption_length','number_pics','average_review_age','average_review_length','average_review_sentiment','number_funny_votes','number_cool_votes','number_useful_votes','average_tip_length','number_tips','average_number_friends','average_days_on_yelp','average_number_fans','average_review_count','average_number_years_elite','weekday_checkins','weekend_checkins']

# all features
all_features = binary_features + numeric_features
In [ ]:

In [ ]:


Otros modelos

Ahora que tenemos listas de diferentes subconjuntos de características, podemos crear nuevos modelos a partir de ellos. Para poder comparar más fácilmente el rendimiento de estos nuevos modelos, hemos creado una función para usted llamada model_these_features().

Esta función replica el proceso de construcción del modelo que acaba de completar con nuestro primer modelo! Tómese un tiempo para revisar cómo funciona la función, analizándola línea por línea. Rellene los comentarios vacíos con una explicación de la tarea que el código debajo está realizando.

import numpy as np

# take a list of features to model as a parameter
def model_these_features(feature_list):

    # define ratings and features, with the features limited to our chosen subset of data
    ratings = df.loc[:,'stars']
    features = df.loc[:,feature_list]

    # perform train, test, split on the data
    X_train, X_test, y_train, y_test = train_test_split(features, ratings, test_size = 0.2, random_state = 1)

    # don't worry too much about these lines, just know that they allow the model to work when
    # we model on just one feature instead of multiple features. Trust us on this one :)
    if len(X_train.shape) < 2:
        X_train = np.array(X_train).reshape(-1,1)
        X_test = np.array(X_test).reshape(-1,1)

    # create and fit the model to the training data
    model = LinearRegression()
    model.fit(X_train,y_train)

    # print the train and test scores
    print('Train Score:', model.score(X_train,y_train))
    print('Test Score:', model.score(X_test,y_test))

    # print the model features and their corresponding coefficients, from most predictive to least predictive
    print(sorted(list(zip(feature_list,model.coef_)),key = lambda x: abs(x[1]),reverse=True))

    # calculate the predicted Yelp ratings from the test data
    y_predicted = model.predict(X_test)

    # plot the actual Yelp Ratings vs the predicted Yelp ratings for the test data
    plt.scatter(y_test,y_predicted)
    plt.xlabel('Yelp Rating')
    plt.ylabel('Predicted Yelp Rating')
    plt.ylim(1,5)
    plt.show()

Copielo y peguelo en la siguiente celda

In [ ]:


Una vez que se sienta cómodo con los pasos de la función, ejecute modelos en los siguientes subconjuntos de datos utilizando model_these_features():

sentiment: sólo average_review_sentiment

binary_features: todas las características que tienen un rango de respuesta [0,1]

numeric_features: todas las características que varían en un rango mayor que [0,1]

all_features: todas las características

feature_subset: su propio subconjunto de características

¿Cómo afecta el cambio de los conjuntos de características al valor R^2 del modelo? ¿Qué características son más importantes para predecir la clasificación Yelp en los diferentes modelos?

In [ ]:

In [ ]:

In [ ]:

In [ ]:


Debut de Danielle's Delicious Delicacies

Ha cargado los datos, los ha limpiado, modelado y evaluado. Estás cansado, pero resplandeciente de orgullo después de todo el trabajo duro. Cierra los ojos y puedes ver claramente el día de apertura de Delicious Delicacies de Danielle con una fila de personas en la puerta. Pero, ¿cuál será su calificación de Yelp? Usemos nuestro modelo para hacer una predicción.

Nuestro mejor modelo era el que utilizaba todas las funciones!!, así que volveremos a trabajar con este modelo. En la celda de abajo imprima all_features para obtener un recordatorio de las características con las que estamos trabajando.

In [ ]:

Ejecute la celda de abajo para agarrar todas las características y volver a entrenar a nuestro modelo en ellas.

features = df.loc[:,all_features]
ratings = df.loc[:,'stars']
X_train, X_test, y_train, y_test = train_test_split(features, ratings, test_size = 0.2, random_state = 1)
model = LinearRegression()
model.fit(X_train,y_train)

In [ ]:

Para darle una perspectiva de los restaurantes que ya existen, hemos proporcionado los valores medios, mínimos y máximos para cada característica/feature/columna a continuación. ¿Será Danielle's Delicious Delicacies otro restaurante promedio, o será un gigante de 5 estrellas entre las masas?

pd.DataFrame(list(zip(features.columns,features.describe().loc['mean'],features.describe().loc['min'],features.describe().loc['max'])),columns=['Feature','Mean','Min','Max'])
In [ ]:

Basado en sus planes para el restaurante, cómo espera que sus clientes califiquen en su página de Yelp para cada uno de los features? llene los espacios en blanco en la matriz NumPy a continuación con sus valores deseados.

El primer espacio en blanco corresponde a la característica en index=0 en el DataFrame de arriba, alcohol? y el último espacio en blanco corresponde a la característica en index=24, weekend_checkins. Asegúrese de introducir 0 o 1 para todas las características binarias, y si no está seguro de qué valor poner para una característica, seleccione la media en el DataFrame de arriba.

Guarde el array de numpy en una variable llamada danielles_delicious_delicacies y recuerde hacerle un reshape(1, -1)

Después de ingresar los valores, ejecute la celda de predicción a continuación para recibir su calificación de Yelp! ¿Cómo va a ser el debut de Danielle Delicious Delicacies?

In [ ]:

In [ ]:


Próximos pasos

Usted ha construido con éxito un modelo de regresión lineal que predice la clasificación Yelp de un restaurante! Como has visto, puede ser bastante difícil predecir una calificación como ésta incluso cuando tenemos una plétora de datos.

¿Qué otras preguntas le vienen a la mente cuando ve los datos que tenemos? ¿Qué ideas cree usted que podrían pronosticar de un tipo diferente de análisis? Aquí hay algunas ideas para reflexionar:
  • ¿Podemos predecir el tipo de cocina de un restaurante en función de los usuarios que la revisan?
  • ¿Qué restaurantes son similares entre sí en otros aspectos además del tipo de cocina?
  • ¿Existe un ambiente diferente en los restaurantes, y qué tipo de restaurantes se ajustan a estos conceptos?
  • ¿Cómo afecta el estatus de las redes sociales a la credibilidad y visibilidad de un restaurante?

A medida que avance en el campo de la ciencia de datos, podrá crear modelos que aborden estas preguntas y muchas más. Pero mientras tanto, felicitece, ha alcanzado un gran logro!!

Solucion:
Recuerda que lo ideal es retarte a ti mismo a hacer estos proyectos de forma individual. Sin embargo, si estas atascado(a) en algún punto, aqui podrás encontrar la solución a este proyecto de machine learning.

“Machine Learning - Project - Makeit / DataSource.ai”
– Daniel Morales twitter social icon Tweet

Share this article:

0 Comments

Post a comment
Log In to Comment
divider graphic

Related Screencasts

Jul 08, 2020
18

Python Data Types

Este video es PRO, suscribete aqui: https://www.datasource.ai/es/home/pricingSi ya estas suscrito, aprende y avanza!

Daniel Morales
By Daniel Morales
May 29, 2020
157

Complete Project with Numpy

Este proyecto abarca los diferentes temas vistos con Numpy

Daniel Morales
By Daniel Morales
May 28, 2020
104

Binomial Distribution and Exercise with NumPy

Para ver este video debes estar inscrito, asi que inscribete y sigue aprendiendo! Si ya estas inscrito, dale play al video y sigue aprendiendo!

Daniel Morales
By Daniel Morales
arrow-up icon