মেশিন লার্নিং হলো একটি শক্তিশালী কম্পিউটিং ক্যাপাবিলিটি জিনিসগুলো প্রেডিক্ট বা ফোরকাস্ট করার জন্য যা কনভেনশনাল অ্যালগরিদম চ্যালেঞ্জিং পায়। মেশিন লার্নিং যাত্রা শুরু হয় ডেটা সংগ্রহ এবং প্রস্তুত করার সাথে—এতটুকু—তারপর সেটি সেই ডেটার উপর ভিত্তি করে ম্যাথেমেটিক্যাল মডেল বিল্ড করে। যদিও এই টাস্কগুলোর জন্য একাধিক টুল ব্যবহার করা যায়, আমি শেল ব্যবহার করতে পছন্দ করি।
একটি শেল হলো একটি ইন্টারফেস অপারেশন পারফর্ম করার জন্য একটি ডিফাইন করা ভাষা ব্যবহার করে। এই ভাষা ইন্টারঅ্যাক্টিভলি বা স্ক্রিপ্টেডভাবে আহ্বান করা যায়। শেল কনসেপ্ট ১৯৭০-এর দশকে ইউনিক্স অপারেটিং সিস্টেমে পরিচয়পন্ন হয়েছিল। সবচেয়ে জনপ্রিয় শেলগুলো হলো Bash, tcsh, এবং Zsh। সেগুলো সব অপারেটিং সিস্টেমের জন্য উপলব্ধ, যাতে লিনাক্স, macOS, এবং উইন্ডোজ, যা তাদের হাই পোর্টেবিলিটি দেয়। এই এক্সারসাইজের জন্য, আমি Bash ব্যবহার করব।
এই আর্টিকেলটি ডেটা সংগ্রহ এবং ডেটা প্রস্তুতির জন্য একটি শেল ব্যবহার করার একটি ইন্ট্রোডাকশন। আপনি যেন একজন ডেটা সায়েন্টিস্ট हों দক্ষ টুল খুঁজছেন বা একজন শেল এক্সপার্ট हों আপনার স্কিল মেশিন লার্নিং-এ ব্যবহার করার জন্য, আমি আশা করি আপনি এখানে মূল্যবান তথ্য পাবেন।
এই আর্টিকেলের উদাহরণ সমস্যা হলো US রাজ্যগুলোর তাপমাত্রা ফোরকাস্ট করার জন্য একটি মেশিন লার্নিং মডেল তৈরি করা। এটি শেল কমান্ড এবং স্ক্রিপ্ট ব্যবহার করে নিচের ডেটা সংগ্রহ এবং ডেটা প্রস্তুতির ধাপগুলো করে:
- ডেটা ডাউনলোড
- প্রয়োজনীয় ফিল্ড এক্সট্র্যাক্ট
- ডেটা অ্যাগ্রিগেট
- টাইম সিরিজ তৈরি
- ট্রেন, টেস্ট, এবং ভ্যালিডেট ডেটা সেট তৈরি
আপনি প্রশ্ন করতে পারেন কেন আপনি শেল দিয়ে এটি করবেন, যখন আপনি সেটি সব পাইথনের মতো একটি মেশিন লার্নিং প্রোগ্রামিং ভাষায় করতে পারেন। এটি একটি ভালো প্রশ্ন। যদি ডেটা প্রসেসিং একটি সহজ, বান্ধব, সমৃদ্ধ টেকনোলজি যেমন একটি শেল দিয়ে পারফর্ম করা হয়, একটি ডেটা সায়েন্টিস্ট শুধু মেশিন লার্নিং মডেলিং-এ ফোকাস করতে পারেন একটি ভাষার ডিটেইলস ছাড়া।
প্রে-রিকোয়ারমেন্টস
প্রথমে, আপনার কাছে একটি শেল ইন্টারপ্রেটার ইনস্টল থাকতে হবে। আপনি যদি লিনাক্স বা macOS ব্যবহার করেন, এটি ইতিমধ্যে ইনস্টল থাকবে, এবং আপনি ইতিমধ্যে এটির সাথে পরিচিত হতে পারেন। আপনি যদি উইন্ডোজ ব্যবহার করেন, MinGW বা Cygwin ট্রাই করুন।
আরো তথ্যের জন্য, দেখুন:
- opensource.com-এ ব্যাশ টিউটোরিয়াল
- স্টিভ পারকারের অফিশিয়াল শেল স্ক্রিপ্টিং টিউটোরিয়াল, বোর্ন শেলের ক্রিয়েটর
- লিনাক্স ডকুমেন্টেশন প্রজেক্টের The Bash Guide for Beginners
- আপনি যদি একটি নির্দিষ্ট কমান্ডের সাথে সাহায্য প্রয়োজন, টাইপ করুন
<commandname> --helpশেলে সাহায্যের জন্য; উদাহরণস্বরূপ:ls --help।
শুরু করুন
এখন আপনার শেল সেট আপ হয়েছে, আপনি মেশিন লার্নিং টেম্পারেচার-প্রেডিকশন সমস্যা için ডেটা প্রস্তুত করা শুরু করতে পারেন।
১. ডেটা ডাউনলোড
এই টিউটোরিয়ালের ডেটা আসে US National Oceanic and Atmospheric Administration (NOAA)-এর কাছ থেকে। আপনি আপনার মডেল ট্রেন করবেন গত ১০টি সম্পূর্ণ বছরের ডেটা ব্যবহার করে। ডেটা সোর্সটি https://www1.ncdc.noaa.gov/pub/data/ghcn/daily/by_year/-এ আছে, এবং ডেটা .csv ফরম্যাটে এবং gzipped।
একটি শেল স্ক্রিপ্ট ব্যবহার করে ডেটা ডাউনলোড এবং আনজিপ করুন। আপনার প্রিয় টেক্সট এডিটর ব্যবহার করে download.sh নামে একটি ফাইল তৈরি করুন এবং নিচের কোড পেস্ট করুন। কোডের কমেন্টগুলো ব্যাখ্যা করে কমান্ডগুলো কী করে:
#!/bin/sh
# এটি হ্যাশব্যাং। এটি এক্সিকিউটরের শনাক্তকরণ করে যা এই ফাইলটি রান করতে ব্যবহৃত হয়।
# এই কেসে, স্ক্রিপ্টটি শেল নিজে দ্বারা এক্সিকিউট হয়।
# যদি নির্দিষ্ট না করা হয়, স্ক্রিপ্ট এক্সিকিউট করার একটি প্রোগ্রাম নির্দিষ্ট করা হবে।
# হ্যাশব্যাং সহ: ./download.sh; হ্যাশব্যাং ছাড়া: sh ./download.sh;
FROM_YEAR=2010
TO_YEAR=2019
year=$FROM_YEAR
# FROM_YEAR=2010 থেকে TO_YEAR=2019 পর্যন্ত সব বছর একে একে
while [ $year -le $TO_YEAR ]
do
# বর্তমান যে বছর ডাউনলোড হচ্ছে সেটি দেখান
echo $year
# ডাউনলোড
wget https://www1.ncdc.noaa.gov/pub/data/ghcn/daily/by_year/${year}.csv.gz
# আনজিপ
gzip -d ${year}.csv.gz
# ইনক্রিমেন্ট কর পরবর্তী বছর যেতে
year=$(($year+1))
done
নোটস:
- আপনি যদি একটি প্রক্সি সার্ভারের পেছনে থাকেন, মার্ক গ্রেনানের how-to দেখুন, এবং ব্যবহার করুন:
export http_proxy=https://username:password@proxyhost:port/
export https_proxy=https://username:password@proxyhost:port/ - নিশ্চিত করুন সব স্ট্যান্ডার্ড কমান্ড ইতিমধ্যে আপনার PATH-এ আছে (যেমন
/binবা/usr/bin)। না হলে, আপনার PATH সেট করুন। - Wget হলো একটি ইউটিলিটি কমান্ড লাইন থেকে ওয়েব সার্ভারের সাথে কানেক্ট করার জন্য। যদি Wget আপনার সিস্টেমে ইনস্টল না থাকে, ডাউনলোড করুন।
- নিশ্চিত করুন আপনার কাছে gzip আছে, কমপ্রেশন এবং ডিকমপ্রেশনের জন্য একটি ইউটিলিটি।
এই স্ক্রিপ্টটি রান করুন ডাউনলোড, এক্সট্র্যাক্ট, এবং ১০ বছরের ডেটা 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 ব্যবহার করুন ২০ দিয়ে শুরু এবং .csv দিয়ে শেষ হওয়া নামের সব ফাইল লিস্ট করতে।
$ ls 20*.csv
2010.csv 2011.csv 2012.csv 2013.csv 2014.csv 2015.csv 2016.csv 2017.csv 2018.csv 2019.csv
২. গড় তাপমাত্রা এক্সট্র্যাক্ট করুন
US অঞ্চলগুলো için CSV গুলো থেকে TAVG (গড় তাপমাত্রা) ডেটা এক্সট্র্যাক্ট করুন:
extract_tavg_us.sh
#!/bin/sh
# "20" দিয়ে শুরু এবং ".csv" দিয়ে শেষ হওয়া নামের প্রতিটি ফাইলের জন্য
for csv_file in `ls 20*.csv`
do
# মেসেজ যে ফাইল নাম $csv_file এক্সট্র্যাক্ট হয়েছে ফাইলে TAVG_US_$csv_file
# উদাহরণ: 2010.csv এক্সট্র্যাক্ট হয়েছে TAVG_US_2010.csv-এ
echo "$csv_file -> TAVG_US_$csv_file"
# grep "TAVG" $csv_file: "TAVG" টেক্সট সহ লাইন এক্সট্র্যাক্ট করুন ফাইলে
# |: পাইপ
# grep "^US": সেগুলো থেকে যেগুলো "US" টেক্সট দিয়ে শুরু করে সেগুলো এক্সট্র্যাক্ট করুন
# > TAVG_US_$csv_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 কমান্ড হলো একটি ইউটিলিটি ফাইলের প্রথম কয়েক লাইন (ডিফল্টভাবে, ১০ লাইন) দেখানোর জন্য।
ডেটাতে আপনার প্রয়োজনের চেয়ে বেশি ইনফো আছে। কলামের সংখ্যা সীমাবদ্ধ করুন কলাম ৩ বাদ দিয়ে (যেহেতু সব ডেটা গড় তাপমাত্রা) এবং কলাম ৫ এরপর। অন্য কথায়, কলাম ১ (ক্লাইমেট স্টেশন), ২ (তারিখ), এবং ৪ (রেকর্ড করা তাপমাত্রা) রাখুন।
key_columns.sh
#!/bin/sh
# "TAVG_US_" দিয়ে শুরু এবং ".csv" দিয়ে শেষ হওয়া নামের প্রতিটি ফাইলের জন্য
for csv_file in `ls TAVG_US_*.csv`
do
echo "Exractiing columns $csv_file"
# cat $csv_file: 'cat' হলো ফাইল কনক্যাটেনেট করার - এখানে একটি বছরের csv ফাইল দেখানোর জন্য ব্যবহার
# |: পাইপ
# cut -d',' -f1,2,4: , ডিলিমিটার দিয়ে কলাম ১,২,৪ কাটুন
# > $csv_file.cut: টেম্পোরারি ফাইলে সেভ করুন
| > $csv_file.cut:
cat $csv_file | cut -d',' -f1,2,4 > $csv_file.cut
# mv $csv_file.cut $csv_file: টেম্পোরারি ফাইলকে মূল ফাইলে রিনেম করুন
mv $csv_file.cut $csv_file
# ফাইল প্রসেস হয়েছে এবং একই ফাইলে সেভ হয়েছে
# এটি করার অন্যান্য উপায়ও আছে
# ইন্টারমিডিয়েট ফাইল ব্যবহার সবচেয়ে विश्वস্ত পদ্ধতি।
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
# এটি বছর পরে , ইনসার্ট করে
sed -i 's/,..../&,/' $csv_file
# এটি মাস পরে , ইনসার্ট করে
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
৩. রাজ্যগুলোর গড় তাপমাত্রা ডেটা অ্যাগ্রিগেট করুন
ওয়েদার ডেটা US শহরগুলোতে অবস্থিত ক্লাইমেট স্টেশন থেকে আসে, কিন্তু আপনি পুরো রাজ্যের তাপমাত্রা ফোরকাস্ট করতে চান। ক্লাইমেট-স্টেশন ডেটাকে স্টেট ডেটাতে কনভার্ট করতে, প্রথমে ক্লাইমেট স্টেশনগুলোকে তাদের স্টেটের সাথে ম্যাপ করুন।
wget ব্যবহার করে ক্লাইমেট স্টেশন লিস্ট ডাউনলোড করুন:
$ wget ftp://ftp.ncdc.noaa.gov/pub/data/ghcn/daily/ghcnd-stations.txt
grep ইউটিলিটি ব্যবহার করে US স্টেশনগুলো এক্সট্র্যাক্ট করুন US লিস্টিং খুঁজে বের করতে। নিচের কমান্ডটি লাইনগুলো সার্চ করে যেগুলো টেক্সট "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 ব্যবহার করে স্টেশন কোডগুলোক তাদের স্টেট লোকেশন দিয়ে রিপ্লেস করুন, যা বড় ডেটা প্রসেসিং-এ ফাংশনালি হাই পারফরম্যান্ট।
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 হয় (শুধু in $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
৪. টাইম-সিরিজ ডেটা তৈরি করুন
এই টাইপের সমস্যা একটি টাইম-সিরিজ মডেল দিয়ে উপযোগীভাবে অ্যাড্রেস করা হয় যেমন লং শর্ট-টার্ম মেমরি (LSTM), যা একটি রিকারেন্ট নিউরাল নেটওয়ার্ক (RNN)। এই ইনপুট ডেটা টাইম স্লাইসে অর্গানাইজড; ২০ দিন কনসিডার করুন একটি স্লাইস।
এটি একটি একক টাইম স্লাইস (যেমন STATE_DAY_TAVG_US_2010.csv):
X (ইনপুট – ২০ সপ্তাহ):
AK,2010,01,01,-181.934
AK,2010,01,02,-199.531
...
AK,2010,01,20,-157.273
y (২১তম সপ্তাহ, এই ২০ সপ্তাহের জন্য প্রেডিকশন):
AK,2010,01,21,-165.31
এই টাইম স্লাইসটি রিপ্রেজেন্ট করা হয়েছে (তাপমাত্রা ভ্যালু যেখানে প্রথম ২০ সপ্তাহ X, এবং ২১ y):
AK, -181.934,-199.531, ... ,
-157.273,-165.3
স্লাইসগুলো টাইম-কন্টিগুয়াস। উদাহরণস্বরূপ, ২০১০-এর শেষ ২০১১-এ চলতে থাকে:
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 state in `cut -d',' -f1 $file | sort | uniq`
do
# স্টেটের সব টেম্পারেচার ভ্যালু পান
state_tavgs=`grep $state $file | cut -d',' -f5`
# এটি কতটি টাইম স্লাইস তৈরি করবে?
# রেকর্ড করা টেম্পারেচারের সংখ্যা মাইনাস এক টাইমস্লাইসের সাইজ
num_slices=`echo $state_tavgs | wc -w`
num_slices=$((${num_slices} - ${TIME_SLICE_PERIOD}))
# ইনিশিয়ালাইজ
slice_start=1; num_slice=0;
# প্রতিটি টাইমস্লাইসের জন্য
while [ $num_slice -lt $num_slices ]
do
# এক টাইমস্লাইস হলো slice_start থেকে slice_end
slice_end=$(($slice_start + $TIME_SLICE_PERIOD - 1))
# X (১-২০)
sliceX="$slice_start-$slice_end"
# y (২১)
slicey=$(($slice_end + 1))
# স্টেট এবং টাইমস্লাইস টেম্পারেচার ভ্যালু প্রিন্ট করুন (কলাম ১-২০ এবং ২১)
echo $state `echo $state_tavgs | cut -d' ' -f$sliceX,$slicey`
# ইনক্রিমেন্ট
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
যদিও এটি কাজ করে, এটি খুব পারফরম্যান্ট নয়। এটি অপ্টিমাইজ করা যায়—আপনি চেষ্টা দিতে পারেন? কমেন্টে রিপোর্ট করুন আপনি কীভাবে করলেন।
৫. ট্রেন, টেস্ট, এবং ভ্যালিডেট ডেটা সেট তৈরি করুন
ডেটাকে ট্রেন, টেস্ট, এবং ভ্যালিডেট সেটে ভাগ করুন।
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
শেল দিয়ে ডেটা প্রসেসিং
যখন আপনার পরবর্তী মেশিন লার্নিং প্রজেক্টের জন্য প্রচুর পরিমাণ ডেটা প্রসেস করতে হয়, শেল কমান্ড এবং স্ক্রিপ্টের দিকে চিন্তা করুন। এটি প্রুভেন এবং ব্যবহার করার জন্য প্রস্তুত বান্ধব কমিউনিটির সাথে যা আপনাকে গাইড এবং সাহায্য করবে।
এই আর্টিকেলটি ডেটা প্রসেসিং-এর জন্য একটি শেল ইন্ট্রোডিউস করে, এবং স্ক্রিপ্টগুলো সুযোগগুলো প্রদর্শন করে। আরও অনেক কিছু সম্ভব। আপনি কি এটিকে আরো আগে নিতে চান? কমেন্টে নিচে বলুন।