Tema 3. Algoritmos aplicados al aprendizaje supervisado y optimización del modelo.docx

Full Transcript

Algoritmos aplicados al aprendizaje supervisado y optimización del modelo Aprendizaje supervisado Concepto Como hemos visto en el tema anterior, el aprendizaje supervisado se caracteriza porque los datos de entrada tienen asociadas etiquetas, de modo que, tras el entrenamiento...

Algoritmos aplicados al aprendizaje supervisado y optimización del modelo Aprendizaje supervisado Concepto Como hemos visto en el tema anterior, el aprendizaje supervisado se caracteriza porque los datos de entrada tienen asociadas etiquetas, de modo que, tras el entrenamiento del algoritmo, el modelo podrá predecir la etiqueta que tendrán los nuevos datos que se van introduciendo en el sistema -clasificación-, o bien una predicción numérica a partir de la función generada por un conjunto de muestras con valores numéricos asociados. La desventaja más importante del aprendizaje supervisado está en la dificultad del etiquetado, que es lento y laborioso, mientras que la mayor ventaja está en que una vez se realiza el entrenamiento, el modelo funciona mucho mejor que el de aprendizaje no supervisado. Métodos del aprendizaje supervisado Podemos distinguir dos métodos dentro del aprendizaje supervisado Regresión: la regresión permite determinar un valor a partir de una serie de valores dados, prediciendo los datos futuros a partir de una serie de datos ya existentes. Clasificación: en este caso se trata de clasificar los datos según etiquetas que corresponden a valores discretos o categorías. Preprocesado de datos Conjunto de entrenamiento y prueba Como hemos visto en el tema anterior, para poder realizar la validación del modelo precisamos dividir los datos en dos conjuntos, de entrenamiento y de prueba. Para ello usamos la función de Scikit-learn llamada train_test_split(), que tiene la siguiente forma donde datos es el conjunto de los atributos, etiquetas es el conjunto de las etiquetas, tam_prueba es el tamaño del conjunto de prueba y random_size genera la partición. Manejo de datos ausentes Los valores ausentes son un problema que impide usar ade- cuadamente los algoritmos de aprendizaje automático generando resultados no esperados. Para resolver este problema hay dos maneras, a vistas en la práctica VII del tema 2: Emplear la función dropna(), que con el parámetro axis a 0 elimina las filas donde hay valores ausentes, y con axis a 1 elimina las columnas donde hay valores ausentes. Emplear el concepto de imputación de valores ausentes, empleando la clase SimpleImputer dentro de sklearn.imputer, que permite sustituir los valores ausentes por la media, mediana o valores constantes. Un ejemplo se puede ver en el cuadro lateral Gestión de datos categóricos En el tema anterior se ha hablado del procedimiento de one-hot-encoding, que permitía convertir datos categóricos en binarios para poder trabajar con ellos. Para aplicarlo usamos la clase LabelEncoder, empleando los métodos fit_transform() y get_dummies(). En ambos casos se generan una serie de variables columna auxiliares de tipo binario a partir de la variable de tipo categórico. Escalamiento: normalización y estandarización También en el tema anterior -Práctica VII- se han estudiado la normalización y estandarización de los datos, conocidas conjuntamente como escalamiento, como una manera de simplificar los datos de manera que sea más fácil su empleo al estar todos en la misma escala. Para ello usamos en Python las funciones MinMaxScaler -normalización-, y StandardScaler -estandarización- de Scikit-learn. Métodos de regresión Introducción El objetivo de las técnicas de regresión es predecir la salida de un sistema a partir de una serie de variables de entrada. Para poder hacer estas predicciones precisamos un conjunto de datos clasificados en función de las características. La regresión puede ser lineal o no lineal -polinómica-. Regresión lineal La regresión lineal se utiliza cuando el conjunto de datos que se utiliza se puede representar como una función del tipo donde xi son las variables independientes, y es la variable dependiente, y wi son los coeficientes que se han de calcular a través de un proceso iterativo de optimización a partir del conjunto de datos disponible para obtener una gráfica -una recta sí solo hay una variable independiente, un plano sí son dos, un hiperplano sí son 3 o más- que pase lo más cerca posible de los puntos del conjunto de datos, -el residuo o diferencia entre el valor real y el valor predicho de la salida sea mínimo - y para poder predecir la salida a partir de nuevos datos. Para la implementación de este método con Python se emplea el método del gradiente descendente, el cual busca un mínimo en el espacio de errores, esto es, los errores más bajos que se puedan encontrar, los cuales se calculan con el SSE, o suma de errores cuadráticos, cuya expresión es: donde $\widehat{y_{i}}$ son los valores esperados e yi son los obtenidos. La biblioteca Scikit-Learn, mediante la clase LinearRegression del módulo sklearn, nos permite obtener la regresión a través de los siguientes pasos Generamos una instancia de la clase que implementa el algoritmo a utilizar, que tiene los parámetros siguientes: Normalize, que permite normalizar los datos de entrada y por defecto está a True Copy_X, que está por defecto a true, y copia X, el conjunto de datos de entrada Atributos: los coeficientes w0 y w1 que en Scikit son intercept_(w0) y coef_(w1) Una vez creada la instancia empleamos el método fit() con parámetros la matriz con los valores de los atributos (X) y un vector Y con los valores de salida Una vez entrenado el modelo usamos el método predict() con parámetro de entrada un conjunto de datos sin etiquetar. La salida serán las etiquetas de los datos predichas. Regresión polinómica A diferencia de la regresión lineal, la regresión polinómica permite ajustar el conjunto de datos a una función de la forma: que para una sola variable independiente o parámetro se convierte en: En este caso el conjunto de datos es una matriz de k columnas -una por coeficiente wi- y n filas -una por registro del conjunto de datos-. La regresión polinómica es útil cuando el modelo de regresión lineal no es lo suficientemente complejo para representar fielmente la relación entre la variable dependiente y la/las variables independientes – subajuste-, por lo que añadimos más parámetros y nuevas características que corresponden a los coeficientes. Sin embargo, como contrapartida hay que vigilar el riesgo de sobreajuste que se produce al elevar el grado del polinomio, que se hace con el objetivo de que los valores obtenidos a partir del modelo empleando como entrada los datos de entrenamiento sean idénticos a los valores conocidos de la variable dependiente. Para trabajar con la regresión polinomial en Scikit-learn empleamos la clase PolynomialFeatures, que tiene como parámetro el grado del polinomio, y del que podemos ver un ejemplo en el cuadro de la derecha. Regresión de los K vecinos más cercanos El método de los K vecinos más próximos nos permite predecir el valor de la variable de salida de una muestra a partir de las K muestras más próximas, calculando la media de los valores de cada una de las variables de entrada de cada una de esas K muestras -conviene normalizar los datos para poder trabajar con valores comparables-. En el cuadro de la derecha de la página actual y en de la izquierda de la siguiente podemos ver ejemplos de este método Regresión Kernel Gaussiana La regresión kernel gaussiana permite buscar relaciones no lineales entre el conjunto de registros de entrada X y las salidas y. Es un método semejante al de los K vecinos más próximos con la diferencia de que aquí se usan todas las muestras como vecinos pero calculando una media ponderada de estas. Para estimar esta ponderación se usa una curva gaussiana en la que los pesos de los vecinos más próximos a la muestra a evaluar son altos mientras que los pesos de los vecinos más alejados son más bajos. Empleando Scikit y el paquete Gaussian_process podemos obtener la regresión gaussiana. Se puede ver un ejemplo en el cuadro de la derecha de la página siguiente. Métricas de evaluación de los modelos de regresión Introducción Una vez obtenidos los modelos de regresión, es fundamental comprobar cuan cercanos a los valores reales son los obtenidos por estos. Para ello emplearemos diferentes métricas o mecanismos de medida del error de la función asociada al modelo, todas ellas basadas en el concepto de residuo o distancia entre el valor esperado y obtenido. Error medio absoluto (MAE) Corresponde a la media los valores absolutos de las distancias entre los puntos reales y los obtenidos mediante las curvas de regresión. Su expresión matemática se muestra a continuación Error cuadrático medio (MSE) Corresponde al valor medio del coste SSE que hemos visto anteriormente. La expresión matemática del mismo se muestra a continuación Raíz del error cuadrático medio (RMSE) Como su propio nombre indica, es la raíz de MSE, como se puede ver en la siguiente expresión Coeficiente de determinación Se define como el porcentaje de varianza que resulta de la aplicación del modelo. Se representa como donde SST es la suma de los cuadrados de las distancias Clasificación Introducción Como hemos comentado en apartados anteriores, la clasificación permite crear modelos a partir de un conjunto de muestras etiquetadas, que nos permite clasificar una muestra nueva como perteneciente a una de las clases existentes. Regresión logística Concepto La regresión logística es un método de clasificación binaria, por el cual tenemos una entrada de la forma donde Xk son las características o atributos de cada registro de datos y una salida cuyo valor está en el intervalo [0,1], que permite clasificar una muestra como perteneciente a una de las dos clases si su valor es mayor o menor que 0.5. La forma de la función binaria que representa esa salida es la sigmoide El aparato matemático que está detrás de la regresión logística va más allá de los objetivos de este curso, que pretende dar una visión procedimental del aprendizaje automático. Baste saber que Python, dentro de la biblioteca Scikit-learn, tiene implementada la clase LogisticRegression, que permite clasificar empleando la regresión logística. En los cuadros laterales de la página anterior y de esta y podemos ver un ejemplo de dicha regresión, en la que tomamos un conjunto de datos sobre cáncer de mama, y de las variables de cada registro seleccionamos dos, el radio medio del tumor y la textura media, y a partir de esos datos generamos un modelo que prediga si un tumor es o no benigno. Regresión logística con regularización La regularización implica modular los valores de los parámetros del modelo de modo que no se produzca sobreajuste y el modelo permita predecir con datos nuevos. Así mismo permite seleccionar las características o atributos más relevantes desechando los no relevantes o redundantes. Se puede aplicar a la regresión lineal o la logística así como a las redes neuronales. Existen tres tipos de regularización que corresponden al parámetro penalty del clasificador SGDClassifier que emplearemos para crear el modelo: La Lasso o L1: en la que añadimos un término de regularización de la forma $\alpha \bullet \sum_{i = 1}^{n}\left| w_{i} \right|$ a la función de coste de la regresión lineal/logística. Este tipo de regularización provoca que los coeficientes de las variables menos importantes sean 0, seleccionando así las más importantes y simplificando el modelo. Ridge o L2: en la que añadimos un término de regularización de la forma $\alpha \bullet \sum_{i = 1}^{n}{w_{i}}^{2}$ a la expresión de la función de coste o error de la regresión lineal/logística, donde α es positivo, por lo que hace que el peso del sumatorio sea más grande haciendo el modelo más sencillo al obligar a los coeficientes a ser más pequeños para minimizar la función de coste. Es aconsejable para reducir el sobreajuste. ElasticNet: es una combinación de las anteriores, en la que el término que se suma a la función de coste es de la forma $r \bullet \alpha \bullet \sum_{i = 1}^{n}\left| w_{i} \right| + (1 - r) \bullet \alpha \bullet \sum_{i = 1}^{n}{w_{i}}^{2}$ donde r es un parámetro que varía entre 0 y 1. Establece un equilibrio entre la regresión Lasso y la Ridge. En el cuadro de la izquierda de la página actual podemos ver un modelo de regresión por regularización empleando Scikit-learn Máquinas de vectores soporte (SVM) Las máquinas de vectores soporte nos permiten clasificar conjuntos de datos con múltiples características o parámetros. El objetivo de este método es buscar una recta -si cada registro tiene una característica-, plano -si tiene dos- o hiperplano – si tiene tres o más- que separa los registros en dos conjuntos. Para ello se buscan dos hiperplanos -hiperplano positivo e hiperplano negativo – paralelos al separador, que separen los registros en dos conjuntos. Estos hiperplanos están limitados o definidos por los llamados vectores soporte, que son los registros del conjunto de datos más próximos a los hiperplanos. Se buscan aquellos hiperplanos que maximicen la distancia entre los vectores soporte, para que los dos grupos estén lo más separados posible. Para generar los hiperplanos se emplean unas funciones no lineales llamadas kernels que, incrementando el número de parámetros, permiten maximizar la distancia entre los dos conjuntos de datos. Las muestras situadas a un lado de la frontera definida por los vectores soporte -hiperplano negativo -tendrán un valor de -1 y las situadas al otro lado un valor de 1 – hiperplano positivo-. Las ecuaciones de ambos hiperplanos se muestran a continuación y la distancia entre ambos hiperplanos es de donde se deduce que minimizando los coeficientes se consigue maximizar la distancia entre vectores soporte. Esta optimización se consigue introduciendo el tipo de kernel como parámetro en el constructor de la clase SVM de Scikit-Learn, como se puede ver en el código de la página 55 y 56. Las SVM funcionan correctamente en espacios con un elevado número de características o dimensiones, pero tienen problemas cuando el número de registros es muy grande o están demasiado mezclados. K vecinos más próximos (KNN) El método de los K vecinos más próximos permite clasificar una muestra por su cercanía a sus vecinos, de modo que se asigna a la clase a la que pertenezcan un mayor número de sus K vecinos más próximos, donde K es un valor que definimos como parámetro. El algoritmo KNN no requiere un aparato matemático complejo más allá de manejar el concepto de distancia entre puntos y que estos tengan magnitudes similares, par lo que conviene normalizar los datos. Así mismo, los cálculos de distancias entre puntos se simplifican cuantas menos características o variables tienen los registros o puntos, con lo que en caso de que haya demasiadas de estas características conviene emplear algún método de reducción de dimensionalidad para o bien conservar aquellas variables que ofrezcan más información acerca del registro o punto, o para crear nuevas variables que sean combinación de las originales y que maximicen la información que tenemos de los registros. El algoritmo que resuelve el método KNN es el siguiente: Se calcula la distancia entre la muestra a clasificar y sus vecinos, para lo cual se emplean los diferentes tipos de métodos para dos vectores (x1,x2,…,xn) y (y1,y2,…,yn) La distancia euclidiana La distancia Manhattan La distancia Minkowsky donde p=1 nos da la distancia Manhattan y p=2 la Euclidiana. Se escogen los k vecinos más próximos y se determina la clase a la que pertenece la muestra como la clase a la que pertenecen la mayoría de sus vecinos. En cuanto al peso de cada uno de los vecinos más próximos, puede ser el mismo o puede estar ponderado. En el cuadro de la izquierda de la página anterior se usa la clase KNeighborsClassifier de la biblioteca Scikit-learn Arboles de decisión Los árboles de decisión son modelos de caja blanca, - esto es, que sus resultados pueden ser entendidos de forma sencilla-, que se emplean tanto en regresión como en clasificación. Permiten determinar los atributos más importantes dentro de los registros del conjunto de datos -los cuales pueden usarse sin normalizar al ser independientes unos de otros-, así como para mostrar cómo funciona un modelo basado en decisiones. Un árbol de decisión está formado por un conjunto de nodos, cada uno de los cuales corresponde a una regla, la cual en función del valor que tome para un atributo de cada muestra del conjunto de datos, implica una decisión determinada. En función de dicha decisión se genera una rama o subconjunto. Cada una de esas ramas lleva a un nuevo nodo de decisión asociado a una nueva regla, lo cual genera nuevas ramas, y así sucesivamente hasta que el valor de la etiqueta asociada a las muestras de cada subconjunto sea el mismo, que corresponde a los nodos hoja. A partir de aquí se pueden usar los árboles ya creados para clasificar -el nodo hoja tiene asociado una variable destino o clase que es un atributo categórico- o para regresión -el nodo hoja tiene asociado una variable destino que es un atributo continuo-. Para construir el árbol de decisión necesitamos escoger el atributo más significativo para efectuar la separación del conjunto de datos -aquel que obtenga la mayor cantidad de muestras pertenecientes a la misma clase en los siguientes nodos del árbol, los cuales serán puros si todas las muestras son de la misma clase en ellos-, y una vez escogido separar los datos en función de él. Una vez hecha la separación volvemos a empezar buscando el atributo más significativo de los que quedan, para hacer la separación de datos de nuevo, y así sucesivamente. Para llevar a cabo el procedimiento de separación de un árbol de decisión podemos emplear dos métricas, la impureza de Gini y la ganancia de información o entropía, que pasamos a explicar a continuación: La impureza de Gini -medida de la probabilidad de clasificar incorrectamente una muestra a partir de un atributo- se calcula a partir de la siguiente fórmula donde pi es la probabilidad de que una muestra del conjunto de datos pertenezca a la clase j. Precisamos también calcular el valor medio ponderado o función de coste para minimizar el valor de Gini de los nodos descendientes de cada uno de los nodos existentes en el árbol, y su forma es la que se muestra a continuación donde D es el dominio de todos las clases o valores de salida posibles y Ni es el número de muestras que tienen la salida ci y N el número total de muestras. La ganancia de información o entropía nos indica el grado de mezcla de clases en un conjunto de muestras donde Pi es la probabilidad de que un registro pertenezca a una clase dada. La entropía será 0 si todas las muestras son de la misma clase -dada por el valor del atributo que usamos para clasificar-. El algoritmo CART, que utiliza la impureza de Gini y la ganancia de información, es el que emplearemos para generar el árbol de decisión. Consta de dos fases: Para cada atributo se ordenan los registros del conjunto de datos -por orden creciente, por ejemplo-, y se localizan los puntos de corte, que se producen cuando cambia el valor del atributo en esa lista ordenada, y cuyo valor será la media de los dos valores a ambos lados del punto de corte. Cada uno de esos puntos de corte separa el conjunto de datos en dos particiones, las de los registros por encima y por debajo del punto de corte. Se busca el punto de corte que genere conjuntos más puros, esto es, con elementos solo de una clase o mayoritariamente de una clase. Para ello se emplea la siguiente expresión donde medidaj es la medida asociada al punto de corte j, Cjv es el número de registros que están correctamente clasificados en cada una de las v -2- particiones considerando que la clase correcta en esa partición es la mayoritaria en ella y N el total de registros de ambas particiones. Se busca la partición del atributo con medida máxima, y el punto de corte y el atributo asociado se convierten en la condición del nodo del árbol de decisión que divide el conjunto en dos subconjuntos. Se repite el procedimiento para cada uno de los dos subconjuntos hasta que la medida sea 1 o hasta llegar a dividir el conjunto en todos los registros existentes, o hasta llegar a una profundidad límite establecida como hiperparámetro, o no se puede encontrar una división que reduzca la impureza. Aparte del hiperparámetro profundidad, tenemos otros hiperparámetros como el número de hijos máximo o la cantidad mínima de patrones. La biblioteca Scikit-learn tiene una clase DecisionTreeClassifier que permite crear un modelo de árbol de decisión empleando el algoritmo CART. En el cuadro de la derecha podemos ver un ejemplo de este modelo. Bosques aleatorios (Random Forest) Los bosques aleatorios conforman una variante de los árboles de decisión que aplica el mismo algoritmo sobre varios subconjuntos de los datos de entrenamiento generados de manera aleatoria -modelo ensemble-. Se elige la más común de las clases o resultados como la valida en el caso de una clasificación, y la media de todas en el caso de una regresión. En Scikit-learn la clase RandomForestClassifier del paquete sklearn.ensemble nos permite calcular el árbol aleatorio. Métricas de evaluación de modelos de clasificación Matriz de confusión Es una matriz cuadrada que permite comparar los valores obtenidos y los predichos en un modelo de aprendizaje automático. La forma de una matriz de confusión se muestra en la imagen siguiente donde VP y VN son verdadero positivo y verdadero negativo -la clase real coincide con la predicha- y FN y FP son falso negativo y falso positivo -la clase real no coincide con la predicha-. Se emplea la función confusión_matrix de Scikit-learn, perteneciente a la clase metrics, para obtener la matriz de confusión en Python donde el primer parámetro son las etiquetas realmente obtenidas y el segundo las predichas. En el ejercicio de ejemplo de la regresión logística podemos ver un ejemplo del uso de confusion_matrix para una clasificación binaria. La generalización de la matriz de confusión para clasificación múltiple es la matriz de confusión multiclase que se muestra en el cuadro lateral de la página anterior Exactitud Es la relación entre el número de predicciones correctas y el número de predicciones totales. Matemáticamente se puede expresar como En Scikit-learn la función score() nos permite calcular la magnitud. También se usa la función accuracy_score() de metrics. En el ejemplo de la regresión logística también se muestra el uso de accuracy_score Precisión Es la relación entre el número de predicciones clasificadas positivas de manera correcta y el total de predicciones correctas. Se representa como En Scikit-learn empleamos la función precisión_score() de la clase metrics para obtener la precisión Sensibilidad La sensibilidad es la relación entre el número de verdaderos positivos dividido entre el total real de positivos -los verdaderos positivos más los falsos negativos, que también son positivos reales -. Se representa como En Scikit-learn usamos la función recall_score() dentro de la clase metrics, con la siguiente sintaxis Podemos ver ejemplos de todas estás métricas en el ejercicio de regresión logística. Se puede emplear también la función classification_report() que devuelve los valores de precisión, sensibilidad y F1 -otra métrica de calidad que no tocamos-. Tasa de falsos positivos Es la relación entre los falsos positivos y el total de negativos, que son los falsos positivos más los negativos correctamente clasificados. Se representa mediante la expresión Plataformas de aprendizaje automático Existen una serie de plataformas relacionadas con las grandes compañías de software que ofrecen herramientas para generar modelos de aprendizaje automático como: Microsoft Azure: es la plataforma cloud de Microsoft, que ofrece herramientas potentes para la IA y el aprendizaje automático, llamadas Servicios Cognitivos de Azure, que ofrece APIS relacionadas con la visión artificial y el recono- cimiento de imágenes, la conversión de texto a voz y viceversa, el procesamiento del lenguaje natural, trabajando o generando lenguajes humanos-análisis de textos para localizar metadatos, traducción, inteligencia conversacional-, y con la toma de decisiones – moderación de contenidos o detección de anomalías-. Dentro de Azure cobra especial interés Azure Machine Learning Studio, que tiene una versión gratuita que permite experimentar con el aprendizaje automático, escalando los proyectos de desarrollo del mismo e integrándolos en aplicaciones comerciales, manejando grandes cantidades de datos que luego preprocesan e introducen en el entrenamiento distribuido que se ejecuta en paralelo en máquinas virtuales sobre procesadores gráficos. Es una herramienta sencilla de usar que emplea el método de drag and drop -arrastrar y soltar – y tiene una versión gratuita. Amazon AWS: la plataforma cloud de Amazon ofrece múltiples herramientas para implementar IA y aprendizaje automático, entre las que podemos destacar Polly – conversión de texto a voz, generación de conversaciones con voces humanas-, Transcribe, que ofrece servicios de conversión de voz a texto, Computer Vision Service -que se emplea para reconocimiento facial, detección de objetos y etiquetado-, herramientas de control de fraudes en la creación de cuentas o el pago de servicios, Lex -un chatbot- y Kendra – búsqueda de documentos-. En Amazon es especialmente interesante Amazon Machine Learning, que permite crear modelos de aprendizaje automático de manera guiada. Incluye algunas de las herramientas indicadas anteriormente, como Lex, Transcribe y otras como Comprehend, que permiten extraer información de un texto escrito. Google Cloud Machine Learning Platform: permite generar proyectos de aprendizaje automático a través de las herramientas de que dispone, como TensorFlow, TPU o TFX, para después emplearlos para la predicción empleando los modelos generados con el entrenamiento. IBM Watson: es la plataforma de IA de IBM orientado a grandes empresas, con herramientas como el Asistente Watson -agente de ayuda a los usuarios-, RegTech -para control de fraudes y gestión de riesgos en general-, Watson Health – para la industria de la salud -, AIOps -para mejo- rar la eficiencia de las operaciones de Tecnologías de la Información-. Watson Machine Learning permite crear modelos de aprendizaje automático de manera gráfica y guiada. Dispone de herramientas de ciencia de datos de código abierto y de implementación de redes neuronales. Watson también ofrece Watson Studio, que permite a los especialistas en aprendizaje automático e inteligencia artificial generar y emplear modelos de IA. Dentro de Watson Studio tenemos IBM SPSS Modeler, que nos permite definir el modelo a usar -aprendizaje supervisado o no supervisado y dentro de estos, regresión, clasificación, aglomerativos, K-Means- y evaluar los resultados, agilizando todas las fases del proceso para obtener una solución de aprendizaje automático. Emplearemos esta herramienta en el módulo de programación de inteligencia artificial. BigML: es una herramienta que se emplea para hacer accesible el aprendizaje automático a todo el mundo importando fuentes de diferentes sitios y construir modelos que se pueden integrar en otros programas. BigML es otra de las herramientas que emplearemos en la parte de prácticas. Fases de un proceso de aprendizaje automático En el apartado 1.2 de la unidad 2 se estudian las fases de la creación de un modelo de aprendizaje automático

Use Quizgecko on...
Browser
Browser