Merge branch 'microsoft:main' into main

pull/505/head
Md. Abdul Mutalib 5 years ago committed by GitHub
commit 423d5c0c88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,13 @@
name: Lock closed issue
on:
issues:
types: [closed]
jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: OSDKDev/lock-issues@v1.1
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"

@ -0,0 +1,207 @@
# Construye un modelo de regresión usando Scikit-learn: prepara y visualiza los datos
![Infografía de visualización de datos](../images/data-visualization.png)
Infografía por [Dasani Madipalli](https://twitter.com/dasani_decoded)
## [Examen previo a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/11/)
> ### [Esta lección se encuentra disponible en R!](../solution/R/lesson_2-R.ipynb)
## Introducción
Ahora que has configurado las herramientas necesarias para iniciar el trabajo con la construcción de modelo de aprendizaje automático con Scikit-learn, estás listo para comenzar a realizar preguntas a tus datos. Mientras trabajas con los datos y aplicas soluciones de ML, es muy importante entender cómo realizar las preguntas correctas para desbloquear el potencial de tu conunto de datos.
En esta lección, aprenderás:
- Cómo preparar tus datos para la construcción de modelos.
- Cómo usar Matplotlib para visualización de datos.
[![Preparación y visualización de datos](https://img.youtube.com/vi/11AnOn_OAcE/0.jpg)](https://youtu.be/11AnOn_OAcE "Video de preparación y visualizción de datos - ¡Clic para ver!")
> 🎥 Da clic en la imagen superior para ver un video de los aspectos clave de esta lección
## Realizando la pregunta correcta a tus datos
La pregunta para la cual necesitas respuesta determinará qué tipo de algoritmos de ML requerirás. Y la calidad de la respuesta que obtendas será altamente dependiente de la naturaleza de tus datos.
Echa un vistazo a los [datos](../../data/US-pumpkins.csv) provistos para esta lección. Puedes abrir este archivo .csv en VS Code. Un vistazo rápido muestra inmediatamente que existen campos en blanco y una mezcla de datos numéricos y de cadena. También hay una columna extraña llamada 'Package' donde los datos están mezclados entre los valores 'sacks', 'bins' y otros. Los datos de hecho, son un pequeño desastre.
De hecho, no es muy común obtener un conjunto de datos que esté totalmente listo para su uso en un modelo de ML. En esta lección, aprenderás cómo preparar un conjunto de datos en crudo usando librerías estándares de Python. También aprenderás varias técnicas para visualizar los datos.
## Caso de estudio: 'El mercado de calabazas'
En este directorio encontrarás un archivo .cvs in la raíz del directorio `data` llamado [US-pumpkins.csv](../../data/US-pumpkins.csv), el cual incluye 1757 líneas de datos acerca del mercado de calabazas, ordenados en agrupaciones por ciudad. Estos son loas datos extraídos de [Reportes estándar de mercados terminales de cultivos especializados](https://www.marketnews.usda.gov/mnp/fv-report-config-step1?type=termPrice) distribuido por el Departamento de Agricultura de los Estados Unidos.
### Preparando los datos
Estos datos son de dominio público. Puede ser descargado en varios archivos por separado, por ciudad, desde el sitio web de USDA. para evitar demasiados archivos por separado, hemos concatenado todos los datos de ciudad en una hoja de cálculo, así ya hemos _preparado_ los datos un poco. Lo siguiente es dar un vistazo más a fondo a los datos.
### Los datos de las calabazas - conclusiones iniciales
¿Qué notas acerca de los datos? Ya has visto que hay una mezcla de cadenas, números, blancos y valores extraños a los cuales debes encontrarle sentido.
¿Qué preguntas puedes hacerle a los datos usando una técnica de regresión? Qué tal el "predecir el precio de la venta de calabaza durante un mes dado". Viendo nuevamente los datos, hay algunos cambios que necesitas hacer para crear las estructuras de datos necesarias para la tarea.
## Ejercicio - Analiza los datos de la calabaza
Usemos [Pandas](https://pandas.pydata.org/), (el nombre es un acrónimo de `Python Data Analysis`) a tool very useful for shaping data, to analyze and prepare this pumpkin data.
### Primero, revisa las fechas faltantes
Necesitarás realizar algunos pasos para revisar las fechas faltantes:
1. Convertir las fechas a formato de mes (las fechas están en formato de EE.UU., por lo que el formato es `MM/DD/YYYY`).
2. Extrae el mes en una nueva columna.
Abre el archivo _notebook.ipynb_ en Visual Studio Code e importa la hoja de cálculo en un nuevo dataframe de Pandas.
1. Usa la función `head()` para visualizar las primeras cinco filas.
```python
import pandas as pd
pumpkins = pd.read_csv('../data/US-pumpkins.csv')
pumpkins.head()
```
✅ ¿Qué función usarías para ver las últimas cinco filas?
1. Revisa si existen datos faltantes en el dataframe actual:
```python
pumpkins.isnull().sum()
```
Hay datos faltabtes, pero quizá no importen para la tarea en cuestión.
1. Para facilitar el trabajo con tu dataframe, elimina varias de sus columnas usando `drop()`, manteniendo sólo las columnas que necesitas:
```python
new_columns = ['Package', 'Month', 'Low Price', 'High Price', 'Date']
pumpkins = pumpkins.drop([c for c in pumpkins.columns if c not in new_columns], axis=1)
```
### Segundo, determina el precio promedio de la calabaza
Piensa en cómo determinar el precio promedio de la calabaza en un mes dado. ¿Qué columnas eligirás para esa tarea? Pista: necesitarás 3 columnas.
Solución: toma el promedio de las columnas `Low Price` y `High Price` para poblar la nueva columna `Price` y convierte la columna `Date` para mostrar únicamente el mes, Afortunadamente, de acuerdo a la revisión de arriba, no hay datos faltantes para las fechas o precios.
1. Para calcular el promedio, agrega el siguiente código:
```python
price = (pumpkins['Low Price'] + pumpkins['High Price']) / 2
month = pd.DatetimeIndex(pumpkins['Date']).month
```
✅ Siéntete libre de imprimir cualquier dato que desees verificar, usando `print(month)`.
2. Ahora, copia tus datos convertidos en un nuevo dataframe de Pandas:
```python
new_pumpkins = pd.DataFrame({'Month': month, 'Package': pumpkins['Package'], 'Low Price': pumpkins['Low Price'],'High Price': pumpkins['High Price'], 'Price': price})
```
Imprimir tu dataframe te mostrará un conjunto de datos limpio y ordenado, en el cual puedes construir tu nuevo modelo de regresión.
### ¡Pero espera!, Hay algo raro aquí
Si observas la columna `Package`, las calabazas se venden en distintas configuraciones. Algunas son vendidas en medidas de '1 1/9 bushel', y otras en '1/2 bushel', algunas por pieza, algunas por libra y otras en grandes cajas de ancho variable.
> Las calabazas parecen muy difíciles de pesar consistentemente.
Indagando en los datos originales, es interesante que cualquiera con el valor `Unit of Sale` igualado a 'EACH' o 'PER BIN' también tiene el tipo de `Package` por pulgada, por cesto, o 'each'. Las calabazas parecen muy difíciles de pesar consistentemente, por lo que las filtraremos seleccionando solo aquellas calabazas con el string 'bushel' en su columna `Package`.
1. Agrega un filtro al inicio del archivo, debajo de la importación inicial del .csv:
```python
pumpkins = pumpkins[pumpkins['Package'].str.contains('bushel', case=True, regex=True)]
```
Si imprimes los datos ahora, puedes ver que solo estás obteniendo alrededor de 415 filas de datos que contienen calabazas por fanegas.
### ¡Pero espera! Aún hay algo más que hacer
¿Notaste que la cantidad de fanegas varían por fila? Necesitas normalizar el precio para así mostrar el precio por fanega, así que haz los cálculos para estandarizarlo.
1. Agrega estas líneas después del bloque para así crear el dataframe new_pumpkins:
```python
new_pumpkins.loc[new_pumpkins['Package'].str.contains('1 1/9'), 'Price'] = price/(1 + 1/9)
new_pumpkins.loc[new_pumpkins['Package'].str.contains('1/2'), 'Price'] = price/(1/2)
```
✅ De acuerdo a [The Spruce Eats](https://www.thespruceeats.com/how-much-is-a-bushel-1389308), el peso de una fanega depende del tipo de producto, ya que es una medida de volumen. "Una fanega de tomates, por ejemplo, se supone pese 56 libras... Las hojas y verduras usan más espacio con menos peso, por lo que una fanega de espinaca es de sólo 20 libras." ¡Todo es tan complicado! No nos molestemos en realizar una conversión fanega-a-libra, y en su lugar hagámosla por precio de fanega. ¡Todo este estudio de las fanegas de calabazas nos mostrará cuán importante es comprender la naturaleza de tus datos!
Ahora, puedes analizar el precio por unidad basándote en su medida de fanega. Si imprimes los datos una vez más, verás que ya están estandarizados.
✅ ¿Notaste que las calabazas vendidas por media fanega son más caras? ¿Puedes descubrir la razón? Ayuda: Las calabazas pequeñas son mucho más caras que las grandes, probablemente porque hay muchas más de ellas por fanega, dado el espacio sin usar dejado por una calabaza grande.
## Estrategias de visualización
parte del rol de un científico de datos es el demostrar la calidad y naturaleza de los dato con los que está trabajando. Para hacerlo, usualmente crean visualizaciones interesantes, o gráficos, grafos, y gráficas, mostrando distintos aspectos de los datos. De esta forma, son capaces de mostrar visualmente las relaciones y brechas de que otra forma son difíciles de descubrir.
Las visualizaciones también ayudan a determinar la técnica de aprendizaje automático más apropiada para los datos. Por ejemplo, un gráfico de dispersión que parece seguir una línea, indica que los datos son un buen candidato para un ejercicio de regresión lineal.
Una librería de visualización de datos que funciona bien en los notebooks de Jupyter es [Matplotlib](https://matplotlib.org/) (la cual también viste en la lección anterior).
> Obtén más experiencia con la visualización de datos en [estos tutoriales](https://docs.microsoft.com/learn/modules/explore-analyze-data-with-python?WT.mc_id=academic-15963-cxa).
## Ejercicio - experimenta con Matplotlib
Intenta crear algunas gráficas básicas para mostrar el nuevo dataframe que acabas de crear. ¿Qué mostraría una gráfica de línea básica?
1. Importa Matplotlib al inicio del archivo, debajo de la importación de Pandas:
```python
import matplotlib.pyplot as plt
```
1. Vuelve a correr todo el notebook para refrescarlo.
1. Al final del notebook, agrega una celda para graficar los datos como una caja:
```python
price = new_pumpkins.Price
month = new_pumpkins.Month
plt.scatter(price, month)
plt.show()
```
![Una gráfica de dispersión mostrando la relación precio a mes](../images/scatterplot.png)
¿La gráfica es útil? ¿Hay algo acerca de ésta que te sorprenda?
No es particularmente útil ya que todo lo que hace es mostrar tus datos como puntos dispersos en un mes dado.
### Hacerlo útil
Para obtener gráficas para mostrar datos útiles, necesitas agrupar los datos de alguna forma. Probemos creando un gráfico donde el eje y muestre los meses y los datos demuestren la distribución de los datos.
1. Agrega una celda para crear una gráfica de barras agrupadas:
```python
new_pumpkins.groupby(['Month'])['Price'].mean().plot(kind='bar')
plt.ylabel("Pumpkin Price")
```
![Una gráfica de bsarras mostrando la relación precio a mes](../images/barchart.png)
¡Esta es una visualización de datos más útil! Parece indicar que el precio más alto para las calabazas ocurre en Septiembre y Octubre. ¿Cumple esto con tus expectativas? ¿por qué sí o por qué no?
---
## 🚀Desafío
Explora los distintos tipos de visualización que ofrece Matplotlib. ¿Qué tipos son los más apropiados para problemas de regresión?
## [Examen posterior a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/12/)
## Revisión y autoestudio
Dale un vistazo a las distintas forma de visualizar los datos. Haz un lista de las distintas librerías disponibles y nota cuales son mejores para cierto tipo de tareas, por ejemplo visualizaciones 2D vs visualizaciones 3D. ¿Qué descubriste?
## Asignación
[Explorando la visualización](assignment.es.md)

@ -1,4 +1,4 @@
# Build a regression model using Scikit-learn: regression two ways # Build a regression model using Scikit-learn: regression four ways
![Linear vs polynomial regression infographic](./images/linear-polynomial.png) ![Linear vs polynomial regression infographic](./images/linear-polynomial.png)
> Infographic by [Dasani Madipalli](https://twitter.com/dasani_decoded) > Infographic by [Dasani Madipalli](https://twitter.com/dasani_decoded)
@ -9,13 +9,15 @@
So far you have explored what regression is with sample data gathered from the pumpkin pricing dataset that we will use throughout this lesson. You have also visualized it using Matplotlib. So far you have explored what regression is with sample data gathered from the pumpkin pricing dataset that we will use throughout this lesson. You have also visualized it using Matplotlib.
Now you are ready to dive deeper into regression for ML. In this lesson, you will learn more about two types of regression: _basic linear regression_ and _polynomial regression_, along with some of the math underlying these techniques. Now you are ready to dive deeper into regression for ML. While visualization allows you to make sense of data, the real power of Machine Learning comes from _training models_. Models are trained on historic data to automatically capture data dependencies, and they allow you to predict outcomes for new data, which the model has not seem before.
In this lesson, you will learn more about two types of regression: _basic linear regression_ and _polynomial regression_, along with some of the math underlying these techniques. Those models will allow us to predict pumpkin prices depending on different input data.
> Throughout this curriculum, we assume minimal knowledge of math, and seek to make it accessible for students coming from other fields, so watch for notes, 🧮 callouts, diagrams, and other learning tools to aid in comprehension. > Throughout this curriculum, we assume minimal knowledge of math, and seek to make it accessible for students coming from other fields, so watch for notes, 🧮 callouts, diagrams, and other learning tools to aid in comprehension.
### Prerequisite ### Prerequisite
You should be familiar by now with the structure of the pumpkin data that we are examining. You can find it preloaded and pre-cleaned in this lesson's _notebook.ipynb_ file. In the file, the pumpkin price is displayed per bushel in a new dataframe. Make sure you can run these notebooks in kernels in Visual Studio Code. You should be familiar by now with the structure of the pumpkin data that we are examining. You can find it preloaded and pre-cleaned in this lesson's _notebook.ipynb_ file. In the file, the pumpkin price is displayed per bushel in a new data frame. Make sure you can run these notebooks in kernels in Visual Studio Code.
### Preparation ### Preparation
@ -26,7 +28,7 @@ As a reminder, you are loading this data so as to ask questions of it.
- Should I buy them in half-bushel baskets or by the 1 1/9 bushel box? - Should I buy them in half-bushel baskets or by the 1 1/9 bushel box?
Let's keep digging into this data. Let's keep digging into this data.
In the previous lesson, you created a Pandas dataframe and populated it with part of the original dataset, standardizing the pricing by the bushel. By doing that, however, you were only able to gather about 400 datapoints and only for the fall months. In the previous lesson, you created a Pandas data frame and populated it with part of the original dataset, standardizing the pricing by the bushel. By doing that, however, you were only able to gather about 400 datapoints and only for the fall months.
Take a look at the data that we preloaded in this lesson's accompanying notebook. The data is preloaded and an initial scatterplot is charted to show month data. Maybe we can get a little more detail about the nature of the data by cleaning it more. Take a look at the data that we preloaded in this lesson's accompanying notebook. The data is preloaded and an initial scatterplot is charted to show month data. Maybe we can get a little more detail about the nature of the data by cleaning it more.
@ -71,251 +73,253 @@ One more term to understand is the **Correlation Coefficient** between given X a
A good linear regression model will be one that has a high (nearer to 1 than 0) Correlation Coefficient using the Least-Squares Regression method with a line of regression. A good linear regression model will be one that has a high (nearer to 1 than 0) Correlation Coefficient using the Least-Squares Regression method with a line of regression.
✅ Run the notebook accompanying this lesson and look at the City to Price scatterplot. Does the data associating City to Price for pumpkin sales seem to have high or low correlation, according to your visual interpretation of the scatterplot? ✅ Run the notebook accompanying this lesson and look at the Month to Price scatterplot. Does the data associating Month to Price for pumpkin sales seem to have high or low correlation, according to your visual interpretation of the scatterplot? Does that change if you use more fine-grained measure instead of `Month`, eg. *day of the year* (i.e. number of days since the beginning of the year)?
## Prepare your data for regression In the code below, we will assume that we have cleaned up the data, and obtained a data frame called `new_pumpkins`, similar to the following:
Now that you have an understanding of the math behind this exercise, create a Regression model to see if you can predict which package of pumpkins will have the best pumpkin prices. Someone buying pumpkins for a holiday pumpkin patch might want this information to be able to optimize their purchases of pumpkin packages for the patch. ID | Month | DayOfYear | Variety | City | Package | Low Price | High Price | Price
---|-------|-----------|---------|------|---------|-----------|------------|-------
70 | 9 | 267 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 15.0 | 15.0 | 13.636364
71 | 9 | 267 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 18.0 | 18.0 | 16.363636
72 | 10 | 274 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 18.0 | 18.0 | 16.363636
73 | 10 | 274 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 17.0 | 17.0 | 15.454545
74 | 10 | 281 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 15.0 | 15.0 | 13.636364
Since you'll use Scikit-learn, there's no reason to do this by hand (although you could!). In the main data-processing block of your lesson notebook, add a library from Scikit-learn to automatically convert all string data to numbers: > The code to clean the data is available in [`notebook.ipynb`](notebook.ipynb). We have performed the same cleaning steps as in the previous lesson, and have calculated `DayOfYear` column using the following expression:
```python ```python
from sklearn.preprocessing import LabelEncoder day_of_year = pd.to_datetime(pumpkins['Date']).apply(lambda dt: (dt-datetime(dt.year,1,1)).days)
new_pumpkins.iloc[:, 0:-1] = new_pumpkins.iloc[:, 0:-1].apply(LabelEncoder().fit_transform)
``` ```
If you look at the new_pumpkins dataframe now, you see that all the strings are now numeric. This makes it harder for you to read but much more intelligible for Scikit-learn! Now that you have an understanding of the math behind linear regression, let's create a Regression model to see if we can predict which package of pumpkins will have the best pumpkin prices. Someone buying pumpkins for a holiday pumpkin patch might want this information to be able to optimize their purchases of pumpkin packages for the patch.
Now you can make more educated decisions (not just based on eyeballing a scatterplot) about the data that is best suited to regression.
Try to find a good correlation between two points of your data to potentially build a good predictive model. As it turns out, there's only weak correlation between the City and Price: ## Looking for Correlation
```python From the previous lesson you have probably seen that the average price for different months looks like this:
print(new_pumpkins['City'].corr(new_pumpkins['Price']))
0.32363971816089226
```
However there's a bit better correlation between the Package and its Price. That makes sense, right? Normally, the bigger the produce box, the higher the price. <img alt="Average price by month" src="../2-Data/images/barchart.png" width="50%"/>
This suggests that there should be some correlation, and we can try training linear regression model to predict the relationship between `Month` and `Price`, or between `DayOfYear` and `Price`. Here is the scatter plot that shows the latter relationship:
<img alt="Scatter plot of Price vs. Day of Year" src="images/scatter-dayofyear.png" width="50%" />
It looks like there are different clusters of prices corresponding to different pumpkin varieties. To confirm this hypothesis, let's plot each pumpkin category using a different color. By passing an `ax` parameter to the `scatter` plotting function we can plot all points on the same graph:
```python ```python
print(new_pumpkins['Package'].corr(new_pumpkins['Price'])) ax=None
0.6061712937226021 colors = ['red','blue','green','yellow']
for i,var in enumerate(new_pumpkins['Variety'].unique()):
df = new_pumpkins[new_pumpkins['Variety']==var]
ax = df.plot.scatter('DayOfYear','Price',ax=ax,c=colors[i],label=var)
``` ```
A good question to ask of this data will be: 'What price can I expect of a given pumpkin package?' <img alt="Scatter plot of Price vs. Day of Year" src="images/scatter-dayofyear-color.png" width="50%" />
Let's build this regression model Our investigation suggests that variety has more effect on the overall price than the actual selling date. So let us focus for the moment only on one pumpkin variety, and see what effect the date has on the price:
## Building a linear model ```python
pie_pumpkins = new_pumpkins[new_pumpkins['Variety']=='PIE TYPE']
pie_pumpkins.plot.scatter('DayOfYear','Price')
```
<img alt="Scatter plot of Price vs. Day of Year" src="images/pie-pumpkins-scatter.png" width="50%" />
Before building your model, do one more tidy-up of your data. Drop any null data and check once more what the data looks like. If we now calculate the correlation between `Price` and `DayOfYear` using `corr` function, we will get something like `-0.27` - which means that training a predictive model makes sense.
> Before training a linear regression model, it is important to make sure that our data is clean. Linear regression does not work well with missing values, thus it makes sense to get rid of all empty cells:
```python ```python
new_pumpkins.dropna(inplace=True) pie_pumpkins.dropna(inplace=True)
new_pumpkins.info() pie_pumpkins.info()
``` ```
Then, create a new dataframe from this minimal set and print it out: Another approach would be to fill those empty values with mean values from the corresponding column.
```python ## Simple Linear Regression
new_columns = ['Package', 'Price']
lin_pumpkins = new_pumpkins.drop([c for c in new_pumpkins.columns if c not in new_columns], axis='columns')
lin_pumpkins To train our Linear Regression model, we will use the **Scikit-learn** library.
```
```output ```python
Package Price from sklearn.linear_model import LinearRegression
70 0 13.636364 from sklearn.metrics import mean_squared_error
71 0 16.363636 from sklearn.model_selection import train_test_split
72 0 16.363636
73 0 15.454545
74 0 13.636364
... ... ...
1738 2 30.000000
1739 2 28.750000
1740 2 25.750000
1741 2 24.000000
1742 2 24.000000
415 rows × 2 columns
``` ```
1. Now you can assign your X and y coordinate data: We start by separating input values (features) and the expected output (label) into separate numpy arrays:
```python
X = lin_pumpkins.values[:, :1]
y = lin_pumpkins.values[:, 1:2]
```
✅ What's going on here? You're using [Python slice notation](https://stackoverflow.com/questions/509211/understanding-slice-notation/509295#509295) to create arrays to populate `X` and `y`.
2. Next, start the regression model-building routines: ```python
X = pie_pumpkins['DayOfYear'].to_numpy().reshape(-1,1)
y = pie_pumpkins['Price']
```
```python > Note that we had to perform `reshape` on the input data in order for the Linear Regression package to understand it correctly. Linear Regression expects a 2D-array as an input, where each row of the array corresponds to a vector of input features. In our case, since we have only one input - we need an array with shape N&times;1, where N is the dataset size.
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) Then, we need to split the data into train and test datasets, so that we can validate our model after training:
lin_reg = LinearRegression()
lin_reg.fit(X_train,y_train)
pred = lin_reg.predict(X_test) ```python
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
```
accuracy_score = lin_reg.score(X_train,y_train) Finally, training the actual Linear Regression model takes only two lines of code. We define the `LinearRegression` object, and fit it to our data using the `fit` method:
print('Model Accuracy: ', accuracy_score)
```
Because the correlation isn't particularly good, the model produced isn't terribly accurate. ```python
lin_reg = LinearRegression()
lin_reg.fit(X_train,y_train)
```
```output The `LinearRegression` object after `fit`-ting contains all the coefficients of the regression, which can be accessed using `.coef_` property. In our case, there is just one coefficient, which should be around `-0.017`. It means that prices seem to drop a bit with time, but not too much, around 2 cents per day. We can also access the intersection point of the regression with Y-axis using `lin_reg.intercept_` - it will be around `21` in our case, indicating the price at the beginning of the year.
Model Accuracy: 0.3315342327998987
```
3. You can visualize the line that's drawn in the process: To see how accurate our model is, we can predict prices on a test dataset, and then measure how close our predictions are to the expected values. This can be done using mean square error (MSE) metrics, which is the mean of all squared differences between expected and predicted value.
```python ```python
plt.scatter(X_test, y_test, color='black') pred = lin_reg.predict(X_test)
plt.plot(X_test, pred, color='blue', linewidth=3)
plt.xlabel('Package') mse = np.sqrt(mean_squared_error(y_test,pred))
plt.ylabel('Price') print(f'Mean error: {mse:3.3} ({mse/np.mean(pred)*100:3.3}%)')
```
plt.show() Our error seems to be around 2 points, which is ~17%. Not too good. Another indicator of model quality is the **coefficient of determination**, which can be obtained like this:
```
![A scatterplot showing package to price relationship](./images/linear.png)
4. Test the model against a hypothetical variety: ```python
score = lin_reg.score(X_train,y_train)
print('Model determination: ', score)
```
If the value is 0, it means that the model does not take input data into account, and acts as the *worst linear predictor*, which is simply a mean value of the result. The value of 1 means that we can perfectly predict all expected outputs. In our case, the coefficient is around 0.06, which is quite low.
```python We can also plot the test data together with the regression line to better see how regression works in our case:
lin_reg.predict( np.array([ [2.75] ]) )
```
The returned price for this mythological Variety is: ```python
plt.scatter(X_test,y_test)
plt.plot(X_test,pred)
```
```output <img alt="Linear regression" src="images/linear-results.png" width="50%" />
array([[33.15655975]])
```
That number makes sense, if the logic of the regression line holds true.
🎃 Congratulations, you just created a model that can help predict the price of a few varieties of pumpkins. Your holiday pumpkin patch will be beautiful. But you can probably create a better model! ## Polynomial Regression
## Polynomial regression
Another type of linear regression is polynomial regression. While sometimes there's a linear relationship between variables - the bigger the pumpkin in volume, the higher the price - sometimes these relationships can't be plotted as a plane or straight line. Another type of Linear Regression is Polynomial Regression. While sometimes there's a linear relationship between variables - the bigger the pumpkin in volume, the higher the price - sometimes these relationships can't be plotted as a plane or straight line.
✅ Here are [some more examples](https://online.stat.psu.edu/stat501/lesson/9/9.8) of data that could use polynomial regression ✅ Here are [some more examples](https://online.stat.psu.edu/stat501/lesson/9/9.8) of data that could use Polynomial Regression
Take another look at the relationship between Variety to Price in the previous plot. Does this scatterplot seem like it should necessarily be analyzed by a straight line? Perhaps not. In this case, you can try polynomial regression. Take another look at the relationship between Date and Price. Does this scatterplot seem like it should necessarily be analyzed by a straight line? Can't prices fluctuate? In this case, you can try polynomial regression.
✅ Polynomials are mathematical expressions that might consist of one or more variables and coefficients ✅ Polynomials are mathematical expressions that might consist of one or more variables and coefficients
Polynomial regression creates a curved line to better fit nonlinear data. Polynomial regression creates a curved line to better fit nonlinear data. In our case, if we include a squared `DayOfYear` variable into input data, we should be able to fit our data with a parabolic curve, which will have a minimum at a certain point within the year.
1. Let's recreate a dataframe populated with a segment of the original pumpkin data: Scikit-learn includes a helpful [pipeline API](https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.make_pipeline.html?highlight=pipeline#sklearn.pipeline.make_pipeline) to combine different steps of data processing together. A **pipeline** is a chain of **estimators**. In our case, we will create a pipeline that first adds polynomial features to our model, and then trains the regression:
```python ```python
new_columns = ['Variety', 'Package', 'City', 'Month', 'Price'] from sklearn.preprocessing import PolynomialFeatures
poly_pumpkins = new_pumpkins.drop([c for c in new_pumpkins.columns if c not in new_columns], axis='columns') from sklearn.pipeline import make_pipeline
poly_pumpkins
```
A good way to visualize the correlations between data in dataframes is to display it in a 'coolwarm' chart: pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())
2. Use the `Background_gradient()` method with `coolwarm` as its argument value: pipeline.fit(X_train,y_train)
```
```python Using `PolynomialFeatures(2)` means that we will include all second-degree polynomials from the input data. In our case it will just mean `DayOfYear`<sup>2</sup>, but given two input variables X and Y, this will add X<sup>2</sup>, XY and Y<sup>2</sup>. We may also use higher degree polynomials if we want.
corr = poly_pumpkins.corr()
corr.style.background_gradient(cmap='coolwarm')
```
This code creates a heatmap:
![A heatmap showing data correlation](./images/heatmap.png)
Looking at this chart, you can visualize the good correlation between Package and Price. So you should be able to create a somewhat better model than the last one. Pipelines can be used in the same manner as the original `LinearRegression` object, i.e. we can `fit` the pipeline, and then use `predict` to get the prediction results. Here is the graph showing test data, and the approximation curve:
### Create a pipeline
Scikit-learn includes a helpful API for building polynomial regression models - the `make_pipeline` [API](https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.make_pipeline.html?highlight=pipeline#sklearn.pipeline.make_pipeline). A 'pipeline' is created which is a chain of estimators. In this case, the pipeline includes polynomial features, or predictions that form a nonlinear path. <img alt="Polynomial regression" src="images/poly-results.png" width="50%" />
1. Build out the X and y columns: Using Polynomial Regression, we can get slightly lower MSE and higher determination, but not significantly. We need to take into account other features!
```python > You can see that the minimal pumpkin prices are observed somewhere around Halloween. How can you explain this?
X=poly_pumpkins.iloc[:,3:4].values
y=poly_pumpkins.iloc[:,4:5].values
```
2. Create the pipeline by calling the `make_pipeline()` method: 🎃 Congratulations, you just created a model that can help predict the price of pie pumpkins. You can probably repeat the same procedure for all pumpkin types, but that would be tedious. Let's learn now how to take pumpkin variety into account in our model!
```python ## Categorical Features
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
pipeline = make_pipeline(PolynomialFeatures(4), LinearRegression()) In the ideal world, we want to be able to predict prices for different pumpkin varieties using the same model. However, the `Variety` column is somewhat different from columns like `Month`, because it contains non-numeric values. Such columns are called **categorical**.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) Here you can see how average price depends on variety:
pipeline.fit(np.array(X_train), y_train) <img alt="Average price by variety" src="images/price-by-variety.png" width="50%" />
y_pred=pipeline.predict(X_test) To take variety into account, we first need to convert it to numeric form, or **encode** it. There are several way we can do it:
```
### Create a sequence * Simple **numeric encoding** will build a table of different varieties, and then replace the variety name by an index in that table. This is not the best idea for linear regression, because linear regression takes the actual numeric value of the index, and adds it to the result, multiplying by some coefficient. In our case, the relationship between the index number and the price is clearly non-linear, even if we make sure that indices are ordered in some specific way.
* **One-hot encoding** will replace the `Variety` column by 4 different columns, one for each variety. Each column will contain `1` if the corresponding row is of a given variety, and `0` otherwise. This means that there will be four coefficients in linear regression, one for each pumpkin variety, responsible for "starting price" (or rather "additional price") for that particular variety.
At this point, you need to create a new dataframe with _sorted_ data so that the pipeline can create a sequence. The code below shows how we can one-hot encode a variety:
Add the following code: ```python
pd.get_dummies(new_pumpkins['Variety'])
```
```python ID | FAIRYTALE | MINIATURE | MIXED HEIRLOOM VARIETIES | PIE TYPE
df = pd.DataFrame({'x': X_test[:,0], 'y': y_pred[:,0]}) ----|-----------|-----------|--------------------------|----------
df.sort_values(by='x',inplace = True) 70 | 0 | 0 | 0 | 1
points = pd.DataFrame(df).to_numpy() 71 | 0 | 0 | 0 | 1
... | ... | ... | ... | ...
1738 | 0 | 1 | 0 | 0
1739 | 0 | 1 | 0 | 0
1740 | 0 | 1 | 0 | 0
1741 | 0 | 1 | 0 | 0
1742 | 0 | 1 | 0 | 0
plt.plot(points[:, 0], points[:, 1],color="blue", linewidth=3) To train linear regression using one-hot encoded variety as input, we just need to initialize `X` and `y` data correctly:
plt.xlabel('Package')
plt.ylabel('Price')
plt.scatter(X,y, color="black")
plt.show()
```
You created a new dataframe by calling `pd.DataFrame`. Then you sorted the values by calling `sort_values()`. Finally you created a polynomial plot: ```python
X = pd.get_dummies(new_pumpkins['Variety'])
y = new_pumpkins['Price']
```
![A polynomial plot showing package to price relationship](./images/polynomial.png) The rest of the code is the same as what we used above to train Linear Regression. If you try it, you will see that the mean squared error is about the same, but we get much higher coefficient of determination (~77%). To get even more accurate predictions, we can take more categorical features into account, as well as numeric features, such as `Month` or `DayOfYear`. To get one large array of features, we can use `join`:
You can see a curved line that fits your data better. ```python
X = pd.get_dummies(new_pumpkins['Variety']) \
.join(new_pumpkins['Month']) \
.join(pd.get_dummies(new_pumpkins['City'])) \
.join(pd.get_dummies(new_pumpkins['Package']))
y = new_pumpkins['Price']
```
Let's check the model's accuracy: Here we also take into account `City` and `Package` type, which gives us MSE 2.84 (10%), and determination 0.94!
```python ## Putting it all together
accuracy_score = pipeline.score(X_train,y_train)
print('Model Accuracy: ', accuracy_score)
```
And voila! To make the best model, we can use combined (one-hot encoded categorical + numeric) data from the above example together with Polynomial Regression. Here is the complete code for your convenience:
```output ```python
Model Accuracy: 0.8537946517073784 # set up training data
``` X = pd.get_dummies(new_pumpkins['Variety']) \
.join(new_pumpkins['Month']) \
.join(pd.get_dummies(new_pumpkins['City'])) \
.join(pd.get_dummies(new_pumpkins['Package']))
y = new_pumpkins['Price']
That's better! Try to predict a price: # make train-test split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
### Do a prediction # setup and train the pipeline
pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())
pipeline.fit(X_train,y_train)
Can we input a new value and get a prediction? # predict results for test data
pred = pipeline.predict(X_test)
Call `predict()` to make a prediction: # calculate MSE and determination
mse = np.sqrt(mean_squared_error(y_test,pred))
print(f'Mean error: {mse:3.3} ({mse/np.mean(pred)*100:3.3}%)')
```python score = pipeline.score(X_train,y_train)
pipeline.predict( np.array([ [2.75] ]) ) print('Model determination: ', score)
``` ```
You are given this prediction:
```output This should give us the best determination coefficient of almost 97%, and MSE=2.23 (~8% prediction error).
array([[46.34509342]])
```
It does make sense, given the plot! And, if this is a better model than the previous one, looking at the same data, you need to budget for these more expensive pumpkins! | Model | MSE | Determination |
|-------|-----|---------------|
| `DayOfYear` Linear | 2.77 (17.2%) | 0.07 |
| `DayOfYear` Polynomial | 2.73 (17.0%) | 0.08 |
| `Variety` Linear | 5.24 (19.7%) | 0.77 |
| All features Linear | 2.84 (10.5%) | 0.94 |
| All features Polynomial | 2.23 (8.25%) | 0.97 |
🏆 Well done! You created two regression models in one lesson. In the final section on regression, you will learn about logistic regression to determine categories. 🏆 Well done! You created four Regression models in one lesson, and improved the model quality to 97%. In the final section on Regression, you will learn about Logistic Regression to determine categories.
--- ---
## 🚀Challenge ## 🚀Challenge

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,342 @@
# Construye un modelo de regresión usando Scikit-learn: regresión de dos formas
![Infografía de regresión lineal vs polinomial](./images/linear-polynomial.png)
> Infografía de [Dasani Madipalli](https://twitter.com/dasani_decoded)
## [Examen previo a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/13/)
> ### [¡Esta lección está disponible en R!](../solution/R/lesson_3-R.ipynb)
### Introducción
Hasta ahora has explorado qué es la regresión con datos obtenidos del conjunto de datos de los precios de las calabazas que usaremos en esta lección. También los has visualizado usando Matplotlib.
Ahora estás listo para profundizar en la regresión para el aprendizaje automático. En esta lección, aprenderás más acerca de dos tipos de regresión: _regresión básica lineal_ y _regresión polinomial_, junto con algo de matemáticas fundamental a estas técnicas.
> A lo largo de este plan de estudios, asumimos un conocimiento mínimo de matemáticas, y buscamos hacerlo accesible para los estudiantes provenientes de otros campos, así que pon atención a las notas, 🧮 llamados, diagramas, y otras herramientas de estudio para ayudar en la comprensión.
### Prerrequisitos
Ahora, debes estar familiarizado con la estructura de los datos de las calabazas que ya examinamos. Puedes encontrarlos precargados y pre-limpiados en el archivo _notebook.ipynb_ de esta lección. En el archivo, el precio de la calabaza se muestra por fanega en un nuevo dataframe. Asegúrate que puedas ejecutar estos notebooks en kernels en Visual Studio Code.
### Preparación
Como recordatorio, estás cargando estos datos para hacer preguntas aceca de estos.
- ¿Cuándo es el mejor momento para comprar calabazas?
- ¿Qué precio puedo esperar para el caso de calabazas miniatura?
- ¿Debería comprarlas en cestos de media fanega o por caja de 1 1/9 de fanega?
Sigamos profundizando en estos datos.
En la lección anterior, creaste un dataframe de Pandas y lo poblaste con parte del conjunto de datos original, estandarizando el precio de la fanega. Haciéndolo, sólo fuiste capaz de reunir alrededor de 400 puntos de datos y sólo para los meses de otoño.
Da un vistazo a los datos que fueron precargados en el notebook que acompaña a esta lección. Los datos están precargados con un gráfico de dispersión inicial para mostrar datos mensuales. Quizá podamos obtener un poco más de detalle acerca de la naturaleza de los datos limpiándolos más.
## Un línea de regresión lineal
Como aprendiste en la lección 1, el objetivo de un ejercicio de regresión lineal es ser capaz de graficar una línea para:
- **Mostrar la relación de las variables**. Mostrar la relación entre las variables
- **Realizar predicciones**. Hacer predicciones precisas en donde un nuevo punto de datos caería en relación a esa línea.
Es típico de la **regresión de mínimos cuadrados** el dibujar este tipo de línea. El término 'mínimos cuadrados' significa que todos los puntos de datos rodeando la línea de regresión se elevan al cuadrado y luego se suman. Idealmente, la suma final es tan pequeña como sea posible, porque queremos un número bajo de errores, o `mínimos cuadrados`.
Lo hacemos así ya que queremos modelar una línea que tiene la menor distancia acumulada de todos nuestros puntos de datos. También elevamos al cuadrado los términos antes de sumarlos ya que nos interesa su magnitud en lugar de su dirección.
> **🧮 Muéstrame las matemáticas**
>
> Esta línea, llamada la _línea de mejor ajuste_ puede ser expresada por [una ecuación](https://en.wikipedia.org/wiki/Simple_linear_regression):
>
> ```
> Y = a + bX
> ```
>
> `X` es la 'variable explicativa'. `Y` es la 'variable dependiente'. La pendiente de la línea es `b` y `a` es la intercepción en y, la cual se refiere a el valor de `Y` cuando `X = 0`.
>
>![Calcula la pendiente](../images/slope.png)
>
> Primero, calcula la pendiente `b`. Infografía de [Jen Looper](https://twitter.com/jenlooper)
>
> En otras palabras, y refiriéndose a nuestra pregunta original de los datos de las calabazas: "predice el precio de una calabaza por fanega por mes", `X` se referiría al precio e `Y` a el mes de venta.
>
>![Completa la ecuación](../images/calculation.png)
>
> Calcula el valor de Y. ¡Si estás pagando alrededor de $4, debe ser Abril! Infografía de [Jen Looper](https://twitter.com/jenlooper)
>
> Las matemáticas que calculan la línea deben demostrar la pendiente de la línea, la cual también depende de la intercepción, o dónde `Y` se sitúa cuando `X = 0`.
>
> Puedes observar el método de cálculo para estos valores en el sitio web [las matemáticas son divertidas](https://www.mathsisfun.com/data/least-squares-regression.html). También visita esta [calculadora de mínimos cuadrados](https://www.mathsisfun.com/data/least-squares-calculator.html) para ver cómo los valores de los números impactan la línea.
## Correlación
Un término más a entender es el **coeficiente de correlación** entre las variables dadas X e Y. Usando un gráfico de dispersión, puedes visualizar rápidamente este coeficiente. Un gráfico con puntos de datos dispersos en una línea ordenada tienen alta correlación, pero un gráfico con puntos de datos dispersos por todas partes entre X e Y tienen baja correlación.
Un buen modelo de regresión lineal será aquél que tenga un alto Coeficiente de Correlación (más cercano a 1 que a 0) usando el métro de regresión de mínimos cuadrados con una línea de regresión.
✅ Ejecuta el notebook que acompaña esta lección y mira el gráfico de Ciudad a Precio. ¿Los datos asociados de Ciudad a Precio para las ventas de calabaza parecen tener correlación alta o baja, de acuerdo a tu interpretación visual del gráfico de dispersión?
## Prepara tus datos para la regresión
Ahora que tienes conocimiento de las matemáticas detrás de este ejercicio, crea un modelo de regresión para ver si puedes predecir cuál de los paquetes de calabazas tendrá los mejores precios. Alguien comprando calabazas para una parcela de calabazas en días festivos quisiera esta información para ser capaz de optimizar sus compras de paquetes de calabazas para la parcela.
Ya que usarás Scikit-learn, no hay razón para hacer esto a mano (¡aunque podrías!). En el bloque principal de procesamientos de datos de tu notebook de lección, agrega una biblioteca de Scikit-learn para convertir automáticamente todos los datos de cadena a números:
```python
from sklearn.preprocessing import LabelEncoder
new_pumpkins.iloc[:, 0:-1] = new_pumpkins.iloc[:, 0:-1].apply(LabelEncoder().fit_transform)
```
Si ahora miras el nuevo dataframe `new_pumpkins`, ves que todas las cadenas ahora son numéricas. ¡Esto te dificulta el leer pero lo hace más comprensible para Scikit-learn!
Ahora puedes tomar decisiones más informadas (no sólo basado en un gráfico de dispersión) acerca de los datos que mejor se ajustan a la regresión.
Intenta encontrar una buena correlación entre dos puntos de tus datos para construir potencialmente un buen modelo predictivo. Como resultado, sólo hay correlación débil entre la Ciudad y el Precio.
```python
print(new_pumpkins['City'].corr(new_pumpkins['Price']))
0.32363971816089226
```
Sin embargo, existe una correlación un poco mejor entre el Paquete y su Precio. Esto tiene sentido, ¿cierto? Normalmente, entre más grande sea la caja producida, mayor será el precio.
```python
print(new_pumpkins['Package'].corr(new_pumpkins['Price']))
0.6061712937226021
```
Una buena pregunta a realizar de estos datos, sería: '¿Qué precio puedo esperar de un paquete de calabazas dado?'
Construyamos este modelo de regresión
## Construyendo un modelo lineal
Antes de construir tu modelo, haz una limpieza más a tus datos. Elimina cualquier dato nulo y verifica una vez cómo lucen los datos.
```python
new_pumpkins.dropna(inplace=True)
new_pumpkins.info()
```
Luego, crea un dataframe nuevo de este conjunto mínimo e imprímelo:
```python
new_columns = ['Package', 'Price']
lin_pumpkins = new_pumpkins.drop([c for c in new_pumpkins.columns if c not in new_columns], axis='columns')
lin_pumpkins
```
```output
Package Price
70 0 13.636364
71 0 16.363636
72 0 16.363636
73 0 15.454545
74 0 13.636364
... ... ...
1738 2 30.000000
1739 2 28.750000
1740 2 25.750000
1741 2 24.000000
1742 2 24.000000
415 rows × 2 columns
```
1. Ahora puedes asignar tus datos de coodenadas X e Y:
```python
X = lin_pumpkins.values[:, :1]
y = lin_pumpkins.values[:, 1:2]
```
✅ ¿Qué está pasando aquí? Estás usando [notación slice de Python](https://stackoverflow.com/questions/509211/understanding-slice-notation/509295#509295) para crear arreglos y así poblar `X` e `Y`.
2. Lo siguiente es, iniciar las rutinas de construcción del modelo de regresión:
```python
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
lin_reg = LinearRegression()
lin_reg.fit(X_train,y_train)
pred = lin_reg.predict(X_test)
accuracy_score = lin_reg.score(X_train,y_train)
print('Model Accuracy: ', accuracy_score)
```
Debido a que la correlación nos es particularmente buena, el modelo producido no es terriblemente preciso.
```output
Model Accuracy: 0.3315342327998987
```
3. Puedes visualziar la línea dibujada en el proceso:
```python
plt.scatter(X_test, y_test, color='black')
plt.plot(X_test, pred, color='blue', linewidth=3)
plt.xlabel('Package')
plt.ylabel('Price')
plt.show()
```
![Un gráfico de dispersión mostrando la relación paquete a precio](../images/linear.png)
4. Prueba el modelo contra una variedad hipotética:
```python
lin_reg.predict( np.array([ [2.75] ]) )
```
El precio devuelto para esta Variedad mitológica es:
```output
array([[33.15655975]])
```
Ese número hace sentido, si la lógica de la regresión lineal es cierta.
🎃 Felicidades, acabas de crear un modelo que puede ayudara predecir el precio de unas pocas variedades de calabazas. Tu parcela de calabazas de días festivos serán hermosas. ¡Pero probablemente puedes crear un mejor modelo!
## Regresión polinomial
Otro tipo de regresión lineal es la regresión polinomial. Mientras algunas veces existe una relación lineal entre las variables - entre más grande el volumen de la calabaza, mayor el precio - algunas veces estas relaciones no pueden ser graficadas como un plano o línea recta.
✅ Aquí hay [más ejemplos](https://online.stat.psu.edu/stat501/lesson/9/9.8) de los datos que podrían usar regresión polinomial.
Da un vistazo más a la relación entre Variedad a Precio en la gráfica anterior. ¿Parece que el gráfico de dispersión debería ser analizado necesariamente por una línea recta? Quizá no. En este caso, puedes probar la regresión polinomial.
✅ Los polinomios son expresiones matemáticas que pueden consistir en una o más variables y coeficientes.
La regresión polinomial crea una línea curva para ajustar mejor los datos no lineales.
1. Recreemos un dataframe poblado con un segmento de los datos originales de las calabazas:
```python
new_columns = ['Variety', 'Package', 'City', 'Month', 'Price']
poly_pumpkins = new_pumpkins.drop([c for c in new_pumpkins.columns if c not in new_columns], axis='columns')
poly_pumpkins
```
Una buena forma de visualizar las correlaciones entre los datos en los dataframes es mostrarlos en una gráfica 'coolwarm':
2. Usa el método `Background_gradient()` con `coolwarm` como valor de su argumento:
```python
corr = poly_pumpkins.corr()
corr.style.background_gradient(cmap='coolwarm')
```
Este código crea un mapa de calor:
![Un mapa de calor mostrando correlación de datos](../images/heatmap.png)
Viendo esta gráfica, puedes visualizar la buena correlación entre Paquete y Precio. Así que deberías ser capaz de crear un modelo algo mejor que el anterior.
### Crea un pipeline
Scikit-learn incluye una API útil para crear modelos de regresión polinomail - la [API](https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.make_pipeline.html?highlight=pipeline#sklearn.pipeline.make_pipeline) `make_pipeline`. Se crea un 'pipeline' que es una cadena de estimadores. En este caso, el pipeline incluye características polinomiales, o predicciones que forman un camino no lineal.
1. Construye las columnas X e Y:
```python
X=poly_pumpkins.iloc[:,3:4].values
y=poly_pumpkins.iloc[:,4:5].values
```
2. Crea el pipeline llamando al método `make_pipeline()`:
```python
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
pipeline = make_pipeline(PolynomialFeatures(4), LinearRegression())
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
pipeline.fit(np.array(X_train), y_train)
y_pred=pipeline.predict(X_test)
```
### Crea una secuencia
En este punto, necesitas crear un nuevo dataframe con datos _ordenados_ para que así el pipeline pueda crear una secuencia.
Agrega el siguiente código:
```python
df = pd.DataFrame({'x': X_test[:,0], 'y': y_pred[:,0]})
df.sort_values(by='x',inplace = True)
points = pd.DataFrame(df).to_numpy()
plt.plot(points[:, 0], points[:, 1],color="blue", linewidth=3)
plt.xlabel('Package')
plt.ylabel('Price')
plt.scatter(X,y, color="black")
plt.show()
```
Creaste un nuevo dataframe llamando `pd.DataFrame`. Luego ordenaste los valores al llamar `sort_values()`. Finalmente creaste un gráfico polinomial:
![Un gráfico polinomial mostrando la relación paquete a precio](../images/polynomial.png)
Puedes ver una línea curva que se ajusta mejor a tus datos.
Revisemos la precisión del modelo:
```python
accuracy_score = pipeline.score(X_train,y_train)
print('Model Accuracy: ', accuracy_score)
```
¡Y voila!
```output
Model Accuracy: 0.8537946517073784
```
¡Es mejor! Intenta predecir un precio:
### Haz un predicción
¿Podemos ingresar un nuevo valor y obtener una predicción?
Llama a `predict()` para hacer una predicción:
```python
pipeline.predict( np.array([ [2.75] ]) )
```
Se te presenta esta predicción:
```output
array([[46.34509342]])
```
¡Hace sentido, dado el gráfico! Y, si este es un mejor modelo que el anterior, viendo los mismos datos, ¡necesitas presupuestar para estas calabazas más caras!
🏆 ¡Bien hecho! Creaste dos modelos de regresión en una lección. En la sección final de regresión, aprenderás acerca de la regresión logística para determinar categorías.
---
## 🚀Desafío
Prueba variables diferentes en este notebook para ver cómo la correlación corresponde a la precisión del modelo.
## [Examen posterior a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/14/)
## Revisión y auto-estudio
En esta lección aprendimos acerca de la regresión lineal. Existen otros tipos importantes de regresión. Lee acerca de las técnicas paso a paso (Stepwise), cresta (Ridge), Lazo y red elástica (Lasso and Elasticnet). Un buen curso para estudiar para aprender más es el [Curso de aprendizaje estadístico de Stanford](https://online.stanford.edu/courses/sohs-ystatslearning-statistical-learning)
## Asignación
[Construye un modelo](assignment.es.md)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 235 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 19 KiB

@ -0,0 +1,313 @@
# Regresión logística para predecir categorías
![Infografía de regresiones lineal vs logística](../images/logistic-linear.png)
> Infografía de [Dasani Madipalli](https://twitter.com/dasani_decoded)
## [Examen previo a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/15/)
> ### [Esta lección se encuentra disponible en R!](../solution/R/lesson_4-R.ipynb)
## Introducción
En esta lección final de Regresión, una de las técnicas básicas _clásicas_ de aprendizaje automático, echaremos un vistazo a la regresión logística. Usarás esta técnica para descubrir patrones que predigan categorías binarias. ¿Este dulce es un chocolate o no lo es? ¿Ésta enfermedad es contagiosa o no?, ¿Este cliente eligirá este producto o no?
En esta lección, aprenderás:
- Una nueva librería para visualización de datos
- Técnicas para regresión logística
✅ Profundiza tu entendimiento de trabajo con este tipo de regresión en este [módulo de aprendizaje(https://docs.microsoft.com/learn/modules/train-evaluate-classification-models?WT.mc_id=academic-15963-cxa)
## Requisitos previos
Haber trabajado con los datos de calabazas, ahora estamos suficientemente familiarizados con estos para entender que hay una categoría binaria que podemos trabajar con `Color`.
Construyamos un modelo de regresión logística para predecirlo, dadas algunas variables, _qué color podría tener una calabaza dada_ (naranja 🎃 o blanca 👻).
> ¿Porqué estamos hablando acerca de clasificación binaria en un grupo de lecciones acerca de regresión? Sólo por conveniencia ligüística, como la regresión logística es [realmente un método de clasificación](https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression), aunque de de base lineal. Aprende acerca de otras formas de clasificar los datos en el siguiente grupo de lecciones.
## Define la pregunta
Para nuestros propósitos, expresaremos esto como un binario: 'Orange' o 'Not Orange'. También hay una categoría 'striped' en nuestro conjunto de datos pero hay menos instancias de éstas, por lo que no las usaremos. Ésta desaparece una vez que removemos los valores nulos de nuestro conjunto de datos, de cualquier forma.
> 🎃 Dato gracioso, algunas veces llamamos 'fantasmas' a las calabazas blancas. No son muy fáciles de tallar, por lo que no son tan populares como las calabazas naranjas, ¡pero se ven geniales!
## Acerca de la regresión logística
La regresión logística difiere de la regresión lineal, lo cual aprendiste previamentem en unas pocas cosas importantes.
### Clasificación binaria
La regresión logística no ofrece las mismas características como la regresión lineal. Las primeras ofrecen una predicción acerca de categorías binarias ("naranja o no naranja") mientras que la segunda es capaz de predecir valores continuos, por ejemplo dado el origen de una calabaza y el tiempo de cosecha, _cuánto incrementará su precio_.
![Modelo de clasificación de calabazas](../images/pumpkin-classifier.png)
> Infografía de [Dasani Madipalli](https://twitter.com/dasani_decoded)
### Otras clasificaciones
Existen otros tipo de regresión logística, incluyendo la multinomial y ordinal:
- **Multinomial**, la cual implica tener más de una categoría - "Orange, White, and Striped".
- **Ordinal**, la cual implica categorías ordenadas, útil si quisieramos ordenar nuestras resultados logicamente, como nuestras calabazas que están ordenadas por un número finito de tamaños (mini,sm,med,lg,xl,xxl).
![Regresión multinomial vs ordinal](../images/multinomial-ordinal.png)
> Infografía de [Dasani Madipalli](https://twitter.com/dasani_decoded)
### Sigue siendo lineal
Aunqeu este tipo de regresión se trata de 'predicciones de categoría', aún funciona mejor cuando hay una relación clara entre la variable dependiente (color) y las otras variables independientes (el resto del conjunto de datos, como el nombre de la ciudad y tamaño). Es bueno tener una idea de si hay alguna linealidad dividiendo estas variables o no.
### Las variables NO tienen correlación
¿Recuerdas cómo la regresión lineal funcionó mejor con variables correlacionadas? La regresión logística es lo opuesto - las variables no se tienen que alinear. Eso funciona para estos datos los cuales tienen correlaciones algo débiles.
### Necesitas muchos datos limpios
La regresión logística te dará resultados más precisos si usas más datos; nuestro pequeño conjunto de datos no es óptimo para esta tarea, así que tenlo en mente.
✅ piensa en los tipos de datos que se prestarían bien para la regresión logística
## Ejercicio - arregla los datos
Primero, limpia los datos un poco, remueve los valores nulos y selecciona sólo algunas de las columnas:
1. Agrega el siguiente código:
```python
from sklearn.preprocessing import LabelEncoder
new_columns = ['Color','Origin','Item Size','Variety','City Name','Package']
new_pumpkins = pumpkins.drop([c for c in pumpkins.columns if c not in new_columns], axis=1)
new_pumpkins.dropna(inplace=True)
new_pumpkins = new_pumpkins.apply(LabelEncoder().fit_transform)
```
Siempre puedes echar un vistazo a tu nuevo dataframe:
```python
new_pumpkins.info
```
### Visualización - cuadrícula lado a lado
Por ahora has cargado el [starter notebook](../notebook.ipynb) con datos de calabazas una vez más y los has limpiado para así preservar el conjunto de datos que contiene unas pocas variables, incluyendo `Color`. Visualizaremos el dataframe en el notebook usando una librería diferente: [Seaborn](https://seaborn.pydata.org/index.html), el cual es construido en Matplotlib que ya usamos anteriormente.
Seaborn ofrece algunas formas ingeniosas de visualizar tus datos. Por ejemplo, puedes comparar distribuciones de los datos para cada punto en una cuadrícula lado a lado.
1. Crea dicha cuadrícula instanciando `PairGrid`, usando nuestros datos de calabazas `new_pumpkins`, seguido de la llamada a `map()`:
```python
import seaborn as sns
g = sns.PairGrid(new_pumpkins)
g.map(sns.scatterplot)
```
![Una cuadrícula de datos visualizados](../images/grid.png)
Al observar los datos lado a lado, puedes ver como los datos de Color se relacionan con las otras columnas.
✅ Dada la cuadrícula del gráfico de dispersión, ¿cuáles son algunas exploraciones interesantes que puedes visualizar?
### Usa un gráfico de enjambre
Dado que Color es una categoría binaria (Naranja o no), se le llaman 'datos categóricos' y necesita 'un [enfoque más especializado](https://seaborn.pydata.org/tutorial/categorical.html?highlight=bar) para visualización. Hay otras formas de visualizar las relaciones de esta categoría con otras variables.
Puedes visualizar variables lado a lado con los gráficos Seaborn.
1. Prueba un gráfico de 'enjambre' (swarm) para mostrar la distribución de valores:
```python
sns.swarmplot(x="Color", y="Item Size", data=new_pumpkins)
```
![Un enjambre de datos visualizados](../images/swarm.png)
### Gráfico de Violín
Un gráfico tipo 'violín' es útil ya que puedes visualizar fácilmente la forma en que los datos se distribuyen en las dos categorías. Los gŕaficos de violín no funcionan muy bien con conjuntos de datos muy pequeños ya que la distribución se muestra más 'suavemente'.
1. Como parámetros `x=Color`, `kind="violin"` y llamada `catplot()`:
```python
sns.catplot(x="Color", y="Item Size",
kind="violin", data=new_pumpkins)
```
![un tipo de gráfico de violín](../images/violin.png)
✅ Prueba a crear este gráfico, y otros gráficos de Seaborn, usando otras variables.
Ahora que tenemos una idea de la relación entre las categorías binarias de color y el grupo mayor de tamaños, exploremos la regresión logística para determinar el color probable de cierta calabaza.
> **🧮 Muéstrame las matemáticas**
>
> ¿Recuerdas cómo la regresión lineal suele ser usó mínimos cuadrados ordinarios para llegar al valor? La regresión logística se basa en el concepto de 'máxima probabilidad' usando [funciones sigmoides](https://wikipedia.org/wiki/Sigmoid_function). Una 'Función Sigmoide' en una gráfico tiene la forma de una 'S'. Toma una valor lo asigna entre 0 y 1. Su curva también es llamada 'curva logística'. Su fórmula luce así:
>
> ![Función logística](../images/sigmoid.png)
>
> Donde el punto medio del sigmoide se encuentra en el punt 0 de las x, L es el valor máximo de la curva, k es la pendiente de la curva. Si el resultado de la función es más de 0.5, la etiqueta en cuestión se le dará la clase '1' de la elección binaria. Si no, será clasificada como '0'.
## Construye tu modelo
Construir un modelo para encontrar estas clasificaciones binarias es sorprendentemente fácil en Scikit-learn.
1. Elige las variable que quieres usar en tu modelo de clasificación y divide el modelo y los conjuntos de pruebas llamando `train_test_split()`:
```python
from sklearn.model_selection import train_test_split
Selected_features = ['Origin','Item Size','Variety','City Name','Package']
X = new_pumpkins[Selected_features]
y = new_pumpkins['Color']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
```
1. Ahora puedes entrenar tu modelo, llamando `fit()` con tus datos entrenados, e imprimir su resultado:
```python
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X_train, y_train)
predictions = model.predict(X_test)
print(classification_report(y_test, predictions))
print('Predicted labels: ', predictions)
print('Accuracy: ', accuracy_score(y_test, predictions))
```
Echa un vistazo al marcador de tu modelo. No es tan malo, considerando tienes solo 1000 filas de datos:
```output
precision recall f1-score support
0 0.85 0.95 0.90 166
1 0.38 0.15 0.22 33
accuracy 0.82 199
macro avg 0.62 0.55 0.56 199
weighted avg 0.77 0.82 0.78 199
Predicted labels: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 1 0 0 1 0 0 0 1 0]
```
## Mejor comprensión a través e una matriz de confusión
Mientras puedes obtener un reporte de [términos](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.classification_report.html?highlight=classification_report#sklearn.metrics.classification_report) del marcador imprimiendo los elementos de arriba, serás capaz de entender tu modelo más fácilmente usando una [matriz de confusión](https://scikit-learn.org/stable/modules/model_evaluation.html#confusion-matrix) para ayudarnos a entender cómo se desempeña el modelo.
> 🎓 Una '[matriz de confusión](https://wikipedia.org/wiki/Confusion_matrix)' (o 'matriz de error') es una table que expresa los verdaderos vs los falsos positivos y negativos de tu modelo, para así medir la precisión de las predicciones.
1. Para usar métricas de confusión, llama `confusion_matrix()`:
```python
from sklearn.metrics import confusion_matrix
confusion_matrix(y_test, predictions)
```
Echa un vistazo a la matriz de confusión de tu modelo:
```output
array([[162, 4],
[ 33, 0]])
```
En Scikit-learn, las filas de las matriaces de confusión (eje 0) son etiquetas reales y las columnas (eje 1) son etiquetas previstas.
| | 0 | 1 |
| :---: | :---: | :---: |
| 0 | TN | FP |
| 1 | FN | TP |
¿Qué pasa aquí? Digamos que se le pidió a tu modelo clasificar las calabaas entre dos categorías binarias, la categoría 'orange' y la categoría 'not-orange'.
- Si tu modelo predice una calabaza como no naranja y esta pertenece a la categoría 'not-orange' en realidad la llamamos como un verdadero negativo, mostrado por el número superior izquierdo.
- Si tu modelo precice una calabaza como naranja y esta pertenece a la categoría 'not-orange' en realidad la llamamos como un falso negativo, mostrado por el número inferior izquierdo.
- Si tu modelo predice una calabaza como no naranja y este pertenece a la categoría 'orange' en realidad la llamamos como un falso positivo, mostrado por el número superior derecho.
- Si tu modelo predice una calabaza como naranja y esta pertenece a la categoría 'naranja' en realidad la llamamos como un verdadero positivo, mostrado por el número inferior derecho.
Como habrás adivinado, es preferible tener un número mayor de verdaderos positivos y verdaderos negativos, y un número menor de falsos positivos y falsos negativos, lo cual implica que el modelo se desempeña mejor.
¿Cómo se relaciona la matriz de confusión con precision (precisión) y recall (recuerdo)? Recuerda, el reporte de clasificación impreso arriba mostró precisión (0.83) y recuerdo (0.98).
Precision = tp / (tp + fp) = 162 / (162 + 33) = 0.8307692307692308
Recall = tp / (tp + fn) = 162 / (162 + 4) = 0.9759036144578314
✅ Q: De acuerdo a la matriz de confusión, ¿cómo lo hizo el modelo? A: No tan mal; existe un buen número de verdaderos positivos pero también varios falsos negativos.
Repasemos los término que vimos anteriormente con la ayuda de la asignación de la matriz de confusión de TP/TN y FP/FN:
🎓 Precision: TP/(TP + FP) La fración de instancias relevantes entre las instancias recuperadas (ejemplo, qué etiquetas fueron bien etiquetadas)
🎓 Recall: TP/(TP + FN) La fracción de instancias relevantes que fueron recuperadas, bien etiquetadas o no
🎓 f1-score: (2 * precision * recall)/(precision + recall) Un promedio ponderado de precisión y recuerdo, siendo lo mejor 1 y lo pero 0
🎓 Soporte: El número de ocurrencias de cada etiqueta recuperada
🎓 Precisión: (TP + TN)/(TP + TN + FP + FN) El porcentaje de etiquetas previstas de forma precisa para la muestra.
🎓 Promedio de macros: El cálculo de métricas medias no ponderadas para cada etiqueta, no tomando en cuenta el desequilibrio de etiquetas.
🎓 Promedio ponderado: El cálculo de las métricas medias para cada etiqueta, tomando en cuenta el desequilibrio de etiquetas al ponderarlas po su soporte (el número de instancias verdaderas para cada etiqueta).
✅ ¿Puedes pensar cuáles métrcias debes observar si quieres que tu modelo para reducir el número de falsos negativos?
## Visualiza la curva ROC de este modelo
Este no es un mal modelo; su precisión está en el rango de 80% ya que idealmente puedes usarlo para precedir el color de una calabaza dado un conjunto de variables.
Hagamos una visualización más para ver el así llamado puntaje 'ROC':
```python
from sklearn.metrics import roc_curve, roc_auc_score
y_scores = model.predict_proba(X_test)
# calculate ROC curve
fpr, tpr, thresholds = roc_curve(y_test, y_scores[:,1])
sns.lineplot([0, 1], [0, 1])
sns.lineplot(fpr, tpr)
```
Usando de nuevo Seaborn, grafica la [característica operativa de recepción](https://scikit-learn.org/stable/auto_examples/model_selection/plot_roc.html?highlight=roc) del modelo o ROC. Las curvas ROC curves son usadas comúnmente para obtener una vista de la salida de un clasificador en términos de sus verdaderos positivos vs falsos positivos. "Las curvas ROC presentan típicamente la tasa de verdaderos positivos en el eje Y, y la tasa falsos positivos en el eje X." Así, la inclinación de la curvay el espeacio entre la línea del punto medio y la curva importan: quieres una curva que suba rápidamente y sobre la línea. En nuestro caso, hay falsos positivos para empezar, y luego la línea sube hacía arriba y continua propiamente:
![ROC](../images/ROC.png)
Finalmente, usa la [API `roc_auc_score`](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.roc_auc_score.html?highlight=roc_auc#sklearn.metrics.roc_auc_score) de Scikit-learn para calcular el 'Área bajo la curva' real (AUC):
```python
auc = roc_auc_score(y_test,y_scores[:,1])
print(auc)
```
El resultado es `0.6976998904709748`. Dado que la AUC varía entre 0 y 1, quieres un puntaje grande, ya que un modelo que es 100% correcto en sus predicciones tendrá un AUC de 1; en este caso el modelo es _bastante bueno_.
En futuras lecciones de clasificación, aprenderás cómo iterar para mejorar los puntajes de tus modelos. Pero por ahora, ¡felicitaciones!, ¡Haz completado estas lecciones de regresión!
---
## 🚀Desafío
¡Hay mucho más para desempacar respecto a la regresión logística! Pero la mejor forma de aprender es experimentar. Encuentra un conjunto de datos que se preste para este tipo de análisis y construye un modelo con él. ¿Qué aprendes? tipo: prueba [Kaggle](https://www.kaggle.com/search?q=logistic+regression+datasets) por conjuntos de datos interesantes.
## [Examen posterior a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/16/)
## Revisión & autoestudio
Lee las primeras páginas de este [artículo de Stanford](https://web.stanford.edu/~jurafsky/slp3/5.pdf) de algunos usos prácticos para la regresión logística. Piensa en las tareas que se ajustan mejor para uno u otro tipo de tareas de regresión que estudiamos hasta el momento. ¿Que funcionaría mejor?
## Asignación
[Reintentando esta regresión](assignment.es.md)

@ -0,0 +1,11 @@
# Reintentando alguna regresión
## Instrucciones
En esta lección, usaste un subconjunto de datos de las calabazas. Hora, vuelve a los datos originales e intenta usar todos ellos, limpios y estandarizados, para construir un modelo de regresión logística.
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | ----------------------------------------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------- |
| | Se presenta un notebook con un modelo bien explicado y realizado | Se presenta un notebook con un modelo con rendimiento mínimo | Se presenta un modelo con un rendimiento precario o nulo |

@ -0,0 +1,36 @@
# मशीन लर्निंग के लिए रिग्रेशन मॉडल
## क्षेत्रीय विषय: उत्तरी अमेरिका में कद्दू की कीमतों के लिए रिग्रेशन मॉडल 🎃
उत्तरी अमेरिका में, कद्दू को अक्सर हैलोवीन के लिए डरावने चेहरों में उकेरा जाता है। आइए इन आकर्षक सब्जियों के बारे में और जानें!
![जैक-ओ-लालटेन](../images/jack-o-lanterns.jpg)
> <a href="https://unsplash.com/@teutschmann?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">बेथ तेउतसच्मैंन</a> द्वारा तस्वीर <a href="https://unsplash.com/s/photos/jack-o-lanterns?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">अनस्पेलश </a> पर
## आप क्या सीखेंगे
[![रिग्रेशन का परिचय](https://img.youtube.com/vi/5QnJtDad4iQ/0.jpg)](https://youtu.be/5QnJtDad4iQ "रिग्रेशन परिचय वीडियो - देखने के लिए क्लिक करें!")
> 🎥 इस पाठ के त्वरित परिचय वीडियो के लिए ऊपर की छवि पर क्लिक करें
इस खंड के पाठ में मशीन लर्निंग के संदर्भ में रिग्रेशन के प्रकारों को शामिल किया गया है। रिग्रेशन मॉडल चरों के बीच _संबंध_ को निर्धारित करने में मदद कर सकते हैं। इस प्रकार का मॉडल लंबाई, तापमान या उम्र जैसे मूल्यों की भविष्यवाणी कर सकता है, इस प्रकार चर के बीच संबंधों को उजागर करता है क्योंकि यह डेटा बिंदुओं का विश्लेषण करता है।
पाठों की इस श्रृंखला में, आप रैखिक और लॉजिस्टिक प्रतिगमन के बीच के अंतरों की खोज करेंगे, और कब कौन सा इस्तेमाल करना चाहिए।
पाठों के इस समूह में, आप मशीन लर्निंग सीखने के कार्यों को शुरू करने के लिए तैयार होंगे, जिसमें नोटबुक को प्रबंधित करने के लिए विजुअल स्टूडियो कोड को कॉन्फ़िगर करना, डेटा वैज्ञानिकों के लिए सामान्य वातावरण शामिल है। आप मशीन लर्निंग के लिए एक लाइब्रेरी स्किकिट-लर्न की खोज करेंगे, और आप इस अध्याय में रिग्रेशन मॉडल पर ध्यान केंद्रित करते हुए अपना पहला मॉडल बनाएंगे।
>ये उपयोगी निम्न-कोड उपकरण हैं जो आपको रिग्रेशन मॉडल के साथ काम करने के बारे में जानने में मदद कर सकते हैं.इस्तेमाल करे [इस कार्य के लिए अज़ूरे एमएल](https://docs.microsoft.com/learn/modules/create-regression-model-azure-machine-learning-designer/?WT.mc_id=academic-15963-cxa)
### पाठ
1. [व्यापार के उपकरण](../1-Tools/README.md)
2. [डेटा प्रबंधित करना](../2-Data/README.md)
3. [लीनियर एंड पोलीनोमिअल रिग्रेशन](../3-Linear/README.md)
4. [लोगिस्टिक रिग्रेशन](../4-Logistic/README.md)
---
### क्रेडिट
"रिग्रेशन के साथ एमएल" [जेन लूपर](https://twitter.com/jenlooper) द्वारा ♥ से लिखा गया
♥️ प्रश्नोत्तरी योगदानकर्ताओं में शामिल हैं: [मुहम्मद साकिब खान इंजन](https://twitter.com/Sakibinan) और [ऑर्नेला अल्तुन्यान](https://twitter.com/ornelladotcom)
[कागल पर इस प्रोजैक्टा](https://www.kaggle.com/usda/a-year-of-pumpkin-prices) द्वारा कद्दू डेटासेट का सुझाव दिया गया है और इसका डेटा संयुक्त राज्य अमेरिका के कृषि विभाग द्वारा वितरित [स्पेशलिटी क्रॉप्स टर्मिनल मार्केट्स स्टैंडर्ड रिपोर्ट्स](https://www.marketnews.usda.gov/mnp/fv-report-config-step1?type=termPrice) से लिया गया है। हमने वितरण को सामान्य करने के लिए विविधता के आधार पर रंग के आसपास कुछ बिंदु जोड़े हैं। यह डेटा पब्लिक डोमेन में है।

@ -0,0 +1,346 @@
# Construye una aplicación web usando un modelo de aprendizaje automático
En esta lección, entrenarás un modelo de aprendizaje automático sobre un conjunto de datos que está fuera de este mundo: _avistamiento de OVNIs durante el siglo pasado_, proporcionados por la base de datos de NUFORC.
Aprenderás:
- Cómo hacer 'pickle' a un modelo entrenado
- Cómo usar ese modelo en una aplicación Flask
Continuaremos nuestro uso de notebooks para limpiar los datos y entrenar nuestro modelo, pero puedes llevar el proceso un paso más allá explorando el uso de un modelo 'en la naturaleza', por así decirlo: en una aplicación web.
Para hacer esto, necesitas construir una aplicación web usando Flask.
## [Examen previo a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/17/)
## Construyendo una aplicación
Existen muchas formas de construir aplicaciones web para consumir modelos de aprendizaje automático. Tu arquitectura web podría influir en la forma que tu modelo es entrenado. Imagina que estás trabajando en un negocio donde el grupo de ciencia de datos ha entrenado un modelo que quieren uses en una aplicación.
### Consideraciones
Hay muchas preguntas que necesitas realizar:
- **¿Es una aplicación web o móvil?** Si estás construyendo una aplicación móvil o necesitas uar el modelo en un contexto de IoT, podrías usar [TensorFlow Lite](https://www.tensorflow.org/lite/) y usar el modelo en una applicación Android o iOS.
- **¿Dónde residirá el modelo?** ¿En la nube o de forma local?
- **Soporte fuera de línea.** ¿La aplicación trabaja en modo fuera de línea?
- **¿Qué tecnología se usó para entrenar al modelo?** La tecnología elegida puede influir en las herramientas que necesitas utilizar.
- **Uso de TensorFlow.** Si estás entrenando un modelo usando TensorFlow, por ejemplo, ese ecosistema proporciona la capacidad de convertir un modelo de TensorFlow para su uso en una aplicación web usando [TensorFlow.js](https://www.tensorflow.org/js/).
- **Uso de PyTorch.** Si estás construyendo un modelo usando una librería como [PyTorch](https://pytorch.org/), tienes la opción de exportarlo en formato [ONNX](https://onnx.ai/) (Open Neural Network Exchange) para usarlo en aplicaciones web de javascript que puedan usar el entorno de ejecución [Onnx Runtime](https://www.onnxruntime.ai/). Esta opción será explorada en una futura lección para un modelo entrenado Scikit-learn.
- **Uso de Lobe.ai o Azure Custom Vision.** Si estás usando un sistema de aprendizaje automático SaaS (Software as a Service) como lo es [Lobe.ai](https://lobe.ai/) o [Azure Custom Vision](https://azure.microsoft.com/services/cognitive-services/custom-vision-service/?WT.mc_id=academic-15963-cxa) para entrenar un modelo, este tipo de software proporciona formas de exportar el modelo a diversas plataformas, incluyendo el construir una API a medida para que esta sea consultada en la nube por tu aplicación en línea.
También tienes la oportunidad de construir una plicación web completamente en Flask que será capaz de entrenar el propio modelo en un navegador web. Esto también puede ser realizado usando TensorFlow.js en un contexto JavaScript.
Para nuestros propósitos, ya que hemos estado trabajando con notebooks basados en Python, exploremos los pasos que necesitas realizar para exportar un modelo entrenado desde un notebook a un formato legible para una aplicación web construida en Python.
## Herramientas
Para esta tarea, necesitas dos herramientas: Flask y Pickle, ambos corren en Python.
✅ ¿Qué es [Flask](https://palletsprojects.com/p/flask/)? Definido como un 'micro-framework' por sus creadores, Flask proporciona las características básicas de los frameworks web usando Python y un motor de plantillas para construir páginas web. Da un vistazo a [este módulo de aprendizaje](https://docs.microsoft.com/learn/modules/python-flask-build-ai-web-app?WT.mc_id=academic-15963-cxa) para practicar construir con Flask.
✅ ¿Qué es [Pickle](https://docs.python.org/3/library/pickle.html)? Pickle 🥒 es un módulo de Python que serializa y deserializa estructura de objetos Python. Cuando conviertes un modelo en 'pickle', serializas o aplanas su estructura para su uso en la web. Sé cuidadoso: Pickle no es intrínsecamente seguro, por lo que debes ser cuidadoso si solicitaste hacer 'un-pickle' en un archivo. Un archivo hecho pickle tiene el sufijo `.pkl`.
## Ejercicio - limpia tus datos
En esta lección usarás datos de 80,000 avistamientos de OVNIs, recopilados por [NUFORC](https://nuforc.org) (El centro nacional de informes OVNI). Estos datos tienen algunas descripciones interesantes de avistamientos OVNI, por ejemplo:
- **Descripción larga del ejemplo.** "Un hombre emerge de un haz de luz que brilla en un campo de hierba por la noche y corre hacia el estacionamiento de Texas Instruments".
- **Descripción corta del ejemplo.** "las luces nos persiguieron".
La hoja de cálculo [ufos.csv](../data/ufos.csv) incluye columnas acerca de los campos `city`, `state` y `country` donde ocurrió el avistamiento, la forma (`shape`) y su latitud (`latitude`) y ubicación (`latitude` y `longitude`).
En el [notebook](../notebook.ipynb) en blanco incluído en esta lección:
1. Importa `pandas`, `matplotlib`, y `numpy` como lo hiciste en lecciones anteriores e importa la hoja de cálculo ufos. Puedes dar un vistazo al conjunto de datos de ejemplo:
```python
import pandas as pd
import numpy as np
ufos = pd.read_csv('./data/ufos.csv')
ufos.head()
```
1. Convierte los datos de OVNIs en un pequeño dataframe con nuevos títulos. Revisa los valores únicos en el campo `Country`.
```python
ufos = pd.DataFrame({'Seconds': ufos['duration (seconds)'], 'Country': ufos['country'],'Latitude': ufos['latitude'],'Longitude': ufos['longitude']})
ufos.Country.unique()
```
1. Ahora, puedes reducir la cantidad de datos que necesitamos manejar eliminando cualquier valor nulo e importando únicamente los avistamientos entre 1 y 60 segundos:
```python
ufos.dropna(inplace=True)
ufos = ufos[(ufos['Seconds'] >= 1) & (ufos['Seconds'] <= 60)]
ufos.info()
```
1. Importa la librería `LabelEncoder` de Scikit-learn para convertir los valores de texto de los países a número:
✅ LabelEncoder codifica los datos alfabéticamente
```python
from sklearn.preprocessing import LabelEncoder
ufos['Country'] = LabelEncoder().fit_transform(ufos['Country'])
ufos.head()
```
Tus datos deberían verse así:
```output
Seconds Country Latitude Longitude
2 20.0 3 53.200000 -2.916667
3 20.0 4 28.978333 -96.645833
14 30.0 4 35.823889 -80.253611
23 60.0 4 45.582778 -122.352222
24 3.0 3 51.783333 -0.783333
```
## Ejercicio - construye tu modelo
Ahora puedes prepararte para entrenar un modelo dividiendo los datos entre los grupos de entrenamiento y pruebas.
1. Selecciona las tres características que quieres entrenar en tu vector X, y el vector Y será `Country`. Quieres ser capaz de introducir `Seconds`, `Latitude` y `Longitude` y obtener un id de país de regreso.
```python
from sklearn.model_selection import train_test_split
Selected_features = ['Seconds','Latitude','Longitude']
X = ufos[Selected_features]
y = ufos['Country']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
```
1. Entrena tu modelo usando regresión logística:
```python
from sklearn.metrics import accuracy_score, classification_report
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X_train, y_train)
predictions = model.predict(X_test)
print(classification_report(y_test, predictions))
print('Predicted labels: ', predictions)
print('Accuracy: ', accuracy_score(y_test, predictions))
```
La precisión no es mala **(alrededor del 95%)**, como era de esperar, ya que `Country` y `Latitude/Longitude` se correlacionan.
El modelo que creaste no es muy revolucionario como deberías ser capaz de inferir un país (`Country`) por su latitud y longitud (`Latitude`, `Longitude`), pero es un buen ejercicio intentar entrenar desde datos en crudo que ya limpiaste, exportaste y luego usa este modelo en una aplicación web.
## Ejercicio - Haz 'pickle' a tu modelo
Ahora, ¡es momento de hacer _pickle_ a tu modelo! Puedes hacer eso con pocas líneas de código. Una vez la hiciste _pickle_, carga tu modelo serializado (pickled) y pruébalo constra un arreglo de datos de muestra que contenga los valores para segundos, latitud y longitud.
```python
import pickle
model_filename = 'ufo-model.pkl'
pickle.dump(model, open(model_filename,'wb'))
model = pickle.load(open('ufo-model.pkl','rb'))
print(model.predict([[50,44,-12]]))
```
El modelo regresa **'3'**, lo cual es el código de país para el Reino Unido (UK). ¡Sorprendente! 👽
## Ejercicio - Construye una aplicación Flask
Ahora puedes construir una aplicación Flask para llamara tu modelo y regresar resultados similares, pero de una forma visualmente más agradable.
1. Comienza por crear un directorio llamado **web-app** junto al archivo _notebook.ipynb_ donde reside el archivo _ufo-model.pkl_.
1. En ese directorio crea 3 directorios más: **static**, con un directorio **css** dentro de el, y **templates**. Ahora tienes la siguiente estructura de directorios:
```output
web-app/
static/
css/
templates/
notebook.ipynb
ufo-model.pkl
```
✅ Consulta el directorio de la solución para una vista de la aplicación terminada.
1. El primer archivo a crear en el directorio _web-app_ es el archivo **requirements.txt**. Así como _package.json_ en una aplicación JavaScript, este archivo lista las dependencias requeridas por la aplicación. En **requirements.txt** agrega las líneas:
```text
scikit-learn
pandas
numpy
flask
```
1. Ahora, ejecuta este archivo navegando a _web-app_:
```bash
cd web-app
```
1. Escribe en tu terminal `pip install`, para instalar las librerías listadas en _requirements.txt_:
```bash
pip install -r requirements.txt
```
1. Ahora, estás listo para crear 3 archivos más y así terminar la aplicación:
1. Crea el archivo **app.py** en la raíz.
2. Crea el archivo **index.html** dentro del directorio _templates_.
3. Crea el archivo **styles.css** dentro del directorio _static/css_.
1. Construye el archivo _styles.css_ file con algunos estilos:
```css
body {
width: 100%;
height: 100%;
font-family: 'Helvetica';
background: black;
color: #fff;
text-align: center;
letter-spacing: 1.4px;
font-size: 30px;
}
input {
min-width: 150px;
}
.grid {
width: 300px;
border: 1px solid #2d2d2d;
display: grid;
justify-content: center;
margin: 20px auto;
}
.box {
color: #fff;
background: #2d2d2d;
padding: 12px;
display: inline-block;
}
```
1. Lo siguiente es constuir el archivo _index.html_:
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>🛸 UFO Appearance Prediction! 👽</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
</head>
<body>
<div class="grid">
<div class="box">
<p>According to the number of seconds, latitude and longitude, which country is likely to have reported seeing a UFO?</p>
<form action="{{ url_for('predict')}}" method="post">
<input type="number" name="seconds" placeholder="Seconds" required="required" min="0" max="60" />
<input type="text" name="latitude" placeholder="Latitude" required="required" />
<input type="text" name="longitude" placeholder="Longitude" required="required" />
<button type="submit" class="btn">Predict country where the UFO is seen</button>
</form>
<p>{{ prediction_text }}</p>
</div>
</div>
</body>
</html>
```
Echa un vistazo a la plantilla en este archivo. Nota la sitaxis 'mustache' alrededor de las variables que serán proporcionadas por la aplicación, como el texto de predicción `{{}}`. También hay un formulario que publica una predicción a la ruta `/predict`.
Finalmente, estás listo para construir el archivo python que maneja el consumo de el modelo y la pantalla de predicciones:
1. En `app.py` agrega:
```python
import numpy as np
from flask import Flask, request, render_template
import pickle
app = Flask(__name__)
model = pickle.load(open("./ufo-model.pkl", "rb"))
@app.route("/")
def home():
return render_template("index.html")
@app.route("/predict", methods=["POST"])
def predict():
int_features = [int(x) for x in request.form.values()]
final_features = [np.array(int_features)]
prediction = model.predict(final_features)
output = prediction[0]
countries = ["Australia", "Canada", "Germany", "UK", "US"]
return render_template(
"index.html", prediction_text="Likely country: {}".format(countries[output])
)
if __name__ == "__main__":
app.run(debug=True)
```
> 💡 Tip: Cuando agregas [`debug=True`](https://www.askpython.com/python-modules/flask/flask-debug-mode) mientras ejecutas la aplicación web usando Flask, cualquier cambio que realices a tu aplicación será reflejado inmediatamente sin la necesidad de reiniciar el servidor. ¡Ten cuidado! No actives este modo en una aplicación en producción.
Si ejecutas `python app.py` o `python3 app.py` - tu servidor web inicia, localmente, y puedes llenar un pequeño formulario para obtener una respuesta a tu pregunta en cuestión acerca de ¡dónde han avistado OVNIs!
Antes de hacerlo, echa un vistazo a las partes de `app.py`:
1. Primero, las dependencias son cargadas y la aplicación inicia.
2. Luego, el modelo es importado.
3. Lo siguiente, el archivo index.html es renderizado en la ruta principal.
En la ruta `/predict`, pasan muchas cosas cuando el formulario se publica:
1. Las variables del formulario son reunidas y convertidas a un arreglo de numpy. Luego estas son enviadas al modelo y se regresa una predicción.
2. Los países que queremos se muestren son re-renderizados como texto legible de su código de país previsto, y ese valor es enviado de vuelta a index.html para ser renderizado en la plantilla.
Usando un modelo de esta forma, con Flask y un modelo hecho pickled, es relativamente sencillo. La cosa más difícil es entender qué forma tienen los datos que deben ser enviados al modelo para obtener una predicción. Todo eso depende en cómo fue entrenado el modelo. Este tiene 3 puntos de datos como entrada para así obtener una predicción.
En un entorno profesional, puedes ver cómo la buena comunicación es necesaria entre las personas las cuales entrenan el modelo y aquellas que lo consumen en una aplicación web o móvil. En nuestro caso, es una sola persona, ¡tú!
---
## 🚀 Desafío
En lugar de trabajar en un notebook e importar el modelo a una aplicación Flask, ¡podrías entrenar el modelo directo en la aplicación Flask! Intenta convertir tu código Python en el notebook, quizá después que tus datos sean limpiados, para entrenar el modelo desde la aplicación en una ruta llamada `train`. ¿Cuáles son los pros y contras de seguir este método?
## [Examen posterior a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/18/)
## Revisión y autoestudio
Hay muchas formas de construir una aplicación web para consumir modelos de aprendizaje automático. Haz una lista de las formas en que podrías usar JavaScript o Python para construir una aplicación web para aprovechar el apredizaje automático. Considera la arquitectura: ¿El modelo debería estar en la aplicación o vivir en la nube? Si es lo segundo, ¿Cómo lo accederías? Dibuja un modelo de arquitectura para una solución web de aprendizaje automático aplicada.
## Asignación
[Prueba un modelo diferente](assignment.es.md)

@ -0,0 +1,11 @@
# Prueba un modelo distinto
## Instrucciones
Ahora que haz construido una aplicación web usando un modelo de regresión entrenado, usa uno de los modelos de la lección anterior de regresión para rehacer esta aplicación web. Puedes conservar el estilo o diseñarlo de forma diferente para reflejar los datos de las calabazas. Sé cuidadoso al cambiar los insumos para reflejar tu método de entrenamiento del modelo.
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejora |
| -------------------------- | --------------------------------------------------------- | --------------------------------------------------------- | -------------------------------------- |
| | La aplicación web se ejecuta como se espera y es desplegda en la nube | La aplicación web contiene defectos o exhibe resultados inesperados | La aplicación web no funciona correctamente |

@ -0,0 +1,21 @@
# Construye una aplicación web para usar tu modelo de aprendizaje automático
En esta sección del curso, se te presentará un tema de aprendizaje automático aplicado: cómo guardar tu modelo Scikit-learn como un archivo que puede ser usado para realizar predicciones desde una aplicación web. Una vez que el modelo es guardado, aprenderás cómo usarlo en una aplicación web construida en Flask. ¡Primero crearás un modelo usando algunos datos relacionados con avistamiento de OVNIs! Luego, construirás una aplicación web que te permitirá ingresar un número de segundos con un valor de latitud y longitud para así predecir qué país reportó haber visto un OVNI.
![Estacionamiento de OVNIs](../images/ufo.jpg)
Fotografía de <a href="https://unsplash.com/@mdherren?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Michael Herren</a> en <a href="https://unsplash.com/s/photos/ufo?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>
## Lecciones
1. [Construye una aplicación web](../1-Web-App/translations/README.es.md)
## Créditos
"Construye una aplicación web"fue escrito con ♥️ por [Jen Looper](https://twitter.com/jenlooper).
♥️ Los cuestionariosfueron escritos por Rohan Raj.
Los conjuntos de datos fueron tomados de [Kaggle](https://www.kaggle.com/NUFORC/ufo-sightings).
La arquitectura de la aplicación web fue sugerida en parte por [este artículo](https://towardsdatascience.com/how-to-easily-deploy-machine-learning-models-using-flask-b95af8fe34d4) and [this repo](https://github.com/abhinavsagar/machine-learning-deployment) por Abhinav Sagar.

@ -0,0 +1,299 @@
# Introducción a la clasificación
En estas cuatro lecciones, explorarás un enfoque fundamental de aprendizaje automático clásico - _classification_. Ensayaremos usando varios algoritmos de clasificación con un conjunto de datos acerca de todas las cocinas brillantes de Asia e India. ¡Espero estés hambriento!
![Solo una pizca!](../images/pinch.png)
> ¡Celebra las cocinas de toda Asia en estas lecciones! Imagen de [Jen Looper](https://twitter.com/jenlooper)
La clasificación es una form de [aprendizaje supervisado](https://wikipedia.org/wiki/Supervised_learning) que conlleva mucho en común con técnicas de regresión. Si el aprendizaje automático trata todo acerca de la predicción de valores o nombres para las cosas usando conjuntos de datos, entonces la clasificación generalmente recae en dos grupos: _clasificación binaria_ y _clasificación multiclase_.
[![Introducción a la clasificación](https://img.youtube.com/vi/eg8DJYwdMyg/0.jpg)](https://youtu.be/eg8DJYwdMyg "Introducción a la clasificación")
> 🎥 Da clic en la imagen de arriba para ver el video: John Guttag del MIT presenta la clasificación
Recuerda:
- **La regresión lineal** te ayudó a predecir las relaciones entre las variables y hacer predicciones precisas donde un nuevo punto de datos podría reacer en una relación a esa línea. Por lo que puedes predecir _qué precio tendrá una calabaza en Septiembre vs Diciembre_, por ejemplo.
- **La regresión logística** te ayudó a descubrir "categorías binarias": en este punto de precio, ¿_la calabaza pertenece a la categoría orange or not-orange_?
La clasificación utiliza varios algorítmos para determinar otras formas de determinar la clase o etiqueta de un punto de datos. Trabajemos con estos datos de cocina para ver si, al observar un grupo de ingredientes, podemos determinar su cocina u origen.
## [Examen previo a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/19/)
> ### [¡Esta lección está disponible en R!](./solution/R/lesson_10-R.ipynb)
### Introducción
La clasificación es una de las actividades fundamentales del investigador de aprendizaje automático y el científico de datos. Desde la clasificación básica de un valor binario ("¿este correo electrónico es o no spam?"), hasta complejas clasificaciones de imágenes y segmentación utilizando la visión por computadora, simpre es útil ser capaz de ordenar los datos en clases y hacerle preguntas.
Para expresar el proceso de una forma más científica, nuestro método de clasificación crea un modelo predictivo que te habilita asignar la relación entre las variables de entrada a las variables de salida.
![Clasificación binaria vs multiclase](../images/binary-multiclass.png)
> Problemas binarios vs multiclase para que los algoritmos de clasificación los manejen. Infografía de [Jen Looper](https://twitter.com/jenlooper)
Antes de empezar el proceso de limpieza de nuestros datos, visualizarlos, y prepararlos para nuestras tareas de aprendizaje automático, aprendamos un poco acerca de las diversas formas en que el aprendizaje automático puede ser aprovechado para clasificar los datos.
Derivado de las clasificaciones [estadísticas](https://wikipedia.org/wiki/Statistical_classification), usando cracterística de uso del aprendizaje automático clásico, como `smoker`, `weight`, y `age` para determinar la _probabilidad de desarrollar X enfermedad_. Como una técnica de aprendizaje supervisada similar para los ejercicios de regresión que desempeñaste anteriormente, tus datos son etiquetados y los algoritmos de aprendizaje automático use esas etiquetas para clasificar y predecir clases (o 'características') de un conjunto de datos y asignarlos a un grupo o resultado.
✅ Date un momento para imaginar un conjunto de datos acerca de las cocinas. ¿Qué sería capaz de responder un modelo multiclase? ¿Qué sería capaz de responder un modelo binario? ¿Qué si quisieras determinar si una cocina dada fuera probable que usara fenogreco? ¿Qué si quisieras ver si, dado un regalo de una bolsa del supermercado llena de anís estrella, alcachofa, coliflor y rábano picante, pudieras crear un platillo Indio típico?
[![Canastas locas y misteriosas](https://img.youtube.com/vi/GuTeDbaNoEU/0.jpg)](https://youtu.be/GuTeDbaNoEU "Canastas locas y misteriosas")
> 🎥 Da clic en la imagen superior para ver un video. Toda la premisa del programa 'Chopped' es el 'cesto misterioso' donde los chefs tienen que hacer algunos platillos a partir de la elección al azar de ingredientes. ¡Seguramente un modelo de aprendizaje automático habría ayudado!
## Hola 'clasificador'
La pregutna que queremos hacer a este conjunto de datos de cocina es realmente una **pregunta multiclase**, así como tenemos muchas cocinas nacionales potenciales para trabajar, Dado un lote de ingredientes, ¿en cuáles de estas muchas clases encajarán los datos?
Scikit-learn ofrece diversos algoritmos distintos para usar en la clasificación de datos, dependiente en la naturaleza del problema que quieres resolver. En las siguientes dos lecciones, aprenderás acerca de varios de estos algoritmos.
## Ejercicio - limpia y equilibra tus datos
La primer tarea a la mano, antes de iniciar este proyecto, es limpiar y **equilibrar** tus datos para obtener mejores resultados. Comienza con el archivo en blanco _notebook.ipynb_ en la raíz de este directorio.
Lo primero a instalar es [imblearn](https://imbalanced-learn.org/stable/). Este es un paquete de Scikit-learn que te permitirá equilibrar mejor los datos (aprenderás más acerca de esta tarea en un minuto).
1. Para instalar `imblearn`, ejecuta `pip install`, así:
```python
pip install imblearn
```
1. Importa los paquetes que necesitas para importar tus datos y visualizarlos, también importa `SMOTE` de `imblearn`.
```python
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
from imblearn.over_sampling import SMOTE
```
Ahora está configurado para leer importart los datos a continuación.
1. La siguiente tarea será importar los datos:
```python
df = pd.read_csv('../data/cuisines.csv')
```
Usando `read_csv()` leerá el contenido del archivo csv _cusines.csv_ y colocarlo en la variable `df`.
1. Comprueba la forma de los datos:
```python
df.head()
```
Las primeras cinco filas lucen así:
```output
| | Unnamed: 0 | cuisine | almond | angelica | anise | anise_seed | apple | apple_brandy | apricot | armagnac | ... | whiskey | white_bread | white_wine | whole_grain_wheat_flour | wine | wood | yam | yeast | yogurt | zucchini |
| --- | ---------- | ------- | ------ | -------- | ----- | ---------- | ----- | ------------ | ------- | -------- | --- | ------- | ----------- | ---------- | ----------------------- | ---- | ---- | --- | ----- | ------ | -------- |
| 0 | 65 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 66 | indian | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 67 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3 | 68 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 4 | 69 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
```
1. Obtén información acerca de estos datos llamando a `info()`:
```python
df.info()
```
Tu salida se parece a:
```output
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2448 entries, 0 to 2447
Columns: 385 entries, Unnamed: 0 to zucchini
dtypes: int64(384), object(1)
memory usage: 7.2+ MB
```
## Ejercicio - aprendiendo acerca de cocinas
Ahora el trabajo comienza a hacerse más interesante. Descubramos la distribución de los datos, por cocina
1. Grafica los datos como barras llamando `barh()`:
```python
df.cuisine.value_counts().plot.barh()
```
![Distribución de datos de cocina](../images/cuisine-dist.png)
Existe un número finito de cocinas, pero la distribución de los datos es irregular. ¡Puedes corregirlo! Anter de hacerlo, explora un poco más.
1. Descubre cuántos datos están disponibles por cocina e imprímelos:
```python
thai_df = df[(df.cuisine == "thai")]
japanese_df = df[(df.cuisine == "japanese")]
chinese_df = df[(df.cuisine == "chinese")]
indian_df = df[(df.cuisine == "indian")]
korean_df = df[(df.cuisine == "korean")]
print(f'thai df: {thai_df.shape}')
print(f'japanese df: {japanese_df.shape}')
print(f'chinese df: {chinese_df.shape}')
print(f'indian df: {indian_df.shape}')
print(f'korean df: {korean_df.shape}')
```
la salida luce así:
```output
thai df: (289, 385)
japanese df: (320, 385)
chinese df: (442, 385)
indian df: (598, 385)
korean df: (799, 385)
```
## Descubriendo ingredientes
Ahora puedes profundizar en los datos y aprender cuáles son los ingredientes típicos por cocina. Deberías limpiar los datos recurrentes que crean confusión entre cocinas, así que aprendamos acerca de este problema.
1. Crea una función `create_ingredient()` en Python para crear un dataframe ingrediente. Esta función comenzará eliminando una columna inútil y ordenando los ingredientes por su conteo:
```python
def create_ingredient_df(df):
ingredient_df = df.T.drop(['cuisine','Unnamed: 0']).sum(axis=1).to_frame('value')
ingredient_df = ingredient_df[(ingredient_df.T != 0).any()]
ingredient_df = ingredient_df.sort_values(by='value', ascending=False,
inplace=False)
return ingredient_df
```
Ahora puedes usar esa función para tener una idea de los 10 ingredientes más populares por cocina.
1. Llama `create_ingredient()` y graficalo llamando `barh()`:
```python
thai_ingredient_df = create_ingredient_df(thai_df)
thai_ingredient_df.head(10).plot.barh()
```
![Tailandeses](../images/thai.png)
1. Haz lo mismo para los datos de ingredientes japoneses:
```python
japanese_ingredient_df = create_ingredient_df(japanese_df)
japanese_ingredient_df.head(10).plot.barh()
```
![Japoneses](../images/japanese.png)
1. Ahora para los ingredientes chinos:
```python
chinese_ingredient_df = create_ingredient_df(chinese_df)
chinese_ingredient_df.head(10).plot.barh()
```
![Chinos](../images/chinese.png)
1. Grafica los ingredientes indios:
```python
indian_ingredient_df = create_ingredient_df(indian_df)
indian_ingredient_df.head(10).plot.barh()
```
![indios](../images/indian.png)
1. Finalmente, grafica los ingredientes coreanos:
```python
korean_ingredient_df = create_ingredient_df(korean_df)
korean_ingredient_df.head(10).plot.barh()
```
![coreanos](../images/korean.png)
1. Ahora, eliminar los ingredientes más comunes que crean confusión entre las distintas cocinas, llamando `drop()`:
¡Todos aman el arroz, el ajo y el gengibre!
```python
feature_df= df.drop(['cuisine','Unnamed: 0','rice','garlic','ginger'], axis=1)
labels_df = df.cuisine #.unique()
feature_df.head()
```
## Equilibra el conjunto de datos
Ahora que has limpiado los datos, usa [SMOTE](https://imbalanced-learn.org/dev/references/generated/imblearn.over_sampling.SMOTE.html) - "Técnica de sobremuestreo de minoritario sintético" - para equilibrarlo.
1. Llama `fit_resample()`, esta estrategia genera nuevas muestras por interpolación.
```python
oversample = SMOTE()
transformed_feature_df, transformed_label_df = oversample.fit_resample(feature_df, labels_df)
```
Al equilibrar tus datos, tendrás mejores resultados cuando los clasifiques. Piensa en una clasificación binaria. Si la mayoría de tus datos es una clase, un modelo de aprendizaje automático va a predecir esa clase más frecuentemente, solo porque hay más datos para ello. Equilibrar los datos toma cualquier dato sesgado y ayuda a remover este desequilibrio.
1. Ahora puedes comprobar los números de etiquetas por ingredientes:
```python
print(f'new label count: {transformed_label_df.value_counts()}')
print(f'old label count: {df.cuisine.value_counts()}')
```
Tu salida luce así:
```output
new label count: korean 799
chinese 799
indian 799
japanese 799
thai 799
Name: cuisine, dtype: int64
old label count: korean 799
indian 598
chinese 442
japanese 320
thai 289
Name: cuisine, dtype: int64
```
Los datos están bien y limpios, equilibrados ¡y muy deliciosos!
1. El último paso es guardar tus datos equilibrados, incluyendo etiquetas y características, en un nuevo dataframe que pueda ser exportado a un archivo:
```python
transformed_df = pd.concat([transformed_label_df,transformed_feature_df],axis=1, join='outer')
```
1. Puedes dar un vistazo más a los datos usando `transformed_df.head()` y `transformed_df.info()`. Guarda una copia de estos datos para un uso en futuras lecciones:
```python
transformed_df.head()
transformed_df.info()
transformed_df.to_csv("../data/cleaned_cuisines.csv")
```
Este nuevo CSV ahora puede ser encontrado en la directorio raíz data.
---
## 🚀Desafío
Este plan de estudios contiene varios conjuntos de datos interesantes. Profundiza en los directorios `data` y ve si alguno contiene conjuntos de datos que serían apropiados para clasificación binaria o multiclase. ¿Qué preguntas harías a este conunto de datos?
## [Examen posterior a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/20/)
## Revisión y autoestudio
Explora la API de SMOTE. ¿Para qué casos de uso es se usa mejor? ¿Qué problemas resuelve?
## Asignación
[Explora métodos de clasificación](assignment.es.md)

@ -0,0 +1,11 @@
# Explore métodos de clasificación
## Instrucciones
En la [documentación de Scikit-learn](https://scikit-learn.org/stable/supervised_learning.html) encontrarás un gran lista de formas de clasificar los datos. Haz una pequeña búsqueda en estos documentos: tu meta es buscar los metódos de clasificación y hacer coincidir un conjunto de datos en este plan de estudios, una pregunta que puedes hacerle, y una técnica de clasificación. Crea una hoja de cálculo o tabla en un archivo .doc y explica cómo el conjunto de datos funcionaría con el algoritmo de clasificación.
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| | Se presentó un documento repasando 5 algoritmos junto a una técnica de clasificación. El resumen está bien explicado y detallado. | Se presentó un documento repasando 3 algoritmos junto a una técnica de clasificación. El resumen está bien explicado y detallado. | Se presentó un documento repasando menos de tres algoritmos junto a una técnica de clasificación y el resumen no está bien detallado ni explicado. |

@ -0,0 +1,245 @@
# Clasificadores de cocina 1
En esta lección, usarás el conjunto de datos que guardaste en la última lección llena de equilibrio, datos limpios todo sobre cocinas.
Usarás este conjunto de datos con una variedad de clasificadores para _predecir una cocina nacional dada basado en un grupo de ingredientes_. Mientras lo haces, aprenderás más acerca de algunas formas en que los algoritmos pueden ser aprovechados para las tareas de clasificación.
## [Examen previo a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/21/)
# Preparación
Asumiendo que completaste la [Lección 1](../../1-Introduction/translations/README.es.md), asegura que existe un archivo _cleaned_cuisines.csv_ en el directorio raíz `/data` para estas cuatro lecciones.
## Ejercicio - predice una cocina nacional
1. Trabaja en el directorio _notebook.ipynb_ de la lección, importa ese archivo junto con la biblioteca Pandas:
```python
import pandas as pd
cuisines_df = pd.read_csv("../data/cleaned_cuisines.csv")
cuisines_df.head()
```
Los datos lucen así:
| | Unnamed: 0 | cuisine | almond | angelica | anise | anise_seed | apple | apple_brandy | apricot | armagnac | ... | whiskey | white_bread | white_wine | whole_grain_wheat_flour | wine | wood | yam | yeast | yogurt | zucchini |
| --- | ---------- | ------- | ------ | -------- | ----- | ---------- | ----- | ------------ | ------- | -------- | --- | ------- | ----------- | ---------- | ----------------------- | ---- | ---- | --- | ----- | ------ | -------- |
| 0 | 0 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 1 | indian | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 2 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3 | 3 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 4 | 4 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
1. Ahora, importa varias bibliotecas más:
```python
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report, precision_recall_curve
from sklearn.svm import SVC
import numpy as np
```
1. Divide las coordenadas X e Y en dos diferentes dataframes para entrenar. `cuisine` puede ser el dataframe de las etiquetas:
```python
cuisines_label_df = cuisines_df['cuisine']
cuisines_label_df.head()
```
Se verá así:
```output
0 indian
1 indian
2 indian
3 indian
4 indian
Name: cuisine, dtype: object
```
1. Elimina la columna `Unnamed: 0` y la columna `cuisine`, llamando a `drop()`. Guarda el resto de los datos como características entrenables:
```python
cuisines_feature_df = cuisines_df.drop(['Unnamed: 0', 'cuisine'], axis=1)
cuisines_feature_df.head()
```
Tus características lucen así:
| | almond | angelica | anise | anise_seed | apple | apple_brandy | apricot | armagnac | artemisia | artichoke | ... | whiskey | white_bread | white_wine | whole_grain_wheat_flour | wine | wood | yam | yeast | yogurt | zucchini |
| ---: | -----: | -------: | ----: | ---------: | ----: | -----------: | ------: | -------: | --------: | --------: | ---: | ------: | ----------: | ---------: | ----------------------: | ---: | ---: | ---: | ----: | -----: | -------: |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
¡Ahora ya estás listo para entrenar tu modelo!
## Eligiendo tu clasificador
Ahora que tus datos están limpios y listos para entrenamiento, tienes que decidir qué algoritmo usar para hacer el trabajo.
Scikit-learn agrupa clasificaciones bajo aprendizaje supervisado, y en esa categoría encontrarás muchas formas de clasificar. [La variedad](https://scikit-learn.org/stable/supervised_learning.html) es bastante abrumadora a primera vista. Los siguientes métodos incluyen técnicas de clasificación:
- Modelos lineales
- Máquinas de vectores de soporte
- Descenso de gradiente estocástico
- Vecinos más cercanos
- Procesos Gaussianos
- Árboles de decisión
- Métodos de conjunto (clasificador de votos)
- Algoritmos multiclase y multisalida (clasificación multiclase y multietiqueta, clasificación multiclase-multisalida)
> También puedes usar [redes neuronales para clasificar los datos](https://scikit-learn.org/stable/modules/neural_networks_supervised.html#classification), pero eso está fuera del alcance de esta lección.
### ¿Qué clasificador usar?
Así que, ¿qué clasificador deberías elegir? A menudo, el ejecutar varios y buscar un buen resultado es una forma de probar. Scikit-lean ofrece una [comparación lado a lado](https://scikit-learn.org/stable/auto_examples/classification/plot_classifier_comparison.html) en un conjunto de datos creado, comparando KNeighbors, SVC two ways, GaussianProcessClassifier, DecisionTreeClassifier, RandomForestClassifier, MLPClassifier, AdaBoostClassifier, GaussianNB y QuadraticDiscrinationAnalysis, mostrando los resultados visualizados:
![Comparación de clasificadores](../images/comparison.png)
> Gráficos generados en la documentación de Scikit-learn
> AutoML resuelve este problema de forma pulcra al ejecutar estas comparaciones en la nube, permitiéndote elegir el mejor algoritmo para tus datos. Pruébalo [aquí](https://docs.microsoft.com/learn/modules/automate-model-selection-with-azure-automl/?WT.mc_id=academic-15963-cxa)
### Un mejor enfoque
Una mejor forma a estar adivinando, es seguir las ideas de esta [hoja de trucos de ML](https://docs.microsoft.com/azure/machine-learning/algorithm-cheat-sheet?WT.mc_id=academic-15963-cxa). Aquí, descubrimos que, para nuestro problema multiclase, tenemos algunas opciones:
![Hoja de trucos para problemas multiclase](../images/cheatsheet.png)
> Una sección de la hoja de trucos de algoritmos de Microsoft, detallando opciones de clasificación multiclase.
✅ ¡Descarga esta hoja de trucos, imprímela y cuélgala en tu pared!
### Razonamiento
Veamos si podemos razonar nuestro camino a través de diferentes enfoques dadas las restricciones que tenemos:
- **Las redes neuronales son muy pesadas**. Dado nuestro conjunto de datos limpio aunque mínimo, y el hecho que estamos ejecutando el entrenamiento de forma local vía los notebooks, las redes neuronales son demasiado pesadas para esta tarea.
- **Sin clasificador de dos clases**. No usamos clasificador de dos clases, por lo que descarta un uno-contra-todos.
- **El árbol de decisión o la regresión logística podría funcionar**. Un árbol de decisión podría funcionar, o la regresión logística para datos multiclase.
- **Los árboles de decisión potenciados multiclase resuelven un problema diferente**. El árbol de decisión potenciado multiclase es el más adecuado para tareas no paramétricas, por ejemplo, las tareas designadas para construir clasificaciones, por lo que no es útil para nosotros.
### Usando Scikit-learn
Usaremos Scikit-learn para analizar nuestros datos. Sin embargo, hay varias formas de usar la regresión logística en Scikit-learn. Da un vistazo a los [parámetros a pasar](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html?highlight=logistic%20regressio#sklearn.linear_model.LogisticRegression).
En esencia, hay dos parámetros importantes - `multi_class` y `solver` - que necesitamos especificar, cuando le pedimos a Scikit-learn realice una regresión logística. El valor `multi_class` aplica cierto comportamiento. El valor del solucionador (`solver`) es el algoritmo a usar. No todos los solucionadores pueden ser emparejados con todos los valores `multi_class`.
De acuerdo a la documentación, en el caso multiclase, el algoritmo de entrenamiento:
- **Usa el esquema uno contra el resto (OvsR)**, si la opción `multi_class` se configura a `ovr`
- **Usa la pérdida de entropía cruzada**, si la opción `multi_class` se configura a `multinomial` (Actualmente la opción `multinomial` es soportada sólo por los solucionadores ‘lbfgs’, ‘sag’, ‘saga’ y ‘newton-cg’.).
> 🎓 Aquí, el 'esquema' puede ser 'ovr' (one-vs-rest) o 'multinomial'. Ya que la regresión logística está diseñada realmente para soportar la clasificación binaria, estos esquemas te permiten manejar mejor las tareas de clasificación multiclase [fuente](https://machinelea
rningmastery.com/one-vs-rest-and-one-vs-one-for-multi-class-classification/).
> 🎓 El 'solucionador' es definido como "el algoritmo a usar en el problema de optimización" [fuente](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html?highlight=logistic%20regressio#sklearn.linear_model.LogisticRegression).
Scikit-learn ofrece esta tabla para explicar como los solucionadores manejan distintos desafíos presentados por distintas clases de datos estructurados:
![solucionadores](../images/solvers.png)
## Ejercicio - divide los datos
Nos podemos enfocar en la regresión logística para nuestra primer prueba de entrenamiento ya que recién aprendiste sobre esto último en la lección anterior.
Divide tus datos en los grupos 'training' y 'testing' al llamar a `train_test_split()`:
```python
X_train, X_test, y_train, y_test = train_test_split(cuisines_feature_df, cuisines_label_df, test_size=0.3)
```
## Ejercicio - aplica la regresión logística
Ya que estás usando un caso multiclase, necesitas elegir qué _esquema_ usar y qué _solucionador_ configurar. Usa LogisticRegression con un ajuste multiclase y el solucionador **liblinear** para entrenar.
1. Crea un regresión logística con un multi_class configurado a `ovr` y el solucionador ajustado a `liblinear`:
```python
lr = LogisticRegression(multi_class='ovr',solver='liblinear')
model = lr.fit(X_train, np.ravel(y_train))
accuracy = model.score(X_test, y_test)
print ("Accuracy is {}".format(accuracy))
```
✅ Prueba un solucionador diferente como `lbfgs`, el cual suele ser configurado por defecto
> Nota, usa la función de Pandas [`ravel`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.ravel.html) para aplanar tus datos cuando sea necesario.
¡La precisión es buena por enciam del **80%*!
1. Puedes ver este modelo en acción al probar una fila de datos (#50):
```python
print(f'ingredients: {X_test.iloc[50][X_test.iloc[50]!=0].keys()}')
print(f'cuisine: {y_test.iloc[50]}')
```
El resultado es impreso:
```output
ingredients: Index(['cilantro', 'onion', 'pea', 'potato', 'tomato', 'vegetable_oil'], dtype='object')
cuisine: indian
```
✅ Prueba un número de fila distinto y revisa los resultados
1. Indagando más, puedes revisar la precisión de esta predicción:
```python
test= X_test.iloc[50].values.reshape(-1, 1).T
proba = model.predict_proba(test)
classes = model.classes_
resultdf = pd.DataFrame(data=proba, columns=classes)
topPrediction = resultdf.T.sort_values(by=[0], ascending = [False])
topPrediction.head()
```
El resultado es impreso - La cocina India es su mejor conjetura, con buena probabilidad:
| | 0 |
| -------: | -------: |
| indian | 0.715851 |
| chinese | 0.229475 |
| japanese | 0.029763 |
| korean | 0.017277 |
| thai | 0.007634 |
✅ ¿Puedes explicar por qué el modelo está muy seguro de que esta es una cocina India?
1. Obtén mayor detalle al imprimir un reporte de clasificación, como lo hiciste en las lecciones de regresión:
```python
y_pred = model.predict(X_test)
print(classification_report(y_test,y_pred))
```
| | precision | recall | f1-score | support |
| ------------ | --------- | ------ | -------- | ------- |
| chinese | 0.73 | 0.71 | 0.72 | 229 |
| indian | 0.91 | 0.93 | 0.92 | 254 |
| japanese | 0.70 | 0.75 | 0.72 | 220 |
| korean | 0.86 | 0.76 | 0.81 | 242 |
| thai | 0.79 | 0.85 | 0.82 | 254 |
| accuracy | 0.80 | 1199 | | |
| macro avg | 0.80 | 0.80 | 0.80 | 1199 |
| weighted avg | 0.80 | 0.80 | 0.80 | 1199 |
## 🚀Desafío
En esta lección, usaste tus datos limpios para construir un modelo de aprendizaje automático que puede predecir una cocina nacional basado en una serie de ingredientes. Toma un tiempo para leer las diversas opciones que provee Scikit-learn para clasificar los datos. Profundiza en el concepto de 'solucionador' para comprender que sucede detrás de escena.
## [Examen posterior a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/22/)
## Revisión y autoestudio
Indaga un poco más en las matemáticas detrás de la regresión logística en [esta lección](https://people.eecs.berkeley.edu/~russell/classes/cs194/f11/lectures/CS194%20Fall%202011%20Lecture%2006.pdf)
## Asignación
[Estudia los solucionadores](assignment.es.md)

@ -22,7 +22,6 @@
数据如下所示: 数据如下所示:
```output
| | Unnamed: 0 | cuisine | almond | angelica | anise | anise_seed | apple | apple_brandy | apricot | armagnac | ... | whiskey | white_bread | white_wine | whole_grain_wheat_flour | wine | wood | yam | yeast | yogurt | zucchini | | | Unnamed: 0 | cuisine | almond | angelica | anise | anise_seed | apple | apple_brandy | apricot | armagnac | ... | whiskey | white_bread | white_wine | whole_grain_wheat_flour | wine | wood | yam | yeast | yogurt | zucchini |
| --- | ---------- | ------- | ------ | -------- | ----- | ---------- | ----- | ------------ | ------- | -------- | --- | ------- | ----------- | ---------- | ----------------------- | ---- | ---- | --- | ----- | ------ | -------- | | --- | ---------- | ------- | ------ | -------- | ----- | ---------- | ----- | ------------ | ------- | -------- | --- | ------- | ----------- | ---------- | ----------------------- | ---- | ---- | --- | ----- | ------ | -------- |
| 0 | 0 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 0 | 0 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
@ -30,7 +29,6 @@
| 2 | 2 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 2 | 2 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3 | 3 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 3 | 3 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 4 | 4 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | | 4 | 4 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
```
1. 现在,再多导入一些库: 1. 现在,再多导入一些库:

@ -0,0 +1,11 @@
# Estudia los solucionadores
## Instrucciones
En esta lección aprendiste acerca de diferentes solucionadores que emparejan algoritmos con un proceso de aprendizaje automático para crear un modelo preciso. Revisa los solucionadores listados en la lección y elige dos. En tus propias palabras, compara y contrasta estos dos solucionadores. ¿Qué clase de problema abordan? ¿Cómo funcionan con varias estructuras de datos? ¿Porqué elegirías uno por encima de otro?
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------ | ---------------------------- |
| | Se presentó un archivo .doc con dos párrafos, uno de cada solucionador, comparándolos seriamente. | Se presentó un archivo .doc con sólo un párrafo | La asignación está incompleta |

@ -0,0 +1,234 @@
# Clasificadores de cocina 2
En esta segunda lección de clasificación, explorarás más formas de clasificar datos numéricos. También aprenderás acerca de las ramificaciones para elegir un clasificador en lugar de otro.
## [Examen previo a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/23/)
### Prerrequisito
Asumimos que has completado las lecciones anteriores y has limpiado el conjunto de datos en tu directorio `data` llamado _cleaned_cuisines.csv_ en la raíz de este directorio 4-lesson.
### Preparación
Hemos cargado tu archivo _notebook.ipynb_ con el conjunto de datos limpio y lo hemos dividido en los dataframes X e Y, listo para el proceso de construcción del modelo.
## Un mapa de clasificación
Anteriormente, aprendiste acerca de las distintas opciones que tienes al clasificar los datos usando la hoja de trucos de Microsoft. Scikit-learn ofrece algo similar, pero la hoja de trucos es más granular que puede ayudar a reducir tus estimadores (otro término para clasificadores):
![Mapa de aprendizaje automático de Scikit-learn](../images/map.png)
> Consejo: [Visita este mapa en línea](https://scikit-learn.org/stable/tutorial/machine_learning_map/) y haz clic en la ruta para leer la documentación.
### El plan
Este mapa es muy útil una vez que tengas una compresión clara de tus datos, como puedas 'caminar' junto a sus rutas para una decisión:
- Tenemos >50 muestras
- Queremos predecir una categoría
- Tenemos datos etiquetados
- Tenemos menos de 100K muestras
- ✨ Podemos elegir un SVC lineal
- Si eso no funciona, ya que tenemos datos numéricos
- Podemos probar un ✨ clasificador KNeighbors
- Si eso no funciona, intenta los clasificadores ✨ SVC y ✨ conjunto
Este es un camino muy útil a seguir.
## Ejercicio - divide los datos
Siguiendo este camino, deberías empezar importando algunas bibliotecas a usar.
1. Importa las bibliotecas necesarias:
```python
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report, precision_recall_curve
import numpy as np
```
1. Divide tus datos de entrenamiento y prueba:
```python
X_train, X_test, y_train, y_test = train_test_split(cuisines_feature_df, cuisines_label_df, test_size=0.3)
```
## Clasificador lineal SVC
El agrupamiento de vectores de soporte (SVC) es un hijo de la familia de máquinas de vectores de soporte de las técnicas de aprendizaje automático (aprende más acerca de estos más adelante). En este método, puedes elegir un 'kernel' para decidir cómo agrupar las etiquetas. El parámetro 'C' se refiere a 'regularization' el cual regula la influencia de los parámetros. El kernel puede ser uno de [varios](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC); aquí lo configuramos a 'linear' para asegurar que aprovechamos la clasificación lineal SVC. La probabilidad por defecto es 'false'; aquí lo configuramos a 'true' para reunir estimaciones de probabilidad. Configuramos el estado aleatorio a '0' para revolver los datos para obtener probabilidades.
### Ejercicio - aplica SVC lineal
Comienza creando un arreglo de clasificadores. Agregarás progresivamente a este arreglo mientras probamos.
1. Empieza con un SVC lineal:
```python
C = 10
# Create different classifiers.
classifiers = {
'Linear SVC': SVC(kernel='linear', C=C, probability=True,random_state=0)
}
```
2. Entrena tu modelo usando el SVC lineal e imprime un reporte:
```python
n_classifiers = len(classifiers)
for index, (name, classifier) in enumerate(classifiers.items()):
classifier.fit(X_train, np.ravel(y_train))
y_pred = classifier.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy (train) for %s: %0.1f%% " % (name, accuracy * 100))
print(classification_report(y_test,y_pred))
```
El resultado es bastante bueno:
```output
Accuracy (train) for Linear SVC: 78.6%
precision recall f1-score support
chinese 0.71 0.67 0.69 242
indian 0.88 0.86 0.87 234
japanese 0.79 0.74 0.76 254
korean 0.85 0.81 0.83 242
thai 0.71 0.86 0.78 227
accuracy 0.79 1199
macro avg 0.79 0.79 0.79 1199
weighted avg 0.79 0.79 0.79 1199
```
## Clasificador K-Neighbors
K-neighbors es parte de la familia de "vecinos" de métodos de aprendizaje automático, el cual puede ser usado para el aprendizaje supervisado y no supervisado. En este método, se crea un número predefinido de puntos y se reúnen los datos alrededor de estos puntos de modo que se puedan predecir etiquetas generalizadas para los datos.
### Ejercicio - aplica el clasificador K-Neighbors
El clasificador previo era bueno, y funcionó bien con los datos, pero quizá podemos obtener mejor precisión. Prueba el clasificador K-Neighbors.
1. Agrega una línea a tu arreglo de clasificadores (agrega una coma después del elemento Linear SVC):
```python
'KNN classifier': KNeighborsClassifier(C),
```
El resultado es ligeramente peor:
```output
Accuracy (train) for KNN classifier: 73.8%
precision recall f1-score support
chinese 0.64 0.67 0.66 242
indian 0.86 0.78 0.82 234
japanese 0.66 0.83 0.74 254
korean 0.94 0.58 0.72 242
thai 0.71 0.82 0.76 227
accuracy 0.74 1199
macro avg 0.76 0.74 0.74 1199
weighted avg 0.76 0.74 0.74 1199
```
✅ Aprende acerca de [K-Neighbors](https://scikit-learn.org/stable/modules/neighbors.html#neighbors)
## Clasificador de vectores de soporte
Los clasificadores de vectores de soporte son parte de la familia de [máquinas de vectores de soporte (SVM)](https://wikipedia.org/wiki/Support-vector_machine) de métodos de aprendizaje automático que son usados para las tareas de clasificación y regresión. Los SVMs "asignan ejemplos de entrenamiento a puntos en el espacio" para maximizar la distancia entre dos categorías. Los datos subsecuentes son asignados en este espacio para que su categoría pueda ser predecida.
### Ejercicio - aplica un clasificador de vectores de soporte
Intentemos un poco más de precisión con un clasificador de vectores de soporte.
1. Agrega una coma después del elemento K-Neighbors, y luego agrega esta línea:
```python
'SVC': SVC(),
```
¡El resultado es bastante bueno!
```output
Accuracy (train) for SVC: 83.2%
precision recall f1-score support
chinese 0.79 0.74 0.76 242
indian 0.88 0.90 0.89 234
japanese 0.87 0.81 0.84 254
korean 0.91 0.82 0.86 242
thai 0.74 0.90 0.81 227
accuracy 0.83 1199
macro avg 0.84 0.83 0.83 1199
weighted avg 0.84 0.83 0.83 1199
```
✅ Aprende acerca de los [vectores de soporte](https://scikit-learn.org/stable/modules/svm.html#svm)
## Clasificadores de conjuntos
Sigamos el camino hasta el final, aunque la prueba anterior fue bastante buena. Probemos algunos clasificadores de conjuntos, específicamente Random Forest y AdaBoost:
```python
'RFST': RandomForestClassifier(n_estimators=100),
'ADA': AdaBoostClassifier(n_estimators=100)
```
El resultado es muy bueno, especialmente para Random Forest:
```output
Accuracy (train) for RFST: 84.5%
precision recall f1-score support
chinese 0.80 0.77 0.78 242
indian 0.89 0.92 0.90 234
japanese 0.86 0.84 0.85 254
korean 0.88 0.83 0.85 242
thai 0.80 0.87 0.83 227
accuracy 0.84 1199
macro avg 0.85 0.85 0.84 1199
weighted avg 0.85 0.84 0.84 1199
Accuracy (train) for ADA: 72.4%
precision recall f1-score support
chinese 0.64 0.49 0.56 242
indian 0.91 0.83 0.87 234
japanese 0.68 0.69 0.69 254
korean 0.73 0.79 0.76 242
thai 0.67 0.83 0.74 227
accuracy 0.72 1199
macro avg 0.73 0.73 0.72 1199
weighted avg 0.73 0.72 0.72 1199
```
✅ Aprende acerca de los [clasificadores de conjuntos](https://scikit-learn.org/stable/modules/ensemble.html)
Este método de aprendizaje automático "combina las predicciones de varios estimadores base" para mejorar la calidad del modelo. En nuestro ejemplo, usamos Random Trees y AdaBoost.
- [Random Forest](https://scikit-learn.org/stable/modules/ensemble.html#forest), un método de promedio, construye un 'bosque' de 'árboles de decisión' infundido con aleatoriedad para evitar sobreajuste. El parámetro n_estimators es configurado a el número de árboles.
- [AdaBoost](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.AdaBoostClassifier.html) ajusta un clasificador a un conjunto de datos y luego ajusta copias de ese clasificador a el mismo conjunto de datos. Se enfoca en los pesos de los elementos clasificados erróneamente y realiza el ajuste para que el siguiente clasificador lo corrija.
---
## 🚀Desafío
Cada una de estas técnicas tiene un gran número de parámetros que puedes modificar. Investiga los parámetros predeterminados de cada uno y piensa en lo que significaría el ajuste de estos parámetros para la calidad del modelo.
## [Examen posterior a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/24/)
## Revisión y autoestudio
Existe mucha jerga en esta lecciones, ¡así que toma unos minutos para revisar [esta lista](https://docs.microsoft.com/dotnet/machine-learning/resources/glossary?WT.mc_id=academic-15963-cxa) de términos útiles!
## Asignación
[Juego de parámetros](assignment.es.md)

@ -0,0 +1,11 @@
# Juega con los parámetros
## Instrucciones
Hay varios parámetros que están configurados de forma predeterminada cuando usas estos clasificadores. Intellisense en VS Code puede ayudarte a profundizar en ellos. Adopta una de las técnicas de clasificación de aprendizaje automático de esta lección y vuelve a entrenar los modelos ajustando varios valores de parámetros. Construye un notebook explicando por qué algunos cambios mejoran la calidad del modelo mientras otros la degradan. Sé minucioso en tu respuesta.
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | ---------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | ----------------------------- |
| | Se presentó un notebook con un clasificador completamente construido, sus parámetros ajustados y los cambios explicados en cajas de texto | Se presentó un notebook parcialmente completo o pobremente explicado | Se presentó un notebook con errores o fallos |

@ -0,0 +1,316 @@
# Construye una aplicación web de recomendación de cocina
En esta lección, construirás un modelo de clasificación usando algunas de las técnicas que aprendiste en las lecciones anteriores y con el conjunto de datos de la cocina deliciosa usada a través de este serie de lecciones. Además, construirás una pequeña aplicación web para usar un modelo guardado, aprovechando el runtime web de Onnx.
Uno de los usos prácticos más útiles del aprendizaje automático es construir sistemas de recomendación, y ¡hoy puedes tomar el primer en esa dirección!
[![Presentando esta aplicación web](https://img.youtube.com/vi/17wdM9AHMfg/0.jpg)](https://youtu.be/17wdM9AHMfg "ML aplicado")
> 🎥 Haz clic en la imagen de arriba para ver el video: Jen Looper construye una aplicación web usando los datos clasificados de cocina.
## [Examen previo a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/25/)
En esta lección aprenderás:
- Cómo construir un modelo y guardarlo como un modelo Onnx
- Cómo usar Netron para inspeccionar el modelo
- Cómo usar tu modelo en una aplicación web por inferencia
## Construye tu modelo
Construir sistemas de aprendizaje automático aplicado es un parte importante de aprovechar estas tecnologías para tus sistemas de negocio. Puedes usar modelos dentro de tus aplicaciones web (y así usarlos de sin conexión en caso de ser necesario) al usar Onnx.
En la [lección anterior](../../../3-Web-App/1-Web-App/translations/README.es.md), construiste un modelo de regresión acerca de los avistamientos OVNI, le hiciste "pickle", y los usaste en una aplicación Flask. Aunque esta arquitectura es muy útil conocerla, es una aplicación Python full-stack, y tus requerimientos pueden incluir el uso de una aplicación JavaScript.
En esta lección, puedes construir un sistema JavaScript básico por inferencia. Pero primero, necesitas entrenar tu modelo y convertirlo para usarlo con Onnx.
## Ejercicio - entrena tu modelo de clasificación
Primero, entrena un modelo de clasificación usando el conjunto limpio de datos de cocina que ya usamos.
1. Comienza importando bibliotecas útiles:
```python
!pip install skl2onnx
import pandas as pd
```
Necesitas '[skl2onnx](https://onnx.ai/sklearn-onnx/)' para ayudar a convertir tu modelo Scikit-learn al formato Onnx.
1. Luego, trabaja con tus datos de la misma forma que lo hiciste en las lecciones anteriores, al leer el archivo CSV usando `read_csv()`:
```python
data = pd.read_csv('../data/cleaned_cuisines.csv')
data.head()
```
1. Elimina las primeras dos columnas y guarda los datos restantes como 'X':
```python
X = data.iloc[:,2:]
X.head()
```
1. Guarda las etiquetas como 'y':
```python
y = data[['cuisine']]
y.head()
```
### Comienza la rutina de entrenamiento
Usaremos la biblioteca 'SVC' la cual tiene buena precisión.
1. Importa las bibliotecas correspondientes de Scikit-learn:
```python
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report
```
1. Separa los conjuntos de entrenamiento y prueba:
```python
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.3)
```
1. Construye un model de clasificación SVC como lo hiciste en la lección anterior:
```python
model = SVC(kernel='linear', C=10, probability=True,random_state=0)
model.fit(X_train,y_train.values.ravel())
```
1. Ahora, prueba tu modelo al llamar a `predict()`:
```python
y_pred = model.predict(X_test)
```
1. Imprime un reporte de clasificación para revisar la calidad del modelo:
```python
print(classification_report(y_test,y_pred))
```
Como vimos anteriormente, la precisión es buena:
```output
precision recall f1-score support
chinese 0.72 0.69 0.70 257
indian 0.91 0.87 0.89 243
japanese 0.79 0.77 0.78 239
korean 0.83 0.79 0.81 236
thai 0.72 0.84 0.78 224
accuracy 0.79 1199
macro avg 0.79 0.79 0.79 1199
weighted avg 0.79 0.79 0.79 1199
```
### Convierte tu modelo a Onnx
Asegúrate que haces la conversión con el número adecuado de Tensor. Este conjunto de datos lista 380 ingredientes, por lo que necesitas anotar ese número en `FloatTensorType`:
1. Conviértelo usando un número de tensor de 380.
```python
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
initial_type = [('float_input', FloatTensorType([None, 380]))]
options = {id(model): {'nocl': True, 'zipmap': False}}
```
1. Crea el onx y guárdalo como un archivo **model.onnx**:
```python
onx = convert_sklearn(model, initial_types=initial_type, options=options)
with open("./model.onnx", "wb") as f:
f.write(onx.SerializeToString())
```
> Nota, puedes pasar [opciones](https://onnx.ai/sklearn-onnx/parameterized.html) a tu script de conversión. En este caso, pasamos 'nocl' como True y 'zipap' como False. Ya que este es un modelo de clasificación, tienes la opción de eliminar ZipMap el cual produce una lista de diccionarios (no necesarios). `nocl` se refiere a la información de clase que se incluye en el modelo. Reduce el tamaño de tu modelo al configurar `nocl` a 'True'.
Al ejecutar todo el notebook construirás un modelo Onnx y lo guardará en su directorio.
## Observa tu modelo
Los modelos Onnx no se aprecian bien en Visual Studio Code, pero muchos investigadores usan buen software libre para visualizar el modelo y asegurar que se construyó de forma adecuada. Descarga [Netron](https://github.com/lutzroeder/Netron) y abre tu archivo `model.onnx`. Puedes visualizar de forma simple tu modelo, con sus 380 entradas y el clasificador listado:
![Netron visual](../images/netron.png)
Netron es una herramienta útil para ver tus modelos.
Ahora estás listo para usar este modelo limpio en una aplicación web. Construyamos una aplicación que nos será útil cuando veas tu refrigerador e intentes descubrir qué combinación de tus ingredientes sobrantes puedes usar para realizar un platillo de cierta cocina, de acuerdo a lo que determina tu modelo.
## Construye una aplicación web de recomendación
Puedes usar tu modelo directamente en la aplicación web. Esta arquitectura también te permite ejecutarlo de forma local e incluso sin conexión en caso de ser necesario. Empieza creando un archivo `index.html` en el mismo directorio donde guardaste tu archivo `model.onnx`.
1. En este archivo _index.html_, agrega el siguiente código:
```html
<!DOCTYPE html>
<html>
<header>
<title>Cuisine Matcher</title>
</header>
<body>
...
</body>
</html>
```
1. Ahora, trabaja dentro de las etiquetas `body`, agrega algo de código para mostrar una lista de checkboxes reflejando algunos ingredientes:
```html
<h1>Revisa tu refrigerador. ¿Qué puedes crear?</h1>
<div id="wrapper">
<div class="boxCont">
<input type="checkbox" value="4" class="checkbox">
<label>apple</label>
</div>
<div class="boxCont">
<input type="checkbox" value="247" class="checkbox">
<label>pear</label>
</div>
<div class="boxCont">
<input type="checkbox" value="77" class="checkbox">
<label>cherry</label>
</div>
<div class="boxCont">
<input type="checkbox" value="126" class="checkbox">
<label>fenugreek</label>
</div>
<div class="boxCont">
<input type="checkbox" value="302" class="checkbox">
<label>sake</label>
</div>
<div class="boxCont">
<input type="checkbox" value="327" class="checkbox">
<label>soy sauce</label>
</div>
<div class="boxCont">
<input type="checkbox" value="112" class="checkbox">
<label>cumin</label>
</div>
</div>
<div style="padding-top:10px">
<button onClick="startInference()">¿Qué clase de cocina puedes preparar?</button>
</div>
```
Nota que a cada checkbox se le asigna un valor. Esto refleja el índice donde se encuentran los ingredientes de acuerdo al conjunto de datos. La manzana (Apple), por ejemplo, en este listado alfabético, ocupa la quinta columna, por lo que su valor es '4' ya que empezamos a contar a partir del 0. Puedes consultar la [hoja de cálculo de los ingredientes](../../data/ingredient_indexes.csv) para descubrir el índice asignado a cierto ingrediente.
Continúa tu trabajo en el archivo index.html, agrega un bloque script donde se llame al modelo, después de el `</div>` final de cierre.
1. Primero, importa el [Runtime de Onnx](https://www.onnxruntime.ai/):
```html
<script src="https://cdn.jsdelivr.net/npm/onnxruntime-web@1.9.0/dist/ort.min.js"></script>
```
> El Runtime de Onnx se usa para permitir ejecutar tus modelos Onnx a través de una gran variedad de plataformas hardware, incluyendo optimizaciones y el uso de una API.
1. Una vez que el Runtime esté en su lugar, puedes llamarlo:
```html
<script>
const ingredients = Array(380).fill(0);
const checks = [...document.querySelectorAll('.checkbox')];
checks.forEach(check => {
check.addEventListener('change', function() {
// toggle the state of the ingredient
// based on the checkbox's value (1 or 0)
ingredients[check.value] = check.checked ? 1 : 0;
});
});
function testCheckboxes() {
// validate if at least one checkbox is checked
return checks.some(check => check.checked);
}
async function startInference() {
let atLeastOneChecked = testCheckboxes()
if (!atLeastOneChecked) {
alert('Please select at least one ingredient.');
return;
}
try {
// create a new session and load the model.
const session = await ort.InferenceSession.create('./model.onnx');
const input = new ort.Tensor(new Float32Array(ingredients), [1, 380]);
const feeds = { float_input: input };
// feed inputs and run
const results = await session.run(feeds);
// read from results
alert('You can enjoy ' + results.label.data[0] + ' cuisine today!')
} catch (e) {
console.log(`failed to inference ONNX model`);
console.error(e);
}
}
</script>
```
En este código, suceden varias cosas:
1. Creaste un arreglo de 380 valores posibles(1 o 0) para ser configurados y enviados al modelo por inferencia, dependiendo si checkbox de ingrediente está seleccionado.
2. Creaste un arreglo de checkboxes y una forma de determinar si fueron seleccionados en una función `init` que es llamada cuando inicia la aplicación. Cuando se selecciona un checkbox, se modifica el arreglo `ingredients` para reflejar al ingrediente seleccionado.
3. Creaste una función `testCheckboxes` que verifica si algún checkbox se seleccionó.
4. Usa la función `startInference` cuando se presione el botón y, si algún checkbox fue seleccionado, comienza la inferencia.
5. La rutina de inferencia incluye:
1. Configuración de una carga asíncrona del modelo
2. Creación de una estructura Tensor para enviar al modelo
3. Creación de 'feeds' que refleja la entrada `float_input` que creaste cuando entrenaste tu modelo (puedes usar Netron para verificar el nombre)
4. Envía estos 'feeds' al modelo y espera la respuesta
## Prueba tu aplicación
Abre una sesión de terminal en Visual Studio Code en el directorio donde reside tu archivo index.html. Asegúrate que tienes instalado [http-server](https://www.npmjs.com/package/http-server) de forma global, y escribe `http-server` en la terminal. Se debería abrir una ventana del navegador web para ver tu aplicación en localhost. Revisa qué cocina es recomendada basada en varios ingredientes:
![Aplicación web de ingredientes](../images/web-app.png)
Felicidades, has creado una aplicación de 'recomendación' con pocos campos. ¡Lleva algo de tiempo el construir este sistema!
## 🚀Desafío
Tu aplicación web es mínima, así que continua construyéndola usando los ingredientes y sus índices de los datos [ingredient_indexes](../../data/ingredient_indexes.csv). ¿Qué combinaciones de sabor funcionan para crear un determinado platillo nacional?
## [Examen posterior a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/26/)
## Revisión y autoestudio
Mientras esta lección sólo se refirió a la utilidad de crear un sistema de recomendación para ingredientes alimenticios, esta área de aplicaciones del aprendizaje automático es muy rica en ejemplos. Lee más acerca de cómo se construyen estos sistemas:
- https://www.sciencedirect.com/topics/computer-science/recommendation-engine
- https://www.technologyreview.com/2014/08/25/171547/the-ultimate-challenge-for-recommendation-engines/
- https://www.technologyreview.com/2015/03/23/168831/everything-is-a-recommendation/
## Asignación
[Construye una nueva aplicación de recomendación](assignment.es.md)

@ -0,0 +1,11 @@
# Construye un recomendador
## Instrucciones
Dados tus ejercicios en esta lección, ahora sabes cómo construir aplicaciones web basadas en JavaScript usando el Runtime Onnx y un modelo Onnx convertido. Experimenta con la construcción de un nuevo recomendador usando los datos de estas lecciones u obtenidos de otro lugar (por favor, da los créditos correspondientes). Debes crear un recomendador de mascotas dados diversos atributos de personalidad, o un recomendador de géneros musicales basados en el estado de ánimo de una persona. ¡Sé creativo!
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | ---------------------------------------------------------------------- | ------------------------------------- | --------------------------------- |
| | Se presentó tanto una aplicación web como un notebook, ambos bien documentados y ejecutándose | Uno de esos dos falta o contiene errores | Ambos faltan o están defectuosos |

@ -0,0 +1,333 @@
# Introducción al agrupamiento
El agrupamiento (clustering) es un tipo de [aprendizaje no supervisado](https://wikipedia.org/wiki/Unsupervised_learning) que supone que un conjunto de datos está sin etiquetar o que sus entradas no están emparejadas con salidas predefinidas. Usa varios algoritmos para ordenar datos sin etiquetar y provee agrupaciones de acuerdo a patrones que discierne en los datos.
[![No One Like You de PSquare](https://img.youtube.com/vi/ty2advRiWJM/0.jpg)](https://youtu.be/ty2advRiWJM "No One Like You de PSquare")
> 🎥 Haz clic en la imagen de arriba para ver el video. Mientras estudias aprendizaje automático con agrupamiento, disfruta de algunas canciones Dance Hall Nigerianas - esta es una canción muy popular del 2014 de PSquare.
## [Examen previo a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/27/)
### Introducción
El [agrupamiento](https://link.springer.com/referenceworkentry/10.1007%2F978-0-387-30164-8_124) es muy útil para la exploración de datos. Veamos si nos puede ayudar a descubrir tendencias y patrones en la forma en que la audiencia Nigeriana consume música.
✅ Piensa por un minuto acerca de los usos del agrupamiento. En la vida real, el agrupamiento sucede siempre que tienes un montón de ropa sucia y necesitas ordenar las prendas de los miembros de la familia 🧦👕👖🩲. En la ciencia de datos, el agrupamiento ocurre cuando intentamos analizar las preferencias de los usuarios, o determinar las características de cualquier conjunto de datos no etiquetado. El agrupamiento, de cierta forma, ayuda a dar sentido al caos, como un cajón de calcetines.
[![introducción al agrupamiento](https://img.youtube.com/vi/esmzYhuFnds/0.jpg)](https://youtu.be/esmzYhuFnds "introducción al agrupamiento")
> 🎥 Haz clic en la imagen de arriba para ver el video: John Guttag del MIT presenta el agrupamiento
En el ámbito profesional, el agrupamiento puede ser usado para determinar temas como la segmentación de mercado, qué grupos de edad compran qué cosas, por citar algunos. Otro uso sería la detección de anomalías, quizá para detectar el fraude de un conjunto de datos de transacciones de tarjetas de crédito. O podrías usar el agrupamiento para determinar tumores en un lote de escaneos médicos.
✅ Piensa un poco acerca de cómo encontrarías el agrupamiento 'en la naturaleza', en un entorno bancario, de comercio electrónico o de negocio.
> 🎓 Curiosamente, el análisis de agrupamiento se originó en los campos de la Antropología y Psicología en los años 1930. ¿Puedes imaginar cómo fue usado?
Alternativamente, puedes usarlo para agrupar resultados de búsqueda - por enlaces de compra, imágenes o reseñas, por citar algunos. El agrupamiento es útil cuando tienes un gran conjunto de datos el cual quieres reducir y sobre el cual deseas realizar un análisis más granular, así la técnica puede ser usada para aprender acerca de los datos antes que se construyan otros modelos.
✅ Una vez que tus datos están organizados en grupos , asignale un Id de grupo, y esta técnica puede ser útil cuando conservas la privacidad de un conjunto de datos; en su lugar te puedes referir a un punto de datos por su id de grupo, en vez de sus datos identificables más reveladores. ¿Puedes pensar en otras razones del por qué preferirías un Id de grupo en lugar de otros elementos del grupo para identificarlo?
Profundiza tu compresión de las técnicas de agrupamiento en este [módulo de aprendizaje](https://docs.microsoft.com/learn/modules/train-evaluate-cluster-models?WT.mc_id=academic-15963-cxa)
## Empezando con el agrupamiento
[Scikit-learn ofrece un gran arreglo](https://scikit-learn.org/stable/modules/clustering.html) de métodos para realizar agrupamiento. El tipo que elijas dependerá de tu caso de uso. De acuerdo a la documentación, cada método tiene varios beneficios. Aquí tienes una tabla simplificada de los métodos soportados por Scikit-learn y sus casos de uso apropiados:
| Nombre del método | Caso de uso |
| :--------------------------- | :-------------------------------------------------------------------------|
| K-Medias | propósito general, inductivo |
| Propagación de afinidad | Muchos, grupos desiguales, inductivo |
| Desplazamiento medio | Muchos, grupos desiguales, inductivo |
| Agrupamiento espectral | Pocos, grupos iguales, transductivo |
| Agrupación jerárquica Ward | Muchos, grupos restringidos, transductivo |
| Agrupación aglomerativa | Muchos, restringidos, distancia no Euclidianas, transductivo |
| DBSCAN | Geometría no plana, grupos desiguales, transductivo |
| OPTICS | Geometría no plana, grupos desiguales con densidad variable, transductivo |
| Mezclas Gaussianas | Geometría plana, inductivo |
| BIRCH | Gran conjunto de datos con valores atípicos, inductivo |
> 🎓 El cómo creamos los grupos tiene mucho que ver con cómo recopilamos los puntos de datos en grupos. Desempaquemos algo de vocabulario:
>
> 🎓 ['Transductivo' vs. 'inductivo'](https://wikipedia.org/wiki/Transduction_(machine_learning))
>
> La inferencia transductiva se deriva de los casos de entrenamiento observados que se asignan a casos de prueba específicos. La inferencia inductiva se deriva de los casos de entrenamiento que se asignan a reglas generales las cuales sólo aplican a los casos de prueba.
>
> Un ejemplo: Imagina que tienes un conjunto de datos que está parcialmente etiquetado. Algunas cosas son 'records', otras 'cds' y unas más están en blanco. Tu trabajo es proveer las etiquetas para los blancos. Si eliges un enfoque inductivo, entrenarías un modelo buscando 'records' y 'cds' y aplicarías esas etiquetas a tus datos sin etiquetar. Este enfoque tendrá problemas clasificando como que en realidad con 'cassettes'. Por otro lado, un enfoque transductivo, maneja estos datos desconocidos de forma más efectiva ya que funciona para agrupar elementos similares y luego aplica una etiqueta a un grupo. En este caso, los agrupamientos reflejan 'cosas musicales redondas' y 'cosas musicales cuadradas'.
>
> 🎓 [Geometría 'no plana' vs 'plana'](https://datascience.stackexchange.com/questions/52260/terminology-flat-geometry-in-the-context-of-clustering)
>
> Derivada de la terminología matemática, la geometría no plana versus plana se refiere a la medida de distancias entre puntos ya sea por métodos geométricos 'planos' ([Euclidianos](https://wikipedia.org/wiki/Euclidean_geometry)) o 'no planos' (no Euclidianos).
>
> En este contexto 'Plano' se refiere a la geometría Euclidiana (partes de las cuales se enseñan como geometría 'plana'), y no plana se refiere a la geometría no Euclidiana. ¿Qué tiene que ver la geometría con el aprendizaje automático? Bien, como dos campos que tienen sus raíces en las matemáticas, debe haber una forma común de medir las distancias entre puntos en los grupos, y eso puede hacerse de forma 'plana' o 'no plana', dependiendo de la naturaleza de los datos. Las [distancias Euclidianas](https://wikipedia.org/wiki/Euclidean_distance) se miden como la longitud de un segmento de línea entre dos puntos. Las [distancias no Euclidianas](https://wikipedia.org/wiki/Non-Euclidean_geometry) se miden como a lo largo de la curva. Si tus datos visualizados parecen no existir en un plano, podrías necesitar usar un algoritmo especializado para realizarlo.
>
![Infografía de geometría plana vs no plana](../images/flat-nonflat.png)
> Infografía de [Dasani Madipalli](https://twitter.com/dasani_decoded)
>
> 🎓 ['Distancias'](https://web.stanford.edu/class/cs345a/slides/12-clustering.pdf)
>
> Los agrupamientos se definen por su matriz de distancia, por ejemplo, las distancias entre puntos. Esta distancia puede ser medida de varias formas. Los agrupamientos Euclidianos se definen por el promedio de los valores de los puntos, y contienen un 'centroide' o punto central. por lo tanto, las distancias son medidas por la distancia al centroide. Las distancias no Euclidianas se refieren a 'clustroides', el punto más cercano a otros puntos. Los clustroides en turno pueden ser definidos de varias formas.
>
> 🎓 ['Restringido'](https://wikipedia.org/wiki/Constrained_clustering)
>
> El [agrupamiento restringido](https://web.cs.ucdavis.edu/~davidson/Publications/ICDMTutorial.pdf) presenta el término aprendizaje 'semi-supervisado' en este método no supervisado. Las relaciones entre los puntos son marcadas como 'cannot link' o 'must-link' por lo que algunas reglas son forzadas en el conjunto de datos.
>
> Un ejemplo: Si se libera un algoritmo en un lote de datos no etiquetados o semi-etiquetados, los agrupamientos que produce pueden ser de baja calidad. En el ejemplo de arriba, los agrupamientos pueden reunir 'round music things' y 'square music things' y 'triangular things' y 'cookies'. Si se proporcionan algunas restricciones o reglas a seguir ("el elemento debe estar hecho de plástico", "el elemento necesita ser capaz de reproducir música") esto puede ayudar a 'restringir' al algoritmo para que realice mejores elecciones.
>
> 🎓 'Densidad'
>
> Los datos que son 'ruidosos' se consideran como 'densos'. Las distancias entre los puntos en cada uno de sus grupos puede probar, al examinarse, ser más o menos densos, o 'atestados' y por lo tanto estos datos necesitan ser analizados con los métodos de agrupamiento apropiados. [Este artículo](https://www.kdnuggets.com/2020/02/understanding-density-based-clustering.html) demuestra la diferencia entre usar los algoritmos K-Medias vs HDBSCAN para explorar un conjunto de datos ruidosos con densidad de agrupamiento desigual.
## Algoritmos de agrupamiento
Existen más de 100 algoritmos de agrupamiento, y sus usos dependen de la naturaleza de los datos que se te presentan. Discutamos algunos de los más importantes:
- **Agrupamiento jerárquico** Si un objeto se clasifica por su proximidad a un objeto cercano, en lugar de uno más lejano, los grupos se forman basados en las distancias de sus miembros hacia y desde otros objetos. El agrupamiento aglomerativo de Scikit-learn es jerárquico.
![Infografía de agrupamiento jerárquico](../images/hierarchical.png)
> Infografía de [Dasani Madipalli](https://twitter.com/dasani_decoded)
- **Agrupamiento de centroide**. Este popular algoritmo require la elección de 'k', o el número de grupos a formar, tras lo cua el algoritmo determina el punto central de un grupo y reúne datos alrededor de ese punto. [El agrupamiento K-Medias](https://wikipedia.org/wiki/K-means_clustering) es una versión popular de agrupamiento de centroide. El centro se determina por la media más cercana, por eso el nombre. La distancia al cuadrado desde el grupo se minimiza.
![Infografía de agrupamiento de centroide](../images/centroid.png)
> Infografía de [Dasani Madipalli](https://twitter.com/dasani_decoded)
- **Agrupamiento basado en distribución**. Se basa en el modelado estadístico, el agrupamiento basado en distribución se centra en determinar la probabilidad de los puntos de datos de pertenecer a un grupo, y los asigna en consecuencia. Los métodos de mezcla Gaussiana pertenecen a este tipo.
- **Agrupamiento basado en densidad**. Los puntos de datos se asignan a grupos basado en su densidad, o su agrupación unos alrededor de otros. Los puntos de datos lejanos del grupo se consideran valores atípicos o ruido. DBSCAN, desplazamiento medio y OPTICS pertenecen a este tipo de agrupamiento.
- **Agrupamiento basado en cuadrícula**. Para conjuntos de datos multi-dimensionales, se crea una cuadrícula y los datos se dividen entre las celdas de la cuadrícula, creando así los grupos.
## Ejercicio - agrupa tus datos
El agrupamiento como técnica recibe mucha ayuda de una buena visualización, así que empecemos por visualizar nuestros datos de música. Este ejercicio nos ayudará a decidir cuál de los métodos de agrupamiento deberíamos usar de forma más efectiva de acuerdo a la naturaleza de estos datos.
1. Abre el archivo _notebook.ipynb_ en este directorio.
1. Importa el paquete `Seaborn` para una buena visualización de datos.
```python
!pip install seaborn
```
1. Adjunta los datos de la canción del archivo _nigerian-songs.csv_. Carga un dataframe con algunos datos de las canciones. Prepárate para explorar estos datos al importar las bibliotecas y volcar los datos:
```python
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv("../data/nigerian-songs.csv")
df.head()
```
Revisa las primeras líneas de datos:
| | name | album | artist | artist_top_genre | release_date | length | popularity | danceability | acousticness | energy | instrumentalness | liveness | loudness | speechiness | tempo | time_signature |
| --- | ------------------------ | ---------------------------- | ------------------- | ---------------- | ------------ | ------ | ---------- | ------------ | ------------ | ------ | ---------------- | -------- | -------- | ----------- | ------- | -------------- |
| 0 | Sparky | Mandy & The Jungle | Cruel Santino | alternative r&b | 2019 | 144000 | 48 | 0.666 | 0.851 | 0.42 | 0.534 | 0.11 | -6.699 | 0.0829 | 133.015 | 5 |
| 1 | shuga rush | EVERYTHING YOU HEARD IS TRUE | Odunsi (The Engine) | afropop | 2020 | 89488 | 30 | 0.71 | 0.0822 | 0.683 | 0.000169 | 0.101 | -5.64 | 0.36 | 129.993 | 3 |
| 2 | LITT! | LITT! | AYLØ | indie r&b | 2018 | 207758 | 40 | 0.836 | 0.272 | 0.564 | 0.000537 | 0.11 | -7.127 | 0.0424 | 130.005 | 4 |
| 3 | Confident / Feeling Cool | Enjoy Your Life | Lady Donli | nigerian pop | 2019 | 175135 | 14 | 0.894 | 0.798 | 0.611 | 0.000187 | 0.0964 | -4.961 | 0.113 | 111.087 | 4 |
| 4 | wanted you | rare. | Odunsi (The Engine) | afropop | 2018 | 152049 | 25 | 0.702 | 0.116 | 0.833 | 0.91 | 0.348 | -6.044 | 0.0447 | 105.115 | 4 |
1. Obtén información acerca del dataframe, llamando a `info()`:
```python
df.info()
```
La salida luce así:
```output
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 530 entries, 0 to 529
Data columns (total 16 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 name 530 non-null object
1 album 530 non-null object
2 artist 530 non-null object
3 artist_top_genre 530 non-null object
4 release_date 530 non-null int64
5 length 530 non-null int64
6 popularity 530 non-null int64
7 danceability 530 non-null float64
8 acousticness 530 non-null float64
9 energy 530 non-null float64
10 instrumentalness 530 non-null float64
11 liveness 530 non-null float64
12 loudness 530 non-null float64
13 speechiness 530 non-null float64
14 tempo 530 non-null float64
15 time_signature 530 non-null int64
dtypes: float64(8), int64(4), object(4)
memory usage: 66.4+ KB
```
1. Vuelve a revisar los valores nulos, al llamar a `isnull()` y verifica que la suma sea 0:
```python
df.isnull().sum()
```
Se ve bien:
```output
name 0
album 0
artist 0
artist_top_genre 0
release_date 0
length 0
popularity 0
danceability 0
acousticness 0
energy 0
instrumentalness 0
liveness 0
loudness 0
speechiness 0
tempo 0
time_signature 0
dtype: int64
```
1. Describe los datos:
```python
df.describe()
```
| | release_date | length | popularity | danceability | acousticness | energy | instrumentalness | liveness | loudness | speechiness | tempo | time_signature |
| ----- | ------------ | ----------- | ---------- | ------------ | ------------ | -------- | ---------------- | -------- | --------- | ----------- | ---------- | -------------- |
| count | 530 | 530 | 530 | 530 | 530 | 530 | 530 | 530 | 530 | 530 | 530 | 530 |
| mean | 2015.390566 | 222298.1698 | 17.507547 | 0.741619 | 0.265412 | 0.760623 | 0.016305 | 0.147308 | -4.953011 | 0.130748 | 116.487864 | 3.986792 |
| std | 3.131688 | 39696.82226 | 18.992212 | 0.117522 | 0.208342 | 0.148533 | 0.090321 | 0.123588 | 2.464186 | 0.092939 | 23.518601 | 0.333701 |
| min | 1998 | 89488 | 0 | 0.255 | 0.000665 | 0.111 | 0 | 0.0283 | -19.362 | 0.0278 | 61.695 | 3 |
| 25% | 2014 | 199305 | 0 | 0.681 | 0.089525 | 0.669 | 0 | 0.07565 | -6.29875 | 0.0591 | 102.96125 | 4 |
| 50% | 2016 | 218509 | 13 | 0.761 | 0.2205 | 0.7845 | 0.000004 | 0.1035 | -4.5585 | 0.09795 | 112.7145 | 4 |
| 75% | 2017 | 242098.5 | 31 | 0.8295 | 0.403 | 0.87575 | 0.000234 | 0.164 | -3.331 | 0.177 | 125.03925 | 4 |
| max | 2020 | 511738 | 73 | 0.966 | 0.954 | 0.995 | 0.91 | 0.811 | 0.582 | 0.514 | 206.007 | 5 |
> 🤔 Si estamos trabajando con el agrupamiento, un método no supervisado que no requiere datos etiquetados. ¿Por qué mostramos estos datos con etiquetas? En la fase de exploración de datos, son útiles, pero no son necesarias para que el algoritmo de agrupamiento funcione. Podrías sólo eliminar los encabezados de columna y referirte a los datos por el número de columna.
Observa los valores generales de los datos. Nota que 'popularity' puede ser '0', lo cual muestra las canciones que no tienen clasificación. Eliminemos esas.
1. Usa un gráfico de barras para descubrir los géneros más populares:
```python
import seaborn as sns
top = df['artist_top_genre'].value_counts()
plt.figure(figsize=(10,7))
sns.barplot(x=top[:5].index,y=top[:5].values)
plt.xticks(rotation=45)
plt.title('Top genres',color = 'blue')
```
![Los más populares](../images/popular.png)
✅ Si te gustaría ver los mejores valores, cambia el valor top `[:5]` por uno mayor, o elimínalo para verlos todos.
Nota, cuando el género superior se describe como 'Missing', que significa que Spotify no lo clasificó, así que deshagámonos de él.
1. Deshazte de los datos faltantes al filtrarlos
```python
df = df[df['artist_top_genre'] != 'Missing']
top = df['artist_top_genre'].value_counts()
plt.figure(figsize=(10,7))
sns.barplot(x=top.index,y=top.values)
plt.xticks(rotation=45)
plt.title('Top genres',color = 'blue')
```
Ahora revisa nuevamente los géneros:
![Los más populares](../images/all-genres.png)
1. Por mucho, los mejores tres géneros dominan este conjunto de datos. Concentrémonos en `afro dancehall`, `afropop`, y `nigerian pop`, adicionalmente filtra el conjunto de datos para remover todo lo que tenga un valor de popularidad de 0 (lo que significa no fue clasificado con una popularidad en el conjunto de datos y puede ser considerado ruido para nuestros propósitos):
```python
df = df[(df['artist_top_genre'] == 'afro dancehall') | (df['artist_top_genre'] == 'afropop') | (df['artist_top_genre'] == 'nigerian pop')]
df = df[(df['popularity'] > 0)]
top = df['artist_top_genre'].value_counts()
plt.figure(figsize=(10,7))
sns.barplot(x=top.index,y=top.values)
plt.xticks(rotation=45)
plt.title('Top genres',color = 'blue')
```
1. Haz una prueba rápida para ver si los datos se correlacionan de alguna forma particularmente fuerte:
```python
corrmat = df.corr()
f, ax = plt.subplots(figsize=(12, 9))
sns.heatmap(corrmat, vmax=.8, square=True)
```
![Correlaciones](../images/correlation.png)
La única correlación fuerte es entre `energy` y `loudness`, lo cual no es de sorprender, dado que la música a todo volumen es usualmente muy energética. De lo contrario, las correlaciones son relativamente débiles. Será interesante ver lo que un algoritmo de agrupamiento puede hacer con estos datos.
> 🎓 ¡Nota que la correlación no implica causalidad! Tenemos prueba de la correlación pero no de la causalidad. Un [sitio web divertido](https://tylervigen.com/spurious-correlations) tiene algunas imágenes que enfatizan este punto.
¿Hay convergencia alguna en este conjunto de datos en torno a la popularidad percibida y bailabilidad de la canción? Una rejilla frontal muestra que hay círculos concéntricos que se alínean, sin importar el género. ¿Podría ser que los gustos Nigerianos converjan a cierto nivel con la bailabilidad de este género?
✅ Prueba distintos puntos de datos (energy, loudness, speechiness) y más o distintos géneros musicales. ¿Qué puedes descubrir? Da un vistazo a la table `df.describe()` para ver la propagación general de los puntos de datos.
### Ejercicio - distribución de datos
¿Son significativamente diferentes estos tres géneros en la percepció nde su bailabilidad, basados en su popularidad?
1. Examina nuestra distribución de datos de los tres mejores géneros por popularidad y bailabilidad junto con un eje x e y dados.
```python
sns.set_theme(style="ticks")
g = sns.jointplot(
data=df,
x="popularity", y="danceability", hue="artist_top_genre",
kind="kde",
)
```
Puedes descubrir círculos concéntricos entorno alrededor de un punto general de convergencia, mostrando la distribución de los puntos.
> 🎓 Nota que este ejemplo usa KDE (Estimación de la Densidad del Kernel), gráfico que representa los datos usando una curva de densidad de probabilidad continua. Esto nos permite interpretar los dato al trabajar con distribuciones múltilples.
En general, los tres géneros se alinean libremente en términos de su probabilidad y bailabilidad. Determinar los grupos en estos datos libremente alineados será un desafío:
![Distribución](../images/distribution.png)
1. Crea un gráfico de dispersión:
```python
sns.FacetGrid(df, hue="artist_top_genre", size=5) \
.map(plt.scatter, "popularity", "danceability") \
.add_legend()
```
Un gráfico de dispersión de los mismos ejes muestra un patrón similar de convergencia
![Cadrícula de facetas](../images/facetgrid.png)
En general, para el agrupamiento, puedes usar gráficos de dispersión para mostrar grupos de datos, por lo que dominar este tipo de visualizaciones es muy útil. En la siguiente lección, tomaremos estos datos filtrados y usaremos el agrupamiento k-medias para descubrir grupos en estos datos que se vean superpuestos de formas interesantes.
---
## 🚀Desafío
En preparación para la siguiente lección, realiza una gráfica acerca de los diverso algoritmos de agrupamiento que puedes descubrir y usar en un ambiente de producción. ¿Qué tipo de problemas trata de abordar el agrupamiento?
## [Examen porterior a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/28/)
## Revisión y auto-estudio
Antes que apliques los algoritmos de agrupamiento, como aprendimos, es buena idea entender la naturaleza de tu conjunto de datos. Lee más sobre este tema [aquí](https://www.kdnuggets.com/2019/10/right-clustering-algorithm.html)
[Este útil artículo](https://www.freecodecamp.org/news/8-clustering-algorithms-in-machine-learning-that-all-data-scientists-should-know/) te guía a través de las distintas formas en que se comportan los distintos algoritmos de agrupamiento, dadas distintas formas de los datos.
## Asignación
[Investiga otras visualizaciones para agrupamiento](assignment.es.md)

@ -0,0 +1,11 @@
# Investiga otras visualizaciones para agruparlas
## Instrucciones
En esta lección, has trabajado con algunas técnicas de visualización para comprender cómo graficar tus datos en preparación para agruparlos. Los gráficos de dispersión son particularmente útiles para encontrar grupos de objetos. Investiga distintas formas y librerías para crear gráficos de dispersión y documenta tu trabajo en un notebook. Puedes usar los datos de esta lección, otras lecciones, o datos que tú mismo proporciones (por favor, dá crédito a su fuente en tu notebook). Grafica algunos datos usando gráficos de dispersión y explica lo que descubras.
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ----------------------------------- |
| | Se presentó un notebook con cinco gráficos de dispersión bien documentados | Se presentó un notebook con menos de cinco gráficos de dispersión y no está bien documentado | Se presentó un notebook incompleto |

@ -0,0 +1,251 @@
# Agrupamiento K-Medias
[![Andrew Ng explica el agrupamiento](https://img.youtube.com/vi/hDmNF9JG3lo/0.jpg)](https://youtu.be/hDmNF9JG3lo "Andrew Ng explica el agrupamiento")
> 🎥 Haz clic en la imagen de arriba para ver el video: Andrew Ng explica el agrupamiento"
## [Examen previo a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/29/)
En esta lección, aprenderás cómo crear grupos usando Scikit-learn y el conjunto de datos de música Nigeriana que importaste anteriormente. Cubriremos los conceptos básicos de K-Medias para agrupamiento. Ten en mente que, como aprendiste en lecciones anteriores, hay muchas formas de de trabajar con grupos y el método que uses depende de tus datos. Probaremos K-medias ya que es la técnica de agrupamiento más común. ¡Comencemos!
Términos que sobre los que aprenderás:
- Puntaje de silueta
- Método del codo
- Inercia
- Varianza
## Introducción
[El agrupamiento K-medias](https://wikipedia.org/wiki/K-means_clustering) es un método derivado del dominio del procesamiento de señales. Se usa para dividir y particionar grupos de datos en 'k' grupos usando una serie de observaciones. Cada observación funciona para agrupar un punto de datos más cercano a su 'media' más cercana, o el punto central de un grupo.
Los grupos pueden ser visualizados como [diagramas Voronoi](https://wikipedia.org/wiki/Voronoi_diagram), los cuales incluye un punto (o 'semilla') y su región correspondiente.
![diagrama Voronoi](../images/voronoi.png)
> Infografía de [Jen Looper](https://twitter.com/jenlooper)
El proceso de agrupamiento K-medias [se ejecuta en un proceso de tres pasos](https://scikit-learn.org/stable/modules/clustering.html#k-means):
1. El algoritmo selecciona el k-número de puntos centrales al hacer muestreo del conjunto de datos. Después de esto, se repite:
1. Se asigna cada muestra al centroide más cercano.
2. Se crean nuevos centroides al tomar el valor medio de todas las muestras asignadas a los centroides previos.
3. Luego, se calcula la diferencia entre los centroides nuevos y viejos y se repite hasta que los centroides se estabilizan.
Un inconveniente de usar K-medias incluye el hecho que necesitarás establecer 'k', que es el número de centroides. Afortunadamente el 'método del codo' ayuda a estimar un buen valor inicial para 'k'. Lo probarás en un minuto.
## Prerrequisitos
Trabajarás en el archivo _notebook.ipynb_ de esta lección, que incluye la importación de datos y limpieza preliminar que hiciste en la última lección.
## Ejercicio - preparación
Comienza por darle otro vistazo a los datos de canciones.
1. Crea un gráfico de caja, llamando a `boxplot()` para cada columna:
```python
plt.figure(figsize=(20,20), dpi=200)
plt.subplot(4,3,1)
sns.boxplot(x = 'popularity', data = df)
plt.subplot(4,3,2)
sns.boxplot(x = 'acousticness', data = df)
plt.subplot(4,3,3)
sns.boxplot(x = 'energy', data = df)
plt.subplot(4,3,4)
sns.boxplot(x = 'instrumentalness', data = df)
plt.subplot(4,3,5)
sns.boxplot(x = 'liveness', data = df)
plt.subplot(4,3,6)
sns.boxplot(x = 'loudness', data = df)
plt.subplot(4,3,7)
sns.boxplot(x = 'speechiness', data = df)
plt.subplot(4,3,8)
sns.boxplot(x = 'tempo', data = df)
plt.subplot(4,3,9)
sns.boxplot(x = 'time_signature', data = df)
plt.subplot(4,3,10)
sns.boxplot(x = 'danceability', data = df)
plt.subplot(4,3,11)
sns.boxplot(x = 'length', data = df)
plt.subplot(4,3,12)
sns.boxplot(x = 'release_date', data = df)
```
Estos datos son un poco ruidosos: al observar cada columna como un gráfico de caja, puedes ver los valores atípicos.
![Valores atípicos](../images/boxplots.png)
Podrías revisar el conjunto de datos y remover estos valores atípicos, pero eso haría que quedara un mínimo de datos.
1. Por ahora, elege qué columnas usarás para tu ejercicio de agrupamiento. Elige unas con rangos similares y codifica la columna `artist_top_genre` como datos numéricos:
```python
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
X = df.loc[:, ('artist_top_genre','popularity','danceability','acousticness','loudness','energy')]
y = df['artist_top_genre']
X['artist_top_genre'] = le.fit_transform(X['artist_top_genre'])
y = le.transform(y)
```
1. Ahora necesitas elegir a cuántos grupos apuntar. Sabes que hay 3 géneros de canciones que extrajimos de el conjunto de datos, así que probemos con 3:
```python
from sklearn.cluster import KMeans
nclusters = 3
seed = 0
km = KMeans(n_clusters=nclusters, random_state=seed)
km.fit(X)
# Predict the cluster for each data point
y_cluster_kmeans = km.predict(X)
y_cluster_kmeans
```
Ves un arreglo impreso con los grupos predichos (0, 1, 0 2) para cada fila del dataframe.
1. Usa este arreglo para calcular una 'puntaje de silueta':
```python
from sklearn import metrics
score = metrics.silhouette_score(X, y_cluster_kmeans)
score
```
## Puntaje de silueta
Busca un puntaje de silueta más cercano a 1. Este puntaje varía de -1 a 1, y si el puntaje es 1, el grupo es denso y bien separado de otros grupos. Un valor cercano a 0 representa grupos superpuestos con muestras muy cercanas al límite de decisión de los grupos vecinos. [Fuente](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam).
Nuestro puntaje es de **.53**, justo a la mitad. Esto indica que nuestros datos no son particularmente adecuados para este tipo de agrupamiento, pero continuemos.
### Ejercicio - construye un modelo
1. Importa `KMeans` e inicia el proceso de agrupamiento.
```python
from sklearn.cluster import KMeans
wcss = []
for i in range(1, 11):
kmeans = KMeans(n_clusters = i, init = 'k-means++', random_state = 42)
kmeans.fit(X)
wcss.append(kmeans.inertia_)
```
Hay algunas partes que requieren explicación.
> 🎓 range: Estas son las iteraciones del proceso de agrupamiento
> 🎓 random_state: "Determina la generación de números aleatorios para la inicialización del centroide." [Fuente](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans)
> 🎓 WCSS: "within-cluster sums of squares (suma de cuadrados dentro del grupo)" mide la distancia cuadrática promedio de todos los puntos dentro de un grupo al centroide dle grupo. [Fuente](https://medium.com/@ODSC/unsupervised-learning-evaluating-clusters-bd47eed175ce).
> 🎓 Inertia: Los algoritmos K-medias intentan elegir los centroides para minimizar la 'inertia (inercia)', "una medida de cuánta coherencia interna tienen los grupos." [Fuente](https://scikit-learn.org/stable/modules/clustering.html). El valor se agrega a la variable wcss en cada iteración.
> 🎓 k-means++: En [Scikit-learn](https://scikit-learn.org/stable/modules/clustering.html#k-means) puedes usar la optimización 'k-means++', la cual "inicializa los centroides para que sean (generalmente) distantes uno de otro, llevando a probablemente mejores resultados que la inicialización aleatoria".
### Método del codo
Anteriormente, supusiste que, porque has apuntado a 3 géneros de canciones, deberías elegir 3 grupos. ¿Pero es el caso?
1. Usa el 'método del codo' para asegurarte.
```python
plt.figure(figsize=(10,5))
sns.lineplot(range(1, 11), wcss,marker='o',color='red')
plt.title('Elbow')
plt.xlabel('Number of clusters')
plt.ylabel('WCSS')
plt.show()
```
Usa la variable `wcss` que construiste en el paso anterior para crear una gráfica que muestre dónde se está 'la curva' en el codo, la cual indica el número óptimo de grupos. ¡Quizá **es** 3!
![Método del codo](../images/elbow.png)
## Ejercicio - muestra los grupos
1. Prueba el proceso de nuevo, esta vez configurando 3 grupos, y muestra los grupos como un gráfico de dispersión:
```python
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters = 3)
kmeans.fit(X)
labels = kmeans.predict(X)
plt.scatter(df['popularity'],df['danceability'],c = labels)
plt.xlabel('popularity')
plt.ylabel('danceability')
plt.show()
```
1. Revisa la precisión del modelo:
```python
labels = kmeans.labels_
correct_labels = sum(y == labels)
print("Result: %d out of %d samples were correctly labeled." % (correct_labels, y.size))
print('Accuracy score: {0:0.2f}'. format(correct_labels/float(y.size)))
```
La precisión de este modelo no es tan buena, y la forma de los grupos te dará una pista del por qué.
![Grupos](../images/clusters.png)
Estos datos están demasiado desequilibrados, muy poco correlacionados y tienen demasiada varianza entre los valores de columna para agrupar bien. De hecho, los grupos que forman están probablemente fuertemente influenciados o sesgados por las tres categorías de géneros que definimos arriba. ¡Eso fue un proceso de aprendizaje!
En la documentación de Scikit-learn, puedes ver que un modelo como este, con grupos no muy bien demarcados, tienen un problema de 'varianza':
![Modelos de problemas](../images/problems.png)
> Infografía de Scikit-learn
## Varianza
La varianza se define como "ep promedio de diferencias cuadráticas de la media". [Fuente](https://www.mathsisfun.com/data/standard-deviation.html). En el contexto de este problema de agrupamiento, se refiere a los datos en los que los números de nuestro conjunto de datos tienden a divergir demasiado de la media.
✅ Este es un buen momento para pensar acerca de todas las formas en que podrías corregir este problema. ¿Modificar los datos un poco más? 'Usar columnas distintas? ¿Usar un algoritmo diferente? Intenta [escalando tus datos](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/) para normalizarlos y probar otras columnas.
> Prueba esta '[calculadora de varianza](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)' para entender un poca más el concepto.
---
## 🚀Desafío
Dedica algo de tiempo a este notebook, ajustando los parámetros. ¿Puedes mejorar la precisión del modelo al limpiar más los datos (eliminando valores atípicos, por ejemplo)? Puedes usar pesos para dar mayor ponderación a las muestras de datos proporcionadas. ¿Qué más puedes hacer para crear mejores grupos?
Pista: Prueba escalar tus datos. Hay código comentado en el notebook que agrega escalado estándar para hacer que las columnas de datos se parezcan más entre sí en términos de rango. Encontrarás que mientras el puntaje de silueta disminuye el 'pliegue' en la gráfica de codo se suaviza. Esto es por qué al dejar los datos sin escalar le permite a los datos con menos variación tengan más peso. Lee un poco más de este problema [aquí](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226).
## [Examen posterior a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/30/)
## Revisión y auto-estudio
Da un vistazo a un simulador K-Medias [como este](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/). Puedes usar esta herramienta para visualizar puntos de datos de muestra y determina sus centroides. Puedes editar la aleatoriedad de los datos, el número de grupos y el número de centroides. ¿Esto te ayuda para tener una idea de cómo se pueden agrupar los datos?
También, da un vistazo a [este folleto de K-Medias](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) de Stanford.
## Asignación
[Prueba distintos métodos de agrupamiento](assignment.es.md)

@ -0,0 +1,11 @@
# Prueba distintos métodos de agrupamiento
## Instrucciones
En esta lección aprendiste acerca del agrupamiento K-Medias. Algunas veces K-Medias no es apropiado para tus datos. Crea un notebook usando los datos ya sea de estas lecciones o de algún otro lugar (dá crédito a tu fuente) y muestra un método de agrupamiento diferente sin usar K-Medias. ¿Qué aprendiste?
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | --------------------------------------------------------------- | -------------------------------------------------------------------- | ---------------------------- |
| | Se presentó un notebook con un modelo de agrupamiento bien documentado | Se presentó un notebook sin buena documentación y/o incompleto | Se envió un trabajo incompleto |

@ -0,0 +1,166 @@
# Introducción al procesamiento del lenguaje natural
Esta lección cubre una breve historia y conceptos importante del *procesamiento del lenguaje natural*, un subcampo de la *ligüística computacional*.
## [Examen previo a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/31/)
## Introducción
NLP, como se conoce comúnmente, es una de las áreas más conocidas donde se ha aplicado y usado el aprendizaje automático en software de producción.
✅ ¿Puedes pensar en software que usas cada d´ia que probablemente tenga algo de NLP embebido? ¿Qué hay de tus programas de procesamiento de palabras o aplicaciones web que usas regularmente?
Aprenderás acerca de:
- **La idea de los idiomas**. Cómo se desarrollaron los idiomas y cuáles han sido las mayores áreas de estudio.
- **Definiciones y conceptos**. También aprenderás definiciones y conceptos acerca de cómo procesan texto las computadoras, incluyendo análisis, gramática e identificación de sustantivos y verbos. Hay algunas tareas de codificación en esta lección, y se presentan varios conceptos importantes que aprenderás a codificar posteriormente en las próximas lecciones.
## Lingüística computacional
La lingüística computacional es una área de la investigación y desarrollo que por varias décadas ha estudiado cómo pueden trabajar las computadoras e incluso entender, traducir y comunicar con idiomas. El procesamiento del lenguaje natural es un campo relacionado que se enfoca en cómo las computadoras pueden procesar el lenguaje 'natural' o humano.
### Ejemplo - dictado telefónico
Si alguna vez has dictado a tu teléfono en lugar de escribir o hacerle una pregunta al asistente virtual, tu voz se convirtió a texto y luego fue procesada o *parseada* desde el idioma que hablaste. Las palabras clave detectadas fueron procesadas en un formato que el teléfono o asistente pueda entender y actuar.
![Comprensión](../images/comprehension.png)
> ¡La comprensión lingüística real es difícil! Imagen de [Jen Looper](https://twitter.com/jenlooper)
### ¿Cómo es posible esta tecnología?
Es posible porque alguien escribió un programa de computadora que lo hace. Hace algunas décadas, algunos escritores de ciencia ficción predijeron que la gente hablaría regularmente con sus computadoras, y las computadoras siempre entenderían exactamente lo que éstas quieren. Tristemente, resultó ser un problema más complejo del que se imaginó, y aunque es un problema mejor comprendido ahora, hay desafíos significativos en lograr un 'perfecto' procesamiento del lenguaje natural cuando se trata de entender el significado de una oración. Este es un problema particularmente difícil cuando se trata de entender el humor o detectar las emociones tal como el sarcasmo en una oración.
En este punto, recordarás las clases escolares donde el profesor cubría las partes de la gramática en una oración. En algunos países, los estudiantes aprenden gramática y lingüística como una materia dedicada, pero en varios casos, estos temas se incluyen como parte del aprendizaje de un idioma: ya sea tu primer idioma en la escuela primaria (aprendiendo a leer y escribir) y quizá como un segundo idioma en la escuela secundaria o la preparatoria. ¡No te preocupes si no eres un experto diferenciando sustantivos de verbos o adverbios de adjetivos!
Si tienes problemas diferenciando entre *presente simple* y *presente continuo*, no estás solo. Esto es un algo desafiante para mucha gente, incluso hablantes nativos de un idioma. La buena noticia es que las computadoras son muy buenas aplicando reglas formales, y aprenderás a escribir código que puede *parsear* una oración tan bien como un humano. El mayor desafío que examinarás más adelante es el entender el *significado* y *sentimiento* de una oración.
## Prerrequisitos
Para esta lección, el prerrequisito principal es ser capaz de leer y comprender el idioma de esta lección. No hay problemas matemáticos ni ecuaciones a resolver. Aunque el actor original escribió esta lección en Inglés, también está traducida a otros idiomas, por lo que podrías leer la traducción. Hay ejemplos donde se usan un número distinto de idiomas (para comparar las distintas reglas gramaticales de los distintos idiomas). Estas *no* son traducidas, pero su texto explicativo sí, así que el significado debería ser claro.
Para las tareas de programación, usarás Python y los ejemplos usan Python 3.8.
En esta sección, necesitarás y usarás:
- **Comprensión de Python 3**. Comprensión del lenguaje de programación Python 3, esta lección usa entradas, ciclos, lectura de archivos, arreglos.
- **Visual Studio Code + extensión**. Usaremos Visual Studio Code y su extensión para Python. También puedes usar algún IDE para Python de tu elección.
- **TextBlob**. [TextBlob](https://github.com/sloria/TextBlob) es una biblioteca de procesamiento de texto simplificada para Python. Sigue las instrucciones en el sitio de TextBlob para instalarla en tu sistema (también instala corpora, como se muestra abajo):
```bash
pip install -U textblob
python -m textblob.download_corpora
```
> 💡 Consejo: Puedes ejecutar Python directamente en los ambientes de VS Code. Revisa la [documentación](https://code.visualstudio.com/docs/languages/python?WT.mc_id=academic-15963-cxa) para mayor información.
## Hablando con las máquinas
La historia de intentar hacer que las computadoras comprendan el lenguaje humano se remota a décadas atrás, y uno de los primeros científicos en considerar el procesamiento del lenguaje natural fue *Alan Turing*.
### La 'prueba de Turing'
Cuando Turing estaba investigando *la inteligencia artificial* en los años 1950, considero que si una prueba conversacional pudiera ser proporcionada a un humano y una computadora (a través de correspondencia mecanografiada) donde el humano en la conversación no estuviese seguro si estuviesen conversando con otro humano o una computadora.
Si, después de cierto tiempo de conversación, el humano no pudiese determinar si las respuestas provinieron de una computadora o no, entonces pudiese decirse que la computadora estaba *pensando*?
### La inspiración - 'el juego de imitación'
La idea para este juego provino de una juego de fiesta llamado *El juego de imitación* donde un interrogador está solo en una habitación y tiene como objetivo determinar cuál de las dos personas (en otra habitación) son hombres y mujeres, respectivamente. El interrogador puede enviar notas, y debe intentar pensar en preguntas donde las respuestas escritas revelen el género de la persona misteriosa. Desde luego, los jugadores en la otra habitación intentan engañar al interrogador al responder a sus preguntas de tal forma que engañen o confundan al interrogador, pero dando la apariencia de responder honestamente.
### Desarrollando a Eliza
En los años 1960s un científico del MIT llamado *Joseph Weizenbaum* desarrolló a [*Eliza*](https://wikipedia.org/wiki/ELIZA), un 'terapeuta' de computadora que realiza preguntas a los humanos y da la sensación de entender sus respuestas. Sin embargo, mientras Eliza podía analizar una oración e identificar ciertas construcciones gramaticales y palabras clase para así darles respuestas razonables, no debería decirse *entender* la oración. Si a Eliza le fuera presentada una oración con el siguiente formato "**I am** <u>sad</u>" podría reorganizar y sustituir palabras en la oración para formar la respuesta "How long have **you been** <u>sad</u>".
Esto daba la impresión que Eliza entendió la oración y le fue hecha una pregunta de seguimiento, aunque en realidad, cambió el tiempo verbal y agregó algunas palabras. Si Eliza no podía identificar una palabra clave para la cual tenía una respuesta, en su lugar daría una respuesta aleatoria que pudiese ser aplicable a distintas oraciones. Eliza podía ser engañada fácilmente, por ejemplo si un usuario escribió "**You are** a <u>bicycle</u>" podría responder con "How long have **I been** a <u>bicycle</u>?", en lugar de una respuesta más elaborada.
[![Chateando con Eliza](https://img.youtube.com/vi/RMK9AphfLco/0.jpg)](https://youtu.be/RMK9AphfLco "Chateando con Eliza")
> 🎥 Da clic en la imagen de arriba para ver el video del programa original ELIZA
> Nota: Puedes leer la descripción original de [Eliza](https://cacm.acm.org/magazines/1966/1/13317-elizaa-computer-program-for-the-study-of-natural-language-communication-between-man-and-machine/abstract) publicado en 1966 si tienes una cuenta ACM, lee acerca de Eliza en [wikipedia](https://wikipedia.org/wiki/ELIZA)
## Ejercicio - Programar un bot conversacional básico
Un bot conversacional, como Eliza, es una programa que obtiene entradas del usuario y parece entender y responder inteligentemente. A diferencia de Eliza, nuestro bot no tendrá varias reglas dándole la apariencia de tener una conversación inteligente. En su lugar, nuestro bot tendrá sólo una habilidad, mantener la conversación con respuestas aleatorias que funcionen en casi cualquier conversación trivial.
### El plan
Tus pasos para construir un bot conversacional:
1. Imprime instrucciones asesorando al usuario cómo interactuar con el bot
2. Empieza un ciclo
1. Acepta la entrada del usuario
2. Si el usuario pidió salir, entonces sal
3. Procesa la entrada del usuario y determina la respuesta (en este caso, la respuesta es una elección aleatoria de una lista de posibles respuestas genéricas)
4. Imprime la respuesta
3. Vuelve al paso 2
### Construye el bot
Ahora creemos el bot. Iniciaremos definiendo algunas frases.
1. Crea este bot tú mismo en Python con las siguientes respuestas aleatorias:
```python
random_responses = ["That is quite interesting, please tell me more.",
"I see. Do go on.",
"Why do you say that?",
"Funny weather we've been having, isn't it?",
"Let's change the subject.",
"Did you catch the game last night?"]
```
Aquí tienes unas salidas de ejemplo para guiarte (la entrada del usuario está en las líneas que empiezan con `>`):
```output
Hello, I am Marvin, the simple robot.
You can end this conversation at any time by typing 'bye'
After typing each answer, press 'enter'
How are you today?
> I am good thanks
That is quite interesting, please tell me more.
> today I went for a walk
Did you catch the game last night?
> I did, but my team lost
Funny weather we've been having, isn't it?
> yes but I hope next week is better
Let's change the subject.
> ok, lets talk about music
Why do you say that?
> because I like music!
Why do you say that?
> bye
It was nice talking to you, goodbye!
```
[Aquí](../solution/bot.py) tienes una posible solución a la tarea.
✅ Detente y considera
1. ¿Crees que las respuestas aleatorias podrías 'engañar' a alguien haciéndole pensar que el bot realmente los entendió?
2. ¿Qué características necesitaría el bot para ser más efectivo?
3. Si el bot pudiera 'entender' realmente el significado de una oración, ¿también necesitaría 'recordar' el significado de oraciones anteriores en una conversación?
---
## 🚀Desafío
Elige uno de los elementos "Detente y considera" de arriba y trata de implementarlos en código o escribe una solución en papel usando pseudo-código.
En la siguiente lección, aprenderás acerca de otros enfoques de cómo analizar el lenguaje natural y aprendizaje automático.
## [Examen posterior a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/32/)
## Revisión y autoestudio
Da un vistazo a las referencias abajo para más oportunidades de lectura.
### Referencias
1. Schubert, Lenhart, "Computational Linguistics", *The Stanford Encyclopedia of Philosophy* (Spring 2020 Edition), Edward N. Zalta (ed.), URL = <https://plato.stanford.edu/archives/spr2020/entries/computational-linguistics/>.
2. Princeton University "About WordNet." [WordNet](https://wordnet.princeton.edu/). Princeton University. 2010.
## Asignación
[Buscar un bot](assignment.es.md)

@ -0,0 +1,11 @@
# Buscar un bot
## Instrucciones
Los bots están en todas partes. Tu asignación: ¡encuentra uno y adóptalo! Los puedes encontrar en sitios web, en aplicaciones bancarias, y en los teléfonos, por ejemplo cuando llamas a compañías de servicios financieros para asesoramiento o información de cuenta. Analiza el bot y ve si puedes confundirlo. Si puedes confundir al bot, ¿por qué piensas que sucedió? Escribe un ensayo corto acerca de tu experiencia.
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | ------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | --------------------- |
| | Se escribió un ensayo a página completa, explicando la presunta arquitectura del bot y describiendo tu experiencia con él | El ensayo está incompleto o no fue bien investigado | No se envió ensayo |

@ -0,0 +1,214 @@
# Tareas y técnicas comunes del procesamiento del lenguaje natural
Para la mayoría de tareas de *procesamiento del lenguaje natural*, el texto a ser procesado debe ser partido en bloques, examinado y los resultados almacenados y tener referencias cruzadas con reglas y conjuntos de datos. Esta tareas, le permiten al programador obtener el _significado_, _intención_ o sólo la _frecuencia_ de los términos y palabras en un texto.
## [Examen previo a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/33/)
Descubramos técnicas comunes usadas en el procesamiento de texto. Combinadas con el aprendizaje automático, estas técnicas te ayudan a analizar grandes cantidades de texto de forma eficiente, Antes de aplicar aprendizaje automático a estas tareas, primero entendamos los problemas encontrados por un especialista del procesamiento del lenguaje natural.
## Tareas comunes al procesamiento del lenguaje natural
Existen distintas forma de analizar un texto en el cual trabajas. Hay tareas que puedes realizar y a través de estas tareas eres capaz de estimar la comprensión del texto y sacar conclusiones. Usualmente llevas a cabo estas tareas en secuencia.
### Tokenización
Probablemente la primer cosa que la mayoría de los algoritmos tiene que hacer es dividir el texto en `tokens`, o palabras. Aunque esto suena simple, teniendo en cuenta la puntuación y distintas palabras y delimitadoras de oraciones en los diferentes idiomas puede hacerlo difícil. Puede que tengas que usar varios métodos para determinar la separación.
![Tokenización](../images/tokenization.png)
> Tokenizando una oración de **Orgullo y Prejuicio**. Infografía de [Jen Looper](https://twitter.com/jenlooper)
### Incrustaciones
[Las incrustaciones de palabras](https://wikipedia.org/wiki/Word_embedding) son una forma de convertir numéricamente tus datos de texto. Las incrustaciones se realizan de tal forma que las palabras con significado similar o palabras que se usan juntas son agrupadas.
![Incrustaciones de palabras](../images/embedding.png)
> "I have the highest respect for your nerves, they are my old friends." - Palabras incrustadas para una oración en **Orgullo y Prejuicio**. Infografía de [Jen Looper](https://twitter.com/jenlooper)
✅ Prueba [esta herramienta interesante](https://projector.tensorflow.org/) par aexperimentar con palabras embebidas. Dando cic en una palabra se muestran grupos de palabras similares: 'toy' se agrupa con 'disney', 'lego', 'playstation', y 'console'.
### Parseo y etiquetado de parte del discurso
Cada palabra que ha sido tokenizada puede ser etiquetada como parte de un discurso - un sustantivo, verbo o adjetivo. La oración `the quick red fox jumped over the lazy brown dog` puede ser etiquetada como parte del discurso como fox = noun, jumped = verb.
![Parseo](../images/parse.png)
> Analizando una oración de **Orgullo y Prejuicio**. Infografía de [Jen Looper](https://twitter.com/jenlooper)
El parseo es reconocer qué palabras están relacionadas con otras en una oración - por ejemplo `the quick red fox jumped` es una secuencia adjetivo-sustantivo-verbo que está separada de la secuencia `lazy brown dog`.
### Frecuencias de palabras y frases
Un procedimiento útil cuando analizas un gran bloque de texto es construir un diccionario de cada palabra o frase de interés y qué tan frecuente aparece. La frase `the quick red fox jumped over the lazy brown dog` tiene una frecuencia de palabra de 2 para `the`.
Veamos un texto de ejemplo donde contamos las frecuencias de las palabras. El poema The Winners de Rudyard Kipling contiene el siguiente verso:
```output
What the moral? Who rides may read.
When the night is thick and the tracks are blind
A friend at a pinch is a friend, indeed,
But a fool to wait for the laggard behind.
Down to Gehenna or up to the Throne,
He travels the fastest who travels alone.
```
Como las frecuencias de frases pueden distinguir entre mayúsculas y minúsculas según se requiera, la frase `a friend` tiene una frecuencia de 2, `the` tiene una frecuencia de 6, y `travels` es 2.
### N-gramas
Un texto puede ser dividido en secuencias de palabras de una longitud definida, una palabra simple (unigrama), dos palabras (bigramas), tres palabras (trigramas) o cualquier número de palabras (n-gramas).
Por ejemplo `the quick red fox jumped over the lazy brown dog` con un n-grama de puntaje 2 produce los siguientes n-gramas:
1. the quick
2. quick red
3. red fox
4. fox jumped
5. jumped over
6. over the
7. the lazy
8. lazy brown
9. brown dog
Podría ser más fácil visualizarlo como una caja deslizante sobre la oración. Aquí se presenta para n-gramas de 3 palabras, el n-grama está en negritas en cada oración:
1. <u>**the quick red**</u> fox jumped over the lazy brown dog
2. the **<u>quick red fox</u>** jumped over the lazy brown dog
3. the quick **<u>red fox jumped</u>** over the lazy brown dog
4. the quick red **<u>fox jumped over</u>** the lazy brown dog
5. the quick red fox **<u>jumped over the</u>** lazy brown dog
6. the quick red fox jumped **<u>over the lazy</u>** brown dog
7. the quick red fox jumped over <u>**the lazy brown**</u> dog
8. the quick red fox jumped over the **<u>lazy brown dog</u>**
![Ventana deslizante de n-gramas](../images/n-grams.gif)
> N-grama de valor 3: Infografía de [Jen Looper](https://twitter.com/jenlooper)
### Extracción de frases nominales
En la mayoría de las oraciones, hay un sustantivo que es el sujeto u objeto de la oración. En Inglés, se suele identificar como al tener 'a', 'an' o 'the' precediéndole. Identificar el sujeto u objeto de una oración al 'extraer la frase nominal' es una tarea común del procesamiento del lenguaje natural al intentar comprender el significado de una oración.
✅ En la oración "I cannot fix on the hour, or the spot, or the look or the words, which laid the foundation. It is too long ago. I was in the middle before I knew that I had begun.", ¿puedes identificar las frases nominales?
En la oración `the quick red fox jumped over the lazy brown dog` hay 2 frases nominales: **quick red fox** y **lazy brown dog**.
### Análisis de sentimiento
Una oración o texto puede ser analizado por sentimiento, o que tan *positivo* o *negativo* es. El sentimiento se mide en *polaridad* y *objetividad/subjetividad*. La polaridad se mide de -1.0 a 1.0 (negativo a positivo) y 0.0 a 1.0 (de más objetivo a más subjetivo).
✅ Más adelante aprenderás que hay distintas formas de determinar el sentimiento usando aprendizaje automático, pero una forma es tener una lista de palabras y frase que son categorizadas como positivas o negativas por un humano experto y aplica ese modelo al texto para calcular un puntaje de polaridad. ¿Puedes ver cómo esto podría funcionar mejor en ciertas circunstancias y peor en otras?
### Inflexión
La inflexión te permite tomar una palabra y obtener el singular o plural de la misma.
### Lematización
Un *lema* es la raíz o palabra principal para un conjunto de palabras, por ejemplo *flew*, *flies*, *flying* tiene como lema el verbo *fly*.
También hay bases de datos útiles para el investigador del procesamiento del lenguaje natural, notablemente:
### WordNet
[WordNet](https://wordnet.princeton.edu/) es una base de datos de palabras, sinónimos antónimos y muchos otros detalles para cada palabra en distintos idiomas. Es increíblemente útil al intentar construir traducciones, correctores ortográficos, o herramientas de idioma de cualquier tipo.
## Bibliotecas NLP
Afortunadamente, no tienes que construir todas estas técnicas por ti mismo, ya que existen excelentes bibliotecas Python disponibles que hacen mucho más accesible a los desarrolladores que no están especializados en el procesamiento de lenguaje natural o aprendizaje automático. Las siguientes lecciones incluyen más ejemplos de estos, pero aquí aprenderás algunos ejemplos útiles para ayudarte con las siguientes tareas.
### Ejercicio - usando la biblioteca `TextBlob`
Usemos una biblioteca llamada TextBlob ya que contiene APIs útiles para abordar este tipo de tareas. TextBlob "se para sobre hombros de gigantes como [NLTK](https://nltk.org) y [pattern](https://github.com/clips/pattern), y se integran bien con ambos." Tiene una cantidad considerable de aprendizaje automático embebido en su API.
> Nota: Hay una guía de [Inicio rápido](https://textblob.readthedocs.io/en/dev/quickstart.html#quickstart) útil disponible para TextBlob que es recomendada por desarrolladores Python experimentados.
Al intentar identificar *frases nominales*, TextBlob ofrece varias opciones de extractores para encontrar frases nominales.
1. Da un vistazo a `ConllExtractor`.
```python
from textblob import TextBlob
from textblob.np_extractors import ConllExtractor
# import and create a Conll extractor to use later
extractor = ConllExtractor()
# later when you need a noun phrase extractor:
user_input = input("> ")
user_input_blob = TextBlob(user_input, np_extractor=extractor) # note non-default extractor specified
np = user_input_blob.noun_phrases
```
> ¿Qué pasa aquí? [ConllExtractor](https://textblob.readthedocs.io/en/dev/api_reference.html?highlight=Conll#textblob.en.np_extractors.ConllExtractor) es "un extractor de frases nominales que usa el análisis de fragmentos entrenado con el corpus de entrenamiento ConLL-2000." ConLL-2000 se refiere a la conferencia en aprendizaje de lenguaje natural computacional del 2000. Cada año la conferencia organiza un talle para abordar un problema difícil del procesamiento del lenguaje natural, y en el 2000 fue de fragmentación de sustantivos. Se entrenó un modelo en el Wall Street Journal, con las "secciones 15 a 18 como datos de entrenamiento (211727 tokens) y la sección 20 como datos de prueba (47377 tokens)". Puedes revisar los procedimientos usados [aquí](https://www.clips.uantwerpen.be/conll2000/chunking/) y los [resultados](https://ifarm.nl/erikt/research/np-chunking.html).
### Desafío - Mejora tu bot con procesamiento del lenguaje natural
En la lección anterior construiste un bot de preguntas y respuestas muy simple. Ahora, harás a Marvin un poco más comprensivo al analizar tu entrada para sentimiento e imprimir una respuesta para emparejar el sentimiento. También necesitarás identificar `noun_phrase` y preguntar al respecto.
Tus pasos al construir un mejor bot conversacional:
1. Imprime las instrucciones avisando al usuario cómo interactuar con el bot
2. Inicia el ciclo
1. Acepta la entrada del usuario
2. Si el usuario pidió salir, entonces sal del programa
3. Procesa la entrada del usuario y determina la respuesta de sentimiento apropiada
4. Si se detectó una frase nominal en el sentimiento, pluralízalo y pide más entradas de ese tema
5. Imprime la respuesta
3. Regresa al paso 2
Aquí tienes el fragmento de código para determinar el sentimiento usando TextBlob. Nota que sólo hay 4 *gradientes* de respuesta de sentimiento (podrías tener más si quisieras):
```python
if user_input_blob.polarity <= -0.5:
response = "Oh dear, that sounds bad. "
elif user_input_blob.polarity <= 0:
response = "Hmm, that's not great. "
elif user_input_blob.polarity <= 0.5:
response = "Well, that sounds positive. "
elif user_input_blob.polarity <= 1:
response = "Wow, that sounds great. "
```
Aquí está una salida de muestra para guiarte (la entrada del usuario está en las líneas que comienzan con >):
```output
Hello, I am Marvin, the friendly robot.
You can end this conversation at any time by typing 'bye'
After typing each answer, press 'enter'
How are you today?
> I am ok
Well, that sounds positive. Can you tell me more?
> I went for a walk and saw a lovely cat
Well, that sounds positive. Can you tell me more about lovely cats?
> cats are the best. But I also have a cool dog
Wow, that sounds great. Can you tell me more about cool dogs?
> I have an old hounddog but he is sick
Hmm, that's not great. Can you tell me more about old hounddogs?
> bye
It was nice talking to you, goodbye!
```
Una posible solución a esta tarea esta [aquí](../solution/bot.py)
✅ Revisión de conocimiento
1. ¿Piensas que las respuestas comprensivas 'engañarían' a alguien a creer que el bot en realidad les entendió?
2. ¿El identificar la frane nominal hace al bot más 'creíble'?
3. ¿Por qué extraer una 'frase nominal' de una oración es algo útil?
---
Implementa el bot con la revisión de conocimiento anterior y pruébalo con un amigo. ¿Pudo engañarlo? ¿Puedes hacer a tu bot más 'creíble'?
## 🚀Desafío
Toma una tarea de la revisión de conocimiento previo y trata de implementarla. Prueba el bot con un amigo. ¿Pudo engañarlo? ¿Puedes hacer a tu bot más 'creíble'?
## [Examen posterior a la lectura](https://white-water-09ec41f0f.azurestaticapps.net/quiz/34/)
## Revisión y autoestudio
En las siguientes lecciones aprenderás más acerca del análisis de sentimiento. Investiga esta técnica interesante en artículos como estos en [KDNuggets](https://www.kdnuggets.com/tag/nlp)
## Asignación
[Haz que un bot responda](assignment.es.md)

@ -0,0 +1,11 @@
# Hacer que un Bot responda
## Instrucciones
En las lecciones anteriores, programaste un bot básico con el cual chatear. Este bot da respuestas aleatorias hasta que le digas 'bye'. ¿Puedes hacer las respuestas menos aleatorias, y activar respuestas si dices cosas específicas, como 'why' o 'how'? Piensa un poco en cómo el aprendizaje automático puede hacer este tipo de trabajo menos manual a medida que extiendes tu bot. Puedes usar las librerías NLTK o TextBlob para hacer tus tareas más fáciles.
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | --------------------------------------------- | ------------------------------------------------ | ----------------------- |
| | Se presentó y documentó un nuevo archivo bot.py | Se presentó un nuevo archivo bot pero contiene fallos | No se presentó un archivo |

@ -0,0 +1,187 @@
# Traducción y análisis de sentimiento con aprendizaje automático
En las lecciones anteriores aprendiste cómo construir un bot básico usando `TextBlob`, una biblioteca que embebe aprendizaje automático tras bambalinas para realizar tareas básicas de procesamiento del lenguaje natural (NLP) tales como extracción de frases nominales. Otro desafío importante en la lingüística computacional es la _traducción_ precisa de una oración de un idioma hablado o escrito a otro.
## [Examen previo a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/35/)
La traducción es siempre un problema difícil compuesto por el hecho que existen miles de idiomas y cada uno puede tener distintas reglas gramaticales. Un enfoque es convertir las reglas gramaticales formales para un idioma, como el Inglés, a una estructura no dependiente del idioma, y luego traducirlo al convertirlo de nuevo a otro idioma. Este enfoque significa que deberías realizar los siguientes pasos:
1. **Identificacción**. Identifica o etiqueta las palabras en el idioma de entrada en sustantivos, verbos, etc.
2. **Crea la traducción**. Produce una traducción directa de cada palabra en el formato del idioma objetivo.
### Oración de ejemplo, Inglés a Irlandés
En 'Inglés', la oración _I feel happy_ es de 3 palabras en el orden:
- **sujeto** (I)
- **verbo** (feel)
- **adjetivo** (happy)
Sin embargo, en el idioma 'Irlandés', la misma oración tiene una estructura gramatical muy diferente - emociones como "*happy*" o "*sad*" se expresan como `being *upon* you`.
La frase en Inglés `I feel happy` en Irlandés sería `Tá athas orm`. Una traducción *literal* sería `Happy is upon me`.
Un hablante Irlandés al traducir al Inglés diría `I feel happy`, no `Happy is upon me`, porque el entiende el significado de la oración, aún si las palabras y la estructura de la oración son diferentes.
El orden formal para la oración en Irlandés es:
- **verbo** (Tá or is)
- **adjetivo** (athas, or happy)
- **sujeto** (orm, or upon me)
## Traducción
Un programa de traducción simple podría traducir sólo las palabras, ignorando la estructura de la oración.
✅ Si has aprendido un segundo (o tercero o más) idioma como adulto, podrías haber comenzado pensando en tu idioma nativo, traduciendo un concepto palabra por palabra en tu cabeza al segundo idioma, y luego diciendo tu traducción. Esto es similar a lo que realizan los programas de traducción simple. ¡Es importante superar esta fase para lograr fluidez!
La traducción simple lleva a malas (y algunas veces divertidas) traducciones: `I feel happy` se traduce literalmente a `Mise bhraitheann athas` en Irlandés. Lo cual significa (literalmente) `me feel happy` y no es una oración Irlandesa válida. Aún cuando el Inglés e Irlandés son idiomas hablados en dos islas vecinas muy cercanas, son idiomas muy diferentes con diferentes estructuras gramaticales.
> Puedes ver más videos acerca de las tradiciones lingüísticas Irlandesas tales como [esta](https://www.youtube.com/watch?v=mRIaLSdRMMs)
### Enfoques del aprendizaje automático
Hasta ahora, hasta aprendido acerca de los enfoques a las reglas formales para el procesamiento del lenguaje natural. Otro enfoque es ignorar el significado de las palabras, y _en su lugar usar aprendizaje automático para detectar patrones_. Esto puede funcionar en traducciones si tienes demasiado texto (un *corpus*) o textos (*corpora*) tanto en el idioma origen como el destino.
Por ejemplo, considera el caso de *Orgullo y Prejuicio*, una novela Ingles muy conocidad escrita por Jane Austen in 1813. Si consultas el libro en Inglés y una traducción humana del libro en *Francés*, podrías detectar frases en uno que están traducidas _idiomáticamente_ al otro. Lo cual harás en un minuto.
Por ejemplo, cuando una frase en Inglés como `I have no money` se traduce literalmente al Francés, se convertiría en `Je n'ai pas de monnaie`. "Monnaie" es un 'falso cognado' francés, ya que 'money' y 'monnaie' no son sinónimos. Una mejor traducción que la humana sería `Je n'ai pas d'argent`, porque transmite mejor el significado de no tener dinero (en lugar de 'loose change' lo cual es el significado de 'monnaie').
![monnaie](../images/monnaie.png)
> Imagen de [Jen Looper](https://twitter.com/jenlooper)
Si un modelo de aprendizaje automático tiene suficientes traducciones humanas para construir un modelo sobre el cual basarse, puede mejorar la precisión de las traducciones al identificar patrones comunes en textos que han sido previamente traducidos por hablantes humanos expertos de ambos idiomas.
### Ejercicio - traducción
Puedes usar `TextBlob` para traducir oraciones. Prueba la famosa primer línea de **Orgullo y Prejuicio**:
```python
from textblob import TextBlob
blob = TextBlob(
"It is a truth universally acknowledged, that a single man in possession of a good fortune, must be in want of a wife!"
)
print(blob.translate(to="fr"))
```
`TextBlob` hace un muy buen trabajo al traducir: "C'est une vérité universellement reconnue, qu'un homme célibataire en possession d'une bonne fortune doit avoir besoin d'une femme!".
Se podría discutir que la traducción de TextBlob es mucho más exacta, que la traducción Francesa de 1932 del libro por V. Leconte y Ch. Pressoir:
"C'est une vérité universelle qu'un célibataire pourvu d'une belle fortune doit avoir envie de se marier, et, si peu que l'on sache de son sentiment à cet egard, lorsqu'il arrive dans une nouvelle résidence, cette idée est si bien fixée dans l'esprit de ses voisins qu'ils le considèrent sur-le-champ comme la propriété légitime de l'une ou l'autre de leurs filles."
En este caso, la traducción proporcionada por el aprendizaje automático realiza un mejor trabajo que el traductor humano quien innecesariamente agrega palabras a las dichas por el autor para dar 'claridad'.
> ¿Qué pasa aquí? ¿y por qué TextBlob es tan bueno al traducir? Bien, tras bambalinas, usa Google translate, una IA sofisticada capaz de analizar millones de frases y predecir las mejores cadenas para la tarea en cuestión. No ocurre nada manual aquí y tienes una conexión a internet para usar `blob.translate`.
✅ Prueba unas oraciones más. ¿Cuál es mejor, la traducción del aprendizaje automático o la humana? ¿En qué casos?
## Análisis de sentimiento
Otra área donde el aprendizaje automático funciona muy bien es el análisis de sentimiento. Un enfoque de no aprendizaje automático al sentimiento es identificar las palabras y frases que son 'positivas' y 'negativas'. Luego, dada una nueva porción de texto, calcular el valor total de las palabras positivas, negativas y neutras para identificar el sentimiento en general.
Este enfoque se puede engañar fácilmente como ya has visto en la tarea de Marvin - La oración `Great, that was a wonderful waste of time, I'm glad we are lost on this dark road` es una oración sarcástica y de sentimiento negativo, pero el algoritmo simple detecta 'great', 'wonderful', 'glad' como positivas y 'waste', 'lost' y 'dark' como negativas. El sentimiento general está influenciado por estas palabras contradictorias.
✅ Detente un segundo y piensa en cómo transmitimos el sarcasmo como hablantes humanos. La inflexión del tono juega un gran rol. Intenta decir la frase "Well, that film was awesome" de distintas formas para descubrir cómo tu voz transmite el significado.
### Enfoques del aprendizaje automático
El enfoque del aprendizaje automático debería ser reunir manualmente los cuerpos de texto negativos y positivos - tweets, o reseñar de películas, o cualquier otra cosa donde el ser humano ha dado una calificación **y** una opinión escrita. Luego las técnicas de procesamiento del lenguaje natural pueden ser aplicadas a las opiniones y calificaciones, para que surjan los patrones (por ejemplo, las reseñas positivas de películas tienden a usar la frase 'merecedora del Oscar' más que las reseñas negativas, o las reseñas positivas de restaurantes dicen 'gourmet' mucho más que 'disgusting').
> ⚖️ **Ejemplo**: Si trabajaste en la oficina de un político y se debatía alguna ley nueva, los constituyentes pueden escribir a la oficina con correos electrónicos emitiendo su apoyo o rechazo a esa nueva ley. Digamos que te asignaron leer los correos electrónicos y ordenarlos en 2 pilas, *for* y *against*. Si hubiera muchos correos electrónicos, podrías estar abrumado al intentar leerlos todos. ¿No sería genial que un bot pudiera leerlos todos por ti, entenderlos y decirte a qué pila pertenecen?
>
> Una forma de lograrlo es usar aprendizaje automático. Entrenarías al modelo con una porción de los correos electrónicos de los que están en contra (*against*) y a favor (*for*). El modelo tendería a asociar frases y palabras con los lados en contra y a favor, *pero no entendería nada del contenido*, a menos que ciertas palabras y patrones fuesen más probables de aparecer en un correo clasificado como *against* o *for*. Podrías probarlo con algunos correo electrónicos que no usaste para entrenar el modelo, y ver si llegó a la misma conclusión que tú. Luego, una vez que estuvieses satisfecho con la precisión del modelo, podrías procesar correos posteriores sin necesidad de leer cada uno.
✅ ¿Este proceso suena como algún proceso que has usado en lecciones previas?
## Ejercicio - oraciones sentimentales
El sentimiento se mide con una *polaridad* de -1 a 1, donde -1 es el sentimiento más negativo, y 1 el más positivo. El sentimiento también puede medirse con el puntaje de 0 a 1, para la objetividad (0) y la subjetividad (1).
Da un vistazo más a *Orgullo y Prejuicio* de Jane Austen. El texto está disponible en [Project Gutenberg](https://www.gutenberg.org/files/1342/1342-h/1342-h.htm). la muestra de abajo muestra un pequeño programa el cual analiza el sentimiento de las primer y última oraciones del libro y muestra su polaridad de sentimiento y el puntaje subjetivo/objetivo.
Deberías usar la biblioteca `TextBlob` (descrita arriba) para determinar el sentimiento (`sentiment`) (no tienes que escribir tu propia calculadora de sentimiento) en la siguiente tarea.
```python
from textblob import TextBlob
quote1 = """It is a truth universally acknowledged, that a single man in possession of a good fortune, must be in want of a wife."""
quote2 = """Darcy, as well as Elizabeth, really loved them; and they were both ever sensible of the warmest gratitude towards the persons who, by bringing her into Derbyshire, had been the means of uniting them."""
sentiment1 = TextBlob(quote1).sentiment
sentiment2 = TextBlob(quote2).sentiment
print(quote1 + " has a sentiment of " + str(sentiment1))
print(quote2 + " has a sentiment of " + str(sentiment2))
```
Verás la siguiente salida:
```output
It is a truth universally acknowledged, that a single man in possession of a good fortune, must be in want # of a wife. has a sentiment of Sentiment(polarity=0.20952380952380953, subjectivity=0.27142857142857146)
Darcy, as well as Elizabeth, really loved them; and they were
both ever sensible of the warmest gratitude towards the persons
who, by bringing her into Derbyshire, had been the means of
uniting them. has a sentiment of Sentiment(polarity=0.7, subjectivity=0.8)
```
## Desafío - revisa la polaridad de sentimiento
Tu tarea es determinar, usando la polaridad de sentimiento, si *Orgullo y Prejuicio* tiene más oraciones absolutamente positivas que absolutamente negativas. Para esta tarea, puedes asumir que un puntaje de polaridad de 1 o -1 es absolutamente positivo o negativo, respectivamente.
**Pasos:**
1. Descarga una [copia de Orgullo y Prejuicio](https://www.gutenberg.org/files/1342/1342-h/1342-h.htm) de Project Gutenberg como archivo .txt. Elimina los metadatos al inicio y final del archivo, dejando solo el texto original.
2. Abre el archivo en python y extrae los contenidos como una cadena.
3. Crea un TextBlob usando la cadena del libro
4. Analiza cada oración en el libro dentro de un ciclo
1. Si la polaridad es 1 o -1 almacena la oración en un arreglo o lista de mensajes positivos o negativos
5. Al final, imprime todas las oraciones positivas y negativas (de forma separada) y el número de cada una.
Aquí tienes una [solución de muestra](../solution/notebook.ipynb).
✅ Verificación de conocimiento
1. El sentimiento se basa en las palabras usadas en la oración, pero ¿el código *entiende* las palabras?
2. ¿Piensas que la polaridad del sentimiento es precisa, o en otras palabras, estás *de acuerdo* con los puntajes?
1. En particular, ¿estás de acuerdo o en desacuerdo con la polaridad **positiva** absoluta de las siguientes oraciones?
* “What an excellent father you have, girls!” said she, when the door was shut.
* “Your examination of Mr. Darcy is over, I presume,” said Miss Bingley; “and pray what is the result?” “I am perfectly convinced by it that Mr. Darcy has no defect.
* How wonderfully these sort of things occur!
* I have the greatest dislike in the world to that sort of thing.
* Charlotte is an excellent manager, I dare say.
* “This is delightful indeed!
* I am so happy!
* Your idea of the ponies is delightful.
2. Las siguientes 3 oraciones fueron puntuadas con un sentimiento positivo absoluto, pero leyendo atentamente, esas no son oraciones positivas. ¿Por qué el análisis de sentimiento piensa que fueron oraciones positivas?
* Happy shall I be, when his stay at Netherfield is over!” “I wish I could say anything to comfort you,” replied Elizabeth; “but it is wholly out of my power.
* If I could but see you as happy!
* Our distress, my dear Lizzy, is very great.
3. ¿Estás de acuerdo o en desacuerdo con la polaridad absoluta **negativa** de las siguientes oraciones?
- Everybody is disgusted with his pride.
- “I should like to know how he behaves among strangers.” “You shall hear then—but prepare yourself for something very dreadful.
- The pause was to Elizabeth’s feelings dreadful.
- It would be dreadful!
✅ Cualquier aficionado de Jane Austen entenderá que ella usa frecuentemente sus libros para criticar los aspectos más ridículo de la sociedad de la Regencia Inglesa. Elizabeth Bennett, el personaje principal en *Orgullo y Prejuicio*, es una aguda observadora social (como la autora) y su lenguaje es a menudo muy matizado. Incluso el Sr. Darcy (el interés amoroso en la historia) nota el lenguaje juguetón y burlón de Elizabeth: "I have had the pleasure of your acquaintance long enough to know that you find great enjoyment in occasionally professing opinions which in fact are not your own."
---
## 🚀Desafío
¿Puedes hacer a Marvin aún mejor al extraer otras características de la entrada del usuario?
## [Examen posterior a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/36/)
## Revisión y autoestudio
Hay varias formas de extraer el sentimiento del texto. Piensa en las aplicaciones de negocios que podrían hacer uso de esta técnica. Piensa cómo puede salir mal. Lee más acerca de los sistemas sofisticados listos para empresas que analizan el sentimiento tal como [Azure Text Analysis](https://docs.microsoft.com/azure/cognitive-services/Text-Analytics/how-tos/text-analytics-how-to-sentiment-analysis?tabs=version-3-1?WT.mc_id=academic-15963-cxa). Prueba algunas de las oraciones de Orgullo y Prejuicio de arriba y observa si se pueden detectar matices.
## Asignación
[Licencia poética](assignment.es.md)

@ -0,0 +1,11 @@
# Licencia poética
## Instrucciones
En [este notebook](https://www.kaggle.com/jenlooper/emily-dickinson-word-frequency) puedes encontrar más de 500 poemas de Emily Dickinson previamente analizados por sentimiento usando análisis de texto de Azure. Usando este conjunto de datos, analízalo usando las técnicas descritas en la lección. ¿El sentimiento sugerido de un poema coincide con la decisión más sofisticada del servicio de Azure? ¿En tu opinión por qué o por qué no? ¿Algo te sorprende?
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | -------------------------------------------------------------------------- | ------------------------------------------------------- | ------------------------ |
| | Se presentó un notebook con un análisis sólido de una muestra de salida del autor | El notebook se presenta incompleto o no ejecuta el análisis | No se presentó un notebook |

@ -0,0 +1,415 @@
# Análisis de sentimiento con reseñas de hoteles - procesando los datos
En esta sección usarás las técnicas de las lecciones anteriores para hacer un ańalisis exploratorio de datos de un gran conjunto de datos. Una vez que tengas un buen entendimiento de la utilidad de las distintas, aprenderás:
- cómo eliminar las columnas innecesarias
- cómo calcular algunos datos nuevos basándote en las columnas existentes
- cómo guardar el conjunto de datos resultante para usarlo en el desafío final
## [Examen previo a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/37/)
### Introducción
hasta ahora has aprendido acerca de cómo los datos de texto es muy diferente a los tipos de datos numéricos. Si el texto fue escrito o hablado por un humano, si puede ser analizado para encontrar patrones y frecuencias, sentimiento y significado. Este lección te lleva a un conjunto de datos reales con un desafío real: **[515K datos de reseñas de hoteles en Europa](https://www.kaggle.com/jiashenliu/515k-hotel-reviews-data-in-europe)** e incluye una [licencia de dominio público: CC0](https://creativecommons.org/publicdomain/zero/1.0/). Se obtuvo mediante scraping de Booking.com de fuentes públicas. El creador del conjunto de datos fue Jiashen Liu.
### Preparación
Necesitarás:
* La habilidad de ejecutar notebooks .ipynb usando Python 3
* pandas
* NLTK, [la cual deberías instalar localmente](https://www.nltk.org/install.html)
* El conjunto de datos el cual está disponible en Kaggle [515K Hotel Reviews Data in Europe](https://www.kaggle.com/jiashenliu/515k-hotel-reviews-data-in-europe). El cual de alrededor de 230MB desempequetado. Descargalo en el directorio raíz `/data` asociado con estas lecciones de NLP.
## Análisis exploratorio de datos
Este desafío asume que estás construyendo un bot de recomendación de hoteles usando análisis de sentimiento y puntajes de reseñas de huéspedes. El conjunto de datos que usarás incluye reseñas de 1493 hoteles distintos en 6 ciudades.
Usando Python, un conjunto de datos de reseñas de hoteles y análisis de sentimiento de NLTK podrías encontrar:
* ¿Cuáles son las frases y palabras usadas con mayor frecuencia en las reseñas?
* ¿Las *etiquetas* oficiales que describen un hotel se correlacionan con los puntajes de las reseñas (por ejemplo son más negativas para un hotel en particular de *Familia con niños pequeños* que *viajero solitario*, quizá indicando que es mejor para *viajeros solitarios*)?
* ¿Los puntajes de sentimiento de NLTK 'concuerdan' (agree) con los puntajes numéricos de quién reseña el hotel?
#### Conjuntos de datos
Exploremos el conjunto de datos que descargaste y guardaste de forma local. Abre el archivo en un editor como VS Code o Excel.
Los encabezados en el conjunto de datos se ven así:
*Hotel_Address, Additional_Number_of_Scoring, Review_Date, Average_Score, Hotel_Name, Reviewer_Nationality, Negative_Review, Review_Total_Negative_Word_Counts, Total_Number_of_Reviews, Positive_Review, Review_Total_Positive_Word_Counts, Total_Number_of_Reviews_Reviewer_Has_Given, Reviewer_Score, Tags, days_since_review, lat, lng*
Aquí están agrupados de cierta forma que sean fáciles de examinar:
##### Columnas Hotel
* `Hotel_Name`, `Hotel_Address`, `lat` (latitud), `lng` (longitud)
* Usando *lat* y *lng* podrías graficar un map con Python mostrando las ubicaciones de hoteles (quiźa usando un código de colores para las reseñas positivas y negativas)
* Hotel_Address obviamente no nos es útil, y probablemente la reemplazaremos con un país para una búsqueda y ordenamiento más fácil.
**Columnas Hotel Meta-review**
* `Average_Score`
* De acuerdo al creador del conjunto de datos, esta columna es el *Puntaje promedio del hotel, basado en el último comentario del último año*. Esto parece una forma inusual de calcular el puntaje, pero son los datos extraídos por lo que podemos tomarlos como valor por ahora.
✅ Basado en las otras columnas de estos datos, ¿puedes pensar en otra forma de calcular el puntaje promedio?
* `Total_Number_of_Reviews`
* El número total de reseñas que ha recibido este hotel. No está claro (sin escribir algo de código) si esto se refiere a las reseñas en el conjunto de datos.
* `Additional_Number_of_Scoring`
* Esto significa que se dió un puntaje de reseña pero no se escribió reseña positiva o negativa por el crítico.
**Columnas Review**
- `Reviewer_Score`
- Este es un valor numérico con máximo 1 posición decimal entre los valores máximos y mínimos de 2.5 y 10
- No se explica por qué 2.5 es el puntaje más bajo posible
- `Negative_Review`
- Si un crítico no escribió nada, este campo tendrá "**No Negative**"
- Nota que un crítico puede escribir una reseña positiva en la columna de reseña negativa (por ejemplo, "there is nothing bad about this hotel")
- `Review_Total_Negative_Word_Counts`
- El conteo de palabras negativas más altas indica un puntaje más bajo (sin revisar el sentimentalismo)
- `Positive_Review`
- Si un crítico no escribió nada, este campo tendrá "**No Positive**"
- Nota que un cŕitico puede escribir una reseña negativa en la columna de reseña positiva (por ejemplo, "there is nothing good about this hotel at all")
- `Review_Total_Positive_Word_Counts`
- El conteo de palabras positivas más altas indica un puntaje más alto (sin revisar el sentimentalismo)
- `Review_Date` y `days_since_review`
- Una medida de frescura o ranciedad puede aplicarse a una reseña (las reseñas más biejas pueden no ser tan precisas como las nuevas ya que la administración del hotel ha cambiado, o se hicieron remodelaciones, o se agregó una alberca, etc.)
- `Tags`
- Estas son breves descriptores que un crítico puede seleccionar para describir el tipo de huéspesd que fueron (ejemplo, `solo` o `family`), el tipo de cuarto que se les asignó, la duración de la estancia y cómo se envió la reseña.
- Desafortunadamente, el usar estas etiquetas es problemático, revisa la sección de abajo la cual discute su utilidad
**Columnas Reviewer**
- `Total_Number_of_Reviews_Reviewer_Has_Given`
- Esta podría ser un factor en un modelo de recomendación, por ejemplo, si pudieras determinar que los críticos más prolíficos con cientos de reseñas tendieran a ser más negativos que positivos. Sin embargo, el crítico de cualquier reseña en particular no se identifica con un código único, y por lo tanto no puede ser vinculado a un conjunto de reseñas. Hay 30 críticos con 100 reseñas o más, pero es díficil ver cómo esto puede ayudar al modelo de recomendación.
- `Reviewer_Nationality`
- Algunas personas podrían pensar que ciertas nacionalidades tienden dar una reseña positiva o negatica debido a una inclinación nacional. Sea cuidadoso al construir dichas vistas anecdóticas en tus modelos. Estos son estereotipos nacionales (y algunas veces raciales), y cada crítico fue un individuo que escribió una reseña basándose en su experiencia. Podría haber sido filtrado a través de varios lentes tal como sus estadías anteriores en hoteles, la distancia viajada, y su temperamento personal. Pensar que su nacionalidad fue el motivo del puntaje de una reseña es difícil de justificar.
##### Ejemplos
| Average Score | Total Number Reviews | Reviewer Score | Negative <br />Review | Positive Review | Tags |
| -------------- | ---------------------- | ---------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | ----------------------------------------------------------------------------------------- |
| 7.8 | 1945 | 2.5 | This is currently not a hotel but a construction site I was terrorized from early morning and all day with unacceptable building noise while resting after a long trip and working in the room People were working all day i e with jackhammers in the adjacent rooms I asked for a room change but no silent room was available To make things worse I was overcharged I checked out in the evening since I had to leave very early flight and received an appropriate bill A day later the hotel made another charge without my consent in excess of booked price It's a terrible place Don't punish yourself by booking here | Nothing Terrible place Stay away | Business trip Couple Standard Double Room Stayed 2 nights |
Como puedes ver, este huésped no tuvo una estancia agradable en el hotel. El hotel tiene un puntaje promedio bueno de 7.8 y 1945 reseñas, pero este crítico le dió 2.5 y escribió 115 palabras acerca de qué tan negativa fue su estancia. Si no escribió nada en la columna Positive_Review, podrías suponer que no hubo nada positivo, pero por desgracia escribió 7 palabras de advertencia. Si contaramos sólo palabras en lugar del significado, o el sentimiento de las palabras, podríamos tener una vista sesgada de la intención del crítico. Extrañamente, su puntaje de 2.5 es confuso, ya que si esa estancia en el hotel fue tan mala, ¿por qué darle una puntuación? Investigando el conjunto de datos más de cerca, verás que el puntaje más bajo posible es de 2.5, no de 0. El puntaje más alto posible es de 10.
##### Etiquetas
Como se mencionó anteriormente, a primera vista, la idea de usar etiquetas (`Tags`) para categorizar los datos, hace sentido. Desafortunadamente estas etiquetas no están estandarizadas, lo cual significa que en cierto hotel, las opciones podrían ser *Single room*, *Twin room*, y *Double room*, pero en otro hotel, son *Deluxe Single Room*, *Classic Queen Room*, y *Executive King Room*. Estas pueden ser las mismas cosas, pero hay tantas variaciones que la elección se convierte en:
1. Intenta cambiar todos los términos a un estándar único, lo cual es muy difícil, por qué no está claro cuál sería la ruta de conversión en cada caso (por ejemplo *Classic single room* se asigna a *Single room* pero *Superior Queen Room with Courtyard Garden or City View* es más difícil de asignar).
1. Podemos tomar un enfoque de NLP y medir la frecuencia de ciertos términos como *Solo*, *Business Traveller*, o *Family with young kids* ya que aplican para cada hotel, y tenerlo en cuenta en la recomendación.
Las etiquetas con frecuencia son (pero no siempre) un campo único que contiene una lista de 5 a 6 valores separados por coma que se alinean al *Tipo de viaje*, *Tipo de huésped*, *Tipo de habitación*, *Número de noches*, y *Tipo de dispositivo de revisión con el que se envió*. Sin embargo, ya que algunos críticos no llenan cada campo (pueden dejar uno en blanco), los valores no siempre aparecen en el mismo orden.
Como ejemplo toma el *Tipo de grupo*. Existen 1025 posibilidades únicas en este campo en la columna `Tags`, y desafortunadamente sólo algunos de ellos se refieren al grupo (algunos son de el tipo de habitación, etc.). Si filtras sólo aquellos que mencionan familia, los resultados contienen varios tipos de resultados *Family room*. Si incluyes el término *with*, esto es, cuenta los valores *Family with*, los resultados mejoran, con más de 80,000 de 515,000 resultados que contienen la frase "Family with young children" o "Family with older children".
Esto significa que la columna `Tags` no nos es completamente unútil, pero nos tomará algo de trabajo hacerla útil.
##### Puntaje promedio de hotel
Hay cierto número de rarezas o discrepancias con el conjunto de datos que no puedo comprender, pero se ilustran aquí para que estés al tanto de ello cuando construyes tus modelos. ¡Si las averiguas, por favor háznoslo saber en la sección de discusión!
El conjunto de datos tiene las siguientes columnas relacionadas al puntaje promedio y el número de reseñas:
1. Hotel_Name
2. Additional_Number_of_Scoring
3. Average_Score
4. Total_Number_of_Reviews
5. Reviewer_Score
El hotel con la mayor cantidad de reseñas de este conjunto de datos es *Britannia International Hotel Canary Wharf* con 4789 reseñas de 515,000. Pero si miramos el valor del `Total_Number_of_Reviews` para este hotel, es de 9086. Puedes suponer que hay mucho más puntaje sin las reseñas, así que quizá deberíamos agregar el valor de la columna `Additional_Number_of_Scoring`. Ese valor es 2682, y sumándolo a 4789 obtenemos 7,471 lo cual está 1615 por debajo de `Total_Number_of_Reviews`.
Si tomas la columna `Average_Score`, puedes suponer que es el promedio de las reseñas del conjunto de datos, pero la descripción de Kaggle es "*Average Score of the hotel, calculado basándose en el último comentario del último año*". Eso no parece ser tan útil, pero podemos calcular nuestro propio promedio basándonos en los puntajes de reseñas del conjunto de datos. Usando el mismo hotel como ejemplo, el puntaje promedio del hotel es 7,1 pero el puntaje calculado (el puntaje del crítico promedio *en* el conjunto de datos) es 6.8. Esto está cerca, pero no es el mismo valor, y sólo podemos adivinar que los puntajes dados en las reseñas de `Additional_Number_of_Scoring` incrementaron el promedio a 7.1. Desafortunadamente sin forma de probar o demostrar esa afirmación, es difícil usar o confiar en `Average_Score`, `Additional_Number_of_Scoring` y `Total_Number_of_Reviews` cuando se basan en, o se refieren a los datos que no tenemos.
Para complicar más las cosas, el hotel con el segundo número más alto de reseñas tiene un puntaje promedio calculado de 8.12 y el conjunto de datos `Average_Score` es de 8.1. ¿este puntaje es correcto o es una coincidencia o el primer hotel tiene una discrepancia?
En la posibilidad que estos hoteles puedan sea un caso atípico, y que tal vez la mayoría de los valores se sumen (pero algunos no por alguna razón), escribiremos un pequeño programa para explorar los valores en le conjunto de datos y determinar el uso correcto (o no uso) de los valores.
> 🚨 Una nota de advertencia
>
> Al trabajar con este conjunto de datos escribirás código que calcula algo a partir del texto sin tener que leer o analizar el texto por ti mismo. Esta es la esencia del procesamiento del lenguaje natural (NLP), el interpretar el significado o sentimiento sin tener que depender de un humano que lo haga. Sin embargo, es posible que leas algunas de las reseñas negativas. Te insisto no lo hagas, ya que no tienes porqué hacerlo. Algunas son tontas, o reseñas negativas irrelevantes del hotel, como "The weather wasn't great", algo fuera del control del hotel, o de hecho nada. Pero también hay un lado obscuro de algunas reseñas. En ocasiones, las reseñas negativas son racistas, sexistas o edadistas. Lo cual es desafortunado pero esperado e un conjunto de datos obtenido de un sitio web público. Algunos críticos dejan reseñas que encontrarás desagradables, incómodas o molestas. Es mejor dejar que el código mida el sentimiento en lugarde leerlo tú mismo y enfadarte. Dicho esto, es una minoría la que escribe esas cosas, pero existen de todas formas.
## Ejercicio - Exploración de datos
### Carga los datos
Ya es suficiente de examinar los datos de forma visual, ¡ahora escribirás algo de código para obtener algunas respuestas! Esta sección usa la biblioteca pandas. Tu primer tarea es asegurarte que puedes cargar y leer los datos del CSV. La biblioteca pandas tiene un cargador CSV rápido, y el resultado se coloca en un dataframe, como en lecciones anteriores. El CSV que estamos cargando tiene más de medio millón filas, pero sólo 17 columnas. Pandas te proporciona muchas formas poderosas de interactuar con un dataframe, incluyendo la capacidad de realizar operaciones en cada fila.
A partir de aquí en esta lección, habrá fragmentos de código y algunas explicaciones del mismo, además de algunas discusiones acerca de lo que significan los resultados. Usa el _notebook.ipynb_ incluido para tu código.
Empecemos cargando el archivo de datos que usarás:
```python
# Load the hotel reviews from CSV
import pandas as pd
import time
# importing time so the start and end time can be used to calculate file loading time
print("Loading data file now, this could take a while depending on file size")
start = time.time()
# df is 'DataFrame' - make sure you downloaded the file to the data folder
df = pd.read_csv('../../data/Hotel_Reviews.csv')
end = time.time()
print("Loading took " + str(round(end - start, 2)) + " seconds")
```
Ahora que se han cargado los datos, podemos realizar operaciones en ellos. Coloca este código al principio de tu programa para la siguiente parte.
## Explora los datos
En este caso, los datos ya se encuentranb *limpios*, lo cual significa que están listos para que trabajemos sobre ellos, y no contienen caracteres en otros idiomas que podrían entorpecer a los algoritmos que esperan únicamente caracteres en Inglés.
✅ Tendrás que trabajar con datos que requieren un procesamiento inicial para formatearlos antes de aplicar técnicas de NLP, pero no este vez. Si así fuera, ¿cómo manejarías los caracteres no pertenecientes al Inglés?
Dedica un momento a asegurarte que una vez se carguen los datos, puedes explorarlos con código. Es muy fácil querer enfocarte en las columnas `Negative_Review` y `Positive_Review`. Las cuales contienen texto natural para procesar por tus algoritmos de NLP. ¡Pero espera! Antes que comiences el procesamiento de lenguaje natural y sentimiento, deberías seguir el código siguiente para cerciorarte si los valores dados en el conjunto de datos coinciden con los valores que calculaste con pandas.
## Operaciones de dataframe
La primer tarea en esta lección es revisar si las siguientes afirmaciones son correctas al escribir algo de código que examine el dataframe (sin modificarlo).
> Como muchas tareas de programación, hay varias formas de completarla, pero un buen consejo es hacerlo de la forma más simple y fácil que puedas, especialmente si seŕa más fácil entenderla cuando volvamos a este código en el futuro. Con dataframes, hay una API eshaustiva que tendrá frecuentemente una forma de hacer lo que quieres de forma eficiente.
Trata las siguientes preguntas como tareas de programación e intenta responderlas sin mirar la solución.
1. Imprime la *forma* del dataframe que acabas de cargar (la forma es el número de filas y columnas)
2. Calcula el conteo de frecuencia para las nacionalidades de los críticos:
1. ¿Cuántos valores distintos existen para la columna `Reviewer_Nationality` y cuáles son?
2. ¿Cuál es la nacionalidad del crítico que es la más común en el conjunto de datos (imprime el país y el número de reseñas)?
3. ¿Cuáles son las 10 nacionalidades encontradas más frecuentemente, y el conteo de sus frecuencias?
3. ¿Cuál fue el hotel más frecuentemente reseñado por cada una del top 10 de nacionalidades de críticos?
4. ¿Cuántas reseñas hay por hotel (conteo de frecuencia de hotel) en el conjunto de datos?
5. Mientras que hay una columna `Average_Score` por cada hotel en el conjunto de datos, también puedes calcular un puntaje promedio (obteniendo el promedio de todos los puntajes de los críticos en el conjunto de datos para cada hotel). Agrega una nueva columna a tu dataframe con el encabezado `Calc_Average_Score` que contenga el promedio calculado.
6. ¿Algunos hoteles tienen el mismo `Average_Score` y `Calc_Average_Score` (redondeado a una posición decimal)?
1. Intenta escribir una función en Python que tome una Serie (fila) como argumento y compare los valores, imprimiendo el mensaje cuando los valores no son iguales. Luego, usa el método `.apply()` para procesar cada fila con la función.
7. Calcula e imprime cuántas filas tienen en la columna `Negative_Review` valores de "No Negative" .
8. Calcula e imprime cuántas filas tienen en la columna `Positive_Review` valores de "No Positive" .
9. Calcula e imprime cuántas filas tienen en la columna `Positive_Review` valores de "No Positive" **y** en la columna `Negative_Review` valores de "No Negative".
### Respuestas al código
1. Imprime la *forma* del dataframe que acabas de cargar (la forma es el número de filas y columnas).
```python
print("The shape of the data (rows, cols) is " + str(df.shape))
> The shape of the data (rows, cols) is (515738, 17)
```
2. Calcula el conteo de frecuencia para las nacionalidades de los críticos:
1. ¿Cuańtos valores distintos hay en la columna `Reviewer_Nationality` y cuáles son?
2. ¿Cuál es la nacionalidad más común para los críticos en el conjunto de datos (imprime el país y el número de reseñas)?
```python
# value_counts() creates a Series object that has index and values in this case, the country and the frequency they occur in reviewer nationality
nationality_freq = df["Reviewer_Nationality"].value_counts()
print("There are " + str(nationality_freq.size) + " different nationalities")
# print first and last rows of the Series. Change to nationality_freq.to_string() to print all of the data
print(nationality_freq)
```
```output
There are 227 different nationalities
United Kingdom 245246
United States of America 35437
Australia 21686
Ireland 14827
United Arab Emirates 10235
...
Comoros 1
Palau 1
Northern Mariana Islands 1
Cape Verde 1
Guinea 1
Name: Reviewer_Nationality, Length: 227, dtype: int64
```
3. ¿Cuáles son los siguientes 10 nacionalidades encontradas más frecuentemente, y su conteo de frecuencia?
```python
print("The highest frequency reviewer nationality is " + str(nationality_freq.index[0]).strip() + " with " + str(nationality_freq[0]) + " reviews.")
# Notice there is a leading space on the values, strip() removes that for printing
# What is the top 10 most common nationalities and their frequencies?
print("The next 10 highest frequency reviewer nationalities are:")
print(nationality_freq[1:11].to_string())
```
```output
The highest frequency reviewer nationality is United Kingdom with 245246 reviews.
The next 10 highest frequency reviewer nationalities are:
United States of America 35437
Australia 21686
Ireland 14827
United Arab Emirates 10235
Saudi Arabia 8951
Netherlands 8772
Switzerland 8678
Germany 7941
Canada 7894
France 7296
```
3. ¿Cuál fue el hotel mayormente reseñado para cada uno del top 10 de las nacionalidades de críticos?
```python
# What was the most frequently reviewed hotel for the top 10 nationalities
# Normally with pandas you will avoid an explicit loop, but wanted to show creating a new dataframe using criteria (don't do this with large amounts of data because it could be very slow)
for nat in nationality_freq[:10].index:
# First, extract all the rows that match the criteria into a new dataframe
nat_df = df[df["Reviewer_Nationality"] == nat]
# Now get the hotel freq
freq = nat_df["Hotel_Name"].value_counts()
print("The most reviewed hotel for " + str(nat).strip() + " was " + str(freq.index[0]) + " with " + str(freq[0]) + " reviews.")
```
```output
The most reviewed hotel for United Kingdom was Britannia International Hotel Canary Wharf with 3833 reviews.
The most reviewed hotel for United States of America was Hotel Esther a with 423 reviews.
The most reviewed hotel for Australia was Park Plaza Westminster Bridge London with 167 reviews.
The most reviewed hotel for Ireland was Copthorne Tara Hotel London Kensington with 239 reviews.
The most reviewed hotel for United Arab Emirates was Millennium Hotel London Knightsbridge with 129 reviews.
The most reviewed hotel for Saudi Arabia was The Cumberland A Guoman Hotel with 142 reviews.
The most reviewed hotel for Netherlands was Jaz Amsterdam with 97 reviews.
The most reviewed hotel for Switzerland was Hotel Da Vinci with 97 reviews.
The most reviewed hotel for Germany was Hotel Da Vinci with 86 reviews.
The most reviewed hotel for Canada was St James Court A Taj Hotel London with 61 reviews.
```
4. ¿Cuántas reseñas hay por hotel (conteo de frecuencia del hotel) en el conjunto de datos?
```python
# First create a new dataframe based on the old one, removing the uneeded columns
hotel_freq_df = df.drop(["Hotel_Address", "Additional_Number_of_Scoring", "Review_Date", "Average_Score", "Reviewer_Nationality", "Negative_Review", "Review_Total_Negative_Word_Counts", "Positive_Review", "Review_Total_Positive_Word_Counts", "Total_Number_of_Reviews_Reviewer_Has_Given", "Reviewer_Score", "Tags", "days_since_review", "lat", "lng"], axis = 1)
# Group the rows by Hotel_Name, count them and put the result in a new column Total_Reviews_Found
hotel_freq_df['Total_Reviews_Found'] = hotel_freq_df.groupby('Hotel_Name').transform('count')
# Get rid of all the duplicated rows
hotel_freq_df = hotel_freq_df.drop_duplicates(subset = ["Hotel_Name"])
display(hotel_freq_df)
```
| Hotel_Name | Total_Number_of_Reviews | Total_Reviews_Found |
| :----------------------------------------: | :---------------------: | :-----------------: |
| Britannia International Hotel Canary Wharf | 9086 | 4789 |
| Park Plaza Westminster Bridge London | 12158 | 4169 |
| Copthorne Tara Hotel London Kensington | 7105 | 3578 |
| ... | ... | ... |
| Mercure Paris Porte d Orleans | 110 | 10 |
| Hotel Wagner | 135 | 10 |
| Hotel Gallitzinberg | 173 | 8 |
Has notado que los resultados de los *contados en el conjunto de datos* no coinciden con el valor en `Total_Number_of_Reviews`. No está claro si este valor en el conjunto de datos representó el número total de reseñas que tuvo el hotel, pero no fueron extraídas, o algún otro cálculo. La columna `Total_Number_of_Reviews`no se usa en el modelo porque no es del todo clara.
5. Mientras que hay una columna `Average_Score` para cada hotel en el conjunto de datos, también puedes calcular un puntaje promedio (obteniendo el promedio de todos los puntajes de los críticos en el conjunto de datos para cada hotel). Agrega una nueva columna a tu dataframe con el encabezado `Calc_Average_Score` que contenga dicho promedio calculado. Imprime las columnas `Hotel_Name`, `Average_Score`, y `Calc_Average_Score`.
```python
# define a function that takes a row and performs some calculation with it
def get_difference_review_avg(row):
return row["Average_Score"] - row["Calc_Average_Score"]
# 'mean' is mathematical word for 'average'
df['Calc_Average_Score'] = round(df.groupby('Hotel_Name').Reviewer_Score.transform('mean'), 1)
# Add a new column with the difference between the two average scores
df["Average_Score_Difference"] = df.apply(get_difference_review_avg, axis = 1)
# Create a df without all the duplicates of Hotel_Name (so only 1 row per hotel)
review_scores_df = df.drop_duplicates(subset = ["Hotel_Name"])
# Sort the dataframe to find the lowest and highest average score difference
review_scores_df = review_scores_df.sort_values(by=["Average_Score_Difference"])
display(review_scores_df[["Average_Score_Difference", "Average_Score", "Calc_Average_Score", "Hotel_Name"]])
```
También te preguntarás aceca de el valor de `Average_Score` y por qué algunas veces es diferente del puntaje promedio calculado. Como no podemos saber por qué algunos de los valores coinciden, pero otros difieren, en esta situación lo más seguro es usar los puntajes de reseñas que tenemos para calcular el promedio por nosotros mismos. Dicho esto, las diferencias suelen ser mínimas, aquí tienes los hoteles con la mayor desviación del promedio del conjunto de datos y el promedio calculado:
| Average_Score_Difference | Average_Score | Calc_Average_Score | Hotel_Name |
| :----------------------: | :-----------: | :----------------: | ------------------------------------------: |
| -0.8 | 7.7 | 8.5 | Best Western Hotel Astoria |
| -0.7 | 8.8 | 9.5 | Hotel Stendhal Place Vend me Paris MGallery |
| -0.7 | 7.5 | 8.2 | Mercure Paris Porte d Orleans |
| -0.7 | 7.9 | 8.6 | Renaissance Paris Vendome Hotel |
| -0.5 | 7.0 | 7.5 | Hotel Royal Elys es |
| ... | ... | ... | ... |
| 0.7 | 7.5 | 6.8 | Mercure Paris Op ra Faubourg Montmartre |
| 0.8 | 7.1 | 6.3 | Holiday Inn Paris Montparnasse Pasteur |
| 0.9 | 6.8 | 5.9 | Villa Eugenie |
| 0.9 | 8.6 | 7.7 | MARQUIS Faubourg St Honor Relais Ch teaux |
| 1.3 | 7.2 | 5.9 | Kube Hotel Ice Bar |
Con sólo 1 hotel que tiene un diferencia de puntaje mayor a 1, esto significa que probablemente podemos ignorar la diferencia y usar el puntaje promedio calculado.
6. Calcula e imprime cuántas filas tienen en la columna `Negative_Review` valores de "No Negative"
7. Calcula e imprime cuántas filas tienen en la columna `Positive_Review` valores de "No Positive"
8. Calcula e imprime cuántas filas tienen en la columna `Positive_Review` valores de "No Positive" **y** en la columna `Negative_Review` valores de "No Negative"
```python
# with lambdas:
start = time.time()
no_negative_reviews = df.apply(lambda x: True if x['Negative_Review'] == "No Negative" else False , axis=1)
print("Number of No Negative reviews: " + str(len(no_negative_reviews[no_negative_reviews == True].index)))
no_positive_reviews = df.apply(lambda x: True if x['Positive_Review'] == "No Positive" else False , axis=1)
print("Number of No Positive reviews: " + str(len(no_positive_reviews[no_positive_reviews == True].index)))
both_no_reviews = df.apply(lambda x: True if x['Negative_Review'] == "No Negative" and x['Positive_Review'] == "No Positive" else False , axis=1)
print("Number of both No Negative and No Positive reviews: " + str(len(both_no_reviews[both_no_reviews == True].index)))
end = time.time()
print("Lambdas took " + str(round(end - start, 2)) + " seconds")
```
```output
Number of No Negative reviews: 127890
Number of No Positive reviews: 35946
Number of both No Negative and No Positive reviews: 127
Lambdas took 9.64 seconds
```
## Otra forma de hacerlo
Otra forma de contar los elementos sin usar Lambdas, y usar la suma para contar las filas:
```python
# without lambdas (using a mixture of notations to show you can use both)
start = time.time()
no_negative_reviews = sum(df.Negative_Review == "No Negative")
print("Number of No Negative reviews: " + str(no_negative_reviews))
no_positive_reviews = sum(df["Positive_Review"] == "No Positive")
print("Number of No Positive reviews: " + str(no_positive_reviews))
both_no_reviews = sum((df.Negative_Review == "No Negative") & (df.Positive_Review == "No Positive"))
print("Number of both No Negative and No Positive reviews: " + str(both_no_reviews))
end = time.time()
print("Sum took " + str(round(end - start, 2)) + " seconds")
```
```output
Number of No Negative reviews: 127890
Number of No Positive reviews: 35946
Number of both No Negative and No Positive reviews: 127
Sum took 0.19 seconds
```
Quizá hayas notado que hay 127 filas que tienen valores tanto "No Negative" como "No Positive" para las columnas `Negative_Review` y `Positive_Review` respectivamente. Lo cual significa que los críticos le dieron al hotel un puntaje numérico, pero se negaron a escribir tanto una reseña positiva como negativa. Afortunadamente este es un número pequeño de filas (127 de 515738, o 0.02%), así que probablemente no sesgará nuestro modelo o los resultados en alguna dirección en particular, pero podrías no haber esperado que un conjunto de datos de reseñas tenga filas sin reseñas, por lo que vale la pena explorar los datos para descubrir filas como esta.
Ahora que has explorado el conjunto de datos, en la próxima lección filtrarás los datos y agregarás algo de análisis de sentimiento.
---
## 🚀Desafío
Esta lección demuestra, como vimos en lecciones anteriores, qué tan críticamente importante es entender tus datos y sus imperfecciones antes de realizar operaciones sobre ellos. Los datos basados en texto, requieren particularmente un minucioso escrutinio. Profundiza en grandes conjuntos de datos basados en texto y ve si puedes descubrir áreas que podrían presentar sesgos o sentimientos sesgados en un modelo.
## [Examen posterior a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/38/)
## Revisión y autoestudio
Toma [esta ruta de aprendizaje de NLP](https://docs.microsoft.com/learn/paths/explore-natural-language-processing/?WT.mc_id=academic-15963-cxa) para descubrir herramientas a probar al construir modelos de voz y de gran cantidad de datos.
## Asignación
[NLTK](assignment.es.md)

@ -0,0 +1,5 @@
# NLTK
## Instrucciones
NLTK es una biblioteca bien conocida para su uso en lingüística computacional y NLP. Toma esta oportunidad para leer el '[libro NLTK](https://www.nltk.org/book/)' y prueba sus ejercicios. En esta asignación sin ponderación, conocerás esta biblioteca más a fondo.

@ -0,0 +1,376 @@
# Análisis de sentimiento con reseñas de hoteles
Ahora que has explorado a detalle el conjunto de datos, es momento de filtrar las columnas y luego usar técnicas de procesamiento del lenguaje natural sobre el conjunto de datos para obtener nuevos conocimientos acerca de los hoteles.
## [Examen previo a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/39/)
### Filtrado y operaciones de análisis de sentimiento
Como quizá ya has notado, el conjunto de datos presenta unos cuantos problemas. Algunas columnas contienen información inútil, otras parecen incorrectas. Si estas son correctas, no está claro cómo fueron calculadas, y las respuestas no pueden verificarse de forma independiente al realizar nuestros propios cálculos.
## Ejercicio: un poco más de procesamiento de datos
Limpia un poco más los datos. Agrega las columnas que usaremos más tarde, cambia los valores en otras columnas y elimina completamente ciertas columnas.
1. Procesamiento inicial de columnas
1. Elimina `lat` y `lng`
2. Reemplaza los valores de `Hotel_Address` con los siguientes valores (si la dirección contiene lo mismo que la ciudad y el país, cámbialo sólo a la ciudad y el país).
Estas son las únicas ciudades y países en el conjunto de datos:
Amsterdam, Netherlands
Barcelona, Spain
London, United Kingdom
Milan, Italy
Paris, France
Vienna, Austria
```python
def replace_address(row):
if "Netherlands" in row["Hotel_Address"]:
return "Amsterdam, Netherlands"
elif "Barcelona" in row["Hotel_Address"]:
return "Barcelona, Spain"
elif "United Kingdom" in row["Hotel_Address"]:
return "London, United Kingdom"
elif "Milan" in row["Hotel_Address"]:
return "Milan, Italy"
elif "France" in row["Hotel_Address"]:
return "Paris, France"
elif "Vienna" in row["Hotel_Address"]:
return "Vienna, Austria"
# Replace all the addresses with a shortened, more useful form
df["Hotel_Address"] = df.apply(replace_address, axis = 1)
# The sum of the value_counts() should add up to the total number of reviews
print(df["Hotel_Address"].value_counts())
```
Ahora puedes consultar datos a nivel de país:
```python
display(df.groupby("Hotel_Address").agg({"Hotel_Name": "nunique"}))
```
| Hotel_Address | Hotel_Name |
| :--------------------- | :--------: |
| Amsterdam, Netherlands | 105 |
| Barcelona, Spain | 211 |
| London, United Kingdom | 400 |
| Milan, Italy | 162 |
| Paris, France | 458 |
| Vienna, Austria | 158 |
2. Procesa las columnas Hotel Meta-review
1. Elimina `Additional_Number_of_Scoring`
1. Reemplaza `Total_Number_of_Reviews` con el número total de reseñas para ese hotel que realmente están en el conjunto de datos
1. Reemplaza `Average_Score` con nuestros propio puntaje calculado
```python
# Drop `Additional_Number_of_Scoring`
df.drop(["Additional_Number_of_Scoring"], axis = 1, inplace=True)
# Replace `Total_Number_of_Reviews` and `Average_Score` with our own calculated values
df.Total_Number_of_Reviews = df.groupby('Hotel_Name').transform('count')
df.Average_Score = round(df.groupby('Hotel_Name').Reviewer_Score.transform('mean'), 1)
```
3. Procesa las columnas review
1. Elimina `Review_Total_Negative_Word_Counts`, `Review_Total_Positive_Word_Counts`, `Review_Date` y `days_since_review`
2. Conserva `Reviewer_Score`, `Negative_Review`, y `Positive_Review` tal cual están,
3. Conserva `Tags` por ahora
- Realizaremos operaciones de filtrado adicionales sobre las etiquetas en la siguiente lección y luego se eliminarán etiquetas
4. Procesa las columnas reviewer
1. Elimina `Total_Number_of_Reviews_Reviewer_Has_Given`
2. Conserva `Reviewer_Nationality`
### Columnas de etiqueta (Tag)
La columna `Tag` es problemática ya que está almacenada como lista (en forma de texto) en la columna. Desafortunadamente el orden y número de subsecciones es esta columna no son siempre los mismos. Es difícil para un humano el identificar las frases correctas en las que estar interesado, ya que hay 515,000 filas, y 1427 hoteles, y cada uno tiene opciones ligeramente diferentes que un crítico podría elegir. Aquí es donde destaca el procesamiento del lenguaje natural. Puedes escanear texto y encontrar las frases más comunes, y contarlas.
Desafortunadamente, no estamos interesados en palabras simples, sino en frases multi-palabra (por ejemplo, *Business trip*). Ejecutar un algoritmo de distribución de frecuencia multi-palabra sobre tantos datos (6762646 palabras) podría tomar un largo período de tiempo, pero sin mirar los datos, estos parecería que es un gasto necesario. Aquí es donde el análisis exploratorio de datos es útil, porque ya has visto una muestra de estas etiquetas tales como `[' Business trip ', ' Solo traveler ', ' Single Room ', ' Stayed 5 nights ', ' Submitted from a mobile device ']` , puedes empezar a preguntar si es posible reducir ampliamente el procesamiento que tienes que hacer. Afortunadamente, así es - pero primero necesitas seguir algunos pasos para determinar las etiquetas de interés.
### Filtrar las etiquetas
Recuerda que el objetivo de los conjuntos de datos es agregar sentimiento y columnas que nos ayudarán a elegir el mejor hotel (para ti o quizá un cliente te pidió realizar un bot de recomendación de hoteles). Necesitas preguntarte si la etiquetas son útiles o no en el conjunto de datos final. Aquí hay una interpretación (si necesitabas el conjunto de datos por otras razones, distintas etiquetas podrían permanecer dentro/fuera de la selección):
1. El tipo de viaje es relevante, y así debería seguir
2. El tipo de grupo de huéspedes es importante, y así debería seguir
3. El tipo de cuarto, suite o estudio en que se quedó el huésped es irrelevante (todos los hoteles tienen básicamente los mismos cuartos)
4. El dispositivo desde el cual se envió la reseña es irrelevante
5. El número de noches que se hospedó el crítico *podría* ser relevante si atribuiste a las estancias largas con mayor gusto por el hotel, pero es exagerado, y probablemente irrelevante
En resumen, **conserva 2 tipos de etiquetas y elimina el resto**.
Primero, no quieres contar las etiquetas hasta que estén en un mejor formato, lo cual significa eliminar los corchetes y comillas. Puedes hacerlo de varias formas, pero quieres la más rápida ya que podría tomar un largo tiempo el procesar demasiados datos. Afortunadamente, pandas tiene una forma fácil de hacer cada uno de estos pasos.
```Python
# Remove opening and closing brackets
df.Tags = df.Tags.str.strip("[']")
# remove all quotes too
df.Tags = df.Tags.str.replace(" ', '", ",", regex = False)
```
Cada etiqueta se convierte en algo así: `Business trip, Solo traveler, Single Room, Stayed 5 nights, Submitted from a mobile device`.
Ahora encontramos un problema. Algunas reseñas o filas tienen 5 columnas, algunas 3, otras 6. Esto es resultado de cómo se creó el conjunto de datos, y es difícil de corregir. Quieres obtener un conteo de frecuencia de cada frase, pero están en distinto orden en cada reseña, ya que el conteo podría estar apagado y un hotel podría no obtener una etiqueta asignada como lo merece.
En su lugar, usarás el orden distinto a tu favor, ¡porque cada etiqueta es multi-palabra pero también está separada por una coma! La forma más simple de hacerlo es crear 6 columnas temporales con cada etiqueta insertada en la columna correspondiente a su orden en la etiqueta. Luego puedes unir las 6 columnas en una sola y ejecutar el método `value_counts()` en la columna resultante. Imprímelo, verás que había 2428 etiquetas únicas. Aquí una pequeña muestra:
| Tag | Count |
| ------------------------------ | ------ |
| Leisure trip | 417778 |
| Submitted from a mobile device | 307640 |
| Couple | 252294 |
| Stayed 1 night | 193645 |
| Stayed 2 nights | 133937 |
| Solo traveler | 108545 |
| Stayed 3 nights | 95821 |
| Business trip | 82939 |
| Group | 65392 |
| Family with young children | 61015 |
| Stayed 4 nights | 47817 |
| Double Room | 35207 |
| Standard Double Room | 32248 |
| Superior Double Room | 31393 |
| Family with older children | 26349 |
| Deluxe Double Room | 24823 |
| Double or Twin Room | 22393 |
| Stayed 5 nights | 20845 |
| Standard Double or Twin Room | 17483 |
| Classic Double Room | 16989 |
| Superior Double or Twin Room | 13570 |
| 2 rooms | 12393 |
Algunas de las etiquetas comunes como `Submitted from a mobile device` no nos son útiles, por lo que podría ser una buena idea quitarlas antes de contar la ocurrencia de las frases, pero es una operación tan rápida que puedes dejarlos e ignorarlos.
### Eliminando la longitud de las etiquetas de estadía
Eliminar estas etiquetas es el paso 1, reduce levemente el número total de etiquetas a ser consideradas. Nota que no las eliminas del conjunto de datos, sólo eliges eliminarlas de la consideración de valores a contar/mantener en el conjunto de datos de reseñas.
| Length of stay | Count |
| ---------------- | ------ |
| Stayed 1 night | 193645 |
| Stayed 2 nights | 133937 |
| Stayed 3 nights | 95821 |
| Stayed 4 nights | 47817 |
| Stayed 5 nights | 20845 |
| Stayed 6 nights | 9776 |
| Stayed 7 nights | 7399 |
| Stayed 8 nights | 2502 |
| Stayed 9 nights | 1293 |
| ... | ... |
Existe una gran variedad de cuartos, suites, studios, departamentos, y así sucesivamente. Estos significan casi lo mismo y no te son relevantes, así que elimínalos de consideración.
| Type of room | Count |
| ----------------------------- | ----- |
| Double Room | 35207 |
| Standard Double Room | 32248 |
| Superior Double Room | 31393 |
| Deluxe Double Room | 24823 |
| Double or Twin Room | 22393 |
| Standard Double or Twin Room | 17483 |
| Classic Double Room | 16989 |
| Superior Double or Twin Room | 13570 |
Finalmente, y esto es placentero (porque no requirió casi nada de procesamiento), te quedarás con las siguientes etiquetas *útiles*:
| Tag | Count |
| --------------------------------------------- | ------ |
| Leisure trip | 417778 |
| Couple | 252294 |
| Solo traveler | 108545 |
| Business trip | 82939 |
| Group (combined with Travellers with friends) | 67535 |
| Family with young children | 61015 |
| Family with older children | 26349 |
| With a pet | 1405 |
Podrías argumentar que `Travellers with friends` es casi lo mismo que `Group`, y sería justo combinar las dos de arriba. El código para identificar las etiquetas correctas es [el notebook de Etiquetas](../solution/1-notebook.ipynb).
El último paso es crear nuevas columnas para cada una de estas etiquetas. Luego, para cada fila de reseña, si la columna `Tag` coincide con una de las nuevas columnas, agrega un 1, si no es así, agrega un 0. El resultado final será un conteo de cuántos críticos eligieron este hotel (en agregado), digamos, para negocios vs ocio, o para traer mascota, y esta es información útil al recomendar un hotel.
```python
# Process the Tags into new columns
# The file Hotel_Reviews_Tags.py, identifies the most important tags
# Leisure trip, Couple, Solo traveler, Business trip, Group combined with Travelers with friends,
# Family with young children, Family with older children, With a pet
df["Leisure_trip"] = df.Tags.apply(lambda tag: 1 if "Leisure trip" in tag else 0)
df["Couple"] = df.Tags.apply(lambda tag: 1 if "Couple" in tag else 0)
df["Solo_traveler"] = df.Tags.apply(lambda tag: 1 if "Solo traveler" in tag else 0)
df["Business_trip"] = df.Tags.apply(lambda tag: 1 if "Business trip" in tag else 0)
df["Group"] = df.Tags.apply(lambda tag: 1 if "Group" in tag or "Travelers with friends" in tag else 0)
df["Family_with_young_children"] = df.Tags.apply(lambda tag: 1 if "Family with young children" in tag else 0)
df["Family_with_older_children"] = df.Tags.apply(lambda tag: 1 if "Family with older children" in tag else 0)
df["With_a_pet"] = df.Tags.apply(lambda tag: 1 if "With a pet" in tag else 0)
```
### Guarda tu archivo
Finalmente, guarda el conjunto de datos tal cual se encuentra ahora con un nuevo nombre.
```python
df.drop(["Review_Total_Negative_Word_Counts", "Review_Total_Positive_Word_Counts", "days_since_review", "Total_Number_of_Reviews_Reviewer_Has_Given"], axis = 1, inplace=True)
# Saving new data file with calculated columns
print("Saving results to Hotel_Reviews_Filtered.csv")
df.to_csv(r'../data/Hotel_Reviews_Filtered.csv', index = False)
```
## Operaciones de análisis de sentimiento
En esta sección final, aplicarás análisis de sentimiento a las columnas de reseña y guardarás los resultados en un conjunto de datos.
## Ejercicio: Carga y guarda los datos filtrados
Nota que ahora estás cargando el conjunto de datos filtrado que fue guardado en la sección anterior, **no** el conjunto de datos original.
```python
import time
import pandas as pd
import nltk as nltk
from nltk.corpus import stopwords
from nltk.sentiment.vader import SentimentIntensityAnalyzer
nltk.download('vader_lexicon')
# Load the filtered hotel reviews from CSV
df = pd.read_csv('../../data/Hotel_Reviews_Filtered.csv')
# You code will be added here
# Finally remember to save the hotel reviews with new NLP data added
print("Saving results to Hotel_Reviews_NLP.csv")
df.to_csv(r'../data/Hotel_Reviews_NLP.csv', index = False)
```
### Eliminando stop words
Si fueses a ejecutar el análisis de sentimiento en las columnas de reseñas positivas y negativas, te llevaría mucho tiempo. Al probarlo en un laptop de pruebas poderosa con una CPU rápida, tomó de 12 - 14 minutos dependiendo en qué biblioteca de sentimientos fue usada. Eso es demasiado tiempo (relativamente), por lo que vale la pena investigar si se puede acelerar.
Eliminar stop words, o palabras comunes del Inglés que no cambian el sentimiento de una oración, es el primer paso. Al eliminarlas, el análisis de sentimiento debería ejecutarse más rápido, pero no sería menos preciso (ya que las stop words no afectan el sentimiento, pero sí ralentizan el análisis).
La reseña negativa más larga fue de 395 palabras, pero después de eliminar las stop words, es de 195 palabras.
Eliminar las stops words también es una operación rápida, remover las stop words de 2 columnas de reseñas de 515,000 filas tomó 3.3 segundos en el dispositivo de prueba, Podría tomar ligeramente más o menos tiempo dependiendo de la velocidad del CPU de tu dispositivo, la RAM, si tienes un disco de estado sólido o no, entre otros factores. La relatividad de corto período de operación significa que si se mejora el tiempo de análisis de sentimiento, entonces vale la pena hacerlo.
```python
from nltk.corpus import stopwords
# Load the hotel reviews from CSV
df = pd.read_csv("../../data/Hotel_Reviews_Filtered.csv")
# Remove stop words - can be slow for a lot of text!
# Ryan Han (ryanxjhan on Kaggle) has a great post measuring performance of different stop words removal approaches
# https://www.kaggle.com/ryanxjhan/fast-stop-words-removal # using the approach that Ryan recommends
start = time.time()
cache = set(stopwords.words("english"))
def remove_stopwords(review):
text = " ".join([word for word in review.split() if word not in cache])
return text
# Remove the stop words from both columns
df.Negative_Review = df.Negative_Review.apply(remove_stopwords)
df.Positive_Review = df.Positive_Review.apply(remove_stopwords)
```
### Realizando análisis de sentimiento
Ahora deberías calcular el análisis de sentimiento tanto para las columnas de reseñas positivas como negativas y almacenar el resultado en 2 nuevas columnas. La prueba del sentimiento será compararlo con el puntaje del crítico para la misma reseña. Por ejemplo, si el sentimiento piensa que la reseña negativa tuvo un sentimiento de 1 (sentimiento extremadamente positivo) y un sentimiento de reseña positiva de 1, pero el crítico le dió al hotel el puntaje más bajo posible, luego que el texto de la reseña no coincide con el puntaje o el analizador de sentimiento no pudo reconocer el sentimiento de forma correcta. Deberías esperar que algunos puntajes de sentimiento sean completamente erróneos, y a menudo será explicable, por ejemplo, la reseña podría ser extremadamente sarcástica "Of course I LOVED sleeping in a room with no heating" y el analizador de sentimiento piensa que es un sentimiento positivo, aunque un humano leyéndolo sabría que fue sarcasmo.
NLTK provee distintos analizadores de sentimiento con los cuales aprender, y puedes sustituirlos y así ver si el sentimiento es más o menos preciso. El análisis de sentimiento VADER se usó aquí.
> Hutto, C.J. & Gilbert, E.E. (2014). VADER: A Parsimonious Rule-based Model for Sentiment Analysis of Social Media Text. Eighth International Conference on Weblogs and Social Media (ICWSM-14). Ann Arbor, MI, June 2014.
```python
from nltk.sentiment.vader import SentimentIntensityAnalyzer
# Create the vader sentiment analyser (there are others in NLTK you can try too)
vader_sentiment = SentimentIntensityAnalyzer()
# Hutto, C.J. & Gilbert, E.E. (2014). VADER: A Parsimonious Rule-based Model for Sentiment Analysis of Social Media Text. Eighth International Conference on Weblogs and Social Media (ICWSM-14). Ann Arbor, MI, June 2014.
# There are 3 possibilities of input for a review:
# It could be "No Negative", in which case, return 0
# It could be "No Positive", in which case, return 0
# It could be a review, in which case calculate the sentiment
def calc_sentiment(review):
if review == "No Negative" or review == "No Positive":
return 0
return vader_sentiment.polarity_scores(review)["compound"]
```
Después en tu programa cuando estés listo para calcular el sentimiento, puedes aplicarlo a ca reseña como sigue:
```python
# Add a negative sentiment and positive sentiment column
print("Calculating sentiment columns for both positive and negative reviews")
start = time.time()
df["Negative_Sentiment"] = df.Negative_Review.apply(calc_sentiment)
df["Positive_Sentiment"] = df.Positive_Review.apply(calc_sentiment)
end = time.time()
print("Calculating sentiment took " + str(round(end - start, 2)) + " seconds")
```
Esto toma aproximadamente 120 segundos en mi computadora, pero varía en cada equipo. Si quieres imprimir los resultados y ver si el sentimiento coincide con la reseña:
```python
df = df.sort_values(by=["Negative_Sentiment"], ascending=True)
print(df[["Negative_Review", "Negative_Sentiment"]])
df = df.sort_values(by=["Positive_Sentiment"], ascending=True)
print(df[["Positive_Review", "Positive_Sentiment"]])
```
¡Lo último por hacer con el archivo antes de usarlo en el desafío, es guardarlo! También deberías considerar reordenar todas tus nuevas columnas para que sean fáciles de usar (para un humano, es un cambio cosmético).
```python
# Reorder the columns (This is cosmetic, but to make it easier to explore the data later)
df = df.reindex(["Hotel_Name", "Hotel_Address", "Total_Number_of_Reviews", "Average_Score", "Reviewer_Score", "Negative_Sentiment", "Positive_Sentiment", "Reviewer_Nationality", "Leisure_trip", "Couple", "Solo_traveler", "Business_trip", "Group", "Family_with_young_children", "Family_with_older_children", "With_a_pet", "Negative_Review", "Positive_Review"], axis=1)
print("Saving results to Hotel_Reviews_NLP.csv")
df.to_csv(r"../data/Hotel_Reviews_NLP.csv", index = False)
```
Deberías ejecutar el código completo del [notebook de análisis](../solution/3-notebook.ipynb) (después de que hayas ejecutado [tu notebook de filtrado](../solution/1-notebook.ipynb) para generar el archivo Hotel_Reviews_Filtered.csv).
Para revisar, los pasos son:
1. Se exploró el archivo original del conjunto de datos **Hotel_Reviews.csv** en la lección anterior con [el notebook explorador](../../4-Hotel-Reviews-1/solution/notebook.ipynb)
2. Se filtró Hotel_Reviews.csv con [el notebook de filtrado](../solution/1-notebook.ipynb) resultando el archivo **Hotel_Reviews_Filtered.csv**
3. Se procesó Hotel_Reviews_Filtered.csv con [el notebook de análisis de sentimiento](../solution/3-notebook.ipynb) obteniendo como resultado **Hotel_Reviews_NLP.csv**
4. Usa Hotel_Reviews_NLP.csv en el desafío NLP de abajo
### Conclusión
Cuando iniciaste, tenías un conjunto de datos con columnas y datos pero no todos ello podían ser verificados o usados. Exploraste los datos, filtraste lo que no necesitas, convertiste etiquetas en algo útil, calculaste tus propios promedios, agregaste algunas columnas de sentimiento y espero hayas aprendido cosas interesantes acerca de procesar texto natural.
## [Examen posterior a la lección](https://white-water-09ec41f0f.azurestaticapps.net/quiz/40/)
## Desafío
Ahora que tienes tu conjunto de datos analizado por sentimiento, observa si puedes usar las estrategias que aprendiste en este plan de estudios (agrupamiento, ¿quizá?) para determinar patrones alrededor del sentimiento.
## Revisión y autoestudio
Toma [este módulo de aprendizaje](https://docs.microsoft.com/en-us/learn/modules/classify-user-feedback-with-the-text-analytics-api/?WT.mc_id=academic-15963-cxa) para aprender más y usar distintas herramientas para explorar el sentimiento en el texto.
## Asignación
[Prueba distintos conjuntos de datos](assignment.es.md)

@ -0,0 +1,11 @@
# Prueba un conjunto de datos diferente
## Instrucciones
Ahora que has aprendido acerca del uso de NLTK para asignar sentimiento al texto, prueba un conjunto de datos diferente. Probablemente necesitarás hacer algo más de procesamiento de datos, por lo cual, crear un notebook y documenta tu proceso de pensamiento. ¿Qué descubriste?
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | ---------------------- |
| | Se presentó tanto un notebook como un conjunto de datos con celdas bien documentadas explicando cómo se asignó el sentimiento | Al notebook le faltan buenas explicaciones | El notebook es defectuoso |

@ -0,0 +1,24 @@
# Primeros pasos con el procesamiento de lenguaje natural
El procesamiento de lenguaje natural (NLP) es la capacidad que tiene un programa de computadora para entender el lenguaje humano como se habla y escribe -- referido como lenguaje natural. Es un componente de la inteligencia artificial (AI). NLP ha existido por más de 50 años y tiene raíces en el campo de la lingüística. Todo el campo está dirigido a ayudar a las máquinas a entender y rpocesar el lenguaje humano. Este luego puede ser usado para realizar tareas como corrección ortográfica o traducción automática. Tiene una variedad de apliciones en el mundo real en un número de campos, incluyendo investigación médica, motores de búsqueda e inteligencia de negocios.
## Tema regional: Los idiomas y literatura europeos y hoteles románticos de Europa ❤️
En esta sección del plan de estudios, se te presentará una de los usos mayormente difundidos del aprendizaje automático: procesamiento del lenguaje natural (NLP). Derivado de la lingüística computacional, esta categoría de inteligencia artificial es el puente entre humanos y máquinas vía comunicación por voz o texto.
En estas lecciones aprenderás las bases del NLP al construir pequeños bots de conversación par aprender como el aprendizaje automático ayuda en hacer estas conversaciones más y más 'inteligentes'. Viajarás tiempo atrás, charlando con Elizabeth Bennett y Mr. Darcy de la novela clásica de Jane Austen, **Orgullo y Prejuico**, publicado 1813. Luego, ampliarás tus conocimientos al aprender acerca de análisis de los sentimientos vía reseñas de hoteles en Europa.
![Libro Orgullo y Prejuicio y té](../images/p&p.jpg)
> Fotografía de <a href="https://unsplash.com/@elaineh?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Elaine Howlin</a> en <a href="https://unsplash.com/s/photos/pride-and-prejudice?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>
## Lecciones
1. [Introducción al procesamiento del lenguaje natural](../1-Introduction-to-NLP/README.md)
2. [Tareas y técnicas comunes de NLP](../2-Tasks/README.md)
3. [Traducción y análisis de sentimiento con aprendizaje automático](../3-Translation-Sentiment/README.md)
4. [Preparando tus datos](../4-Hotel-Reviews-1/README.md)
5. [NLTK para análisis de sentimiento](../5-Hotel-Reviews-2/README.md)
## Créditos
Estas lecciones de procesamiento del lenguaje natural fueron escritas con ☕ por [Stephen Howell](https://twitter.com/Howell_MSFT)

@ -0,0 +1,11 @@
# Visualiza algunas series de tiempo más
## Instrucciones
Has comenzado a aprender acerca de la predicción de series de tiempo al mirar el tipo de datos que requiere este modelado especial. Ya has visualizado algunos datos referentes a la energía. Ahora, busca otros datos que te beneficiarían de la predicción de series de tiempo. Encuentra tres ejemplos (prueba [Kaggle](https://kaggle.com) y [Azure Open Datasets](https://azure.microsoft.com/en-us/services/open-datasets/catalog/?WT.mc_id=academic-15963-cxa)) y crea un notebook para visualizarlos. Anota cualquier característica especial que tengan (estacionalidad, cambios abruptos, u otras tendencias) en el notebook.
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | ------------------------------------------------------ | ---------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| | Se graficaron y explicaron tres conjuntos de datos en un notebook | Se graficaron y explicaron dos conjuntos de datos en un notebook | Se graficaron y explicaron pocos conjuntos de datos en un notebook o los datos presentados fueron insuficientes |

@ -0,0 +1,11 @@
# Un nuevo modelo ARIMA
## Instrucciones
Ahora que has construido un modelo de ARIMA, construye uno nuevo con datos frescos (prueba uno de [estos conjuntos de datos de Duke](http://www2.stat.duke.edu/~mw/ts_data_sets.html)). Anota tu trabajo en un notebook, visualiza los datos y tu modelo, y prueba su precisión usando MAPE.
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | ------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ----------------------------------- |
| | Se presentó un notebook con nuevo modelo de ARIMA construido, probado y explicado con visualizaciones y precisión declarada. | El notebook presentado no está anotado o contiene bugs | Se presentó un notebook incompleto |

@ -0,0 +1,13 @@
# Un nuevo modelo SVR
## Instrucciones [^1]
Ahora que has construido un modelo SVR, construye uno nuevo con datos frescos (prueba uno de [estos conjuntos de datos de Duke](http://www2.stat.duke.edu/~mw/ts_data_sets.html)). Anota tu trabajo en un notebook. Visualiza los datos y tu modelo, y prueba su precisión usando MAPE y gráficos apropiados. También prueba ajustando distintos hiperparámetros y valores para los pasos de tiempo.
## Rúbrica [^1]
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | ------------------------------------------------------------ | --------------------------------------------------------- | ----------------------------------- |
| | Se presentó un notebook on un modelo SVR construido, probado y explicado con visualizaciones y precisión declarada. | El notebook presentado no está anotado o contiene errores. | Se presentó un notebook incompleto. |
[^1]:El texto en esta sección se basó en la [asignación de ARIMA](https://github.com/microsoft/ML-For-Beginners/tree/main/7-TimeSeries/2-ARIMA/assignment.md)

@ -0,0 +1,23 @@
# Introducción a la predicción de series de tiempo
¿Qué es la predicción de series de tiempo? Se trata de predecir eventos futuros al analizar las tendencias del pasado.
## Tema regional: Uso de la electricidad en el mundo ✨
En estas dos lecciones, se te presentará la predicción de series de tiempo, un área algo menos conocida del aprendizaje automático que sin embargo es extremadamente valiosa para la industria y aplicaciones empresariales, entre otros campos. Mientras las redes neuronales pueden ser usadas para mejorar la utilidad de estos modelos, las estudiaremos en el contexto del aprendizaje automático clásico como modelos que ayudan a predecir el desempeño futuro basado en el pasado.
Nuestro enfoque regional es el uso de la electricidad en el mundo, un conjunto de datos interesante para aprender a predecir el uso de la energía a futuro basado en patrones de cargas pasadas. Puedes ver cómo esta clase de predicción puede ser extremadamente útil en un entorno empresarial.
![Red eléctrica](../images/electric-grid.jpg)
Fotografía de [Peddi Sai hrithik](https://unsplash.com/@shutter_log?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) de torres eléctricas en una carretera en Rajasthan en [Unsplash](https://unsplash.com/s/photos/electric-india?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)
## Lecciones
1. [Introducción a la predicción de series de tiempo](../1-Introduction/README.md)
2. [Construyendo modelos de series de tiempo con ARIMA](../2-ARIMA/README.md)
3. [Construyendo un Regresor de Soporte Vectorial para la predicción de series de tiempo](../3-SVR/README.md)
## Créditos
"Introducción a la predicción de series de tiempo" fue escrito con ⚡️ por [Francesca Lazzeri](https://twitter.com/frlazzeri) y [Jen Looper](https://twitter.com/jenlooper). Los notebooks aparecieron primero en el [repo de Azure "Aprendizaje profundo para series de tiempo"](https://github.com/Azure/DeepLearningForTimeSeriesForecasting) originalmente escrito por Francesca Lazzeri. La lección de SVR fue escrita por [Anirban Mukherjee](https://github.com/AnirbanMukherjeeXD)

@ -0,0 +1,27 @@
# Un mundo más realista
En nuestro caso, Pedro (Peter) fue capaz de moverse y casi sin cansarse o estar hambriento. En un mundo más realista, él tiene que sentarse y descansar de vez en cuando, así como también alimentarse. Hagamos nuestro mundo más realista, al implementar las siguientes reglas:
1. Al moverse de un lugar a otro, Pedro pierde **energía** y obtiene algo de **fatiga**.
2. Pedro puede adquirir más energía al comer manzanas.
3. Pedro puede deshacerse de la fatiga al descansar bajo un árbol o en el pasto (ej. caminar en una ubicación del tablero con un árbol o pasto - campo verde)
4. Pedro necesita encontrar y matar al lobo
5. Con el fin de matar al lobo, Pedro necesita tener ciertos niveles de energía y fatiga, de lo contrario pierde la batalla.
## Instrucciones
Usa el notebook original [notebook.ipynb](../notebook.ipynb) como punto de partida para tu solución.
Modifica la función reward de arriba de acuerdo a las reglas del juego, ejecuta el algoritmo de aprendizaje reforzado para aprender la mejor estrategia para ganar el juego, y compara los resultados de caminata aleatoria con tu algoritmo en términos de el número de juegos ganados y perdidos.
> **Nota**: En tu nuevo mundo, el estado es más complejo, y además a la posición humana también incluye la fatiga y los niveles de energía. Puedes optar por representar el estado como una tupla (tablero, energía, fatiga), o definir una clase para el estado (también puedes querer derivarlo de `Board`), o incluso modifica la clase original `Board` dentro de [rlboard.py](../rlboard.py).
En tu solución, mantén el código responsable de la estrategia de caminata aleatoria, y compara los resultados de tu algoritmo con la caminata aleatoria al final.
> **Nota**: Puedes necesitar ajustar los hiperparámetros para hacerlo funcionar, especialmente el número de épocas. Porque el éxito del juego (pelear contra el lobo) es un evento raro, puedes esperar un tiempo de entrenamiento mayor.
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| | Se presentó un notebook con la definición de las nuevas reglas del mundo. El algoritmo Q-Learning y algunas explicaciones textuales. Q-Learning es capaz de mejorar significativamente los resultados comparado con la caminata aleatoria. | Se presentó un notebook, Q-Learning se implementó y mejoró los resultados comparado con la caminata aleatoria, pero no de forma significativa; o el notebook está pobremente documentado y el código no está bien estructurado | Se hicieron algunos intentos para redefinir las reglas del mundo, pero el algoritmo de Q-Learning no funciona, o la función reward no está totalmente definida |

@ -0,0 +1,44 @@
# Entrena el carrito de montaña
[OpenAI Gym](http://gym.openai.com) ha sido diseñado de tal forma que todos los ambientes proveen la misma API - esto es, los mismos métodos `reset`, `step` y `render`, y las mismas abstracciones de **action space** y **observation space**. Así sería posible adaptar los mismos algoritmos de aprendizaje reforzado a diferentes ambientes con mínimos cambios al código.
## Un ambiente de carrito de montaña
El [ambiente de carrito de montaña](https://gym.openai.com/envs/MountainCar-v0/) contiene un carrito atrapado en un valle:
<img src="../images/mountaincar.png" width="300"/>
El objetivo es salir del valle y capturar la bandera, al hacer a cada paso una de las siguientes acciones:
| Valor | Significado |
|---|---|
| 0 | Acelerar a la izquierda |
| 1 | No acelerar |
| 2 | Acelerar a la derecha |
El truco principal de este problema es, no obstante, que el motor del carrito no es lo suficientemente potente para escalar la montaña en una sola pasada. Por lo tanto, la única forma de lograrlo es conducir hacia atrás y adelante para generar impulso.
El espacio de observación consiste de sólo dos valores:
| Num | Observación | Min | Max |
|-----|-----------------------|-------|------|
| 0 | Posición del carrito | -1.2 | 0.6 |
| 1 | Velocidad del carrito | -0.07 | 0.07 |
El sistema de recompensas para el carrito de montaña es engañoso:
* La recompensa de 0 es otorgada si el agente alcanzó la bandera (posición = 0.5) en la cima de la montaña.
* La recompensa de -1 es otorgada si la posición del agente es menos de 0.5.
El episodio termina si la posición del carrito es más de 0.5, o la longitud del episodio es mayor que 200.
## Instrucciones
Adapta nuestro algoritmo de aprendizaje reforzado para resolver el problema del carrito de montaña. Comienza con el código existente en [notebook.ipynb](../notebook.ipynb), substituye el nuevo ambiente, cambia las funciones de discretización de estado, e intenta hacer que el algoritmo existente entrene con mínimas modificaciones al código. Optimiza el resultado al ajustar los hiperparámetros.
> **Nota**: Es probable que ajustar los hiperparámetros sea necesario para hacer que el algoritmo converja.
## Rúbrica
| Criterio | Ejemplar | Adecuado | Necesita mejorar |
| -------- | --------- | -------- | ----------------- |
| | El algoritmo Q-Learning se adaptó de forma exitosa a partir del ejemplo CartPole, con mínimas modificaciones al código, el cual es capaz de resolver el problema al capturar la bandera con menos de 200 pasos. | Se adoptó un nuevo algoritmo Q-Learning de internet, pero está bien documentado; o se adoptó el algoritmo existente, pero no cumple los resultados deseados | El estudiante no fue capaz de adoptar ningún algoritmo de forma exitosa, pero ha hecho pasos substanciales hacia la solución (implementó la discretización de estado, la estructura de datos de Q-Table, etc.) |

@ -28,7 +28,7 @@ Travel with us around the world as we apply these classic techniques to data fro
# Getting Started # Getting Started
**Students**, to use this curriculum, fork the entire repo to your own GitHub account and complete the exercises on your own or with a group: **[Students](https://aka.ms/student-page)**, to use this curriculum, fork the entire repo to your own GitHub account and complete the exercises on your own or with a group:
- Start with a pre-lecture quiz. - Start with a pre-lecture quiz.
- Read the lecture and complete the activities, pausing and reflecting at each knowledge check. - Read the lecture and complete the activities, pausing and reflecting at each knowledge check.
@ -87,7 +87,7 @@ By ensuring that the content aligns with projects, the process is made more enga
| 04 | Techniques for machine learning | [Introduction](1-Introduction/README.md) | What techniques do ML researchers use to build ML models? | [Lesson](1-Introduction/4-techniques-of-ML/README.md) | Chris and Jen | | 04 | Techniques for machine learning | [Introduction](1-Introduction/README.md) | What techniques do ML researchers use to build ML models? | [Lesson](1-Introduction/4-techniques-of-ML/README.md) | Chris and Jen |
| 05 | Introduction to regression | [Regression](2-Regression/README.md) | Get started with Python and Scikit-learn for regression models | <ul><li>[Python](2-Regression/1-Tools/README.md)</li><li>[R](2-Regression/1-Tools/solution/R/lesson_1-R.ipynb)</li></ul> | <ul><li>Jen</li><li>Eric Wanjau</li></ul> | | 05 | Introduction to regression | [Regression](2-Regression/README.md) | Get started with Python and Scikit-learn for regression models | <ul><li>[Python](2-Regression/1-Tools/README.md)</li><li>[R](2-Regression/1-Tools/solution/R/lesson_1-R.ipynb)</li></ul> | <ul><li>Jen</li><li>Eric Wanjau</li></ul> |
| 06 | North American pumpkin prices 🎃 | [Regression](2-Regression/README.md) | Visualize and clean data in preparation for ML | <ul><li>[Python](2-Regression/2-Data/README.md)</li><li>[R](2-Regression/2-Data/solution/R/lesson_2-R.ipynb)</li></ul> | <ul><li>Jen</li><li>Eric Wanjau</li></ul> | | 06 | North American pumpkin prices 🎃 | [Regression](2-Regression/README.md) | Visualize and clean data in preparation for ML | <ul><li>[Python](2-Regression/2-Data/README.md)</li><li>[R](2-Regression/2-Data/solution/R/lesson_2-R.ipynb)</li></ul> | <ul><li>Jen</li><li>Eric Wanjau</li></ul> |
| 07 | North American pumpkin prices 🎃 | [Regression](2-Regression/README.md) | Build linear and polynomial regression models | <ul><li>[Python](2-Regression/3-Linear/README.md)</li><li>[R](2-Regression/3-Linear/solution/R/lesson_3-R.ipynb)</li></ul> | <ul><li>Jen</li><li>Eric Wanjau</li></ul> | | 07 | North American pumpkin prices 🎃 | [Regression](2-Regression/README.md) | Build linear and polynomial regression models | <ul><li>[Python](2-Regression/3-Linear/README.md)</li><li>[R](2-Regression/3-Linear/solution/R/lesson_3-R.ipynb)</li></ul> | <ul><li>Jen and Dmitry</li><li>Eric Wanjau</li></ul> |
| 08 | North American pumpkin prices 🎃 | [Regression](2-Regression/README.md) | Build a logistic regression model | <ul><li>[Python](2-Regression/4-Logistic/README.md) </li><li>[R](2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb)</li></ul> | <ul><li>Jen</li><li>Eric Wanjau</li></ul> | | 08 | North American pumpkin prices 🎃 | [Regression](2-Regression/README.md) | Build a logistic regression model | <ul><li>[Python](2-Regression/4-Logistic/README.md) </li><li>[R](2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb)</li></ul> | <ul><li>Jen</li><li>Eric Wanjau</li></ul> |
| 09 | A Web App 🔌 | [Web App](3-Web-App/README.md) | Build a web app to use your trained model | [Python](3-Web-App/1-Web-App/README.md) | Jen | | 09 | A Web App 🔌 | [Web App](3-Web-App/README.md) | Build a web app to use your trained model | [Python](3-Web-App/1-Web-App/README.md) | Jen |
| 10 | Introduction to classification | [Classification](4-Classification/README.md) | Clean, prep, and visualize your data; introduction to classification | <ul><li> [Python](4-Classification/1-Introduction/README.md) </li><li>[R](4-Classification/1-Introduction/solution/R/lesson_10-R.ipynb) | <ul><li>Jen and Cassie</li><li>Eric Wanjau</li></ul> | | 10 | Introduction to classification | [Classification](4-Classification/README.md) | Clean, prep, and visualize your data; introduction to classification | <ul><li> [Python](4-Classification/1-Introduction/README.md) </li><li>[R](4-Classification/1-Introduction/solution/R/lesson_10-R.ipynb) | <ul><li>Jen and Cassie</li><li>Eric Wanjau</li></ul> |

39
package-lock.json generated

@ -1241,10 +1241,13 @@
"dev": true "dev": true
}, },
"node-fetch": { "node-fetch": {
"version": "2.6.1", "version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"dev": true "dev": true,
"requires": {
"whatwg-url": "^5.0.0"
}
}, },
"normalize-path": { "normalize-path": {
"version": "3.0.0", "version": "3.0.0",
@ -1433,9 +1436,9 @@
"dev": true "dev": true
}, },
"prismjs": { "prismjs": {
"version": "1.25.0", "version": "1.27.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.25.0.tgz", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
"integrity": "sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg==", "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==",
"dev": true "dev": true
}, },
"process-nextick-args": { "process-nextick-args": {
@ -1868,6 +1871,12 @@
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
"dev": true "dev": true
}, },
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
"dev": true
},
"tweezer.js": { "tweezer.js": {
"version": "1.5.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/tweezer.js/-/tweezer.js-1.5.0.tgz", "resolved": "https://registry.npmjs.org/tweezer.js/-/tweezer.js-1.5.0.tgz",
@ -2009,6 +2018,22 @@
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
"dev": true "dev": true
}, },
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
"dev": true
},
"whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
"dev": true,
"requires": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"which-module": { "which-module": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",

@ -2378,18 +2378,6 @@
"webpack": ">=2.0.0 <5.0.0" "webpack": ">=2.0.0 <5.0.0"
} }
}, },
"node_modules/@vue/cli-plugin-eslint/node_modules/rimraf": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
"dev": true,
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
}
},
"node_modules/@vue/cli-plugin-router": { "node_modules/@vue/cli-plugin-router": {
"version": "4.5.15", "version": "4.5.15",
"resolved": "https://registry.npmjs.org/@vue/cli-plugin-router/-/cli-plugin-router-4.5.15.tgz", "resolved": "https://registry.npmjs.org/@vue/cli-plugin-router/-/cli-plugin-router-4.5.15.tgz",
@ -7039,9 +7027,9 @@
} }
}, },
"node_modules/follow-redirects": { "node_modules/follow-redirects": {
"version": "1.14.5", "version": "1.14.8",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
"integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==", "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -13732,9 +13720,9 @@
} }
}, },
"node_modules/url-parse": { "node_modules/url-parse": {
"version": "1.5.3", "version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"querystringify": "^2.1.1", "querystringify": "^2.1.1",
@ -16944,15 +16932,6 @@
"object-hash": "^1.1.4", "object-hash": "^1.1.4",
"rimraf": "^2.6.1" "rimraf": "^2.6.1"
} }
},
"rimraf": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
} }
} }
}, },
@ -20732,9 +20711,9 @@
} }
}, },
"follow-redirects": { "follow-redirects": {
"version": "1.14.5", "version": "1.14.8",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
"integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==", "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==",
"dev": true "dev": true
}, },
"for-in": { "for-in": {
@ -26174,9 +26153,9 @@
} }
}, },
"url-parse": { "url-parse": {
"version": "1.5.3", "version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"querystringify": "^2.1.1", "querystringify": "^2.1.1",

@ -0,0 +1,133 @@
[![GitHub license](https://img.shields.io/github/license/microsoft/ML-For-Beginners.svg)](https://github.com/microsoft/ML-For-Beginners/blob/master/LICENSE)
[![GitHub contributors](https://img.shields.io/github/contributors/microsoft/ML-For-Beginners.svg)](https://GitHub.com/microsoft/ML-For-Beginners/graphs/contributors/)
[![GitHub issues](https://img.shields.io/github/issues/microsoft/ML-For-Beginners.svg)](https://GitHub.com/microsoft/ML-For-Beginners/issues/)
[![GitHub pull-requests](https://img.shields.io/github/issues-pr/microsoft/ML-For-Beginners.svg)](https://GitHub.com/microsoft/ML-For-Beginners/pulls/)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
[![GitHub watchers](https://img.shields.io/github/watchers/microsoft/ML-For-Beginners.svg?style=social&label=Watch)](https://GitHub.com/microsoft/ML-For-Beginners/watchers/)
[![GitHub forks](https://img.shields.io/github/forks/microsoft/ML-For-Beginners.svg?style=social&label=Fork)](https://GitHub.com/microsoft/ML-For-Beginners/network/)
[![GitHub stars](https://img.shields.io/github/stars/microsoft/ML-For-Beginners.svg?style=social&label=Star)](https://GitHub.com/microsoft/ML-For-Beginners/stargazers/)
# Aprendizaje automático para principiantes - Un plan de estudios
> 🌍 Viaja alrededor del mundo mientras exploramos el aprendizaje automático a través de las culturas del mundo 🌍
Los Azure Cloud Advocates de Microsoft están emocionados en ofrecer un plan de estudios de 12 semanas, con 26 lecciones, todas acerca de **aprendizaje automático**. En este plan de estudios, aprenderás sobre lo que algunas veces es llamado **aprendizaje automático clásico**, usando principalmente Scikit-learn y evitando el aprendizaje profundo, el cual se aborda en nuestro próximo plan de estudios 'IA para principiantes'. ¡Acompaña estas lecciones con nuestro [plan de estudios 'Ciencia de Datos para principiantes'](https://aka.ms/datascience-beginners)!
Viaja con nosotros alrededor del mundo mientras aplicamos técnicas clásicas a los datos de distintas áreas del mundo. Cada lección incluye:
- Exámenes previos y posteriores a cada lección
- Instrucciones para completar dicha lección
- Una solución
- Un ejercicio y más
Nuestra metodología de enseñanza basada en proyectos, te permite aprender mientras practicas; esta es una forma comprobada para que adquieras nuevas habilidades.
**✍️ Agradecimientos de todo corazón** a Jen Looper, Stephen Howell, Francesca Lazzeri, Tomomi Imura, Cassie Breviu, Dmitry Soshnikov, Chris Noring, Anirban Mukherjee, Ornella Altunyan, y Amy Boyd.
**🎨 Gracias también a nuestros ilustradores** Tomomi Imura, Dasani Madipalli, y Jen Looper.
**🙏 Agradecimientos especiales 🙏 a nuestros autores de Embajadores Estudiantiles de Microsoft, revisores, y colaboradores de contenido**, notablemente a Rishit Dagli, Muhammad Sakib Khan Inan, Rohan Raj, Alexandru Petrescu, Abhishek Jaiswal, Nawrin Tabassum, Ioan Samuila, y Snigdha Agarwal.
**🤩 ¡Agradecimiento adicional al embajador estudiantil de Microsoft Eric Wanjau por nuestras lecciones de R!**
---
# Empezando con el plan de estudio
**Estudiantes**, para usar este plan de estudios, realiza un fork del repositorio completo en tu cuenta de GitHub y completa los ejercicios por ti mismo o en grupo:
- Realiza el examen previo a la lección.
- Lee las lecciones y completa las actividades, pausando y reflexionando en cada verificación de conocimiento.
- Intenta crear los proyectos para comprender las lecciones en lugar de ejecutar el código de la solución; sin embargo ese código se encuentra disponible en los directorios `/solution` en cada lección orientada a proyecto.
- Realiza el examen posterior a la lección.
- Completa el desafío.
- Completa el ejercicio.
- Después de completar un grupo de lecciones, visita el [tablero de discusión](https://github.com/microsoft/ML-For-Beginners/discussions) y "aprende en voz alta" llenando la rúbrica PAT apropiada. Un 'PAT' es una herramienta de evaluación del progreso que es una rúbrica la cual llenas para avanzar en tu aprendizaje. También puede reaccionar a otros PATs y así aprender juntos.
> Para aprender más, recomendamos seguir estos módulos y rutas de aprendizaje de [Microsoft Learn](https://docs.microsoft.com/en-us/users/jenlooper-2911/collections/k7o7tg1gp306q4?WT.mc_id=academic-15963-cxa).
**Profesores**, hemos [incluido algunas sugerencias](../for-teachers.md) de cómo usar este plan de estudios.
---
## Conoce al equipo
[![Video promocional](../ml.gif)](https://youtu.be/Tj1XWrDSYJU "Video promocional")
**Gif de** [Mohit Jaisal](https://linkedin.com/in/mohitjaisal)
> 🎥 ¡Da clic a la imagen de arriba para ver un video acerca del proyecto y la gente que lo creó!
---
## Pedagogía
Hemos elegido dos principios pedagógicos mientras construimos este plan de estudios: asegurar que es práctico **basado en proyectos** y que incluye **exámenes frecuentes**. Además, este plan de estudios tiene un **tema** común para darle cohesión.
Al asegurar que el contenido se alinea con los proyectos, el proceso se hace más atractivo par los estudiantes y la retención de conceptos incrementará. Además, un pequeño examen antes de cada clase para establecer la intención del estudiante de aprender un tema, mientras el segundo examen después de la clase asegura una mayor retención. Este plan de estudios fue diseñado para ser flexible y divertido y puede se tomado en su totalidad o por partes. Los proyectos comienzan pequeños y van incrementando en complejidad durante el ciclo de 12 semanas. Este plan de estudios también incluye una nota al final sobre aplicaciones de aprendizaje automático en el mundo real, la cual puede ser usada como cŕeditos extra o como base para discusión.
> Encuentra nuestros lineamientos de [Código de conducta](../CODE_OF_CONDUCT.md), [Contribución](../CONTRIBUTING.md), y [Traducción](../TRANSLATIONS.md). ¡Son bienvenidos tus comentarios constructivos!
## Cada lección incluye:
- boceto opcional
- video suplementario opcional
- examen diagnóstico previo a la lección
- lección escrita
- para lecciones basadas en proyectos, guías paso a paso de cómo construir el proyecto
- verificaciones de conocimiento
- un desafío
- lectura suplementaria
- un ejercicio
- examen posterior a la lección
> **Una nota acerca de los lenguajes**: Estas lecciones están escritas principalmente en Python, pero muchas también están disponibles en R. Para completar una lección en R, ve al directorio `/solution` y busca las lecciones. Ellas incluyen una extensión .rmd que representa un archivo **Markdown R** el cual puede ser definido simplemente como `porciones de código` embebido (de R u otros lenguajes) y un `encabezado YAML` (que guía cómo dar formato a las salidas, por ejemplo PDF) en un `documento Markdown`. Como tal, este sirve como un framework ejemplar de autoría para la ciencia de datos ya que permite combinar tu código, su salida, y tus pensamientos al permitirte escribirlos en Markdown. Es más, los documentos Markdown R pueden ser representados como formatos de salida tal como PDF, HTML, o Word.
> **Una nota acerca de los exámenes**: Todos los exámenes están contenidos [en esta app](https://white-water-09ec41f0f.azurestaticapps.net/), para un total de 52 exámenes de 3 preguntas cada uno, Ellos están vinculados dentro de las lecciones pero la aplicación de exámenes puede ser ejecutada localmente; sigue las instrucciones en el directorio `quiz-app`.
| Número de lección | Tema | Agrupación de lecciones | Objetivos de aprendizaje | Lección vinculada | Autor |
| :-----------: | :------------------------------------------------------------: | :-------------------------------------------------: | ------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------: |
| 01 | Introducción al aprendizaje automático | [Introducción](../1-Introduction/translations/README.es.md) | Aprende los conceptos básicos detrás del aprendizaje automático | [Lección](../1-Introduction/1-intro-to-ML/translations/README.es.md) | Muhammad |
| 02 | La historia del aprendizaje automático | [Introducción](../1-Introduction/translations/README.es.md) | Aprende la historia de este campo | [Lección](../1-Introduction/2-history-of-ML/translations/README.es.md) | Jen y Amy |
| 03 | Justicia y aprendizaje automático | [introducción](../1-Introduction/translations/README.es.md) | ¿Cuáles son los problemas filosóficos importantes alrededor de la justicia que los estudiantes deberían considerar al construir y aplicar modelos de aprendizaje automático? | [Lección](../1-Introduction/3-fairness/translations/README.es.md) | Tomomi |
| 04 | Técnicas para el aprendizaje automático | [introducción](../1-Introduction/translations/README.es.md) | ¿Qué técnicas usan los investigadores de aprendizaje automático para construir modelos de ML? | [Lección](../1-Introduction/4-techniques-of-ML/translations/README.es.md) | Chris y Jen |
| 05 | Introducción a la regresión | [Regresión](../2-Regression/translations/README.es.md) | Comienza con Python y Scikit-learn para modelos de regresión | <ul><li>[Python](../2-Regression/1-Tools/translations/README.es.md)</li><li>[R](../2-Regression/1-Tools/solution/R/lesson_1-R.ipynb)</li></ul> | <ul><li>Jen</li><li>Eric Wanjau</li></ul> |
| 06 | Precios de la calabaza en Norte América 🎃 | [Regresión](../2-Regression/translations/README.es.md) | Visualiza y limpia los datos en preparación para el aprendizaje automático | <ul><li>[Python](../2-Regression/2-Data/translations/README.es.md)</li><li>[R](../2-Regression/2-Data/solution/R/lesson_2-R.ipynb)</li></ul> | <ul><li>Jen</li><li>Eric Wanjau</li></ul> |
| 07 | Precios de la calabaza en Norte América 🎃 | [Regresión](../2-Regression/translations/README.es.md) | Construye modelos de regresión lineal y polinomial | <ul><li>[Python](../2-Regression/3-Linear/translations/README.es.md)</li><li>[R](../2-Regression/3-Linear/solution/R/lesson_3-R.ipynb)</li></ul> | <ul><li>Jen</li><li>Eric Wanjau</li></ul> |
| 08 | Precios de la calabaza en Norte América 🎃 | [Regresión](../2-Regression/translations/README.es.md) | Construye un modelo de regresión logística | <ul><li>[Python](../2-Regression/4-Logistic/translations/README.es.md) </li><li>[R](../2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb)</li></ul> | <ul><li>Jen</li><li>Eric Wanjau</li></ul> |
| 09 | Una aplicación web 🔌 | [Aplicación web](../3-Web-App/translations/README.es.md) | Construye una aplicación web para usar tu modelo entrenado | [Python](../3-Web-App/1-Web-App/translations/README.es.md) | Jen |
| 10 | Introducción a la clasificación | [Clasificación](../4-Classification/translations/README.es.md) | Limpia, prepara y visualiza tus datos; introducción a la clasificación | <ul><li> [Python](../4-Classification/1-Introduction/translations/README.es.md) </li><li>[R](../4-Classification/1-Introduction/solution/R/lesson_10-R.ipynb) | <ul><li>Jen y Cassie</li><li>Eric Wanjau</li></ul> |
| 11 | Deliciosas cocinas Asiática e India 🍜 | [Clasificación](../4-Classification/translations/README.es.md) | Introducción a los clasificadores | <ul><li> [Python](../4-Classification/2-Classifiers-1/translations/README.es.md)</li><li>[R](../4-Classification/2-Classifiers-1/solution/R/lesson_11-R.ipynb) | <ul><li>Jen y Cassie</li><li>Eric Wanjau</li></ul> |
| 12 | Deliciosas cocinas Asiática e India 🍜 | [Clasificación](../4-Classification/translations/README.es.md) | Más clasificadores | <ul><li> [Python](../4-Classification/3-Classifiers-2/translations/README.es.md)</li><li>[R](../4-Classification/3-Classifiers-2/solution/R/lesson_12-R.ipynb) | <ul><li>Jen y Cassie</li><li>Eric Wanjau</li></ul> |
| 15 | Explorando los gustos musicales de Nigeria 🎧 | [Agrupamiento](../5-Clustering/translations/README.es.md) | Explora el método de agrupamiento K-medias | <ul><li> [Python](../5-Clustering/2-K-Means/translations/README.es.md)</li><li>[R](../5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb) | <ul><li>Jen</li><li>Eric Wanjau</li></ul> |
| 16 | Introducción al procesamiento de lenguaje natural ☕️ | [Procesamiento de lenguaje natural](../6-NLP/translations/README.es.md) | Aprende las bases acerca de NLP al construir un bot simple | [Python](../6-NLP/1-Introduction-to-NLP/translations/README.es.md) | Stephen |
| 18 | Traducción y análisis de sentimiento ♥️ | [Procesamiento de lenguaje natural](../6-NLP/translations/README.es.md) | Traducción y análisis de sentimiento con Jane Austen | [Python](../6-NLP/3-Translation-Sentiment/translations/README.es.md) | Stephen |
| 19 | Hoteles románticos de Europa ♥️ | [Procesamiento de lenguaje natural](../6-NLP/translations/README.es.md) | Análisis de sentimiento con reseñas de hoteles 1 | [Python](../6-NLP/4-Hotel-Reviews-1/translations/README.es.md) | Stephen |
| 20 | Hoteles románticos de Europa ♥️ | [Procesamiento de lenguaje natural](../6-NLP/translations/README.es.md) | Análisis de sentimiento con reseñas de hoteles 2 | [Python](../6-NLP/5-Hotel-Reviews-2/translations/README.es.md) | Stephen |
| 21 | Introducción a la predicción de series de tiempo | [Series de tiempo](../7-TimeSeries/translations/README.es.md) | Introducción a la predicción de series de tiempo | [Python](../7-TimeSeries/1-Introduction/translations/README.es.md) | Francesca |
| 22 | ⚡️ Uso de energía mundial ⚡️ - predicción de series de tiempo con ARIMA | [Series de tiempo](../7-TimeSeries/translations/README.es.md) | Predicción de series de tiempo con ARIMA | [Python](../7-TimeSeries/2-ARIMA/translations/README.es.md) | Francesca |
| 23 | ⚡️ Uso de energía mundial ⚡️ - predicción de series de tiempo con SVR | [Series de tiempo](../7-TimeSeries/translations/README.es.md) | Predicción de series de tiempo con Regresor de soporte vectorial | [Python](../7-TimeSeries/3-SVR/translations/README.es.md) | Anirban |
| 24 | Introducción al aprendizaje reforzado | [Aprendizaje reforzado](../8-Reinforcement/translations/README.es.md) | introducción al aprendizaje reforzado con Q-Learning | [Python](../8-Reinforcement/1-QLearning/translations/README.es.md) | Dmitry |
| 25 | ¡Ayuda a Pedro a evitar al lobo! 🐺 | [Aprendizaje reforzado](../8-Reinforcement/translations/README.es.md) | Gimnasio de aprendizaje reforzado | [Python](../8-Reinforcement/2-Gym/translations/README.es.md) | Dmitry |
| Postdata | Escenarios y aplicaciones del aprendizaje automático en el mundo real | [Aprendizaje automático en la naturaleza](../9-Real-World/translations/README.es.md) | Interesantes y reveladoras aplicaciones del mundo real del aprendizaje automático clásico | [Lección](../9-Real-World/1-Applications/translations/README.es.md) | Equipo |
## Acceso sin conexión
Puedes ejecutar esta documentación sin conexión al usar [Docsify](https://docsify.js.org/#/). Crea un fork de este repositorio, [instala Docsify](https://docsify.js.org/#/quickstart) en tu equipo local, y luego en el directorio raíz de este repositorio, escribe `docsify serve`. El sitio web será servido en el puerto 3000 de tu host local: `localhost:3000`.
## PDFs
Encuentra [aquí](https://microsoft.github.io/ML-For-Beginners/pdf/readme.pdf) un pdf de el plan de estudios con enlaces.
## ¡Necesitamos tu ayuda!
¿Te gustaría contribuir con una traducción? Por favor lee nuestros [lineamientos de traducción](../TRANSLATIONS.md) y agrega un issue basado en la plantilla para administrar la carga de trabajo [aquí](https://github.com/microsoft/ML-For-Beginners/issues).
## Otros planes de estudio
¡Nuestro equipo produce otros planes de estudio! Revísalos:
- [Desarrollo Web para principiantes](https://aka.ms/webdev-beginners)
- [Internet de las cosas para principiantes](https://aka.ms/iot-beginners)
- [Ciencia de Datos para principiantes](https://aka.ms/datascience-beginners)

@ -0,0 +1,129 @@
[![GitHub license](https://img.shields.io/github/license/microsoft/ML-For-Beginners.svg)](https://github.com/microsoft/ML-For-Beginners/blob/master/LICENSE)
[![GitHub contributors](https://img.shields.io/github/contributors/microsoft/ML-For-Beginners.svg)](https://GitHub.com/microsoft/ML-For-Beginners/graphs/contributors/)
[![GitHub issues](https://img.shields.io/github/issues/microsoft/ML-For-Beginners.svg)](https://GitHub.com/microsoft/ML-For-Beginners/issues/)
[![GitHub pull-requests](https://img.shields.io/github/issues-pr/microsoft/ML-For-Beginners.svg)](https://GitHub.com/microsoft/ML-For-Beginners/pulls/)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
[![GitHub watchers](https://img.shields.io/github/watchers/microsoft/ML-For-Beginners.svg?style=social&label=Watch)](https://GitHub.com/microsoft/ML-For-Beginners/watchers/)
[![GitHub forks](https://img.shields.io/github/forks/microsoft/ML-For-Beginners.svg?style=social&label=Fork)](https://GitHub.com/microsoft/ML-For-Beginners/network/)
[![GitHub stars](https://img.shields.io/github/stars/microsoft/ML-For-Beginners.svg?style=social&label=Star)](https://GitHub.com/microsoft/ML-For-Beginners/stargazers/)
# शुरुआती के लिए मशीन लर्निंग - एक पाठ्यक्रम
> 🌍दुनिया भर में यात्रा करें क्योंकि हम विश्व संस्कृतियों के माध्यम से मशीन लर्निंग का पता लगाते हैं 🌍
माइक्रोसॉफ्ट के एज़्योर क्लाउड एडवोकेट्स को 12-सप्ताह, 26-पाठ पाठ्यक्रम की पेशकश करके प्रसन्नता हो रही है **मशीन लर्निंग** के बारे में 12-सप्ताह, 26-पाठ पाठ्यक्रम की पेशकश करके प्रसन्न हैं। इस पाठ्यक्रम में, आप प्राथमिक रूप से स्किकिट-लर्न को एक पुस्तकालय के रूप में उपयोग करते हुए और हमारे आगामी 'एआई फॉर बिगिनर्स' पाठ्यक्रम में शामिल गहन शिक्षण से बचने के लिए, जिसे कभी-कभी **क्लासिक मशीन लर्निंग** कहा जाता है, के बारे में जानेंगे। इन पाठों को हमारे साथ जोड़ें ['शुरुआती के लिए डेटा विज्ञान' पाठ्यक्रम](https://aka.ms/datascience-beginners), भी!
दुनिया भर में हमारे साथ यात्रा करें क्योंकि हम इन क्लासिक तकनीकों को दुनिया के कई क्षेत्रों के डेटा पर लागू करते हैं। प्रत्येक पाठ में पाठ से पहले और बाद में प्रश्नोत्तरी, पाठ को पूरा करने के लिए लिखित निर्देश, एक समाधान, एक असाइनमेंट, और बहुत कुछ शामिल हैं। हमारी परियोजना-आधारित शिक्षाशास्त्र आपको निर्माण करते समय सीखने की अनुमति देता है, जो नए कौशल को 'छड़ी' करने का एक सिद्ध तरीका है।
**✍️ हमारे लेखकों** जेन लूपर, स्टीफन हॉवेल, फ्रांसेस्का लाज़ेरी, टोमोमी इमुरा, कैसी ब्रेवियू, दिमित्री सोशनिकोव, क्रिस नोरिंग, अनिर्बान मुखर्जी, ओरनेला अल्टुनियन और एमी बॉयड को हार्दिक धन्यवाद।
**🎨 हमारे चित्रकारों** तोमोमी इमुरा, दासानी मदिपल्ली और जेन लूपर को भी धन्यवाद
**🙏 हमारे Microsoft छात्र राजदूत लेखकों, समीक्षकों और सामग्री योगदानकर्ताओं के लिए विशेष धन्यवाद**, विशेष रूप से रिषित डागली, मुहम्मद साकिब खान इनान, रोहन राज, अलेक्जेंड्रू पेट्रेस्कु, अभिषेक जायसवाल, नवरीन तबस्सुम, इओन समुइला, और स्निग्धा अग्रवाल
**🤩 हमारे R पाठों के लिए Microsoft छात्र राजदूत एरिक वंजाउ का अतिरिक्त आभार!**
---
# शुरू करना
**विद्यार्थी**, इस पाठ्यक्रम का उपयोग करने के लिए, संपूर्ण रेपो को अपने स्वयं के गिटहब खाते में फोर्क करें और अभ्यास स्वयं या समूह के साथ पूरा करें:
- प्री-लेक्चर क्विज से शुरुआत करें।
- व्याख्यान पढ़ें और गतिविधियों को पूरा करें, प्रत्येक ज्ञान जांच पर रुकें और प्रतिबिंबित करें।
- समाधान कोड चलाने के बजाय पाठों को समझकर प्रोजेक्ट बनाने का प्रयास करें; हालांकि वह कोड प्रत्येक परियोजना-उन्मुख पाठ में `/ समाधान` फ़ोल्डर में उपलब्ध है।
- व्याख्यान के बाद प्रश्नोत्तरी लें।
- चुनौती को पूरा करें।
- असाइनमेंट पूरा करें।
- एक पाठ समूह पूरा करने के बाद, [चर्चा बोर्ड](https://github.com/microsoft/ML-For-Beginners/discussions) पर जाएँ और उपयुक्त PAT रूब्रिक भरकर "ज़ोर से सीखें"। एक 'पीएटी' एक प्रगति आकलन उपकरण है जो एक रूब्रिक है जिसे आप अपने सीखने को आगे बढ़ाने के लिए भरते हैं। आप अन्य पीएटी पर भी प्रतिक्रिया कर सकते हैं ताकि हम एक साथ सीख सकें।
> आगे के अध्ययन के लिए, हम इन [माइक्रोसॉफ्ट लर्न](https://docs.microsoft.com/en-us/users/jenlooper-2911/collections/k7o7tg1gp306q4?WT.mc_id=academic-15963-cxa) मॉड्यूल और सीखने के रास्तों का अनुसरण करने की सलाह देते हैं।.
**शिक्षक**, हमारे पास [कुछ सुझाव शामिल हैं](../for-teachers.md) इस पाठ्यक्रम का उपयोग कैसे करें।
---
## टीम से मिलो
[![Promo video](../ml.gif)](https://youtu.be/Tj1XWrDSYJU "Promo video")
**Gif by** [मोहित जैसल](https://linkedin.com/in/mohitjaisal)
> 🎥 परियोजना और इसे बनाने वाले लोगों के बारे में वीडियो के लिए ऊपर की छवि पर क्लिक करें!
---
## शिक्षा शास्त्र
इस पाठ्यक्रम का निर्माण करते समय हमने दो शैक्षणिक सिद्धांतों को चुना है: यह सुनिश्चित करना कि यह व्यावहारिक रूप से **परियोजना-आधारित** है और इसमें **लगातार प्रश्नोत्तरी** शामिल हैं। इसके अलावा, इस पाठ्यक्रम में एक समान **थीम** है जो इसे एकता प्रदान करता है।
यह सुनिश्चित करके कि सामग्री परियोजनाओं के साथ संरेखित होती है, छात्रों के लिए प्रक्रिया को और अधिक आकर्षक बनाया जाता है और अवधारणाओं के प्रतिधारण को बढ़ाया जाएगा। इसके अलावा, कक्षा से पहले एक कम-दांव प्रश्नोत्तरी छात्र के विषय को सीखने के इरादे को निर्धारित करती है, जबकि कक्षा के बाद दूसरी प्रश्नोत्तरी आगे प्रतिधारण सुनिश्चित करती है। इस पाठ्यक्रम को लचीला और मजेदार बनाने के लिए डिज़ाइन किया गया था और इसे पूर्ण या आंशिक रूप से लिया जा सकता है। परियोजनाएं छोटी शुरू होती हैं और 12-सप्ताह के चक्र के अंत तक तेजी से जटिल हो जाती हैं। इस पाठ्यक्रम में एमएल के वास्तविक-विश्व अनुप्रयोगों पर एक पोस्टस्क्रिप्ट भी शामिल है, जिसका उपयोग अतिरिक्त क्रेडिट के रूप में या चर्चा के आधार के रूप में किया जा सकता है।
> हमारी [आचार संहिता](../CODE_OF_CONDUCT.md), [योगदान](../CONTRIBUTING.md), और [अनुवाद](../TRANSLATIONS.md) दिशानिर्देश खोजें। हम आपकी रचनात्मक प्रतिक्रिया का स्वागत करते हैं!
## प्रत्येक पाठ में शामिल हैं:
- वैकल्पिक स्केचनोट
- वैकल्पिक पूरक वीडियो
- पूर्व व्याख्यान वार्मअप प्रश्नोत्तरी
- लिखित पाठ
- प्रोजेक्ट-आधारित पाठों के लिए, प्रोजेक्ट बनाने के तरीके के बारे में चरण-दर-चरण मार्गदर्शिका
- ज्ञान जांच
- एक चुनौती
- पूरक पठन
- कार्यभार
- व्याख्यान के बाद प्रश्नोत्तरी
> **भाषाओं के बारे में एक नोट**: ये पाठ मुख्य रूप से पायथन में लिखे गए हैं, लेकिन कई आर में भी उपलब्ध हैं। एक आर पाठ को पूरा करने के लिए, `/ समाधान` फ़ोल्डर में जाएं और आर पाठ देखें। उनमें एक .rmd एक्सटेंशन शामिल है जो एक **R मार्कडाउन** फ़ाइल का प्रतिनिधित्व करता है जिसे केवल `कोड चंक्स` (आर या अन्य भाषाओं के) के एम्बेडिंग के रूप में परिभाषित किया जा सकता है और एक `वाईएएमएल हेडर` (जो इस तरह के आउटपुट को प्रारूपित करने का मार्गदर्शन करता है) पीडीएफ के रूप में) एक `मार्कडाउन दस्तावेज़` में। जैसे, यह डेटा विज्ञान के लिए एक अनुकरणीय संलेखन ढांचे के रूप में कार्य करता है क्योंकि यह आपको अपने कोड, इसके आउटपुट और आपके विचारों को मार्कडाउन में लिखने की अनुमति देकर आपको संयोजित करने की अनुमति देता है। इसके अलावा, आर मार्कडाउन दस्तावेजों को पीडीएफ, एचटीएमएल या वर्ड जैसे आउटपुट स्वरूपों में प्रस्तुत किया जा सकता है।
> **क्विज़ के बारे में एक नोट**: सभी क्विज़ शामिल हैं [इस ऐप में](https://white-water-09ec41f0f.azurestaticapps.net/), प्रत्येक तीन प्रश्नों के कुल 52 क्विज़ के लिए। वे पाठों के भीतर से जुड़े हुए हैं लेकिन प्रश्नोत्तरी ऐप को स्थानीय रूप से चलाया जा सकता है; `क्विज़-ऐप` फ़ोल्डर में दिए गए निर्देशों का पालन करें।
| पाठ संख्या | विषय | पाठ समूहन | सीखने के मकसद | जुड़ा हुआ पाठ | लेखक |
| :-----------: | :------------------------------------------------------------: | :-------------------------------------------------: | ------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------: |
| 01 | मशीन लर्निंग का परिचय | [परिचय](../1-Introduction/README.md) | मशीन लर्निंग के पीछे की बुनियादी अवधारणाओं को जानें | [पाठ](../1-Introduction/1-intro-to-ML/README.md) | मुहम्मद |
| 02 | मशीन लर्निंग का इतिहास | [परिचय](../1-Introduction/README.md) | इस क्षेत्र में अंतर्निहित इतिहास को जानें | [पाठ](../1-Introduction/2-history-of-ML/README.md) | जेन और एमी |
| 03 | निष्पक्षता और मशीन लर्निंग | [परिचय](../1-Introduction/README.md) | निष्पक्षता के आसपास कौन से महत्वपूर्ण दार्शनिक मुद्दे हैं जिन पर छात्रों को एमएल मॉडल बनाते और लागू करते समय विचार करना चाहिए? | [पाठ](../1-Introduction/3-fairness/README.md) | तोमोमी |
| 04 | मशीन सीखने की तकनीक | [परिचय](../1-Introduction/README.md) | एमएल शोधकर्ता एमएल मॉडल बनाने के लिए किन तकनीकों का उपयोग करते हैं? | [पाठ](../1-Introduction/4-techniques-of-ML/README.md) | क्रिस और जेन |
| 05 | प्रतिगमन का परिचय | [रिग्रेशन](../2-Regression/README.md)| रिग्रेशन मॉडल के लिए पायथन और स्किकिट-लर्न के साथ शुरुआत करें | <ul><li>[Python](../2-Regression/1-Tools/README.md)</li><li>[R](../2-Regression/1-Tools/solution/R/lesson_1-R.ipynb )</li></ul> | <ul><li>जेन</li><li>एरिक वंजाउ</li></ul> |
| 06 | उत्तर अमेरिकी कद्दू की कीमतें 🎃 | [रिग्रेशन](../2-Regression/README.md) | एमएल की तैयारी में डेटा को विज़ुअलाइज़ और साफ़ करें | <ul><li>[Python](../2-Regression/2-Data/README.md)</li><li>[R](../2-Regression/2-Data/solution/R/lesson_2-R.ipynb )</li></ul> | <ul><li>जेन</li><li>एरिक वंजाउ</li></ul> |
| 07 | उत्तर अमेरिकी कद्दू की कीमतें 🎃 | [रिग्रेशन](../2-Regression/README.md) | रैखिक और बहुपद प्रतिगमन मॉडल बनाएं | <ul><li>[Python](../2-Regression/3-Linear/README.md)</li><li>[R](../2-Regression/3-Linear/solution/R/lesson_3-R.ipynb) )</li></ul> | <ul><li>जेन</li><li>एरिक वंजाउ</li></ul> |
| 08 | उत्तर अमेरिकी कद्दू की कीमतें 🎃 | [रिग्रेशन](../2-Regression/README.md) | लॉजिस्टिक रिग्रेशन मॉडल बनाएं | <ul><li>[Python](../2-Regression/4-Logistic/README.md) </li><li>[R](../2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb )</li></ul> | <ul><li>जेन</li><li>एरिक वंजाउ</li></ul> |
| 09 | एक वेब ऐप | [वेब ऐप](../3-Web-App/README.md) | अपने प्रशिक्षित मॉडल का उपयोग करने के लिए एक वेब ऐप बनाएं | [पायथन](../3-Web-App/1-Web-App/README.md) | जेन |
| 10 | वर्गीकरण का परिचय | [वर्गीकरण](../4-Classification/README.md) | अपने डेटा को साफ़, तैयार और विज़ुअलाइज़ करें; वर्गीकरण का परिचय | <ul><li> [पायथन](../4-Classification/1-Introduction/README.md) </li><li>[R](4-वर्गीकरण/1-परिचय/समाधान/R/lesson_10-R.ipynb ) | <ul><li>जेन और कैसी</li><li>एरिक वंजाउ</li></ul> |
| 11 | स्वादिष्ट एशियाई और भारतीय व्यंजन 🍜 | [वर्गीकरण](../4-Classification/README.md) | क्लासिफायर का परिचय | <ul><li> [पायथन](../4-Classification/2-Classifiers-1/README.md) </li><li>[R](../4-Classification/2-Classifiers-1/solution/R/lesson_11-R.ipynb) | <ul><li>जेन और कैसी</li><li>एरिक वंजाउ</li></ul> |
| 12 | स्वादिष्ट एशियाई और भारतीय व्यंजन 🍜 | [वर्गीकरण](../4-Classification/README.md) | अधिक क्लासिफायर | <ul><li> [पायथन](../4-Classification/3-Classifiers-2/README.md)</li><li>[R](../4-Classification/3-Classifiers-2/solution/R/lesson_12-R.ipynb) | <ul><li>जेन और कैसी</li><li>एरिक वंजाउ</li></ul> |
| 13 | स्वादिष्ट एशियाई और भारतीय व्यंजन 🍜 | [वर्गीकरण](../4-Classification/README.md) | अपने मॉडल का उपयोग करके एक अनुशंसाकर्ता वेब ऐप बनाएं | [पायथन](../4-Classification/4-Applied/README.md) | जेन |
| 14 | क्लस्टरिंग का परिचय | [क्लस्टरिंग](../5-Clustering/README.md) | अपने डेटा को साफ़, तैयार और विज़ुअलाइज़ करें; क्लस्टरिंग का परिचय | <ul><li> [पायथन](5-Clustering/1-Visualize/README.md)</li><li>[R](../5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb) | <ul><li>जेन</li><li>एरिक वंजाउ</li></ul> |
| 15 | नाइजीरियाई संगीत स्वाद की खोज 🎧 | [क्लस्टरिंग](../5-Clustering/README.md) | K-मीन्स क्लस्टरिंग विधि का अन्वेषण करें | <ul><li> [पायथन](../5-Clustering/2-K-Means/README.md)</li><li>[R](../5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb) | <ul><li>जेन</li><li>एरिक वंजाउ</li></ul> |
| 16 | प्राकृतिक भाषा प्रसंस्करण का परिचय ️ | [प्राकृतिक भाषा संसाधन](../6-NLP/README.md) | एक साधारण बॉट बनाकर एनएलपी के बारे में मूल बातें जानें | [पायथन](../6-NLP/1-Introduction-to-NLP/README.md) | स्टीफन |
| 17 | सामान्य एनएलपी कार्य ☕️ | [प्राकृतिक भाषा संसाधन](../6-NLP/README.md)) | भाषा संरचनाओं से निपटने के लिए आवश्यक सामान्य कार्यों को समझकर अपने एनएलपी ज्ञान को गहरा करें | [पायथन](../6-NLP/2-Tasks/README.md) | स्टीफन |
| 18 | अनुवाद और भावना विश्लेषण ♥️ | [प्राकृतिक भाषा संसाधन](../6-NLP/README.md)) | जेन ऑस्टेन के साथ अनुवाद और भावना विश्लेषण | [पायथन](../6-NLP/README.md) | स्टीफन |
| 19 | यूरोप के रोमांटिक होटल ♥️ | [प्राकृतिक भाषा संसाधन](../6-NLP/README.md)) | होटल समीक्षाओं के साथ भावनाओं का विश्लेषण 1 | [पायथन](../6-NLP/4-Hotel-Reviews-1/README.md) | स्टीफन |
| 20 | यूरोप के रोमांटिक होटल ♥️ | [प्राकृतिक भाषा संसाधन](../6-NLP/README.md)) | होटल समीक्षाओं के साथ भावनाओं का विश्लेषण 2 | [पायथन](../6-NLP/5-Hotel-Reviews-2/README.md) | स्टीफन |
| 21 | समय श्रृंखला पूर्वानुमान का परिचय | [समय श्रृंखला](../7-TimeSeries/README.md) | समय श्रृंखला पूर्वानुमान का परिचय | [पायथन](../7-TimeSeries/1-Introduction/README.md) | फ्रांसेस्का |
| 22 | ⚡️ विश्व शक्ति उपयोग ️ - अरिमा के साथ समय श्रृंखला पूर्वानुमान | [समय श्रृंखला](../7-TimeSeries/README.md) | ARIMA के साथ समय श्रृंखला पूर्वानुमान | [पायथन](../7-TimeSeries/2-ARIMA/README.md) | फ्रांसेस्का |
| 23 | ⚡️ विश्व शक्ति उपयोग ️ - एसवीआर के साथ समय श्रृंखला पूर्वानुमान | [समय श्रृंखला](../8-Reinforcement/README.md) | सपोर्ट वेक्टर रेजिस्टर के साथ टाइम सीरीज़ फोरकास्टिंग | [पायथन](../7-TimeSeries/3-SVR/README.md) | अनिर्बान |
| 24 | सुदृढीकरण सीखने का परिचय | [सुदृढीकरण सीखना](../8-Reinforcement/README.md)| क्यू-लर्निंग के साथ सुदृढीकरण सीखने का परिचय | [पायथन](../8-Reinforcement/1-QLearning/README.md) | दिमित्री |
| 25 | पीटर को भेड़िये से बचने में मदद करें! | [सुदृढीकरण सीखना](../8-Reinforcement/README.md) | सुदृढीकरण सीखने जिम | [पायथन](../8-Reinforcement/2-Gym/README.md) | दिमित्री |
| पोस्टस्क्रिप्ट | रीयल-वर्ल्ड एमएल परिदृश्य और अनुप्रयोग | [एमएल इन द वाइल्ड](../9-Real-World/README.md)| शास्त्रीय एमएल के दिलचस्प और खुलासा वास्तविक दुनिया के अनुप्रयोग | [पाठ](../9-Real-World/1-Applications/README.md) | टीम |
## ऑफ़लाइन पहुंच
आप [Docsify](https://docsify.js.org/#/) का उपयोग करके इस दस्तावेज़ को ऑफ़लाइन चला सकते हैं। इस रेपो को फोर्क करें, [इंस्टॉल Docsify](https://docsify.js.org/#/quickstart) अपनी स्थानीय मशीन पर, और फिर इस रेपो के रूट फ़ोल्डर में, `docsify सर्व करें` टाइप करें। वेबसाइट को आपके लोकलहोस्ट पर पोर्ट 3000 पर परोसा जाएगा: `localhost:3000`।
## पीडीएफ़
लिंक के साथ पाठ्यक्रम का एक पीडीएफ खोजें [यहां](https://microsoft.github.io/ML-For-Beginners/pdf/readme.pdf)।
## मदद अपेक्षित!
क्या आप अनुवाद में योगदान देना चाहेंगे? कृपया हमारे [अनुवाद दिशानिर्देश](TRANSLATIONS.md) पढ़ें और कार्यभार को प्रबंधित करने के लिए एक टेम्पलेट समस्या जोड़ें [यहां](https://github.com/microsoft/ML-For-Beginners/issues)।
## अन्य पाठ्यक्रम
हमारी टीम अन्य पाठ्यक्रम तैयार करती है! चेक आउट:
- [शुरुआती के लिए वेब देव](https://aka.ms/webdev-beginners)
- [शुरुआती के लिए IoT](https://aka.ms/iot-beginners)
- [शुरुआती के लिए डेटा विज्ञान](https://aka.ms/datascience-beginners)

@ -74,31 +74,31 @@
| 课程编号 | 主体 | 课程组 | 学习目标 | 课程链接 | 作者 | | 课程编号 | 主体 | 课程组 | 学习目标 | 课程链接 | 作者 |
| :------: | :------------------------------------------: | :-----------------------------------------------: | ----------------------------------------------------------------------- | :----------------------------------------------------: | :-----------: | | :------: | :------------------------------------------: | :-----------------------------------------------: | ----------------------------------------------------------------------- | :----------------------------------------------------: | :-----------: |
| 01 | 机器学习简介 | [简介](../1-Introduction/README.md) | 了解机器学习背后的基本概念 | [课程](../1-Introduction/1-intro-to-ML/README.md) | Muhammad | | 01 | 机器学习简介 | [简介](../1-Introduction/translations/README.zh-cn.md) | 了解机器学习背后的基本概念 | [课程](../1-Introduction/1-intro-to-ML/translations/README.zh-cn.md) | Muhammad |
| 02 | 机器学习的历史 | [简介](../1-Introduction/README.md) | 了解该领域的历史 | [课程](../1-Introduction/2-history-of-ML/README.md) | Jen 和 Amy | | 02 | 机器学习的历史 | [简介](../1-Introduction/translations/README.zh-cn.md) | 了解该领域的历史 | [课程](../1-Introduction/2-history-of-ML/translations/README.zh-cn.md) | Jen 和 Amy |
| 03 | 机器学习与公平 | [简介](../1-Introduction/README.md) | 在构建和应用机器学习模型时,我们应该考虑哪些有关公平的重要哲学问题? | [课程](../1-Introduction/3-fairness/README.md) | Tomomi | | 03 | 机器学习与公平 | [简介](../1-Introduction/translations/README.zh-cn.md) | 在构建和应用机器学习模型时,我们应该考虑哪些有关公平的重要哲学问题? | [课程](../1-Introduction/3-fairness/translations/README.zh-cn.md) | Tomomi |
| 04 | 机器学习的技术工具 | [简介](../1-Introduction/README.md) | 机器学习研究者使用哪些技术来构建机器学习模型? | [课程](../1-Introduction/4-techniques-of-ML/README.md) | Chris 和 Jen | | 04 | 机器学习的技术工具 | [简介](../1-Introduction/translations/README.zh-cn.md) | 机器学习研究者使用哪些技术来构建机器学习模型? | [课程](../1-Introduction/4-techniques-of-ML/translations/README.zh-cn.md) | Chris 和 Jen |
| 05 | 回归简介 | [回归](../2-Regression/README.md) | 开始使用 Python 和 Scikit-learn 构建回归模型 | [课程](../2-Regression/1-Tools/README.md) | Jen | | 05 | 回归简介 | [回归](../2-Regression/translations/README.zh-cn.md) | 开始使用 Python 和 Scikit-learn 构建回归模型 | [课程](../2-Regression/1-Tools/translations/README.zh-cn.md) | Jen |
| 06 | 北美南瓜价格 🎃 | [回归](../2-Regression/README.md) | 可视化、进行数据清理,为机器学习做准备 | [课程](../2-Regression/2-Data/README.md) | Jen | | 06 | 北美南瓜价格 🎃 | [回归](../2-Regression/translations/README.zh-cn.md) | 可视化、进行数据清理,为机器学习做准备 | [课程](../2-Regression/2-Data/translations/README.zh-cn.md) | Jen |
| 07 | 北美南瓜价格 🎃 | [回归](../2-Regression/README.md) | 建立线性和多项式回归模型 | [课程](../2-Regression/3-Linear/README.md) | Jen | | 07 | 北美南瓜价格 🎃 | [回归](../2-Regression/translations/README.zh-cn.md) | 建立线性和多项式回归模型 | [课程](../2-Regression/3-Linear/translations/README.zh-cn.md) | Jen |
| 08 | 北美南瓜价格 🎃 | [回归](../2-Regression/README.md) | 构建逻辑回归模型 | [课程](../2-Regression/4-Logistic/README.md) | Jen | | 08 | 北美南瓜价格 🎃 | [回归](../2-Regression/translations/README.zh-cn.md) | 构建逻辑回归模型 | [课程](../2-Regression/4-Logistic/translations/README.zh-cn.md) | Jen |
| 09 | 一个网页应用 🔌 | [网页应用](../3-Web-App/README.md) | 构建一个 Web 应用程序以使用经过训练的模型 | [课程](../3-Web-App/1-Web-App/README.md) | Jen | | 09 | 一个网页应用 🔌 | [网页应用](../3-Web-App/translations/README.zh-cn.md) | 构建一个 Web 应用程序以使用经过训练的模型 | [课程](../3-Web-App/1-Web-App/translations/README.zh-cn.md) | Jen |
| 10 | 分类简介 | [分类](../4-Classification/README.md) | 清理、准备和可视化数据; 分类简介 | [课程](../4-Classification/1-Introduction/README.md) | Jen 和 Cassie | | 10 | 分类简介 | [分类](../4-Classification/translations/README.zh-cn.md) | 清理、准备和可视化数据; 分类简介 | [课程](../4-Classification/1-Introduction/translations/README.zh-cn.md) | Jen 和 Cassie |
| 11 | 美味的亚洲和印度美食 🍜 | [分类](../4-Classification/README.md) | 分类器简介 | [课程](../4-Classification/2-Classifiers-1/README.md) | Jen 和 Cassie | | 11 | 美味的亚洲和印度美食 🍜 | [分类](../4-Classification/translations/README.zh-cn.md) | 分类器简介 | [课程](../4-Classification/2-Classifiers-1/translations/README.zh-cn.md) | Jen 和 Cassie |
| 12 | 美味的亚洲和印度美食 🍜 | [分类](../4-Classification/README.md) | 关于分类器的更多内容 | [课程](../4-Classification/3-Classifiers-2/README.md) | Jen 和 Cassie | | 12 | 美味的亚洲和印度美食 🍜 | [分类](../4-Classification/translations/README.zh-cn.md) | 关于分类器的更多内容 | [课程](../4-Classification/3-Classifiers-2/translations/README.zh-cn.md) | Jen 和 Cassie |
| 13 | 美味的亚洲和印度美食 🍜 | [分类](../4-Classification/README.md) | 使用您的模型构建一个可以「推荐」的 Web 应用 | [课程](../4-Classification/4-Applied/README.md) | Jen | | 13 | 美味的亚洲和印度美食 🍜 | [分类](../4-Classification/translations/README.zh-cn.md) | 使用您的模型构建一个可以「推荐」的 Web 应用 | [课程](../4-Classification/4-Applied/translations/README.zh-cn.md) | Jen |
| 14 | 聚类简介 | [聚类](../5-Clustering/README.md) | 清理、准备和可视化数据; 聚类简介 | [课程](../5-Clustering/1-Visualize/README.md) | Jen | | 14 | 聚类简介 | [聚类](../5-Clustering/translations/README.zh-cn.md) | 清理、准备和可视化数据; 聚类简介 | [课程](../5-Clustering/1-Visualize/translations/README.zh-cn.md) | Jen |
| 15 | 探索尼日利亚人的音乐品味 🎧 | [聚类](../5-Clustering/README.md) | 探索 K-Means 聚类方法 | [课程](../5-Clustering/2-K-Means/README.md) | Jen | | 15 | 探索尼日利亚人的音乐品味 🎧 | [聚类](../5-Clustering/translations/README.zh-cn.md) | 探索 K-Means 聚类方法 | [课程](../5-Clustering/2-K-Means/translations/README.zh-cn.md) | Jen |
| 16 | 自然语言处理 (NLP) 简介 ☕️ | [自然语言处理](../6-NLP/README.md) | 通过构建一个简单的 bot (机器人) 来了解 NLP 的基础知识 | [课程](../6-NLP/1-Introduction-to-NLP/README.md) | Stephen | | 16 | 自然语言处理 (NLP) 简介 ☕️ | [自然语言处理](../6-NLP/translations/README.zh-cn.md) | 通过构建一个简单的 bot (机器人) 来了解 NLP 的基础知识 | [课程](../6-NLP/1-Introduction-to-NLP/translations/README.zh-cn.md) | Stephen |
| 17 | 常见的 NLP 任务 ☕️ | [自然语言处理](../6-NLP/README.md) | 通过理解处理语言结构时所需的常见任务来加深对于自然语言处理 (NLP) 的理解 | [课程](../6-NLP/2-Tasks/README.md) | Stephen | | 17 | 常见的 NLP 任务 ☕️ | [自然语言处理](../6-NLP/translations/README.zh-cn.md) | 通过理解处理语言结构时所需的常见任务来加深对于自然语言处理 (NLP) 的理解 | [课程](../6-NLP/2-Tasks/README.md) | Stephen |
| 18 | 翻译和情感分析 ♥️ | [自然语言处理](../6-NLP/README.md) | 对简·奥斯汀的文本进行翻译和情感分析 | [课程](../6-NLP/3-Translation-Sentiment/README.md) | Stephen | | 18 | 翻译和情感分析 ♥️ | [自然语言处理](../6-NLP/translations/README.zh-cn.md) | 对简·奥斯汀的文本进行翻译和情感分析 | [课程](../6-NLP/3-Translation-Sentiment/README.md) | Stephen |
| 19 | 欧洲的浪漫酒店 ♥️ | [自然语言处理](../6-NLP/README.md) | 对于酒店评价进行情感分析(上) | [课程](../6-NLP/4-Hotel-Reviews-1/README.md) | Stephen | | 19 | 欧洲的浪漫酒店 ♥️ | [自然语言处理](../6-NLP/translations/README.zh-cn.md) | 对于酒店评价进行情感分析(上) | [课程](../6-NLP/4-Hotel-Reviews-1/README.md) | Stephen |
| 20 | 欧洲的浪漫酒店 ♥️ | [自然语言处理](../6-NLP/README.md) | 对于酒店评价进行情感分析(下) | [课程](../6-NLP/5-Hotel-Reviews-2/README.md) | Stephen | | 20 | 欧洲的浪漫酒店 ♥️ | [自然语言处理](../6-NLP/translations/README.zh-cn.md) | 对于酒店评价进行情感分析(下) | [课程](../6-NLP/5-Hotel-Reviews-2/README.md) | Stephen |
| 21 | 时间序列预测简介 | [时间序列](../7-TimeSeries/README.md) | 时间序列预测简介 forecasting | [课程](../7-TimeSeries/1-Introduction/README.md) | Francesca | | 21 | 时间序列预测简介 | [时间序列](../7-TimeSeries/translations/README.zh-cn.md) | 时间序列预测简介 forecasting | [课程](../7-TimeSeries/1-Introduction/README.md) | Francesca |
| 22 | ⚡️ 世界用电量 ⚡️ - 使用 ARIMA 进行时间序列预测 | [时间序列](../7-TimeSeries/README.md) | 使用 ARIMA 进行时间序列预测 | [课程](../7-TimeSeries/2-ARIMA/README.md) | Francesca | | 22 | ⚡️ 世界用电量 ⚡️ - 使用 ARIMA 进行时间序列预测 | [时间序列](../7-TimeSeries/translations/README.zh-cn.md) | 使用 ARIMA 进行时间序列预测 | [课程](../7-TimeSeries/2-ARIMA/README.md) | Francesca |
| 23 | 强化学习简介 | [强化学习](../8-Reinforcement/README.md) | Q-Learning 强化学习简介 | [课程](../8-Reinforcement/1-QLearning/README.md) | Dmitry | | 23 | 强化学习简介 | [强化学习](../8-Reinforcement/translations/README.zh-cn.md) | Q-Learning 强化学习简介 | [课程](../8-Reinforcement/1-QLearning/translations/README.zh-cn.md) | Dmitry |
| 24 | 帮助 Peter 避开狼!🐺 | [强化学习](../8-Reinforcement/README.md) | 强化学习练习 | [课程](../8-Reinforcement/2-Gym/README.md) | Dmitry | | 24 | 帮助 Peter 避开狼!🐺 | [强化学习](../8-Reinforcement/translations/README.zh-cn.md) | 强化学习练习 | [课程](../8-Reinforcement/2-Gym/translations/README.zh-cn.md) | Dmitry |
| 后记 | 现实世界中的机器学习场景和应用 | [自然场景下的机器学习](../9-Real-World/README.md) | 探索有趣的经典机器学习方法,了解现实世界中机器学习的应用 | [课程](../9-Real-World/1-Applications/README.md) | 团队 | | 后记 | 现实世界中的机器学习场景和应用 | [自然场景下的机器学习](../9-Real-World/translations/README.zh-cn.md) | 探索有趣的经典机器学习方法,了解现实世界中机器学习的应用 | [课程](../9-Real-World/1-Applications/README.md) | 团队 |
## 离线访问 ## 离线访问
您可以使用 [Docsify](https://docsify.js.org/#/) 离线运行此文档。 Fork 这个仓库,并在你的本地机器上[安装 Docsify](https://docsify.js.org/#/quickstart),并在这个仓库的根文件夹中运行 `docsify serve`。你可以通过 localhost 的 3000 端口访问此文档:`localhost:3000`。 您可以使用 [Docsify](https://docsify.js.org/#/) 离线运行此文档。 Fork 这个仓库,并在你的本地机器上[安装 Docsify](https://docsify.js.org/#/quickstart),并在这个仓库的根文件夹中运行 `docsify serve`。你可以通过 localhost 的 3000 端口访问此文档:`localhost:3000`。

@ -0,0 +1,132 @@
[![GitHub license](https://img.shields.io/github/license/microsoft/ML-For-Beginners.svg)](https://github.com/microsoft/ML-For-Beginners/blob/master/LICENSE)
[![GitHub contributors](https://img.shields.io/github/contributors/microsoft/ML-For-Beginners.svg)](https://GitHub.com/microsoft/ML-For-Beginners/graphs/contributors/)
[![GitHub issues](https://img.shields.io/github/issues/microsoft/ML-For-Beginners.svg)](https://GitHub.com/microsoft/ML-For-Beginners/issues/)
[![GitHub pull-requests](https://img.shields.io/github/issues-pr/microsoft/ML-For-Beginners.svg)](https://GitHub.com/microsoft/ML-For-Beginners/pulls/)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
[![GitHub watchers](https://img.shields.io/github/watchers/microsoft/ML-For-Beginners.svg?style=social&label=Watch)](https://GitHub.com/microsoft/ML-For-Beginners/watchers/)
[![GitHub forks](https://img.shields.io/github/forks/microsoft/ML-For-Beginners.svg?style=social&label=Fork)](https://GitHub.com/microsoft/ML-For-Beginners/network/)
[![GitHub stars](https://img.shields.io/github/stars/microsoft/ML-For-Beginners.svg?style=social&label=Star)](https://GitHub.com/microsoft/ML-For-Beginners/stargazers/)
# ஆரம்பநிலைக்கான இயந்திர கற்றல் - ஒரு பாடத்திட்டம்
> 🌍 உலக கலாச்சாரங்களின் மூலம் இயந்திர கற்றலை நாங்கள் ஆராயும்போது உலகம் முழுவதும் பயணம் செய்யுங்கள் 🌍
மைக்ரோசாப்ட் நிறுவனத்தில் உள்ள அஸூர் கிளவுட் வக்கீல்கள், இயந்திர கற்றல் பற்றிய 12-வாரம், 26-பாடம் பாடத்திட்டத்தை வழங்குவதில் மகிழ்ச்சியடைகிறார்கள். இந்தப் பாடத்திட்டத்தில், சில சமயங்களில் கிளாசிக் மெஷின் லேர்னிங் என்று அழைக்கப்படுவதைப் பற்றி நீங்கள் அறிந்துகொள்வீர்கள், முதன்மையாக ஸ்கிகிட்-லேர்னை நூலகமாகப் பயன்படுத்தி, ஆழ்ந்த கற்றலைத் தவிர்ப்பீர்கள், இது எங்களின் வரவிருக்கும் 'ஆரம்பநிலையாளர்களுக்கான AI' பாடத்திட்டத்தில் உள்ளடக்கப்பட்டுள்ளது. இந்தப் பாடங்களை எங்களுடன் இணைக்கவும் ['தொடக்கங்களுக்கான தரவு அறிவியல்' பாடத்திட்டம்](https://aka.ms/datascience-beginners), அத்துடன்!
உலகின் பல பகுதிகளில் உள்ள தரவுகளுக்கு இந்த உன்னதமான நுட்பங்களைப் பயன்படுத்துவதால், எங்களுடன் உலகம் முழுவதும் பயணம் செய்யுங்கள். ஒவ்வொரு பாடத்திலும் பாடத்திற்கு முந்தைய மற்றும் பிந்தைய வினாடி வினாக்கள், பாடத்தை முடிக்க எழுதப்பட்ட வழிமுறைகள், ஒரு தீர்வு, ஒரு பணி மற்றும் பல உள்ளன. எங்கள் திட்ட அடிப்படையிலான கற்பித்தல், புதிய திறன்களை 'ஒட்டிக்கொள்ள' ஒரு நிரூபிக்கப்பட்ட வழி, கட்டும் போது கற்றுக்கொள்ள அனுமதிக்கிறது.
**✍️ எங்கள் ஆசிரியர்களுக்கு மனமார்ந்த நன்றிகள்** ஜென் லூப்பர், ஸ்டீபன் ஹோவெல், ஃபிரான்செஸ்கா லாஸ்ஸெரி, டோமோமி இமுரா, காஸ்ஸி ப்ரீவியூ, டிமிட்ரி சோஷ்னிகோவ், கிறிஸ் நோரிங், அனிர்பன் முகர்ஜி, ஓர்னெல்லா அல்துன்யன் மற்றும் ஆமி பாய்ட்
**🎨 எங்கள் ஓவியர்களுக்கும் நன்றி** டோமோமி இமுரா, தசானி மடிபல்லி மற்றும் ஜென் லூப்பர்
**🙏 சிறப்பு நன்றி 🙏 எங்கள் Microsoft மாணவர் தூதர் ஆசிரியர்கள், விமர்சகர்கள் மற்றும் உள்ளடக்க பங்களிப்பாளர்களுக்கு**, குறிப்பாக ரிஷித் டாக்லி, முஹம்மது சாகிப் கான் இனான், ரோஹன் ராஜ், அலெக்ஸாண்ட்ரு பெட்ரெஸ்கு, அபிஷேக் ஜெய்ஸ்வால், நவ்ரின் தபாசும், இயோன் சாமுயிலா மற்றும் ஸ்னிக்தா அகர்வால்
**🤩 எங்கள் R பாடங்களுக்காக மைக்ரோசாஃப்ட் மாணவர் தூதர் எரிக் வான்ஜாவுக்கு கூடுதல் நன்றி!**
---
# தொடங்குதல்
**[மாணவர்கள்](https://docs.microsoft.com/en-gb/learn/student-hub/)**, இந்தப் பாடத்திட்டத்தைப் பயன்படுத்த, உங்கள் சொந்த கிட்ஹப் கணக்கில் முழு ரெப்போவையும் பிரித்து, பயிற்சிகளை நீங்களே அல்லது ஒரு குழுவுடன் முடிக்கவும்:
- விரிவுரைக்கு முந்தைய வினாடி வினாவுடன் தொடங்கவும்.
- விரிவுரையைப் படித்து செயல்பாடுகளை முடிக்கவும், ஒவ்வொரு அறிவுச் சரிபார்ப்பிலும் இடைநிறுத்தப்பட்டு பிரதிபலிக்கவும்.
- தீர்வுக் குறியீட்டை இயக்குவதை விட பாடங்களைப் புரிந்துகொண்டு திட்டங்களை உருவாக்க முயற்சிக்கவும்; இருப்பினும் அந்த குறியீடு ஒவ்வொரு திட்டம் சார்ந்த பாடத்திலும் `/தீர்வு` கோப்புறைகளில் கிடைக்கும்.
- விரிவுரைக்குப் பிந்தைய வினாடி வினாவை எடுத்துக் கொள்ளுங்கள்.
- சவாலை முடிக்கவும்.
- வேலையை முடிக்கவும்.
- ஒரு பாடம் குழுவை முடித்த பிறகு, பார்வையிடவும் [கலந்துரையாடல் குழு](https://github.com/microsoft/ML-For-Beginners/discussions) மற்றும் "சத்தமாக கற்க" பொருத்தமான PAT rubric ஐ நிரப்புவதன் மூலம். ஒரு 'PAT' என்பது முன்னேற்ற மதிப்பீட்டுக் கருவியாகும், இது உங்கள் கற்றலை மேலும் மேம்படுத்த நீங்கள் நிரப்பும் ரூபிரிக் ஆகும். நீங்கள் மற்ற PAT களுக்கு எதிர்வினையாற்றலாம், எனவே நாங்கள் ஒன்றாகக் கற்றுக்கொள்ளலாம்.
> மேலும் ஆய்வுக்கு, இவற்றைப் பின்பற்ற பரிந்துரைக்கிறோம் [மைக்ரோசாப்ட் கற்றல்](https://docs.microsoft.com/en-us/users/jenlooper-2911/collections/k7o7tg1gp306q4?WT.mc_id=academic-15963-cxa)தொகுதிகள் மற்றும் கற்றல் பாதைகள்.
**ஆசிரியர்கள்**, எங்களிடம் உள்ளது [சில பரிந்துரைகளை உள்ளடக்கியது](https://github.com/microsoft/ML-For-Beginners/blob/main/for-teachers.md) இந்த பாடத்திட்டத்தை எவ்வாறு பயன்படுத்துவது.
---
## குழுவை சந்திக்கவும்
[![Promo video](../ml.gif)](https://youtu.be/Tj1XWrDSYJU "Promo video")
**Gif de** [Mohit Jaisal](https://linkedin.com/in/mohitjaisal)
> 🎥 திட்டம் மற்றும் அதை உருவாக்கியவர்கள் பற்றிய வீடியோவிற்கு மேலே உள்ள படத்தை கிளிக் செய்யவும்!
---
## கல்வியியல்
இந்தப் பாடத்திட்டத்தை உருவாக்கும் போது இரண்டு கல்வியியல் கோட்பாடுகளை நாங்கள் தேர்ந்தெடுத்துள்ளோம்: இது நடைமுறையில் இருப்பதை உறுதி செய்தல் **திட்ட அடிப்படையிலான**
மற்றும் அதில் அடங்கும் **அடிக்கடி வினாடி வினா**. கூடுதலாக, இந்த பாடத்திட்டம் பொதுவானது **தீம்** அதை ஒருங்கிணைக்க.
திட்டங்களுடன் உள்ளடக்கம் சீரமைக்கப்படுவதை உறுதி செய்வதன் மூலம், செயல்முறை மாணவர்களுக்கு மிகவும் ஈடுபாட்டுடன் உருவாக்கப்படுகிறது மற்றும் கருத்துகளைத் தக்கவைத்தல் அதிகரிக்கப்படும். கூடுதலாக, ஒரு வகுப்பிற்கு முன் ஒரு குறைந்த வினாடி வினா, ஒரு தலைப்பைக் கற்கும் மாணவர்களின் நோக்கத்தை அமைக்கிறது, அதே நேரத்தில் வகுப்பிற்குப் பிறகு இரண்டாவது வினாடி வினா மேலும் தக்கவைப்பை உறுதி செய்கிறது. இந்த பாடத்திட்டம் நெகிழ்வான மற்றும் வேடிக்கையாக வடிவமைக்கப்பட்டுள்ளது மற்றும் முழுமையாகவோ அல்லது பகுதியாகவோ எடுக்கப்படலாம். திட்டங்கள் சிறியதாக தொடங்கி 12 வார சுழற்சியின் முடிவில் பெருகிய முறையில் சிக்கலானதாக மாறும். இந்தப் பாடத்திட்டத்தில் ML இன் நிஜ-உலகப் பயன்பாடுகள் பற்றிய போஸ்ட்ஸ்கிரிப்ட் உள்ளது, இது கூடுதல் கடன் அல்லது விவாதத்திற்கான அடிப்படையாகப் பயன்படுத்தப்படலாம்.
> எங்களுடையதைக் கண்டுபிடி [நடத்தை விதிகள்](https://github.com/microsoft/ML-For-Beginners/blob/main/CODE_OF_CONDUCT.md), [பங்களிக்கிறது](https://github.com/microsoft/ML-For-Beginners/blob/main/CONTRIBUTING.md), மற்றும் [மொழிபெயர்ப்பு](https://github.com/microsoft/ML-For-Beginners/blob/main/TRANSLATIONS.md) வழிகாட்டுதல்கள். உங்கள் ஆக்கபூர்வமான கருத்தை நாங்கள் வரவேற்கிறோம்!
## ஒவ்வொரு பாடமும் அடங்கும்:
- விருப்ப ஓவியக் குறிப்பு
- விருப்பமான துணை வீடியோ
- விரிவுரைக்கு முந்தைய பயிற்சி வினாடி வினா
- எழுதப்பட்ட பாடம்
- திட்ட அடிப்படையிலான பாடங்களுக்கு, திட்டத்தை எவ்வாறு உருவாக்குவது என்பது குறித்த படிப்படியான வழிகாட்டிகள்
- அறிவு சோதனைகள்
- சவால்
- துணை வாசிப்பு
- பணி நியமனம்
- விரிவுரைக்குப் பிந்தைய வினாடிவினா
> மொழிகள் பற்றிய குறிப்பு: இந்தப் பாடங்கள் முதன்மையாக பைத்தானில் எழுதப்பட்டுள்ளன, ஆனால் பல R இல் கிடைக்கின்றன. ஆர் பாடத்தை முடிக்க, செல்லவும் `/தீர்வு` கோப்புறை மற்றும் R பாடங்களைத் தேடுங்கள். அவை ஒரு .rmd நீட்டிப்பைக் குறிக்கும் **ஆர் மார்க் டவுன்** ஒரு உட்பொதிவு என எளிமையாக வரையறுக்கக்கூடிய கோப்பு `குறியீடு துண்டுகள்` (ஆர் அல்லது பிற மொழிகளில்) மற்றும் ஏ
> `YAML தலைப்பு` (PDF போன்ற வெளியீடுகளை எப்படி வடிவமைப்பது என்று வழிகாட்டுகிறது)
> ஒரு `மார்க் டவுன் ஆவணம்`. எனவே, இது தரவு அறிவியலுக்கான முன்மாதிரியான ஆசிரியர் கட்டமைப்பாக செயல்படுகிறது, ஏனெனில் இது உங்கள் குறியீடு, அதன் வெளியீடு மற்றும் உங்கள் எண்ணங்களை மார்க் டவுனில் எழுத அனுமதிப்பதன் மூலம் ஒருங்கிணைக்க அனுமதிக்கிறது. மேலும், R மார்க் டவுன் ஆவணங்கள் PDF, HTML அல்லது Word போன்ற வெளியீட்டு வடிவங்களுக்கு வழங்கப்படலாம்.
> வினாடி வினா பற்றிய குறிப்பு: அனைத்து வினாடி வினாக்களும் அடங்கியுள்ளன [இந்த பயன்பாட்டில்](https://white-water-09ec41f0f.azurestaticapps.net/), தலா மூன்று கேள்விகள் கொண்ட 52 மொத்த வினாடி வினாக்களுக்கு. அவை பாடங்களுக்குள் இருந்து இணைக்கப்பட்டுள்ளன ஆனால் வினாடி வினா பயன்பாட்டை உள்நாட்டில் இயக்க முடியும்; இல் உள்ள வழிமுறைகளைப் பின்பற்றவும் `வினாடி வினா-பயன்பாடு`.
| பாடம் எண் | தலைப்பு | பாடம் தொகுத்தல் | கற்றல் நோக்கங்கள் | இணைக்கப்பட்ட பாடம் | நூலாசிரியர் |
| :--------: | :-----------------------------------------: | :----------------------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------- | :-----------------------------------------------------: | :-----------------: |
| 01 | இயந்திர கற்றல் அறிமுகம் | [இயந்திர கற்றல் அறிமுகம்](../1-Introduction/README.md) | இயந்திர கற்றலுக்குப் பின்னால் உள்ள அடிப்படைக் கருத்துகளைக் கற்றுக்கொள்ளுங்கள் | [பாடம்](../1-Introduction/1-intro-to-ML/README.md) | முஹம்மது |
| 02 | இயந்திர கற்றலின் வரலாறு | [அறிமுகம்](../1-Introduction/README.md) | இந்தத் துறையில் உள்ள வரலாற்றைக் கற்றுக்கொள்ளுங்கள் | [பாடம்](../1-Introduction/2-history-of-ML/README.md) | ஜென் மற்றும் ஆமி |
| 03 | நேர்மை மற்றும் இயந்திர கற்றல் | [அறிமுகம்](../1-Introduction/README.md) | எம்எல் மாடல்களை உருவாக்கி பயன்படுத்தும்போது மாணவர்கள் கருத்தில் கொள்ள வேண்டிய நியாயத்தன்மையைச் சுற்றியுள்ள முக்கியமான தத்துவ சிக்கல்கள் என்ன? | [பாடம்](../1-Introduction/3-fairness/README.md) | டோமோமி |
| 04 | இயந்திர கற்றலுக்கான நுட்பங்கள் | [அறிமுகம்](../1-Introduction/README.md) | ML மாதிரிகளை உருவாக்க ML ஆராய்ச்சியாளர்கள் என்ன த்துகிறார்கள்? | [பாடம்](../1-Introduction/4-techniques-of-ML/README.md) | கிறிஸ் மற்றும் ஜென் |
| 05 | பின்னடைவு அறிமுகம் | [பின்னடைவு](../2-Regression/README.md) | பின்னடைவு மாதிரிகளுக்கான பைதான் மற்றும் Scikit-Learn உடன் தொடங்கவும் | [பாடம்](../2-Regression/1-Tools/README.md) | ஜென் |
| 06 | பின்னடைவு அறிமுகம் 🎃 | [பின்னடைவு](../2-Regression/README.md) | ML க்கான தயாரிப்பில் தரவை காட்சிப்படுத்தவும் மற்றும் சுத்தம் செய்யவும் | [பாடம்](../2-Regression/2-Data/README.md) | ஜென் |
| 07 | பின்னடைவு அறிமுகம் 🎃 | [பின்னடைவு](../2-Regression/README.md) | நேரியல் மற்றும் பல்லுறுப்புக்கோவை பின்னடைவு மாதிரிகளை உருவாக்கவும் | [பாடம்](../2-Regression/3-Linear/README.md) | ஜென் |
| 08 | பின்னடைவு அறிமுகம் 🎃 | [பின்னடைவு](../2-Regression/README.md) | லாஜிஸ்டிக் பின்னடைவு மாதிரியை உருவாக்கவும் | [பாடம்](../2-Regression/4-Logistic/README.md) | ஜென் |
| 09 | ஒரு இணைய பயன்பாடு 🔌 | [இணைய ஆப்](../3-Web-App/README.md) | நீங்கள் பயிற்சி பெற்ற மாதிரியைப் பயன்படுத்த இணைய பயன்பாட்டை உருவாக்கவும் | [பாடம்](../3-Web-App/1-Web-App/README.md) | ஜென் |
| 10 | வகைபடின் அறிமுகம் 🎃 | [வகைப்பாடு](../4-Classification/README.md) | உங்கள் தரவை சுத்தம் செய்யவும், தயார் செய்யவும் மற்றும் காட்சிப்படுத்தவும்; வகைப்பாட்டின் அறிமுகம் | [பாடம்](../4-Classification/1-Introduction/README.md) | ஜென் மற்றும் காசி |
| 11 | சுவைய மற்றும் இந்திய வகைகள் 🍜 | [வகைப்பாடு](../4-Classification/README.md) | வகைப்படுத்தின அறிமுகம் | [பாடம்](../4-Classification/2-Classifiers-1/README.md) | ஜென் மற்றும் காசி |
| 12 | சுவையான ஆசிய மற்றும் இந்திய உணவு வகைகள் 🍜 | [வகைப்பாடு](../4-Classification/README.md) | மேலும் வகைப்படுத்திகள் | [பாடம்](../4-Classification/3-Classifiers-2/README.md) | ஜென் மற்றும் காசி |
| 13 | சுவையான ஆசிய மற்றும் இந்திய உணவு வகைகள் 🍜 | [வகைப்பாடு](../4-Classification/README.md) | உங்கள் மாதிரியைப் பயன்படுத்தி பரிந்துரைக்கும் இணைய பயன்பாட்டை உருவாக்கவும் | [பாடம்](../4-Classification/4-Applied/README.md) | ஜென் |
| 14 | கிளஸ்டரிங் அறிமுகம் | [கிளஸ்டரிங்](../5-Clustering/README.md) | உங்கள் தரவை சுத்தம் செய்யவும், தயார் செய்யவும் மற்றும் காட்சிப்படுத்தவும்; கிளஸ்டரிங் அறிமுகம் | [பாடம்](../5-Clustering/1-Visualize/README.md) | ஜென் |
| 15 | நைஜீரிய இசை சுவைகளை ஆராய்தல் 🎧 | [கிளஸ்டரிங்](../5-Clustering/README.md) | K-Means கிளஸ்டரிங் முறையை ஆராயுங்கள் அறிமுகம் | [பாடம்](../5-Clustering/2-K-Means/README.md) | ஜென் |
| 16 | இயற்கை மொழி செயலாக்கம் ☕️ அறிமுகம் | [இயற்கை மொழி செக்கம்](../6-NLP/README.md) | ஒரு எளிய போட்டன் மூலம் NLP பற்றிய டைகளை அறியவும் | [பாடம்](../6-NLP/1-Introduction-to-NLP/README.md) | ஸ்டீபன் |
| 17 | StepheCommon NLP பணிகள் ☕️ | [இயற்கை மொழி செயகம்](../6-NLP/README.md) | மொழி கட்டமைப்புகளைக் கையடும் பொதுவான பணிகளைப் புரிந்தள்வதன் மூலம் உங்கள் NLP அறிவை ஆழமாக்குங்கள் | [பாடம்](../6-NLP/2-Tasks/README.md) | ஸ்டீபன் |
| 18 | மொழிபெயர்ப்பு மற்றும் ♥️ | [இயற்கை செயலா](../6-NLP/README.md) | ஜேன் ஆஸ்டனுடன் மொழிபெயர்ப்பு | [பாடம்](../6-NLP/3-Translation-Sentiment/README.md) | ஸ்டீபன் |
| 19 | ஐரோப்பாவின் காதல் ♥ | [இயற்கை மொழி செயலாக்கம்](../6-NLP/README.md) | ஹோட்டல் மதிப்புரைகளுடன் உணர்வு பகுப்பாய்வு 1 | [பாடம்](../6-NLP/4-Hotel-Reviews-1/README.md) | ஸ்டீபன் |
| 20 | ஐரோப்பாவின் காதல் ♥ | [இயற்கை மொழி செயலாக்கம்](../6-NLP/README.md) | ஹோட்டல் மதிப்புரைகளுடன் உணர்வு பகுப்பாய்வு 2 | [பாடம்](../6-NLP/5-Hotel-Reviews-2/README.md) | ஸ்டீபன் |
| 21 | நேரத் தொடர் முன்னறிவிப்பு | [நேரத் தொடர்](../7-TimeSeries/README.md) | Iநேரத் தொடர் முன்னறிவிப்பு | [பாடம்](../7-TimeSeries/1-Introduction/README.md) | பிரான்செஸ்கா |
| 22 | ⚡️ உலக சக்தபாடு ⚡️ - ARIMA உடன | [நேரத் தொடர்](../7-TimeSeries/README.md) | ARIMA உடன் நே முன்னறிவிப்பு | [பாடம்](../7-TimeSeries/2-ARIMA/README.md) | பிரான்செஸ்கா |
| 23 | ⚡️ உலக சக்தி பயன்பாடு ⚡️ - SVR உடன் நேரர் | [நேரத் தொடர்](../8-Reinforcement/README.md) | ஆதரவு வெக்டர் ரிக்ரஸருடன் நேரத் தொடர் | [பாடம்](../8-Reinforcement/1-QLearning/README.md) | அனிர்பன் |
| 24 | ஓநாயை தவிர்க்க உதவுங்கள்! 🐺 | [வலுவூட்டல் கற்றல்](../8-Reinforcement/README.md) | வலுவூட்டல் கற்றல் | [பாடம்](../8-Reinforcement/2-Gym/README.md) | டிமிட்ரி |
| Postscript | நிஜ உலக ML காட்சிகள் மற்றும் பயன்பாடுகள் | [காட்டில் எம்.எல்](../9-Real-World/README.md) | கிளாசிக்கல் ML இன் சுவாரஸ்யமான மற்றும் வெளிப்படுத்தும் நிஜ உலக பயன்பாடுகள் | [பாடம்](../9-Real-World/1-Applications/README.md) | குழு |
## ஆஃப்லைன் அணுகல்
பயன்படுத்தி இந்த ஆவணத்தை ஆஃப்லைனில் இயக்கலாம் [ஆவணப்படுத்து](https://docsify.js.org/#/). Dá fork neste repositório, [Docsify ஐ நிறுவவும்](https://docsify.js.org/#/quickstart) உங்கள் உள்ளூர் கணினியில், பின்னர் இந்த ரெப்போவின் ரூட் கோப்புறையில் தட்டச்சு செய்யவும் `docsify சேவை`. உங்கள் லோக்கல் ஹோஸ்டில் போர்ட் 3000 இல் இணையதளம் `வழங்கப்படும்:3000`.
## PDFகள்
இணைப்புகளுடன் பாடத்திட்டத்தின் pdfஐக் கண்டறியவும் [இங்கே](https://microsoft.github.io/ML-For-Beginners/pdf/readme.pdf)
## உதவி தேவை!
மொழிபெயர்ப்பில் பங்களிக்க விரும்புகிறீர்களா? தயவுசெய்து எங்களுடையதைப் படியுங்கள் [மொழிபெயர்ப்பு வழிகாட்டுதல்கள்](../TRANSLATIONS.md)
மற்றும் நிர்வகிக்க டெம்ப்ளேட் சிக்கலைச் சேர்க்கவும் பணிச்சுமை [இங்கே](https://github.com/microsoft/ML-For-Beginners/issues/71)
## பிற பாடத்திட்டங்கள்
எங்கள் குழு மற்ற பாடத்திட்டங்களை உருவாக்குகிறது! சரிபார்:
- [தொடக்கநிலையாளர்களுக்கான Web Dev](https://aka.ms/webdev-beginners)
- [ஆரம்பநிலைக்கு IoT](https://aka.ms/iot-beginners)
- [ஆரம்பநிலைக்கான தரவு அறிவியல்](https://aka.ms/datascience-beginners)
Loading…
Cancel
Save