Quan treballem en la resolució d'un problema d'aprenentatge automàtic,
el primer pas fonamental és conèixer les dades amb les quals treballarem
i preparar-les adequadament.
Advertència
Treballar amb dades sense cap preparació impedirà obtenir resultats
satisfactoris en la majoria dels casos.
En aquesta secció, veurem com preparar les dades per poder-les utilitzar
en els models d'aprenentatge automàtic.
Conjunt de dades adult-dataset
En aquests apunts treballarem en el següent conjunt de dades
adult-dataset.
El primer pas és conèixer les dades amb les quals treballarem.
Podem obtindre informació sobre les dades utilitzant diferents mètodes.
Els mètodes head(), tail(), info() vists a
Manipulació de dades amb Pandas)
ens permeten obtenir una visió general de les dades.
Exemple: head(), tail() i info()
file_path="../../files/ud3/adult.data"df=pd.read_csv(file_path,header=None)print("Head of the dataset:")print(df.head(),"\n")print("Tail of the dataset:")print(df.tail(),"\n")print("Info of the dataset:")df.info()print()
A més, podem utilitzar els següents mètodes
per obtindre més informació:
shape: proporciona el nombre de files i columnes del conjunt de dades.
describe(): proporciona estadístiques descriptives del conjunt de dades com el nombre de valors no nuls,
la mitjana, la desviació estàndard, el valor mínim, els quartils i el valor màxim.
unique(): proporciona els valors únics d'una columna.
value_counts(): proporciona el nombre de vegades que es repeteix cada valor d'una columna.
Exemple: shape, describe() i unique()
print("Shape of the dataset:")print(df.shape,"\n")print("Description of the dataset:")print(df.describe(),"\n")print("Unique values of workclass column:")print(df['workclass'].unique(),"\n")print("Value counts of workclass column:")print(df['workclass'].value_counts(dropna=False),"\n")
Un dels problemes més comuns en les dades són els valors nuls,
ja que la majoria de models no permeten treballar amb valors no numèrics.
Podem identificar els valors nuls amb el mètode isnull().
Exemple: isnull()
Warning
Hem modificat el conjunt de dades inicial per afegir un valor nul a la columna age.
df.loc[50,'age']=None# Assignem un valor nul a la columna 'age' de la fila 50print("Number of null values in each column:")print(df.isnull().sum(),"\n")
Number of null values in each column:
age 1
workclass 1836
fnlwgt 0
education 0
education-num 0
marital-status 0
occupation 1843
relationship 0
race 0
sex 0
capital-gain 0
capital-loss 0
hours-per-week 0
native-country 583
income 0
dtype: int64
En aquest cas, podem tractar-los de tres maneres diferents:
Eliminar les files amb valors nuls.
Eliminar la columna amb valors nuls.
Inferir els valors nuls.
Depenent de la tipologia de les dades, una opció serà més adequada que una altra.
Els models d'aprenentatge automàtic no poden treballar directament
amb dades categòriques o amb text, per tant, és necessari processar-les
per poder-les utilitzar.
Per identificar les columnes amb dades categòriques, podem utilitzar
el mètode dtypes i filtrar les columnes amb el tipus object.
Per transformar les dades categòriques en dades numèriques,
podem utilitzar diferents mètodes com:
OrdinalEncoder i LabelEncoder: transformen les dades categòriques en valors numèrics.
La diferència principal és que OrdinalEncoder està pensat per transformar les característiques
de les dades, mentre que LabelEncoder està pensat per transformar les etiquetes (target).
Per aquesta raó, OrdinalEncoder permet transformar més d'una columna a la vegada i,
en canvi, LabelEncoder només permet transformar una única columna.
Aquest tipus de transformació és adequada quan les dades categòriques tenen un ordre implícit.
OneHotEncoder: transforma les dades categòriques en variables binàries.
Aquest mètode crea una columna per a cada valor únic de la columna original,
assignant un valor de 1 si el valor és present i 0 si no ho és.
Aquest tipus de transformació és adequada quan les dades categòriques no tenen un ordre implícit.
El OrdinalEncoder transforma les dades categòriques en valors ordinals, és a dir,
assigna un valor numèric a cada categoria.
Info
OrdinalEncoder no suporta valors nuls, per tant, és necessari tractar-los
abans de fer la transformació.
Exemple: Transformació de workclass amb OrdinalEncoder
# Assignem un valor '?' als valors nulsdf.loc[df['workclass'].isnull(),'workclass']='?'workclass_oe=OrdinalEncoder()df['workclass_oe']=workclass_oe.fit_transform(df[['workclass']])# print each unique value and its corresponding labelprint("Unique values of workclass column:")unique_pairs=df[['workclass','workclass_oe']].drop_duplicates().sort_values('workclass_oe').reset_index(drop=True)print(unique_pairs,"\n")
El OneHotEncoder transforma les dades categòriques en múltiples columnes binàries,
que s'indica amb un 1 si el valor és d'aquella categoria i 0 si no ho és.
#!/usr/bin/env pythonfromurllib.requestimporturlopenimportpandasaspdimportosdefdownload(url,filepath):http_response=urlopen(url)content=http_response.read()withopen(filepath,'wb')asf:f.write(content)files_folder='../../files/ud3'ifnotos.path.exists(files_folder):os.makedirs(files_folder)file_path=os.path.join(files_folder,'adult.data.csv')ifnotos.path.exists(file_path):adult_dataset_url='https://raw.githubusercontent.com/joapuiib/saa-datasets/refs/heads/main/adult.data.csv'print('Downloading dataset...')download(adult_dataset_url,file_path)else:print(f'Dataset found at {file_path}')df=pd.read_csv(file_path)print("Head of the dataset:")print(df.head(),"\n")print("Tail of the dataset:")print(df.tail(),"\n")print("Info of the dataset:")df.info()print()print("Shape of the dataset:")print(df.shape,"\n")print("Description of the dataset:")print(df.describe(),"\n")print("Unique values of workclass column:")print(df['workclass'].unique(),"\n")print("Value counts of workclass column:")print(df['workclass'].value_counts(dropna=False),"\n")## Valors nulsdf.loc[50,'age']=None# Assignem un valor nul a la columna 'age' de la fila 50print("Number of null values in each column:")print(df.isnull().sum(),"\n")## Eliminar files amb valors nulsprint(df[df['age'].isnull()])rows=df.shape[0]df.dropna(subset=['age'],inplace=True)print(f"Deleted {rows-df.shape[0]} rows with null values in 'age' column","\n")print("Categorical columns:")print(df.select_dtypes(include='object').columns,"\n")# Assignem un valor '?' als valors nulsdf.loc[df['workclass'].isnull(),'workclass']='?'workclass_oe=OrdinalEncoder()df['workclass_oe']=workclass_oe.fit_transform(df[['workclass']])# print each unique value and its corresponding labelprint("Unique values of workclass column:")unique_pairs=df[['workclass','workclass_oe']].drop_duplicates().sort_values('workclass_oe').reset_index(drop=True)print(unique_pairs,"\n")encoder=OneHotEncoder()encoded_data=encoder.fit_transform(df[['sex']])encoded_columns=encoder.get_feature_names_out(['sex'])df_encoded=pd.DataFrame(encoded_data.toarray(),columns=encoded_columns)df=pd.concat([df,df_encoded],axis=1)print("OneHot encoded columns:")print(df[['sex','sex_Male','sex_Female']].head(),"\n")