Crea un modelo de aprendizaje automático con Bash
Bash, Tcsh o Zsh pueden ayudarle a prepararse para el aprendizaje automático.
El aprendizaje automático es una poderosa capacidad informática para predecir o pronosticar cosas que los algoritmos convencionales encuentran desafiantes. El viaje del aprendizaje automático comienza con la recopilación y preparación de datos (muchos) y luego construye modelos matemáticos basados en esos datos. Si bien se pueden usar varias herramientas para estas tareas, a mí me gusta usar el shell.
Un shell es una interfaz para realizar operaciones utilizando un lenguaje definido. Este lenguaje se puede invocar de forma interactiva o mediante script. El concepto de shell se introdujo en los sistemas operativos Unix en la década de 1970. Algunos de los shells más populares incluyen Bash, tcsh y Zsh. Están disponibles para todos los sistemas operativos, incluidos Linux, macOS y Windows, lo que les confiere una alta portabilidad. Para este ejercicio, usaré Bash.
Este artículo es una introducción al uso de un shell para la recopilación y preparación de datos. Si es un científico de datos que busca herramientas eficientes o un experto en shell que busca utilizar sus habilidades para el aprendizaje automático, espero que encuentre información valiosa aquí.
El problema de ejemplo de este artículo es la creación de un modelo de aprendizaje automático para pronosticar temperaturas en los estados de EE. UU. Utiliza scripts y comandos de shell para realizar los siguientes pasos de recopilación y preparación de datos:
- Descargar datos
- Extrae los campos necesarios
- Información agregada
- hacer series de tiempo
- Crear conjuntos de datos para entrenar, probar y validar
Quizás se pregunte por qué debería hacer esto con Shell, cuando puede hacerlo todo en un lenguaje de programación de aprendizaje automático como Python. Esta es una buena pregunta. Si el procesamiento de datos se realiza con una tecnología rica, sencilla y amigable como un shell, un científico de datos se centra únicamente en el modelado de aprendizaje automático y no en los detalles de un lenguaje.
Requisitos previos
Primero, necesita tener instalado un intérprete de shell. Si usas Linux o macOS, ya estará instalado y es posible que ya estés familiarizado con él. Si usa Windows, pruebe MinGW o Cygwin.
Para más información, ver:
- Tutoriales de Bash aquí en opensource.com
- El tutorial oficial de scripting de shell de Steve Parker, el creador de Bourne shell
- La guía de Bash para principiantes por el proyecto de documentación de Linux
- Si necesita ayuda con un comando específico, escriba
en el shell para obtener ayuda; por ejemplo:--help ls --help.
Empezar
Ahora que su shell está configurado, puede comenzar a preparar datos para el problema de predicción de temperatura del aprendizaje automático.
1. Descargar datos
Los datos para este tutorial provienen de la Administración Nacional Oceánica y Atmosférica de EE. UU. (NOAA). Entrenará su modelo utilizando los últimos 10 años completos de datos. La fuente de datos está en https://www1.ncdc.noaa.gov/pub/data/ghcn/daily/by_year/, y los datos están en formato .csv y comprimidos con gzip.
Descargue y descomprima los datos usando un script de shell. Utilice su editor de texto favorito para crear un archivo llamado download.sh
y pegue el código siguiente. Los comentarios en el código explican qué hacen los comandos:
#!/bin/sh
# This is called hashbang. It identifies the executor used to run this file.
# In this case, the script is executed by shell itself.
# If not specified, a program to execute the script must be specified.
# With hashbang: ./download.sh; Without hashbang: sh ./download.sh;
FROM_YEAR=2010
TO_YEAR=2019
year=$FROM_YEAR
# For all years one by one starting from FROM_YEAR=2010 upto TO_YEAR=2019
while [ $year -le $TO_YEAR ]
do
# show the year being downloaded now
echo $year
# Download
wget https://www1.ncdc.noaa.gov/pub/data/ghcn/daily/by_year/${year}.csv.gz
# Unzip
gzip -d ${year}.csv.gz
# Move to next year by incrementing
year=$(($year+1))
done
Notas:
Si está detrás de un servidor proxy, consulte el procedimiento de Mark Grennan y utilice:
export http_proxy=http://username:password@proxyhost:port/ export https_proxy=https://username:password@proxyhost:port/
- Asegúrese de que todos los comandos estándar ya estén en su RUTA (como
/bin
o/usr/bin
). Si no, configure su RUTA. - Wget es una utilidad para conectarse a servidores web desde la línea de comandos. Si Wget no está instalado en su sistema, descárguelo.
- Asegúrate de tener gzip, una utilidad utilizada para comprimir y descomprimir.
Ejecute este script para descargar, extraer y hacer que los datos de 10 años estén disponibles como archivos CSV:
$ ./download.sh
2010
--2020-10-30 19:10:47-- https://www1.ncdc.noaa.gov/pub/data/ghcn/daily/by_year/2010.csv.gz
Resolving www1.ncdc.noaa.gov (www1.ncdc.noaa.gov)... 205.167.25.171, 205.167.25.172, 205.167.25.178, ...
Connecting to www1.ncdc.noaa.gov (www1.ncdc.noaa.gov)|205.167.25.171|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 170466817 (163M) [application/gzip]
Saving to: '2010.csv.gz'
0K .......... .......... .......... .......... .......... 0% 69.4K 39m57s
50K .......... .......... .......... .......... .......... 0% 202K 26m49s
100K .......... .......... .......... .......... .......... 0% 1.08M 18m42s
...
El comando ls enumera el contenido de una carpeta. Utilice ls 20*.csv
para enumerar todos sus archivos con nombres que comiencen con 20 y terminen con .csv.
$ ls 20*.csv
2010.csv 2011.csv 2012.csv 2013.csv 2014.csv 2015.csv 2016.csv 2017.csv 2018.csv 2019.csv
2. Extraer temperaturas medias
Extraiga los datos TAVG (temperatura promedio) de los CSV para las regiones de EE. UU.:
extract_tavg_us.sh
#!/bin/sh
# For each file with name that starts with "20" and ens with ".csv"
for csv_file in `ls 20*.csv`
do
# Message that says file name $csv_file is extracted to file TAVG_US_$csv_file
# Example: 2010.csv extracted to TAVG_US_2010.csv
echo "$csv_file -> TAVG_US_$csv_file"
# grep "TAVG" $csv_file: Extract lines in file with text "TAVG"
# |: pipe
# grep "^US": From those extract lines that begin with text "US"
# > TAVG_US_$csv_file: Save xtracted lines to file TAVG_US_$csv_file
grep "TAVG" $csv_file | grep "^US" > TAVG_US_$csv_file
done
Este guión:
$ ./extract_tavg_us.sh
2010.csv -> TAVG_US_2010.csv
...
2019.csv -> TAVG_US_2019.csv
crea estos archivos:
$ ls TAVG_US*.csv
TAVG_US_2010.csv TAVG_US_2011.csv TAVG_US_2012.csv TAVG_US_2013.csv
TAVG_US_2014.csv TAVG_US_2015.csv TAVG_US_2016.csv TAVG_US_2017.csv
TAVG_US_2018.csv TAVG_US_2019.csv
Aquí están las primeras líneas de TAVG_US_2010.csv
:
$ head TAVG_US_2010.csv
USR0000AALC,20100101,TAVG,-220,,,U,
USR0000AALP,20100101,TAVG,-9,,,U,
USR0000ABAN,20100101,TAVG,12,,,U,
USR0000ABCA,20100101,TAVG,16,,,U,
USR0000ABCK,20100101,TAVG,-309,,,U,
USR0000ABER,20100101,TAVG,-81,,,U,
USR0000ABEV,20100101,TAVG,-360,,,U,
USR0000ABEN,20100101,TAVG,-224,,,U,
USR0000ABNS,20100101,TAVG,89,,,U,
USR0000ABLA,20100101,TAVG,59,,,U,
El comando head es una utilidad para mostrar las primeras líneas (de forma predeterminada, 10 líneas) de un archivo.
Los datos tienen más información de la que necesitas. Limite el número de columnas eliminando la columna 3 (ya que todos los datos son temperatura promedio) y la columna 5 en adelante. En otras palabras, mantenga las columnas 1 (estación climática), 2 (fecha) y 4 (temperatura registrada).
key_columns.sh
#!/bin/sh
# For each file with name that starts with "TAVG_US_" and ens with ".csv"
for csv_file in `ls TAVG_US_*.csv`
do
echo "Exractiing columns $csv_file"
# cat $csv_file: 'cat' is to con'cat'enate files - here used to show one year csv file
# |: pipe
# cut -d',' -f1,2,4: Cut columns 1,2,4 with , delimitor
# > $csv_file.cut: Save to temporary file
| > $csv_file.cut:
cat $csv_file | cut -d',' -f1,2,4 > $csv_file.cut
# mv $csv_file.cut $csv_file: Rename temporary file to original file
mv $csv_file.cut $csv_file
# File is processed and saved back into the same
# There are other ways to do this
# Using intermediate file is the most reliable method.
done
Ejecute el script:
$ ./key_columns.sh
Extracting columns TAVG_US_2010.csv
...
Extracting columns TAVG_US_2019.csv
Las primeras líneas de TAVG_US_2010.csv
con los datos innecesarios eliminados son:
$ head TAVG_US_2010.csv
USR0000AALC,20100101,-220
USR0000AALP,20100101,-9
USR0000ABAN,20100101,12
USR0000ABCA,20100101,16
USR0000ABCK,20100101,-309
USR0000ABER,20100101,-81
USR0000ABEV,20100101,-360
USR0000ABEN,20100101,-224
USR0000ABNS,20100101,89
USR0000ABLA,20100101,59
Las fechas están en forma de cadena (YMD). Para entrenar su modelo correctamente, sus algoritmos deben reconocer los campos de fecha en el formato Y,M,D separados por comas (por ejemplo, 20100101
se convierte en 2010,01,01
) . Puedes convertirlos con la utilidad sed.
fecha_formato.sh
for csv_file in `ls TAVG_*.csv`
do
echo Date formatting $csv_file
# This inserts , after year
sed -i 's/,..../&,/' $csv_file
# This inserts , after month
sed -i 's/,....,../&,/' $csv_file
done
Ejecute el script:
$ ./date_format.sh
Date formatting TAVG_US_2010.csv
...
Date formatting TAVG_US_2019.csv
Las primeras líneas de TAVG_US_2010.csv
con el formato de fecha separada por comas son:
$ head TAVG_US_2010.csv
USR0000AALC,2010,01,01,-220
USR0000AALP,2010,01,01,-9
USR0000ABAN,2010,01,01,12
USR0000ABCA,2010,01,01,16
USR0000ABCK,2010,01,01,-309
USR0000ABER,2010,01,01,-81
USR0000ABEV,2010,01,01,-360
USR0000ABEN,2010,01,01,-224
USR0000ABNS,2010,01,01,89
USR0000ABLA,2010,01,01,59
3. Datos agregados de temperatura promedio de los estados
Los datos meteorológicos provienen de estaciones climáticas ubicadas en ciudades de EE. UU., pero desea pronosticar las temperaturas de estados enteros. Para convertir los datos de las estaciones climáticas en datos estatales, primero, asigne las estaciones climáticas a sus estados.
Descargue la lista de estaciones climáticas usando wget:
$ wget ftp://ftp.ncdc.noaa.gov/pub/data/ghcn/daily/ghcnd-stations.txt
Extraiga las estaciones de EE. UU. con la utilidad grep para buscar listados de EE. UU. El siguiente comando busca líneas que comiencen con el texto "US
". >
es una redirección que escribe la salida en un archivo, en este caso, en un archivo llamado us_stations.txt
:
$ grep "^US" ghcnd-stations.txt > us_stations.txt
Este archivo fue creado para una impresión bonita, por lo que los separadores de columnas son inconsistentes:
$ head us_stations.txt
US009052008 43.7333 -96.6333 482.0 SD SIOUX FALLS (ENVIRON. CANADA)
US10RMHS145 40.5268 -105.1113 1569.1 CO RMHS 1.6 SSW
US10adam001 40.5680 -98.5069 598.0 NE JUNIATA 1.5 S
...
Hágalos consistentes usando cat para imprimir el archivo, usando tr para comprimir las repeticiones y enviarlo a un archivo temporal, y cambiando el nombre del archivo temporal al original, todo en una línea:
$ cat us_stations.txt | tr -s ' ' > us_stations.txt.tmp; cp us_stations.txt.tmp us_stations.txt;
Las primeras líneas de la salida del comando:
$ head us_stations.txt
US009052008 43.7333 -96.6333 482.0 SD SIOUX FALLS (ENVIRON. CANADA)
US10RMHS145 40.5268 -105.1113 1569.1 CO RMHS 1.6 SSW
US10adam001 40.5680 -98.5069 598.0 NE JUNIATA 1.5 S
...
Contiene mucha información (coordenadas GPS y demás), pero solo necesita el código y el estado de la estación. Usar corte:
$ cut -d' ' -f1,5 us_stations.txt > us_stations.txt.tmp; mv us_stations.txt.tmp us_stations.txt;
Las primeras líneas de la salida del comando:
$ head us_stations.txt
US009052008 SD
US10RMHS145 CO
US10adam001 NE
US10adam002 NE
...
Convierta esto en un CSV y cambie los espacios a separadores de coma usando sed:
$ sed -i s/' '/,/g us_stations.txt
Las primeras líneas de la salida del comando:
$ head us_stations.txt
US009052008,SD
US10RMHS145,CO
US10adam001,NE
US10adam002,NE
...
Aunque utilizó varios comandos para estas tareas, es posible realizar todos los pasos en una sola ejecución. Inténtalo tú mismo.
Ahora, reemplace los códigos de estación con sus ubicaciones estatales usando AWK, que tiene un alto rendimiento funcional para el procesamiento de datos de gran tamaño.
estación_a_estado_data.sh
#!/bin/sh
for DATA_FILE in `ls TAVG_US_*.csv`
do
echo ${DATA_FILE}
awk -v FILE=$DATA_FILE -F, '
{
state_day_sum[$1 "," $2 "," $3 "," $4] = state_day_sum[$1 "," $2 "," $3 "," $4] + $5
state_day_num[$1 "," $2 "," $3 "," $4] = state_day_num[$1 "," $2 "," $3 "," $4] + 1
}
END {
for (state_day_key in state_day_sum) {
print state_day_key "," state_day_sum[state_day_key]/state_day_num[state_day_key]
}
}
' OFS=, $DATA_FILE > STATE_DAY_${DATA_FILE}.tmp
sort -k1 -k2 -k3 -k4 < STATE_DAY_${DATA_FILE}.tmp > STATE_DAY_$DATA_FILE
rm -f STATE_DAY_${DATA_FILE}.tmp
done
Esto es lo que significan estos parámetros:
-F,
El separador de campo es
,
FNR
Número de línea en cada archivo
NR
Número de línea en ambos archivos juntos
FNR==NR
Es VERDADERO solo en el primer archivo
$ {PATTERN_FILE}
{ x[$1]=$2; next; }
Si
FNR==NR
es VERDADERO (solo para todas las líneas en$PATTERN_FILE
)- x
Variable para almacenar el mapa
station=state
- x[$1]=$2
Agrega datos de
station=state
al mapa- $1
Primera columna del primer archivo (códigos de estación)
- $2
Segunda columna del primer archivo (códigos de estado)
- x
Mapa de todas las estaciones, por ejemplo,
x[US009052008]=SD
,x[US10RMHS145]=CO
, ...,x[USW00096409]=AK
- next
Vaya a la siguiente línea que coincida con
FNR==NR
(esencialmente, esto crea un mapa de todas las estaciones-estados del$ {PATTERN_FILE}
{ $1=x[$1]; print $0 }
Si
FNR==NR
es FALSO (solo para todas las líneasen $DATA_FILE
)- $1=x[$1]
Reemplace el primer campo con
x[$1]
; esencialmente, reemplace el código de estación con el código de estado- print $0
Imprima todas las columnas (incluido el
$1
reemplazado)OFS=,
El separador de campos de salida es
,
El CSV con códigos de estación:
$ head TAVG_US_2010.csv
USR0000AALC,2010,01,01,-220
USR0000AALP,2010,01,01,-9
USR0000ABAN,2010,01,01,12
USR0000ABCA,2010,01,01,16
USR0000ABCK,2010,01,01,-309
USR0000ABER,2010,01,01,-81
USR0000ABEV,2010,01,01,-360
USR0000ABEN,2010,01,01,-224
USR0000ABNS,2010,01,01,89
USR0000ABLA,2010,01,01,59
Ejecute el comando:
$ ./station_to_state_data.sh
TAVG_US_2010.csv
...
TAVG_US_2019.csv
Las estaciones ahora están asignadas a los estados:
$ head TAVG_US_2010.csv
AK,2010,01,01,-220
AZ,2010,01,01,-9
AL,2010,01,01,12
AK,2010,01,01,16
AK,2010,01,01,-309
AK,2010,01,01,-81
AK,2010,01,01,-360
AK,2010,01,01,-224
AZ,2010,01,01,59
AK,2010,01,01,-68
Cada estado tiene varias lecturas de temperatura para cada día, por lo que debes calcular el promedio de las lecturas de cada estado para un día. Utilice AWK para procesar texto, ordenar para asegurarse de que los resultados finales estén en un orden lógico y rm para eliminar el archivo temporal después del procesamiento.
estación_a_estado_data.sh
PATTERN_FILE=us_stations.txt
for DATA_FILE in `ls TAVG_US_*.csv`
do
echo ${DATA_FILE}
awk -F, \
'FNR==NR { x[$1]=$2; next; } { $1=x[$1]; print $0 }' \
OFS=, \
${PATTERN_FILE} ${DATA_FILE} > ${DATA_FILE}.tmp
mv ${DATA_FILE}.tmp ${DATA_FILE}
done
Esto es lo que significan los parámetros AWK:
FILE=$DATA_FILE
Archivo CSV procesado como
FILE
-F,
El separador de campo es
,
state_day_sum[$1 "," $2 "," $3 "," $4] = $5
state_day_sum[$1 "," $2 "," $3 "," $4] + $5Suma de temperatura (
$5
) para el estado($1
) en el año ($2
), mes ($3
) , día ($4) state_day_num[$1 "," $2 "," $3 "," $4] = $5
state_day_num[$1 "," $2 "," $3 "," $4] + 1Número de lecturas de temperatura para el estado (
$1
) en el año ($2
), mes ($3
), día ($4
código>)END
Al final, después de recopilar la suma y el número de lecturas para todos los estados, años, meses y días, calcule los promedios.
for (state_day_key in state_day_sum)
Para cada estado-año-mes-día
print state_day_key "," state_day_sum[state_day_key]/state_day_num[state_day_key]
Estado de impresión, año, mes, día, promedio
OFS=,
El separador de campos de salida es
,
$DATA_FILE
Archivo de entrada (todos los archivos con nombres que comienzan con
TAVG_US_
y terminan con.csv
, uno por uno)> STATE_DAY_${DATA_FILE}.tmp
Guardar el resultado en un archivo temporal
Ejecute el script:
$ ./TAVG_avg.sh
TAVG_US_2010.csv
TAVG_US_2011.csv
TAVG_US_2012.csv
TAVG_US_2013.csv
TAVG_US_2014.csv
TAVG_US_2015.csv
TAVG_US_2016.csv
TAVG_US_2017.csv
TAVG_US_2018.csv
TAVG_US_2019.csv
Estos archivos se crean:
$ ls STATE_DAY_TAVG_US_20*.csv
STATE_DAY_TAVG_US_2010.csv STATE_DAY_TAVG_US_2015.csv
STATE_DAY_TAVG_US_2011.csv STATE_DAY_TAVG_US_2016.csv
STATE_DAY_TAVG_US_2012.csv STATE_DAY_TAVG_US_2017.csv
STATE_DAY_TAVG_US_2013.csv STATE_DAY_TAVG_US_2018.csv
STATE_DAY_TAVG_US_2014.csv STATE_DAY_TAVG_US_2019.csv
Vea un año de datos para todos los estados (menos es una utilidad para ver el resultado de una página a la vez):
$ less STATE_DAY_TAVG_US_2010.csv
AK,2010,01,01,-181.934
...
AK,2010,01,31,-101.068
AK,2010,02,01,-107.11
...
AK,2010,02,28,-138.834
...
WY,2010,01,01,-43.5625
...
WY,2010,12,31,-215.583
Fusiona todos los archivos de datos en uno:
$ cat STATE_DAY_TAVG_US_20*.csv > TAVG_US_2010-2019.csv
Ahora tienes un archivo, con todos los estados, para todos los años:
$ cat TAVG_US_2010-2019.csv
AK,2010,01,01,-181.934
...
WY,2018,12,31,-167.421
AK,2019,01,01,-32.3386
...
WY,2019,12,30,-131.028
WY,2019,12,31,-79.8704
4.Crear datos de series temporales
Un problema como este se aborda adecuadamente con un modelo de series de tiempo como la memoria a corto plazo (LSTM), que es una red neuronal recurrente (RNN). Estos datos de entrada se organizan en intervalos de tiempo; considere 20 días como una porción.
Este es un segmento único (como en STATE_DAY_TAVG_US_2010.csv
):
X (input – 20 weeks):
AK,2010,01,01,-181.934
AK,2010,01,02,-199.531
...
AK,2010,01,20,-157.273
y (21st week, prediction for these 20 weeks):
AK,2010,01,21,-165.31
Este intervalo de tiempo se representa como (valores de temperatura donde las primeras 20 semanas son X y 21 es y):
AK, -181.934,-199.531, ... ,
-157.273,-165.3
Las porciones son contiguas en el tiempo. Por ejemplo, el final de 2010 continúa en 2011:
AK,2010,12,22,-209.92
...
AK,2010,12,31,-79.8523
AK,2011,01,01,-59.5658
...
AK,2011,01,10,-100.623
Lo que resulta en la predicción:
AK,2011,01,11,-106.851
Este intervalo de tiempo se toma como:
AK, -209.92, ... ,-79.8523,-59.5658, ... ,-100.623,-106.851
y así sucesivamente, para todos los estados, años, meses y fechas. Para obtener más explicaciones, consulte este tutorial sobre pronóstico de series de tiempo.
Escriba un guión para crear intervalos de tiempo:
timeslices.sh
#!/bin/sh
TIME_SLICE_PERIOD=20
file=TAVG_US_2010-2019.csv
# For each state in file
for state in `cut -d',' -f1 $file | sort | uniq`
do
# Get all temperature values for the state
state_tavgs=`grep $state $file | cut -d',' -f5`
# How many time slices will this result in?
# mber of temperatures recorded minus size of one timeslice
num_slices=`echo $state_tavgs | wc -w`
num_slices=$((${num_slices} - ${TIME_SLICE_PERIOD}))
# Initialize
slice_start=1; num_slice=0;
# For each timeslice
while [ $num_slice -lt $num_slices ]
do
# One timeslice is from slice_start to slice_end
slice_end=$(($slice_start + $TIME_SLICE_PERIOD - 1))
# X (1-20)
sliceX="$slice_start-$slice_end"
# y (21)
slicey=$(($slice_end + 1))
# Print state and timeslice temperature values (column 1-20 and 21)
echo $state `echo $state_tavgs | cut -d' ' -f$sliceX,$slicey`
# Increment
slice_start=$(($slice_start + 1)); num_slice=$(($num_slice + 1));
done
done
Ejecute el script. Utiliza espacios como separadores de columnas; hazlos comas con sed:
$ ./timeslices.sh > TIMESLICE_TAVG_US_2010-2019.csv; sed -i s/' '/,/g TIME_VARIANT_TAVG_US_2010-2019.csv
Aquí están las primeras líneas y las últimas líneas del archivo .csv de salida:
$ head -3 TIME_VARIANT_TAVG_US_2009-2019.csv
AK,-271.271,-290.057,-300.324,-277.603,-270.36,-293.152,-292.829,-270.413,-256.674,-241.546,-217.757,-158.379,-102.585,-24.9517,-1.7973,15.9597,-5.78231,-33.932,-44.7655,-92.5694,-123.338
AK,-290.057,-300.324,-277.603,-270.36,-293.152,-292.829,-270.413,-256.674,-241.546,-217.757,-158.379,-102.585,-24.9517,-1.7973,15.9597,-5.78231,-33.932,-44.7655,-92.5694,-123.338,-130.829
AK,-300.324,-277.603,-270.36,-293.152,-292.829,-270.413,-256.674,-241.546,-217.757,-158.379,-102.585,-24.9517,-1.7973,15.9597,-5.78231,-33.932,-44.7655,-92.5694,-123.338,-130.829,-123.979
$ tail -3 TIME_VARIANT_TAVG_US_2009-2019.csv
WY,-76.9167,-66.2315,-45.1944,-27.75,-55.3426,-81.5556,-124.769,-137.556,-90.213,-54.1389,-55.9907,-30.9167,-9.59813,7.86916,-1.09259,-13.9722,-47.5648,-83.5234,-98.2963,-124.694,-142.898
WY,-66.2315,-45.1944,-27.75,-55.3426,-81.5556,-124.769,-137.556,-90.213,-54.1389,-55.9907,-30.9167,-9.59813,7.86916,-1.09259,-13.9722,-47.5648,-83.5234,-98.2963,-124.694,-142.898,-131.028
WY,-45.1944,-27.75,-55.3426,-81.5556,-124.769,-137.556,-90.213,-54.1389,-55.9907,-30.9167,-9.59813,7.86916,-1.09259,-13.9722,-47.5648,-83.5234,-98.2963,-124.694,-142.898,-131.028,-79.8704
Si bien esto funciona, no tiene mucho rendimiento. Se puede optimizar. ¿Puedes intentarlo? Informe en los comentarios a continuación cómo lo hizo.
5. Cree conjuntos de datos para entrenar, probar y validar
Divida los datos en conjuntos entrenamiento, prueba y validación.
conjuntos_de datos.sh
#!/bin/sh
GEN=SEQ
# GEN=RAN
FILE=TIMESLICE_TAVG_US_2010-2019.csv
TRAIN_SET_PERCENT=70
TEST_SET_PERCENT=20
VAL_SET_PERCENT=$(( 100 - $TRAIN_SET_PERCENT - $TEST_SET_PERCENT ))
TRAIN_DATA=TRAIN_$FILE
TEST_DATA=TEST_$FILE
VAL_DATA=VAL_$FILE
> $TRAIN_DATA
> $TEST_DATA
> $VAL_DATA
for state in `cut -d',' -f1 $FILE | sort | uniq`
do
NUM_STATE_DATA=`grep "$state" $FILE | wc -l`
echo "$state: $NUM_STATE_DATA"
TRAIN_NUM_DATA=$(( $NUM_STATE_DATA * $TRAIN_SET_PERCENT / 100 ))
TEST_NUM_DATA=$(( $NUM_STATE_DATA * $TEST_SET_PERCENT / 100 ))
VAL_NUM_DATA=$(( $NUM_STATE_DATA - $TRAIN_NUM_DATA - $TEST_NUM_DATA ))
if [ $GEN == "SEQ" ]
then
echo "Sequential"
STATE_DATA=`grep $state $FILE`
elif [ $GEN == "RAN" ]
then
echo "Randomized"
STATE_DATA=`grep $state $FILE | shuf`
else
echo "Unknown data gen type: " $GEN
exit 1
fi
# Train set
per=$TRAIN_SET_PERCENT
num=$TRAIN_NUM_DATA; from=1; to=$(($from + $num - 1));
echo Train set: $per% $num from=$from to=$to
echo "$STATE_DATA" | head -$to >> $TRAIN_DATA
# Test set
per=$TEST_SET_PERCENT
num=$TEST_NUM_DATA; from=$(($to + 1)); to=$(($from + $num - 1));
echo Test set: $per% $num from=$from to=$to
echo "$STATE_DATA" | head -$to | tail -$num >> $TEST_DATA
# Validate set
per=$VAL_SET_PERCENT
num=$VAL_NUM_DATA; from=$(($to + 1)); to=$NUM_STATE_DATA;
echo Validate set: $per% $num from=$from to=$to
echo "$STATE_DATA" | tail -$num >> $VAL_DATA
echo
done
Esto genera conjuntos de datos que pueden ser secuenciales o aleatorios configurando GEN=SEQ
o GEN=RAN
en el script, y puede mezclar datos con shuf.
Ejecute el script:
$ ./data_sets.sh
AK: 3652
Sequential
Train set: 70% 2556 from=1 to=2556
Test set: 20% 730 from=2557 to=3286
Validate set: 10% 366 from=3287 to=3652
...
WY: 3352
Sequential
Train set: 70% 2346 from=1 to=2346
Test set: 20% 670 from=2347 to=3016
Validate set: 10% 336 from=3017 to=3352
Para crear estos archivos de datos:
$ ls *_TIMESLICE_TAVG_US_2010-2019.csv
TEST_TIMESLICE_TAVG_US_2010-2019.csv VAL_TIMESLICE_TAVG_US_2010-2019.csv
TRAIN_TIMESLICE_TAVG_US_2010-2019.csv
Procesamiento de datos con shell
Cuando necesite procesar una enorme cantidad de datos para su próximo proyecto de aprendizaje automático, piense en scripts y comandos de shell. Está probado y listo para usar con comunidades amigables para guiarlo y ayudarlo.
Este artículo presenta un shell para el procesamiento de datos y los scripts demuestran oportunidades. Es posible mucho más. ¿Quieres sacarlo adelante? Cuéntanos en los comentarios a continuación.