Folla de trucos do Bloc de notas para o procesamento rápido de datos

Moitas veces, as persoas que entran no campo da ciencia de datos teñen expectativas menos que realistas do que lles espera. Moita xente pensa que agora escribirán redes neuronais interesantes, crearán un asistente de voz de Iron Man ou vencerán a todos nos mercados financeiros.
Pero traballar Data O científico está dirixido polos datos, e un dos aspectos máis importantes e que consumen moito tempo é procesar os datos antes de alimentalos nunha rede neuronal ou analizalos de certa maneira.

Neste artigo, o noso equipo describirá como pode procesar os datos de forma rápida e sinxela con instrucións e código paso a paso. Tentamos que o código fose bastante flexible e podería usarse para diferentes conxuntos de datos.

É posible que moitos profesionais non atopen nada extraordinario neste artigo, pero os principiantes poderán aprender algo novo, e calquera que teña soño durante moito tempo con facer un caderno separado para un procesamento de datos rápido e estruturado pode copiar o código e formatealo por si mesmo, ou descarga o caderno rematado de Github.

Recibimos o conxunto de datos. Que facer a continuación?

Entón, o estándar: necesitamos entender o que estamos a tratar, o panorama xeral. Para iso, usamos pandas para definir simplemente diferentes tipos de datos.

import pandas as pd #импортируем pandas
import numpy as np  #импортируем numpy
df = pd.read_csv("AB_NYC_2019.csv") #читаем датасет и записываем в переменную df

df.head(3) #смотрим на первые 3 строчки, чтобы понять, как выглядят значения

Folla de trucos do Bloc de notas para o procesamento rápido de datos

df.info() #Демонстрируем информацию о колонках

Folla de trucos do Bloc de notas para o procesamento rápido de datos

Vexamos os valores das columnas:

  1. O número de liñas de cada columna corresponde ao número total de liñas?
  2. Cal é a esencia dos datos de cada columna?
  3. A que columna queremos orientar para facer predicións para ela?

As respostas a estas preguntas permitiranche analizar o conxunto de datos e deseñar un plan para as túas próximas accións.

Ademais, para unha ollada máis profunda aos valores de cada columna, podemos usar a función describe() pandas. Non obstante, a desvantaxe desta función é que non proporciona información sobre as columnas con valores de cadea. Tratarémolos máis tarde.

df.describe()

Folla de trucos do Bloc de notas para o procesamento rápido de datos

Visualización máxica

Vexamos onde non temos ningún valor:

import seaborn as sns
sns.heatmap(df.isnull(),yticklabels=False,cbar=False,cmap='viridis')

Folla de trucos do Bloc de notas para o procesamento rápido de datos

Esta foi unha pequena ollada desde arriba, agora pasaremos a cousas máis interesantes

Tentemos buscar e, se é posible, eliminar columnas que teñan só un valor en todas as filas (non afectarán o resultado de ningún xeito):

df = df[[c for c
        in list(df)
        if len(df[c].unique()) > 1]] #Перезаписываем датасет, оставляя только те колонки, в которых больше одного уникального значения

Agora protexémonos a nós mesmos e ao éxito do noso proxecto de liñas duplicadas (liñas que conteñen a mesma información na mesma orde que unha das liñas existentes):

df.drop_duplicates(inplace=True) #Делаем это, если считаем нужным.
                                 #В некоторых проектах удалять такие данные с самого начала не стоит.

Dividimos o conxunto de datos en dous: un con valores cualitativos e outro con valores cuantitativos

Aquí temos que facer unha pequena aclaración: se as liñas con datos que faltan en datos cualitativos e cuantitativos non están moi correlacionadas entre si, entón teremos que decidir o que sacrificamos: todas as liñas con datos que faltan, só unha parte delas, ou determinadas columnas. Se as liñas están correlacionadas, entón temos todo o dereito a dividir o conxunto de datos en dous. En caso contrario, primeiro terás que tratar coas liñas que non correlacionan os datos que faltan en cualitativos e cuantitativos, e só despois dividir o conxunto de datos en dous.

df_numerical = df.select_dtypes(include = [np.number])
df_categorical = df.select_dtypes(exclude = [np.number])

Facemos isto para facilitarnos o procesamento destes dous tipos diferentes de datos; máis tarde entenderemos o máis fácil que nos facilita a vida.

Traballamos con datos cuantitativos

O primeiro que debemos facer é determinar se hai "columnas espía" nos datos cuantitativos. Chamámoslles así a estas columnas porque se presentan como datos cuantitativos, pero actúan como datos cualitativos.

Como podemos identificalos? Por suposto, todo depende da natureza dos datos que estea a analizar, pero en xeral, tales columnas poden ter poucos datos únicos (na rexión de 3-10 valores únicos).

print(df_numerical.nunique())

Unha vez que teñamos identificadas as columnas espía, pasarémolas de datos cuantitativos a datos cualitativos:

spy_columns = df_numerical[['колонка1', 'колока2', 'колонка3']]#выделяем колонки-шпионы и записываем в отдельную dataframe
df_numerical.drop(labels=['колонка1', 'колока2', 'колонка3'], axis=1, inplace = True)#вырезаем эти колонки из количественных данных
df_categorical.insert(1, 'колонка1', spy_columns['колонка1']) #добавляем первую колонку-шпион в качественные данные
df_categorical.insert(1, 'колонка2', spy_columns['колонка2']) #добавляем вторую колонку-шпион в качественные данные
df_categorical.insert(1, 'колонка3', spy_columns['колонка3']) #добавляем третью колонку-шпион в качественные данные

Finalmente, separamos completamente os datos cuantitativos dos cualitativos e agora podemos traballar con eles correctamente. O primeiro é entender onde temos valores baleiros (NaN, e nalgúns casos aceptarase 0 como valores baleiros).

for i in df_numerical.columns:
    print(i, df[i][df[i]==0].count())

Neste punto, é importante comprender en que columnas os ceros poden indicar valores que faltan: é debido a como se recolleron os datos? Ou podería estar relacionado cos valores dos datos? Estas preguntas deben responderse caso por caso.

Entón, se aínda decidimos que nos poden faltar datos onde hai ceros, deberíamos substituír os ceros por NaN para facilitar o traballo con estes datos perdidos máis tarde:

df_numerical[["колонка 1", "колонка 2"]] = df_numerical[["колонка 1", "колонка 2"]].replace(0, nan)

Agora vexamos onde nos faltan datos:

sns.heatmap(df_numerical.isnull(),yticklabels=False,cbar=False,cmap='viridis') # Можно также воспользоваться df_numerical.info()

Folla de trucos do Bloc de notas para o procesamento rápido de datos

Aquí os valores dentro das columnas que faltan deben marcarse en amarelo. E agora comeza a diversión: como tratar con estes valores? Debo eliminar filas con estes valores ou columnas? Ou enche estes valores baleiros con outros?

Aquí tes un diagrama aproximado que pode axudarche a decidir que se pode facer, en principio, con valores baleiros:

Folla de trucos do Bloc de notas para o procesamento rápido de datos

0. Elimina as columnas innecesarias

df_numerical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True)

1. O número de valores baleiros desta columna é superior ao 50%?

print(df_numerical.isnull().sum() / df_numerical.shape[0] * 100)

df_numerical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True)#Удаляем, если какая-то колонка имеет больше 50 пустых значений

2. Elimina liñas con valores baleiros

df_numerical.dropna(inplace=True)#Удаляем строчки с пустыми значениями, если потом останется достаточно данных для обучения

3.1. Inserir un valor aleatorio

import random #импортируем random
df_numerical["колонка"].fillna(lambda x: random.choice(df[df[column] != np.nan]["колонка"]), inplace=True) #вставляем рандомные значения в пустые клетки таблицы

3.2. Inserir un valor constante

from sklearn.impute import SimpleImputer #импортируем SimpleImputer, который поможет вставить значения
imputer = SimpleImputer(strategy='constant', fill_value="<Ваше значение здесь>") #вставляем определенное значение с помощью SimpleImputer
df_numerical[["новая_колонка1",'новая_колонка2','новая_колонка3']] = imputer.fit_transform(df_numerical[['колонка1', 'колонка2', 'колонка3']]) #Применяем это для нашей таблицы
df_numerical.drop(labels = ["колонка1","колонка2","колонка3"], axis = 1, inplace = True) #Убираем колонки со старыми значениями

3.3. Insira o valor medio ou máis frecuente

from sklearn.impute import SimpleImputer #импортируем SimpleImputer, который поможет вставить значения
imputer = SimpleImputer(strategy='mean', missing_values = np.nan) #вместо mean можно также использовать most_frequent
df_numerical[["новая_колонка1",'новая_колонка2','новая_колонка3']] = imputer.fit_transform(df_numerical[['колонка1', 'колонка2', 'колонка3']]) #Применяем это для нашей таблицы
df_numerical.drop(labels = ["колонка1","колонка2","колонка3"], axis = 1, inplace = True) #Убираем колонки со старыми значениями

3.4. Insira o valor calculado por outro modelo

Ás veces, os valores pódense calcular usando modelos de regresión usando modelos da biblioteca sklearn ou outras bibliotecas similares. O noso equipo dedicará un artigo separado sobre como se pode facer isto nun futuro próximo.

Entón, polo momento, a narrativa sobre os datos cuantitativos interromperase, porque hai moitos outros matices sobre como facer mellor a preparación e o preprocesamento dos datos para diferentes tarefas, e neste artigo tivéronse en conta as cousas básicas para os datos cuantitativos, e agora é o momento de volver aos datos cualitativos.que separamos varios pasos atrás dos cuantitativos. Podes cambiar este caderno como queiras, adaptándoo ás diferentes tarefas, para que o preprocesamento de datos vaia moi rápido!

Datos cualitativos

Basicamente, para os datos cualitativos, utilízase o método One-hot-coding para formatealos desde unha cadea (ou obxecto) a un número. Antes de pasar a este punto, usemos o diagrama e o código anteriores para tratar con valores baleiros.

df_categorical.nunique()

sns.heatmap(df_categorical.isnull(),yticklabels=False,cbar=False,cmap='viridis')

Folla de trucos do Bloc de notas para o procesamento rápido de datos

0. Elimina as columnas innecesarias

df_categorical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True)

1. O número de valores baleiros desta columna é superior ao 50%?

print(df_categorical.isnull().sum() / df_numerical.shape[0] * 100)

df_categorical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True) #Удаляем, если какая-то колонка 
                                                                          #имеет больше 50% пустых значений

2. Elimina liñas con valores baleiros

df_categorical.dropna(inplace=True)#Удаляем строчки с пустыми значениями, 
                                   #если потом останется достаточно данных для обучения

3.1. Inserir un valor aleatorio

import random
df_categorical["колонка"].fillna(lambda x: random.choice(df[df[column] != np.nan]["колонка"]), inplace=True)

3.2. Inserir un valor constante

from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='constant', fill_value="<Ваше значение здесь>")
df_categorical[["новая_колонка1",'новая_колонка2','новая_колонка3']] = imputer.fit_transform(df_categorical[['колонка1', 'колонка2', 'колонка3']])
df_categorical.drop(labels = ["колонка1","колонка2","колонка3"], axis = 1, inplace = True)

Entón, por fin temos un control sobre os valores nulos nos datos cualitativos. Agora é o momento de realizar unha codificación única nos valores que hai na súa base de datos. Este método úsase con moita frecuencia para garantir que o teu algoritmo poida aprender de datos de alta calidade.

def encode_and_bind(original_dataframe, feature_to_encode):
    dummies = pd.get_dummies(original_dataframe[[feature_to_encode]])
    res = pd.concat([original_dataframe, dummies], axis=1)
    res = res.drop([feature_to_encode], axis=1)
    return(res)

features_to_encode = ["колонка1","колонка2","колонка3"]
for feature in features_to_encode:
    df_categorical = encode_and_bind(df_categorical, feature))

Entón, por fin rematamos de procesar datos cualitativos e cuantitativos separados; é hora de combinalos de novo

new_df = pd.concat([df_numerical,df_categorical], axis=1)

Despois de combinar os conxuntos de datos nun só, finalmente podemos usar a transformación de datos usando MinMaxScaler da biblioteca sklearn. Isto fará que os nosos valores estean entre 0 e 1, o que axudará á hora de adestrar o modelo no futuro.

from sklearn.preprocessing import MinMaxScaler
min_max_scaler = MinMaxScaler()
new_df = min_max_scaler.fit_transform(new_df)

Estes datos agora están listos para calquera cousa: redes neuronais, algoritmos estándar de ML, etc.

Neste artigo, non tivemos en conta o traballo con datos de series temporais, xa que para tales datos deberías utilizar técnicas de procesamento lixeiramente diferentes, dependendo da túa tarefa. No futuro, o noso equipo dedicará un artigo separado a este tema e esperamos que poida aportar algo interesante, novo e útil á túa vida, como este.

Fonte: www.habr.com

Engadir un comentario