Dataset de atención médica con Spark

Spark es un proyecto de código abierto de Apache. También es el motor de análisis más utilizado para grandes volúmenes de datos y aprendizaje automático.

Esta publicación se centrará en un comienzo rápido para desarrollar un algoritmo de predicción con Spark.

Elegí el conjunto de datos “Dataset de Datos de salud” para trabajar con de kaggle.com, la comunidad más grande del mundo de científicos de datos y aprendizaje automático.

Contenido:

Según la Organización Mundial de la Salud, la enfermedad cardíaca isquémica y el accidente cerebrovascular son las principales causas de muerte. 19659002] Información del sitio oficial: http://www.who.int/news-room/fact-sheets/detail/the-top-10-causes-of-death

Lo que necesitamos hacer es predecir la probabilidad de accidente cerebrovascular utilizando la información dada de los pacientes. Es un problema de clasificación, donde trataremos de predecir la probabilidad de que una observación pertenezca a una categoría (en nuestro caso, la probabilidad de tener un accidente cerebrovascular).

Hay muchos algoritmos para resolver problemas de clasificación Usaré el Árbol de decisiones algorithm.

Configuración de Spark y obtención de datos

 de   pyspark.sql   importación  SparkSession 
 importación   pyspark.sql   como   sparksql 
 spark = SparkSession.builder.appName (& # 039; stroke & # 039;). GetOrCreate ()
 train = spark.read.csv (& # 039; train_2v.csv & # 039 ;, inferSchema =  Verdadero encabezado =  Verdadero )

Exploración de datos

La primera operación que se realiza después de importar datos es obtener información sobre su aspecto. Es posible hacerlo con los siguientes comandos:

  • df.printSchema ()
  • df.describe ()
  • df.dtypes
 train.groupBy (& # 039; stroke & # 039;) cuenta ( ) .show ()
 + ------ + ----- + 
 | stroke | count | 
 + ------ + ----- + 
 | 1 | 783 | 
 | 0 | 42617 | 
 + ------ + ----- +

Como se puede ver a partir de esta observación. Este es un conjunto de datos desequilibrado donde el número de observaciones pertenecientes a una clase es significativamente menor que las pertenecientes a las otras clases. En este caso, el modelo predictivo podría ser sesgado e impreciso. Existen diferentes estrategias para manejar conjuntos de datos desequilibrados, por lo tanto, está fuera del alcance de esta publicación, en su lugar me centraré en Spark. Para obtener más información sobre el conjunto de datos desequilibrado:

https://www.analyticsvidhya.com/blog/2017/03/imbalanced-classification-problem/

Aquí tenemos las medidas clínicas (por ejemplo, hipertensión , enfermedad cardíaca, edad, antecedentes familiares de enfermedad) para una cantidad de pacientes, así como información sobre si cada paciente ha tenido un accidente cerebrovascular. En la práctica, queremos que este método prediga con precisión el riesgo de accidente cerebrovascular para futuros pacientes en función de sus mediciones clínicas.

Análisis

Realice un breve análisis utilizando operaciones básicas. Es posible hacerlo de varias maneras:

  • DataFrames proporciona un lenguaje específico de dominio para la manipulación de datos estructurados, el acceso a las columnas de un DataFrame puede ser por atributo o por indexación.
  • para ejecutar consultas SQL programáticamente y devolver el resultado como una DataFrame

Por ejemplo, para ver qué tipo de trabajo tiene más casos de trazo, podemos hacer lo siguiente:

 # create DataFrame como una vista temporal 
 train.createOrReplaceTempView (& # 039; table & # 039;)

Consulta SQL

 spark.sql ("SELECT work_type, count (work_type) as work_type_count FROM table WHERE stroke == 1 GROUP BY work_type ORDER BY work_type_count DESC"). Show ()
 + ---- --------- + --------------- + 
 | work_type | work_type_count | 
 + ------------- + --------------- + 
 | Privado | 441 | 
 | Trabajador por cuenta propia | 251 | 
 | Govt_job | 89 | 
 | niños | 2 | 
 + ------------- + --------------- +

Parece que la ocupación privada es el tipo de trabajo más peligroso en este conjunto de datos.

Descubramos quién participó en esta medición clínica.

 spark.sql ("SELECCIONE género, recuento (género) como count_gender, count (gender) * 100 / sum (count (gender)) over ( ) como porcentaje FROM table GROUP BY género "). show ()
 + ------ + ------------ + ------------ ------- + 
 | gender | count_gender | por ciento | 
 + ------ + ------------ + ------------------- + 
 | Mujer | 25665 | 59.13594470046083 | 
 | Otro | 11 | 0.02534562211981567 | 
 | Hombre | 17724 | 40.83870967741935 | 
 + ------ + ------------ + ------------------- +

59 % de todas las personas son mujeres y solo el 40% son hombres que participaron en la investigación de accidentes cerebrovasculares.

A partir de esta información existe la posibilidad de recuperar información sobre cuántas mujeres / hombres tienen un accidente cerebrovascular:

 spark.sql ("SELECCIONE el género , count (gender), (COUNT (gender) * 100.0) / (SELECT count (gender) FROM table WHERE == & # 039; Male & # 039;) como porcentaje FROM table WHERE stroke = & # 039; 1 & # 039 ; y sexo = & # 039; Hombre & # 039; GRUPO POR sexo "). show ()
 + ------ + ------------- + ---- ---------------- + 
 | gender | count (gender) | porcentaje | 
 + ------ + ------------- + -------------------- + 
 | Hombre | 352 | 1.986007673211464 ... | 
 + ------ + ------------- + ------------------ - +
 
 spark.sql ("SELECCIONE género, recuento (género), (COUNT (género) * 100.0) / (SELECCIONE recuento (género) DE la tabla DONDE sexo == & # 039; Femenino & # 039 ;) como porcentaje FROM table WHERE stroke = & # 039; 1 & # 039; y gender = & # 039; Female & # 039; GROUP BY gender "). show ()
 + ------ + - ----------- + -------------------- + 
 | gender | count (gender) | porcentaje | 
 + ------ + ------------- + -------------------- + 
 | Mujer | 431 | 1.679329826612117 ... | 
 + ------ + ------------- + ------------------ - +

1,68% Hembra y casi 2% Hembras han tenido un accidente cerebrovascular.

También podemos ver si la edad influye en el accidente cerebrovascular y cuál es el riesgo por edad.

 spark.sql ("SELECCIONAR edad, contar (edad) como edad_contestar DE la tabla WHERE stroke == 1 GROUP BY edad ORDER BY age_count DESC"). Show ()
 + ---- + --------- + 
 | edad | age_count | 
 + ---- + --------- + 
 | 79.0 | 70 | 
 | 78.0 | 57 | 
 | 80.0 | 49 | 
 | 81.0 | 43 | 
 | 82.0 | 36 | 
 | 70.0 | 25 | 
 | 77.0 | 24 | 
 | 74.0 | 24 | 
 | 76.0 | 24 | 
 | 67.0 | 23 | 
 | 75.0 | 23 | 
 | 72.0 | 21 | 
 | 68.0 | 20 | 
 | 59.0 | 20 | 
 | 69.0 | 20 | 
 | 71.0 | 19 | 
 | 57.0 | 19 | 
 | 63.0 | 18 | 
 | 65.0 | 18 | 
 | 66.0 | 17 | 
 + ---- + --------- + 
 solo mostrando las 20 mejores filas

Puedo usar el filtro operación para calcular el número de casos de apoplejía para personas después de 50 años.

 train.filter ((tren ['stroke'] == 1) & (tren ['age']> & # 039; 50 & # 039;)). count ()
resultado: 708 [19659026] Como podemos ver  La edad  es un factor de riesgo importante para desarrollar un accidente cerebrovascular.

Datos de limpieza

El próximo paso de la exploración es tratar con valores categóricos y faltantes. Faltan valores para los parámetros smoking_status y bmi.

Rellenaré smoking_status con un valor de parámetro ‘Sin información’ y bmi con valor medio.

 # fill en valores faltantes 
 train_f = train.na.fill (& # 039; Sin información & # 039 ;, subconjunto = ['smoking_status'])
  # completar los valores de error con la media  
 de   pyspark.sql.functions   import  mean 
 mean = train_f.select (mean (train_f ['bmi'])) collect () 
 mean_bmi = mean [0][0]
 train_f = train_f. na.fill (mean_bmi, ['bmi'])

La mayoría de los algoritmos ML no pueden trabajar directamente con datos categóricos . La codificación permite algoritmos que esperan que las características continuas usen características categóricas.

StringIndexer -> OneHotEncoder -> VectorAssembler

  desde   pyspark.ml.feature   import  (VectorAssembler, OneHotEncoder, 
 StringIndexer)

No es necesario saber cuántas categorías en una función de antemano la combinación de StringIndexer y OneHotEncoder se ocupa de ello.

El siguiente paso es crear un ensamblador, que combina una lista dada de columnas en una sola columna vectorial para entrenar el modelo ML. Utilizaré las columnas vectoriales que obtuvimos después de one_hot_encoding.

 assembler = VectorAssembler (inputCols = ['genderVec'
 & # 039; age & # 039;, 
 & # 039 ; hipertensión & # 039 ;, 
 & # 039; heart_disease & # 039 ;, 
 & # 039; ever_marriedVec & # 039;, 
 & # 039; work_typeVec & # 039 ;, 
 & # 039; Residence_typeVec & # 039;, 
 & # 039; avg_glucose_level & # 039;, 
 & # 039; bmi & # 039 ;, 
 & # 039; smoking_statusVec & # 039;]outputCol = & # 039; features & # 039 ;)

Luego crearemos un objeto Decision Tree. Para hacer esto necesitamos importar DecisionTreeClassifier.

  desde   pyspark.ml.classification   import  DecisionTreeClassifier
 dtc = DecisionTreeClassifier (labelCol = & # 039; stroke & # 039 ;, featuresCol = & # 039; features & # 039;)

Hasta ahora tenemos una especie de tarea compleja que contiene un montón de etapas, que deben realizarse para procesar los datos. Para envolver todo eso, Spark ML representa un flujo de trabajo como Pipeline que consiste en una secuencia de PipelineStages para ejecutarse en un orden específico.

  from [19659011] pyspark.ml   import  Pipeline
 pipeline = Pipeline (stages = [gender_indexerever_married_indexerwork_type_indexerResidence_type_indexer
 smoking_status_indexer, gender_encoder, ever_married_encoder, work_type_encoder, 
 Residence_type_encoder, smoking_status_encoder, ensamblador , dtc])

El siguiente paso es dividir conjunto de datos para entrenar y probar.

 train_data, test_data = train_f.randomSplit ([0.7,0.3])

Lo que voy a hacer ahora es para adaptarse al modelo. Para esto, usaré la tubería que se creó y train_data

 model = pipeline.fit (train_data)

Después de eso, se transformaron los test_data.

 dtc_predictions = model.transform (test_data)

Ahora es el momento de evaluar un modelo

  de   pyspark.ml.evaluation   import  MulticlassClassificationEvaluator
  # Seleccionar (predicción, etiqueta verdadera) y calcular error de prueba 
 acc_evaluator = MulticlassClassificationEvaluator (labelCol = "stroke", predictionCol = "prediction", metricName = "accuracy")
 dtc_acc = acc_evaluator.evaluate (dtc_predictions)
 print (& # 039; Un algoritmo de Decision Tree tenía una precisión de:  {0: 2.2f} % & # 039; .format (dtc_acc * 100))

Un algoritmo de Decision Tree tenía una precisión de: 98.08%

Como se definió al principio, el modelo predictivo de un conjunto de datos desequilibrado podría ser con precisión engañosa.

Conclusión

Apache Spark es una fuente abierta marco, es muy conciso y fácil de usar.


Healthcare Dataset with Spark se publicó originalmente en Towards Data Science en Medium, donde las personas continúan la conversación resaltando y respondiendo a esta historia .

Dejá un comentario