Logotipo de Zephyrnet

Predicción de la enfermedad renal crónica mediante el aprendizaje automático

Fecha:

df.corr()

Salida:

Visualización de matrices | Enfermedad Renal Crónica ML

Averigüemos cuántos de cada clase son:

df['clase'].value_counts()

Salida:

ckd 250 notckd 150 Nombre: clase, dtype: int64

Inferencia: De la siguiente salida podemos sacar nuestra inferencia de que esto está cerca de un “conjunto de datos desequilibrado”.

Representación de la variable objetivo en porcentaje

countNoEnfermedad = len(df[df['clase'] == 0]) countHaveEnfermedad = len(df[df['class'] == 1]) print("Porcentaje de pacientes que no tienen enfermedad cardíaca: {:.2f }%".format((countNoDisease / (len(df['class']))*100))) print("Porcentaje de pacientes con enfermedad cardíaca: {:.2f}%".format((countHaveDisease / (len (df['clase']))*100)))

Salida:

Porcentaje de pacientes que no tienen enfermedad cardíaca: 0.00 % Porcentaje de pacientes que tienen enfermedad cardíaca: 0.00 %

Comprender el equilibrio de los datos visualmente

df['clase'].value_counts().plot(kind='bar',color=['salmon','lightblue'],title="Recuento de diagnóstico de enfermedad renal")

Salida:

Salida

Aquí estaremos comprobando la distribución de la columna de edad.

df['edad'].plot(tipo='hist')

Salida:

Enfermedad Renal Crónica ML

Inferencia: Aquí con la ayuda del histograma podemos ver que Grupo de edad 50-60 las personas están muy dispersas en este conjunto de datos.

Aquí estamos trazando el gráfico para ver los valores nulos en el conjunto de datos.

p = msno.bar(datos)

Salida:

Salida | Enfermedad Renal Crónica ML

Inferencia: Aquí, cualquier característica que no haya tocado la marca 400 en la parte superior tiene valores nulos.

plt.subplot(121), sns.distplot(data['bp']) plt.subplot(122), data['bp'].plot.box(figsize=(16,5)) plt.show()

Salida:

Enfermedad Renal Crónica ML

Inferencia: Aquí en el gráfico anterior podemos ver la distribución de la presión arterial y también en el subtrama es visible que la columna bp tiene algunos valores atípicos.

Ahora convertiremos los valores categóricos (objeto) a valores categóricos (int)

datos['clase'] = datos['clase'].map({'ckd':1,'notckd':0}) datos['htn'] = datos['htn'].map({'sí' :1,'no':0}) datos['dm'] = datos['dm'].map({'sí':1,'no':0}) datos['cad'] = datos[' cad'].map({'sí':1,'no':0}) datos['appet'] = datos['appet'].map({'bueno':1,'pobre':0}) datos['ane'] = datos['ane'].map({'sí':1,'no':0}) datos['pe'] = datos['pe'].map({'sí' :1,'no':0}) datos['ba'] = datos['ba'].map({'present':1,'notpresent':0}) datos['pcc'] = datos[' pcc'].map({'presente':1,'notpresent':0}) datos['pc'] = datos['pc'].map({'anormal':1,'normal':0}) datos['rbc'] = datos['rbc'].map({'anormal':1,'normal':0}) datos['clase'].value_counts()

Salida:

1 250 0 150 Nombre: clase, tipo de d: int64

Encontrar la correlación entre las parcelas

plt.figure(figsize = (19,19)) sns.heatmap(data.corr(), annot = True, cmap = 'coolwarm') # buscando fuertes correlaciones con la fila "clase"

Salida:

Correlación entre parcelas

Análisis exploratorio de datos (EDA)

Veamos la forma del conjunto de datos nuevamente después del análisis.

datos.forma

Salida:

(400, 25)

Ahora veamos las columnas finales presentes en nuestro conjunto de datos.

columnas.de.datos

Salida:

Índice(['edad', 'bp', 'sg', 'al', 'su', 'rbc', 'pc', 'pcc', 'ba', 'bgr', 'bu', 'sc' , 'sod', 'pot', 'hemo', 'pcv', 'wbcc', 'rbcc', 'htn', 'dm', 'cad', 'appet', 'pe', 'ane', ' clase'], dtype='objeto')

Ahora soltando los valores nulos.

datos.forma[0], datos.dropna().forma[0]

Salida:

(400, 158)

Aquí de la salida anterior, podemos ver que hay 158 valores nulos en el conjunto de datos. Ahora, aquí nos quedan dos opciones: podemos descartar todos los valores nulos o mantenerlos cuando eliminemos los valores NA, por lo que debemos entender que nuestro conjunto de datos no es tan grande y si descartamos esos valores nulos, entonces sería aún más pequeño en ese caso si proporcionamos muy pocos datos a nuestro modelo de aprendizaje automático, entonces el rendimiento sería mucho menor y aún no sabemos si estos valores nulos están relacionados con algunas otras características en el conjunto de datos.

Entonces, por esta vez mantendré estos valores y veré cómo se comportará el modelo en este conjunto de datos.

Además, cuando estamos trabajando en algún proyecto de atención médica en el que predeciremos si la persona padece esa enfermedad o no, entonces una cosa que debemos en mi mente es que la evaluación del modelo debe tener la menor cantidad de errores falsos positivos.

data.dropna(inplace=True) data.shape

Salida:

(158, 25)

Construcción del modelo

  1. Regresión logística
from sklearn.linear_model import LogisticRegression logreg = LogisticRegression() X = data.iloc[:,:-1] y = data['class'] X_train, X_test, y_train, y_test = train_test_split(X,y, estratificar = y, barajar = Verdadero) logreg.fit(tren_X,tren_y)

Salida:

Regresión logística()

Puntaje de entrenamiento

logreg.puntuación(tren_X,tren_y)

Salida:

1.0

Exactitud de prueba

logreg.puntuación(X_test,y_test)

Salida:

0.975

Impresión de la precisión del entrenamiento y las pruebas

from sklearn.metrics import precision_score, confusion_matrix print('Precisión del tren: ', precision_score(y_train, train_pred)) print('Exactitud de la prueba: ', precision_score(y_test, test_pred))

Salida:

Precisión del tren: 1.0 Precisión de la prueba: 0.975

La siguiente celda muestra los coeficientes para cada variable.

(ejemplo sobre la lectura de los coeficientes de una regresión logística: un aumento de una unidad en la edad hace que una persona tenga aproximadamente e^0.14 veces más probabilidades de tener ERC, mientras que un aumento de una unidad en la presión arterial hace que una persona tenga aproximadamente e^-0.07 veces probable que tenga ERC.

pd.DataFrame(logreg.coef_, columnas=X.columnas)

Salida:

Construcción de maquetas | Enfermedad Renal Crónica ML

Matriz de confusión

sns.set (font_scale = 1.5)
def plot_conf_mat(y_test,y_preds): """ Esta función seguirá trazando la matriz de confusión usando seaborn """ fig,ax=plt.subplots(figsize=(3,3)) ax=sns.heatmap(confusion_matrix (y_test,y_preds),annot=Verdadero,cbar=Falso) plt.xlabel("Etiqueta verdadera") plt.ylabel("Etiqueta predicha") 
log_pred = logreg.predict(X_test) plot_conf_mat(y_test, log_pred)

Salida:

salida
tn, fp, fn, tp = confusion_matrix(y_test, test_pred).ravel() print(f'True Neg: {tn}') print(f'False Pos: {fp}') print(f'False Neg: { fn}') print(f'Posición Verdadera: {tp}')

Salida:

salida

K-Clasificador de vecinos más cercanos

Es una buena práctica primero equilibrar bien la clase antes de usar KNN, ya que sabemos que en el caso de clases desequilibradas, KNN no funciona bien.

df["clase"].value_counts()

Salida:

0 115 1 43 Nombre: clase, tipo de d: int64

Ahora vamos a CONCATENAR nuestras variables de clase juntas.

df_balanceado = pd.concat([df[df["clase"] == 0], df[df["clase"] == 1].sample(n = 115, replace = True)], eje = 0) df_balanceado .reset_index(soltar=Verdadero, en lugar=Verdadero) balance_df["clase"].value_counts()

Salida:

1 115 0 115 Nombre: clase, tipo de d: int64

Ahora reduzcamos los datos

ss = StandardScaler() ss.fit(X_train) X_train = ss.transform(X_train) X_test = ss.transform(X_test)

Ahora ajustaremos el modelo KNN para una mayor precisión.

desde sklearn.neighbours importa KNeighboursClassifier
knn = KNeighborsClassifier() params = { "n_neighbors":[3,5,7,9], "weights":["uniforme","distance"], "algorithm":["ball_tree","kd_tree"," brute"], "leaf_size":[25,30,35], "p":[1,2] } gs = GridSearchCV(knn, param_grid=params) modelo = gs.fit(X_train,y_train) preds = modelo. predecir(X_test) precision_score(y_test, preds)

Salida:

1.0

Matriz de confusión para el modelo KNN

knn_pred = model.predict(X_test) plot_conf_mat(y_test, knn_pred)

Salida:

Enfermedad Renal Crónica ML
tn, fp, fn, tp = confusion_matrix(y_test, preds).ravel() print(f'True Neg: {tn}') print(f'False Pos: {fp}') print(f'False Neg: { fn}') print(f'Posición Verdadera: {tp}')

Salida:

Enfermedad Renal Crónica ML

Importancia de la característica

feature_dict=dict(zip(df.columns,list(logreg.coef_[0]))) feature_dict

Aquí obtendremos el coeficiente de las características que indicará el peso de cada característica.

Salida:

Importancia de la característica

Visualizar la importancia de las características

feature_df=pd.DataFrame(feature_dict,index=[0]) feature_df.T.plot(kind="hist",legend=False,title="Característica Importancia")

Salida:

Salida

Visualizar la importancia de las características: transponer

feature_df=pd.DataFrame(feature_dict,index=[0]) feature_df.T.plot(tipo="barra",leyenda=False,title="Importancia de la característica")

Salida:

Importancia de la característica

Guardando el modelo

importar pepinillos

# Ahora, con la ayuda del modelo pickle, guardaremos el modelo entrenado
modelo_guardado = pickle.dumps(logreg) # Cargar el modelo decapado
logreg_from_pickle = pickle.loads(modelo_guardado)

# Ahora aquí cargaremos el modelo
logreg_from_pickle.predict(X_test)

Salida:

Guardando el modelo

Notas finales

Aquí está el repositorio liga a este artículo. Espero que les haya gustado mi artículo sobre la enfermedad renal crónica ML. Si tiene alguna opinión o pregunta, comente a continuación.

Leer en AV Blog sobre varias predicciones usando Machine Learning.

Acerca de mí

Saludos a todos, actualmente estoy trabajando. in TCS y anteriormente, trabajé como analista de ciencia de datos in Zorba Consulting India. Junto con el trabajo de tiempo completo, tengo un gran interés en el mismo campo, es decir, la ciencia de datos, junto con sus otros subconjuntos de inteligencia artificial, como la visión por computadora, el aprendizaje automático y el aprendizaje profundo; no dude en colaborar conmigo en cualquier proyecto en los dominios mencionados anteriormente (Etiqueta LinkedIn).

Aquí puede acceder a mis otros artículos, que se publican en Analytics Vidhya como parte del Blogathon (liga).

Los medios que se muestran en este artículo no son propiedad de Analytics Vidhya y se utilizan a discreción del autor. 

punto_img

Información más reciente

punto_img