การทำนายไฟป่าโดยใช้การเรียนรู้ของเครื่อง

โหนดต้นทาง: 1194873

บทความนี้มีเนื้อหาเกี่ยวกับอะไร?

ไฟป่า พุ่มไม้ หรือไฟมังสวิรัติ สามารถอธิบายได้ว่าเป็นการเผาไหม้หรือการเผาไหม้พืชที่ไม่มีการควบคุมและไม่ได้กำหนดไว้ในสภาพแวดล้อมตามธรรมชาติ เช่น ป่า ทุ่งหญ้า ฯลฯ ในบทความนี้ เราไม่ได้กำหนดว่าไฟป่าจะเกิดขึ้นหรือไม่ หรือไม่ เรากำลังทำนายความเชื่อมั่นของไฟป่าตามคุณลักษณะบางประการ

การทำนายไฟป่าโดยใช้ ML
1 รูปภาพ

ทำไมเราต้องมีโมเดลทำนายไฟป่า?

คำถามแรกเกิดขึ้นเพราะเหตุใดเราจึงต้องการเรียนรู้ด้วยเครื่องเพื่อทำนายไฟป่าในพื้นที่นั้น ๆ ใช่ คำถามนั้นถูกต้องทั้งที่มีกรมป่าไม้ที่มีประสบการณ์ซึ่งจัดการกับปัญหาเหล่านี้มาเป็นเวลานานแล้วเหตุใดจึงจำเป็นต้องมี ML โดยกล่าวว่าคำตอบนั้นค่อนข้างง่ายที่กรมป่าไม้ที่มีประสบการณ์สามารถตรวจสอบได้ใน 3- พารามิเตอร์ 4 ตัวจากใจมนุษย์ แต่ ML นั้นสามารถจัดการกับพารามิเตอร์ต่างๆ ได้มากมาย ไม่ว่าจะเป็นละติจูด ลองจิจูด ดาวเทียม รุ่น และอื่นๆ ดังนั้นการจัดการกับพารามิเตอร์หลายความสัมพันธ์นี้ที่รับผิดชอบไฟป่า เราต้องการ ML แน่นอน!

สารบัญ

  1. การนำเข้าไลบรารีที่จำเป็น
  2. การวิเคราะห์ข้อมูลเชิงสำรวจ
  3. การทำความสะอาดข้อมูล
  4. การพัฒนาแบบจำลอง (RandomForestRegressor)
  5. การปรับโมเดล (RandomSearchCV)
  6. โมดูล bz2 (โบนัสก้อนใหญ่)

การนำเข้าไลบรารี

นำเข้าวันที่และเวลาเป็น dt นำเข้าแพนด้าเป็น pd นำเข้าจำนวนเป็น np นำเข้าทะเลเป็น sns นำเข้า matplotlib.pyplot เป็น plt %matplotlib แบบอินไลน์จาก sklearn.model_selection นำเข้า train_test_split จาก sklearn.metrics นำเข้าความถูกต้อง_score, types_report จาก sklearn.ensemble นำเข้า RandomForestReport

กำลังอ่านชุดข้อมูลการสำรวจไฟป่า (.csv)

ป่า = pd.read_csv('fire_archive.csv')

มาดูชุดข้อมูลของเรา (2.7+ MB)

ป่าหัว ()

Output:

การอ่านชุดข้อมูลการทำนายไฟป่า

การสำรวจข้อมูล

ป่า.รูปร่าง

Output:

(36011, 15)

ที่นี่เราจะเห็นว่าเรามี 36011 แถว และ คอลัมน์ 15 ในชุดข้อมูลของเราเห็นได้ชัดว่าเราต้องทำความสะอาดข้อมูลเป็นจำนวนมาก แต่ก่อนอื่น

มาสำรวจชุดข้อมูลนี้กันมากขึ้น

ป่าไม้.คอลัมน์

Output:

ดัชนี (['ละติจูด', 'ลองจิจูด', 'ความสว่าง', 'สแกน', 'แทร็ก', 'acq_date', 'acq_time', 'ดาวเทียม', 'เครื่องมือ', 'ความมั่นใจ', 'เวอร์ชัน', 'bright_t31' , 'frp', 'daynight', 'type'], dtype='object')

กำลังตรวจสอบค่า Null ในชุดข้อมูลการทำนายไฟป่า

ป่า.isnull().ผลรวม()

Output:

ละติจูด 0 ลองจิจูด 0 ความสว่าง 0 สแกน 0 แทร็ก 0 acq_date 0 acq_time 0 ดาวเทียม 0 เครื่องมือ 0 ความมั่นใจ 0 รุ่น 0 bright_t31 0 frp 0 กลางวัน 0 ประเภท 0 dtype: int64

โชคดีที่เราไม่มีค่า Null ในชุดข้อมูลนี้

ป่า.describe()

Output:

อธิบายชุดข้อมูล
plt.figure(figsize=(10, 10)) sns.heatmap(forest.corr(),annot=True,cmap='viridis',linewidths=.5)

Output:

แผนที่ความหนาแน่นสำหรับชุดข้อมูล

การทำความสะอาดข้อมูล

forest = forest.drop(['ติดตาม'], แกน = 1)

เรากำลังวางคอลัมน์แทร็ก

หมายเหตุ จากชุดข้อมูลเราไม่พบว่ามีไฟป่าเกิดขึ้นหรือไม่ เรากำลังพยายามค้นหาความมั่นใจว่าไฟป่าจะเกิดขึ้น อาจดูเหมือนเป็นสิ่งเดียวกันแต่มีความแตกต่างกันเล็กน้อยมาก พยายามหาสิ่งนั้น🙂

ค้นหาข้อมูลหมวดหมู่

print("คอลัมน์ที่สแกน") print(forest['scan'].value_counts()) print() print("คอลัมน์ aqc_time") print(forest['acq_time'].value_counts()) print() พิมพ์ ( "คอลัมน์ดาวเทียม") print(forest['satellite'].value_counts()) print() print("The instrument column") print(forest['instrument'].value_counts()) print() print("The รุ่นคอลัมน์") พิมพ์ (ฟอเรสต์['รุ่น'].value_counts()) พิมพ์ () พิมพ์ ("คอลัมน์กลางวัน") พิมพ์ (ฟอเรสต์['กลางวัน'].value_counts()) พิมพ์ ()

Output:

คอลัมน์สแกน 1.0 8284 1.1 6000 1.2 3021 1.3 2412 1.4 1848 1.5 1610 1.6 1451 1.7 1281 1.8 1041 1.9 847 2.0 707 2.2 691 2.1 649 2.3 608 2.5 468 2.4 433 2.8 422 3.0 402 2.7 366 2.9 361 2.6 347 3.1 259 3.2 244 3.6 219 3.4 203 3.3 203 3.8 189 3.9 156 4.7 149 4.3 137 3.5 134 3.7 134 4.1 120 4.6 118 4.5 116 4.2 108 4.0 103 4.4 100 4.8 70 ชื่อ: scan, dtype: int64 คอลัมน์ aqc_time 506 851 454 631 122 612 423 574 448 563 ... 1558 1 635 1 1153 1 302 1 1519 1 ชื่อ: acq_time, ความยาว: 662, dtype: int64 คอลัมน์ดาวเทียม Aqua 20541 Terra 15470 ชื่อ: satellite, dtype: int64 คอลัมน์เครื่องมือ MODIS 36011 ชื่อ: เครื่องมือ, dtype: int64 คอลัมน์รุ่น 6.3 36011 ชื่อ: รุ่น dtype: int64 คอลัมน์กลางวัน D 28203 N 7808 ชื่อ: กลางวัน dtype: int64

จากข้อมูลข้างต้น จะเห็นว่าบางคอลัมน์มีเพียงแค่ ค่าหนึ่งที่เกิดขึ้นในนั้นหมายความว่าไม่มีค่าสำหรับเรา
ดังนั้นเราจะปล่อยพวกเขาทั้งหมด
เท่านั้น ดาวเทียม และ กลางวัน-กลางคืน คอลัมน์เท่านั้น ประเภทหมวดหมู่.

ที่กล่าวว่า เรายังสามารถใช้ the การสแกน คอลัมน์เพื่อปรับโครงสร้างเป็น ประเภทข้อมูลหมวดหมู่ คอลัมน์. ซึ่งเราจะทำในอีกสักครู่

forest = forest.drop(['เครื่องมือ', 'เวอร์ชัน'], แกน = 1)
ป่าหัว ()

Output:

ส่องหัวข้อมูลทำนายไฟป่า
daynight_map = {"D": 1, "N": 0} satellite_map = {"Terra": 1, "Aqua": 0} forest['daynight'] = forest['daynight'].map (daynight_map) ป่า[ 'ดาวเทียม'] = ป่า['ดาวเทียม'].map(satellite_map)
ป่าหัว ()

Output:

การดูแถวเริ่มต้นของชุดข้อมูล

การดูประเภทคอลัมน์อื่น

ฟอเรสต์['type'].value_counts()

Output:

0 35666 2 335 3 10 ชื่อ: พิมพ์ dtype: int64

การต่อฟอเรสต์และประเภท data frame

ประเภท = pd.get_dummies(ป่า['ประเภท']) ป่า = pd.concat([ป่า ประเภท] แกน=1)
forest = forest.drop(['type'], แกน = 1) forest.head()

Output:

การดูข้อมูลหลังจากเชื่อมฟอเรสต์และประเภท dataframe

เปลี่ยนชื่อคอลัมน์เพื่อความเข้าใจที่ดีขึ้น

forest = forest.rename(columns={0: 'type_0', 2: 'type_2', 3: 'type_3'})

วิธีการ Binning

  • ตอนนี้ฉันบอกว่าเราจะแปลงคอลัมน์สแกนเป็นประเภทหมวดหมู่ เราจะทำสิ่งนี้โดยใช้ วิธีการ binning
  • ช่วงสำหรับคอลัมน์เหล่านี้คือ 1 ถึง 4.8
ถังขยะ = [0, 1, 2, 3, 4, 5] labels = [1,2,3,4,5] forest['scan_binned'] = pd.cut(forest['scan'], bins=bins, ฉลาก=ฉลาก)
ป่าหัว ()

Output:

ใช้วิธี Binning

การแปลงประเภทข้อมูลเป็นประเภทวันที่จาก สตริงหรือ NumPy

ฟอเรสต์['acq_date'] = pd.to_datetime(ฟอเรสต์['acq_date'])

ตอนนี้เราจะปล่อย การสแกน คอลัมน์และที่จับ ประเภทวันที่ ข้อมูล – เราสามารถดึงข้อมูลที่เป็นประโยชน์จากประเภทข้อมูลเหล่านี้ได้เช่นเดียวกับที่เราทำกับ ข้อมูลหมวดหมู่

forest = forest.drop(['scan'], แกน = 1)

การสร้างคอลัมน์ปีใหม่ด้วยความช่วยเหลือของ acq_date column

forest['year'] = ฟอเรสต์['acq_date'].dt.year forest.head()

Output:

การสร้างคอลัมน์ใหม่

ตามที่เราได้เพิ่มคอลัมน์ปีในทำนองเดียวกันเราจะเพิ่ม เดือน และ วัน คอลัมน์

forest['month'] = forest['acq_date'].dt.month forest['day'] = ป่า['acq_date'].dt.day

ตรวจสอบรูปร่างของชุดข้อมูลอีกครั้ง

ป่า.รูปร่าง

Output:

(36011, 17)

ตอนนี้ ดังที่เราเห็นว่ามีการเพิ่มคอลัมน์อีกสองคอลัมน์ซึ่งเป็นรายละเอียดของคอลัมน์วันที่

การแยกตัวแปรเป้าหมายของเรา

y = forest['confidence'] fin = forest.drop(['confidence', 'acq_date', 'acq_time', 'bright_t31', 'type_0'], แกน = 1)

ตรวจสอบความสัมพันธ์อีกครั้ง

plt.figure(figsize=(10, 10)) sns.heatmap(fin.corr(),annot=True,cmap='viridis',linewidths=.5)

Output:

กำลังตรวจสอบความสัมพันธ์
ภาพโดยผู้เขียน

มาดูชุดข้อมูลที่ล้างและจัดเรียงกันเถอะ

ครีบหัว ()

Output:

กำลังดูข้อมูลที่ล้างและจัดเรียง

แยกข้อมูลที่ชัดเจนออกเป็นชุดข้อมูลการฝึกอบรมและการทดสอบ

Xtrain, Xtest, ytrain, ytest = train_test_split(fin.iloc[:, :500], y, test_size=0.2)

การสร้างแบบจำลอง

การใช้ RandomForestRegressor สำหรับการสร้างแบบจำลอง

random_model = RandomForestRegressor (n_estimators = 300, random_state = 42, n_jobs = -1)
#Fit random_model.fit(Xtrain, ytrain) y_pred = random_model.predict(Xtest) #ตรวจสอบความแม่นยำ random_model_accuracy = รอบ (random_model.score(Xtrain, ytrain)*100,2) พิมพ์ (รอบ (random_model_accuracy, 2), '% ')

Output:

95.32%

ตรวจสอบความถูกต้อง

random_model_accuracy1 = รอบ (random_model.score (Xtest, ytest)*100,2) พิมพ์ (รอบ (random_model_accuracy1, 2), '%')

Output:

65.32%

การบันทึกโมเดลด้วยโมดูลดองโดยใช้รูปแบบอนุกรม

นำเข้าของดองที่ save_model = pickle.dump (random_model, open ('ForestModelOld.pickle', 'wb'))

การปรับแต่งโมเดล

  • ความแม่นยำไม่ค่อยดีนัก แถมโมเดลยังฟิตอีกด้วย
  • ดังนั้นเราจึงใช้ RandomCV

รับพารามิเตอร์ทั้งหมดจากโมเดล

Random_model.get_params()

Output:

{'bootstrap': True, 'ccp_alpha': 0.0, 'criterion': 'mse', 'max_depth': None, 'max_features': 'auto', 'max_leaf_nodes': ไม่มี 'max_samples': ไม่มี 'min_impurity_decrease' : 0.0, 'min_impurity_split': ไม่มี, 'min_samples_leaf': 1, 'min_samples_split': 2, 'min_weight_fraction_leaf': 0.0, 'n_estimators': 300, 'n_jobs': -1, 'oob_score'_: เท็จ, 'สุ่ม' 42, 'verbose': 0, 'warm_start': เท็จ}

นำ RadomizedSearchCV ไปใช้จริง!

""" n_estimators = จำนวนต้นไม้ในฟอเรสต์ max_features = จำนวนคุณลักษณะที่พิจารณาสำหรับการแยกโหนดสูงสุด max_deep = จำนวนระดับสูงสุดในแต่ละแผนผังการตัดสินใจ min_samples_split = จำนวนจุดข้อมูลต่ำสุดที่วางอยู่ในโหนดก่อนแยกโหนด min_samples_leaf = จำนวนจุดข้อมูลขั้นต่ำที่อนุญาตใน leaf node bootstrap = วิธีการสุ่มตัวอย่างจุดข้อมูล (มีหรือไม่มีการแทนที่) """
จาก sklearn.model_selection นำเข้า RandomizedSearchCV
จำนวนต้นไม้ในป่าสุ่ม
n_estimators = [int(x) สำหรับ x ใน np.linspace(start = 300, stop = 500, num = 20)]
จำนวนคุณสมบัติที่ต้องพิจารณาในทุกการแยก
max_features = ['อัตโนมัติ', 'sqrt']
จำนวนระดับสูงสุดในต้นไม้
max_deep = [int(x) สำหรับ x ใน np.linspace(15, 35, num = 7)] max_depth.append(None)
จำนวนตัวอย่างขั้นต่ำที่ต้องใช้ในการแยกโหนด
min_samples_split = [2, 3, 5]
จำนวนตัวอย่างขั้นต่ำที่ต้องการในแต่ละโหนดลีฟ
min_samples_leaf = [1, 2, 4]
สร้างตารางสุ่ม
random_grid = {'n_estimators': n_estimators, 'max_features': max_features, 'max_depth': max_depth, 'min_samples_split': min_samples_split, 'min_samples_leaf': min_samples_leaf, } พิมพ์ (random_samples_leaf, })

Output:

{'n_estimators': [300, 310, 321, 331, 342, 352, 363, 373, 384, 394, 405, 415, 426, 436, 447, 457, 468, 478, 489, 500], 'max_features' : ['auto', 'sqrt'], 'max_depth': [15, 18, 21, 25, 28, 31, 35, None], 'min_samples_split': [2, 3, 5], 'min_samples_leaf': [ 1, 2, 4]}
  • การค้นหาพารามิเตอร์แบบสุ่ม โดยใช้การตรวจสอบข้าม 3 เท่า ค้นหาชุดค่าผสมต่างๆ กว่า 100 ชุด และใช้คอร์ที่มีอยู่ทั้งหมด
  • n_iter ซึ่งควบคุมจำนวนของชุดค่าผสมต่างๆ ที่จะลอง และ cv ซึ่งเป็นจำนวนเท่าที่จะใช้สำหรับการตรวจสอบข้าม
rf_random = RandomizedSearchCV (ตัวประมาณ = random_model, param_distributions = random_grid, n_iter = 50, cv = 3, verbose=2, random_state=42) # ปรับรูปแบบการค้นหาแบบสุ่ม rf_random.fit (Xtrain, ytrain)

Output:

ผลลัพธ์ของแบบจำลองของเราสำหรับการทำนายไฟป่า

เช่นเดียวกับตัวอย่างนี้จะมี หลายเท่า ใน RandomizedSearchCV นี้

รับพารามิเตอร์ที่ดีที่สุดจากมัน

rf_random.best_params_

Output:

{'n_estimators': 394, 'min_samples_split': 2, 'min_samples_leaf': 1, 'max_features': 'sqrt', 'max_depth': 25}

การสร้างโมเดลใหม่ด้วยพารามิเตอร์ที่ปรับแต่งแล้ว

random_new = RandomForestRegressor (n_estimators = 394, min_samples_split = 2, min_samples_leaf = 1, max_features = 'sqrt', max_depth = 25, bootstrap = True)
#พอดี random_new.fit(Xtrain, ytrain)
y_pred1 = random_new.predict (Xtest)
#ตรวจสอบความถูกต้อง random_model_accuracy1 = round(random_new.score(Xtrain, ytrain)*100,2) print(round(random_model_accuracy1, 2), '%')

Output:

95.31%

ตรวจสอบความถูกต้อง

random_model_accuracy2 = รอบ (random_new.score (Xtest, ytest)*100,2) พิมพ์ (รอบ (random_model_accuracy2, 2), '%')

Output:

67.39%

การบันทึกโมเดลที่ปรับแต่งด้วยโมดูล Pickle โดยใช้รูปแบบซีเรียลไลซ์

save_model = pickle.dump(random_new, open('ForestModel.pickle','wb'))

กำลังโหลดโมเดลดองที่ปรับแต่งแล้ว

reg_from_pickle = pickle.load (saved_model)

bz2file.bzXNUMX

เชอร์รี่ในส่วนเค้กมาถึงแล้ว (โบนัสของบทความนี้) มาทำความเข้าใจว่าโมดูล bz2file นี้เกี่ยวกับอะไร มาเริ่มกันเลย!

bz2file คืออะไร

bz2file เป็นหนึ่งในโมดูลใน python ซึ่งมีหน้าที่ในการบีบอัดและคลายการบีบอัดไฟล์ ดังนั้นจึงสามารถช่วยลดขนาดไฟล์ซีเรียลไลซ์หรือดีซีเรียลไลซ์ให้มีขนาดเล็กลง ซึ่งจะมีประโยชน์มากในระยะยาวเมื่อเรามีชุดข้อมูลขนาดใหญ่

bz2file มีประโยชน์อย่างไรที่นี่

อย่างที่เราทราบดีว่าชุดข้อมูลของเรามีขนาด 2.7+ MB และโมเดลฟอเรสต์สุ่มของเรามีขนาด 700+ MB ดังนั้นเราจึงต้องบีบอัดข้อมูลนั้นเพื่อไม่ให้โมเดลดังกล่าวเป็นสถานการณ์ที่วุ่นวายในการจัดเก็บ

จะติดตั้ง bz2file ได้อย่างไร?

  • สมุดบันทึก Jupyter: !pip ติดตั้ง bz2file
  • พรอมต์อนาคอนดา/CMD: pip ติดตั้ง bz2file

ดังนั้นฉันจึงติดตั้ง bz2file ซึ่งใช้ในการบีบอัดข้อมูล นี่เป็นแพ็คเกจช่วยชีวิตสำหรับผู้ที่มีพื้นที่ว่างน้อยบนดิสก์ แต่ต้องการจัดเก็บหรือใช้ชุดข้อมูลขนาดใหญ่ ตอนนี้ไฟล์ดองหมดแล้ว 700 MB ในขนาดที่เมื่อใช้ bz2 บีบอัดเป็นไฟล์ size 93 MB หรือน้อยกว่า.

นำเข้า bz2 compressionLevel = 9 source_file = 'ForestModel.pickle' # ไฟล์นี้สามารถอยู่ในรูปแบบอื่น เช่น .csv หรืออื่น ๆ... destination_file = 'ForestModel.bz2' โดยเปิด (source_file, 'rb') เป็นข้อมูล: tarbz2contents = bz2.compress(data.read(), compressionLevel) fh = open(destination_file, "wb") fh.write(tarbz2contents) fh.close()

รหัสนี้จะระงับขนาดของรุ่นดองที่ปรับแล้ว

โอเค นั่นคือห่อจากด้านข้างของฉัน!

เชิงอรรถ

ขอบคุณที่อ่านบทความของฉัน🙂

ฉันหวังว่าพวกคุณจะชอบการเรียนรู้ทีละขั้นตอนของ ทำนายไฟป่าด้วยแมชชีนเลิร์นนิง. สิ่งสุดท้ายที่ฉันอยากจะพูดถึงคือ ฉันตระหนักดีถึงความจริงที่ว่าความแม่นยำของแบบจำลองนั้นไม่ค่อยดีนัก แต่วัตถุประสงค์ของบทความนั้นค่อนข้างสมดุล ดังนั้นพวกคุณสามารถลองใช้อัลกอริทึม Ml ที่แตกต่างกันเพื่อค้นหาความแม่นยำที่ดีขึ้น .

นี่คือ repo ลิงค์ บทความนี้

ที่นี่ คุณสามารถเข้าถึงบทความอื่นๆ ของฉันซึ่งเผยแพร่บน Analytics Vidhya ซึ่งเป็นส่วนหนึ่งของ Blogathon (ลิงค์)

หากมีคำถามใด ๆ คุณสามารถเชื่อมต่อกับฉันใน LinkedIn อ้างถึงสิ่งนี้ ลิงค์

เกี่ยวกับฉัน

สวัสดีทุกคน ตอนนี้ฉันทำงานอยู่ in TCS และก่อนหน้านี้ฉันทำงานเป็น Data Science Associate Analyst in ซอร์บา คอนซัลติ้ง อินเดีย นอกจากงานเต็มเวลาแล้ว ฉันยังมีความสนใจอย่างมากในสาขาเดียวกัน เช่น Data Science พร้อมกับส่วนย่อยของปัญญาประดิษฐ์อื่นๆ เช่น Computer Vision, Machine Learning และ Deep learning ที่จะร่วมมือกับฉันในทุกโครงการ ในโดเมนที่กล่าวถึงข้างต้น (LinkedIn).

ที่มาของภาพ -

  1. ภาพที่ 1 – https://www.theleader.info/wp-content/uploads/2017/08/forest-fire.jpg

สื่อที่แสดงในบทความนี้เกี่ยวกับการทำนายไฟป่าไม่ได้เป็นของ Analytics Vidhya และใช้ดุลยพินิจของผู้เขียน

ที่มา: https://www.analyticsvidhya.com/blog/2021/10/forest-fire-prediction-using-machine-learning/

ประทับเวลา:

เพิ่มเติมจาก การวิเคราะห์ วิทยา