机器学习是一种强大的计算能力,可以预测或预测传统算法难以处理的事情。机器学习之旅从收集和准备数据(大量数据)开始,然后基于这些数据构建数学模型。虽然可以使用多种工具来完成这些任务,但我喜欢使用 shell。
Shell 是使用定义的语言执行操作的接口。可以使用交互方式或脚本方式调用此语言。shell 的概念是在 1970 年代的 Unix 操作系统中引入的。一些最流行的 shell 包括 Bash、tcsh 和 Zsh。它们适用于包括 Linux、macOS 和 Windows 在内的所有操作系统,这使它们具有很高的可移植性。在本练习中,我将使用 Bash。
本文介绍了如何使用 shell 进行数据收集和数据准备。无论您是寻求高效工具的数据科学家,还是希望将您的技能用于机器学习的 shell 专家,我都希望您能在此处找到有价值的信息。
本文中的示例问题是创建一个机器学习模型来预测美国各州的气温。它使用 shell 命令和脚本来执行以下数据收集和数据准备步骤
- 下载数据
- 提取必要的字段
- 聚合数据
- 制作时间序列
- 创建训练、测试和验证数据集
您可能会问,当您可以使用 Python 等机器学习编程语言完成所有这些工作时,为什么要使用 shell 来完成呢?这是一个很好的问题。如果使用像 shell 这样简单、友好、丰富的技术执行数据处理,那么数据科学家将只专注于机器学习建模,而不是语言的细节。
先决条件
首先,您需要安装一个 shell 解释器。如果您使用 Linux 或 macOS,它将已经安装,并且您可能已经熟悉它。如果您使用 Windows,请尝试 MinGW 或 Cygwin。
有关更多信息,请参见
- Bash 教程 在 opensource.com 上
- Steve Parker (Bourne shell 的创建者) 编写的官方 shell 脚本教程
- Linux 文档项目的 Bash 初学者指南
- 如果您需要特定命令的帮助,请在 shell 中键入
<命令名> --help
以获得帮助;例如:ls --help
。
开始
现在您的 shell 已设置好,您可以开始为机器学习温度预测问题准备数据。
1. 下载数据
本教程的数据来自美国国家海洋和大气管理局 (NOAA)。您将使用最近 10 个完整年份的数据来训练您的模型。数据源位于 https://www1.ncdc.noaa.gov/pub/data/ghcn/daily/by_year/,数据为 .csv 格式,并经过 gzipped 压缩。
使用 shell 脚本下载并解压缩数据。使用您喜欢的文本编辑器创建一个名为 download.sh
的文件,然后粘贴以下代码。代码中的注释解释了命令的作用
#!/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
备注
- 如果您位于代理服务器之后,请查阅 Mark Grennan 的 操作指南,并使用
export http_proxy=http://username:password@proxyhost:port/ export https_proxy=https://username:password@proxyhost:port/
- 确保所有标准命令都已在您的 PATH 中(例如
/bin
或/usr/bin
)。如果不是,请 设置您的 PATH。 - Wget 是一个用于从命令行连接到 Web 服务器的实用程序。如果您的系统上未安装 Wget,请 下载它。
- 确保您已安装 gzip,这是一个用于压缩和解压缩的实用程序。
运行此脚本以下载、提取并使 10 年的数据以 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
...
ls 命令列出文件夹的内容。使用 ls 20*.csv
列出所有名称以 20 开头并以 .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. 提取平均温度
从美国地区的 CSV 文件中提取 TAVG(平均温度)数据
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
此脚本
$ ./extract_tavg_us.sh
2010.csv -> TAVG_US_2010.csv
...
2019.csv -> TAVG_US_2019.csv
创建以下文件
$ 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
以下是 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,
head 命令是一个实用程序,用于显示文件的前几行(默认情况下,10 行)。
数据包含的信息超出您的需要。通过消除第 3 列(因为所有数据都是平均温度)和第 5 列及之后的列来限制列数。换句话说,保留第 1 列(气候站)、第 2 列(日期)和第 4 列(记录的温度)。
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
运行脚本
$ ./key_columns.sh
Extracting columns TAVG_US_2010.csv
...
Extracting columns TAVG_US_2019.csv
TAVG_US_2010.csv
的前几行(已删除不需要的数据)是
$ 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
日期采用字符串形式 (YMD)。为了正确训练您的模型,您的算法需要识别逗号分隔的 Y,M,D 形式的日期字段(例如,20100101
变为 2010,01,01
)。您可以使用 sed 实用程序转换它们。
date_format.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
运行脚本
$ ./date_format.sh
Date formatting TAVG_US_2010.csv
...
Date formatting TAVG_US_2019.csv
TAVG_US_2010.csv
的前几行(采用逗号分隔的日期格式)是
$ 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. 聚合各州的平均温度数据
天气数据来自位于美国城市的气候站,但您想预测整个州的气温。要将气候站数据转换为州数据,首先将气候站映射到其州。
使用 wget 下载气候站列表
$ wget ftp://ftp.ncdc.noaa.gov/pub/data/ghcn/daily/ghcnd-stations.txt
使用 grep 实用程序提取美国站点以查找美国列表。以下命令搜索以文本 "US
." 开头的行。>
是一个 重定向,将输出写入文件,在本例中,写入名为 us_stations.txt
的文件
$ grep "^US" ghcnd-stations.txt > us_stations.txt
此文件是为漂亮的打印而创建的,因此列分隔符不一致
$ 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
...
使用 cat 打印文件,使用 tr 挤压重复项并输出到临时文件,并将临时文件重命名回原始文件,从而使它们保持一致,所有操作都在一行中完成
$ cat us_stations.txt | tr -s ' ' > us_stations.txt.tmp; cp us_stations.txt.tmp us_stations.txt;
命令输出的前几行
$ 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
...
这包含很多信息(GPS 坐标等),但您只需要站点代码和州。使用 cut
$ cut -d' ' -f1,5 us_stations.txt > us_stations.txt.tmp; mv us_stations.txt.tmp us_stations.txt;
命令输出的前几行
$ head us_stations.txt
US009052008 SD
US10RMHS145 CO
US10adam001 NE
US10adam002 NE
...
将其制作成 CSV 并使用 sed 将空格更改为逗号分隔符
$ sed -i s/' '/,/g us_stations.txt
命令输出的前几行
$ head us_stations.txt
US009052008,SD
US10RMHS145,CO
US10adam001,NE
US10adam002,NE
...
虽然您使用了多个命令来完成这些任务,但可以在一次运行中执行所有步骤。自己尝试一下。
现在,使用 AWK 将站点代码替换为其州位置,AWK 在功能上对于大型数据处理具有很高的性能。
station_to_state_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
以下是这些参数的含义
-F, |
字段分隔符为 , |
FNR |
每个文件中的行号 |
NR |
两个文件中行号的总和 |
FNR==NR |
仅在第一个文件 ${PATTERN_FILE} 中为 TRUE |
{ x[$1]=$2; next; } |
如果 FNR==NR 为 TRUE(仅适用于 $PATTERN_FILE 中的所有行) |
- x |
用于存储 station=state 映射的变量 |
- x[$1]=$2 |
将 station=state 的数据添加到映射 |
- $1 |
第一个文件中的第一列(站点代码) |
- $2 |
第一个文件中的第二列(州代码) |
- x |
所有站点的映射,例如,x[US009052008]=SD 、x[US10RMHS145]=CO 、...、x[USW00096409]=AK |
- next |
转到与 FNR==NR 匹配的下一行(本质上,这从 ${PATTERN_FILE} 创建所有站点状态的映射) |
{ $1=x[$1]; print $0 } |
如果 FNR==NR 为 FALSE(仅适用于 $DATA_FILE 中的所有行) |
- $1=x[$1] |
将第一个字段替换为 x[$1] ;本质上,将站点代码替换为州代码 |
- print $0 |
打印所有列(包括替换的 $1 ) |
OFS=, |
输出字段分隔符为 , |
带有站点代码的 CSV
$ 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
运行命令
$ ./station_to_state_data.sh
TAVG_US_2010.csv
...
TAVG_US_2019.csv
站点现在已映射到州
$ 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
每个州每天都有多个温度读数,因此您需要计算每天每个州的读数的平均值。使用 AWK 进行文本处理,使用 sort 确保最终结果以逻辑顺序排列,并使用 rm 在处理后删除临时文件。
station_to_state_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
以下是 AWK 参数的含义
FILE=$DATA_FILE |
CSV 文件被处理为 FILE |
-F, |
字段分隔符为 , |
state_day_sum[$1 "," $2 "," $3 "," $4] = $5 |
州($1 )在年($2 )、月($3 )、日($4 )的温度总和($5 ) |
state_day_num[$1 "," $2 "," $3 "," $4] = $5 |
州($1 )在年($2 )、月($3 )、日($4 )的温度读数数量 |
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 |
输入文件(一个接一个地以 TAVG_US_ 开头并以 .csv 结尾的所有文件) |
> STATE_DAY_${DATA_FILE}.tmp |
将结果保存到临时文件 |
运行脚本
$ ./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
创建这些文件
$ 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
查看所有州的某一年数据(less 是一个实用程序,可以一次查看一页输出)
$ 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
将所有数据文件合并为一个
$ cat STATE_DAY_TAVG_US_20*.csv > TAVG_US_2010-2019.csv
现在您有了一个文件,其中包含所有州、所有年份的数据
$ 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. 制作时间序列数据
像这样的问题很适合用时间序列模型来解决,例如长短期记忆网络(LSTM),它是一种循环神经网络(RNN)。输入数据被组织成时间切片;例如,将20天作为一个切片。
这是一个单独的时间切片(如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
该时间切片表示为(温度值,其中前20周为X,第21周为y)。
AK, -181.934,-199.531, ... ,
-157.273,-165.3
这些切片在时间上是连续的。 例如,2010年末延续到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
这将产生以下预测:
AK,2011,01,11,-106.851
这个时间切片被认为是:
AK, -209.92, ... ,-79.8523,-59.5658, ... ,-100.623,-106.851
等等,针对所有州、年份、月份和日期。 更多解释请参阅关于时间序列预测的教程。
编写一个脚本来创建时间切片。
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
运行脚本。 它使用空格作为列分隔符;使用 sed 将它们更改为逗号。
$ ./timeslices.sh > TIMESLICE_TAVG_US_2010-2019.csv; sed -i s/' '/,/g TIME_VARIANT_TAVG_US_2010-2019.csv
以下是输出 .csv 文件的前几行和后几行。
$ 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
虽然这确实有效,但效率不高。 可以对其进行优化——你能尝试一下吗? 在下面的评论中报告你是如何做的。
5. 创建训练、测试和验证数据集
将数据拆分为训练、测试和验证集。
data_sets.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
这将生成数据集,可以通过在脚本中设置GEN=SEQ
或GEN=RAN
来顺序或随机化这些数据集,并且可以使用shuf来打乱数据。
运行脚本
$ ./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
要创建这些数据文件。
$ 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
使用 shell 进行数据处理
当您需要为下一个机器学习项目处理大量数据时,请考虑 shell 命令和脚本。 它们经过验证,可以随时使用,并且有友好的社区来指导和帮助您。
本文介绍了用于数据处理的 shell,脚本展示了各种可能性。 还有更多可能。 您想继续深入研究吗? 在下面的评论中告诉我们。
3 条评论