Wat houdt dit artikel in?
Bos-, struik- of vegetarische brand kan worden omschreven als elke ongecontroleerde en niet-voorgeschreven verbranding of verbranding van planten in een natuurlijke omgeving zoals een bos, grasland, enz. In dit artikel bepalen we niet of er een bosbrand zal plaatsvinden. Of niet, we voorspellen de zekerheid van een bosbrand op basis van enkele kenmerken.
Waarom hebben we een bosbrandvoorspellingsmodel nodig?
De eerste vraag rijst: waarom hebben we eigenlijk machinaal leren nodig om bosbranden in dat specifieke gebied te voorspellen? Dus ja, de vraag is geldig, ondanks dat er een ervaren bosafdeling is die zich al heel lang met deze problemen bezighoudt, waarom is er dan behoefte aan ML? Dat gezegd zijnde is het antwoord vrij eenvoudig dat de ervaren bosafdeling kan controleren op 3- 4 parameters uit hun menselijke geest, maar ML kan daarentegen de talrijke parameters verwerken, of het nu breedtegraad, lengtegraad, satelliet, versie en wat dan ook kan zijn, dus omgaan met deze multi-relatie van een parameter die verantwoordelijk is voor de brand in het bos we hebben zeker ML nodig!
Inhoudsopgave
- Benodigde bibliotheken importeren
- Verkennende gegevensanalyse
- Gegevens opschonen
- Modelontwikkeling (RandomForestRegressor)
- Het model afstemmen (RandomSearchCV)
- bz2-module (grote bonus)
Bibliotheken importeren
importeer datetime als dt importeer panda's als pd importeer numpy als np import zeegeboren als sns importeer matplotlib.pyplot als plt %matplotlib inline uit sklearn.model_selection import train_test_split van sklearn.metrics importeer nauwkeurigheid_score, classificatie_rapport van sklearn.ensemble importeer RandomForestRegressor
Gegevensset voor onderzoek naar bosbranden lezen (.csv)
bos = pd.read_csv('fire_archive.csv')
Laten we eens kijken naar onze dataset (2.7+ MB)
bos.head()
Output:
Gegevensverkenning
bosvorm
Output:
(36011, 15)
Hier kunnen we zien dat we dat hebben gedaan 36011 rijen en 15 kolommen in onze dataset moeten we uiteraard veel gegevens opschonen, maar eerst
Laten we deze dataset verder verkennen
bos.kolommen
Output:
Index(['breedtegraad', 'lengtegraad', 'helderheid', 'scan', 'track', 'acq_date', 'acq_time', 'satelliet', 'instrument', 'vertrouwen', 'versie', 'bright_t31' , 'frp', 'dagnacht', 'type'], dtype='object')
Controleren op nulwaarden in de gegevensset voor bosbrandvoorspellingen
bos.isnull().sum()
Output:
breedtegraad 0 lengtegraad 0 helderheid 0 scannen 0 spoor 0 acq_date 0 acq_tijd 0 satelliet 0 instrument 0 vertrouwen 0 versie 0 bright_t31 0 frp 0 dagnacht 0 typ 0 dtype: int64
Gelukkig hebben we geen nulwaarden in deze dataset
bos.describe()
Output:
plt.figure(figsize=(10, 10)) sns.heatmap(forest.corr(),annot=True,cmap='viridis',linewidths=.5)
Output:
Gegevens opschonen
bos = bos.drop(['spoor'], as = 1)
Hier laten we de trackkolom vallen
Opmerking: Uit de dataset kunnen we overigens niet opmaken of de bosbrand wel of niet plaatsvindt; we proberen het vertrouwen te achterhalen dat de bosbrand zal plaatsvinden. Ze lijken misschien hetzelfde, maar er is een heel klein verschil tussen hen, probeer dat te vinden ๐
Categorische gegevens vinden
print("De scankolom") print(forest['scan'].value_counts()) afdrukken() print("De aqc_time kolom") print(forest['acq_time'].value_counts()) afdrukken() print("De satellietkolom") print(forest['satelliet'].value_counts()) afdrukken() print("De instrumentenkolom") print(bos['instrument'].value_counts()) afdrukken() print("De versiekolom") print(forest['versie'].value_counts()) afdrukken() print("De dagnachtkolom") print(bos['dagnacht'].value_counts()) afdrukken()
Output:
De scankolom 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 Naam: scan, dtype: int64 De kolom aqc_time 506 851 454 631 122 612 423 574 448 563 ... 1558 1 635 1 1153 1 302 1 1519 1 Naam: acq_time, lengte: 662, dtype: int64 De satellietkolom Aqua20541 Terra 15470 Naam: satelliet, dtype: int64 De instrumentenkolom MODIS36011 Naam: instrument, dtype: int64 De versiekolom 6.3 36011 Naam: versie, dtype: int64 De dagnachtkolom D28203 N 7808 Naam: dagnacht, dtype: int64
Uit de bovenstaande gegevens kunnen we zien dat sommige kolommen net รฉรฉn waarde die daarin terugkeert, wat betekent dat ze niet waardevol voor ons zijn
We laten ze dus helemaal vallen.
Alleen dus satelliet en dag nacht kolommen zijn de enige categorisch soort.
Dat gezegd hebbende, kunnen we zelfs de aftasten kolom om deze te herstructureren in een categorisch gegevenstype kolom. Wat we over een tijdje gaan doen.
forest = forest.drop(['instrument', 'versie'], as = 1)
bos.head()
Output:
daynight_map = {"D": 1, "N": 0} satelliet_map = {"Terra": 1, "Aqua": 0} bos['dagnacht'] = bos['dagnacht'].map(dagnacht_kaart) bos['satelliet'] = bos['satelliet'].map(satelliet_kaart)
bos.head()
Output:
Kijken naar het type van een andere kolom
bos['type'].value_counts()
Output:
0 35666 2 335 3 10 Naam: type, dtype: int64
Aaneengeschakeld bos en gegevensframe van typen
types = pd.get_dummies(forest['type']) bos = pd.concat([bos, typen], as=1)
bos = bos.drop(['type'], as = 1) bos.head()
Output:
De naam van kolommen wijzigen voor een beter begrip
forest = bos.hernoemen(columns={0: 'type_0', 2: 'type_2', 3: 'type_3'})
Binning-methode
- Nu heb ik gezegd dat we de scankolom naar het categorische type zullen converteren, we zullen dit doen met behulp van de binning methode.
- Het bereik voor deze kolommen was 1 tot 4.8
bakken = [0, 1, 2, 3, 4, 5] labels = [1,2,3,4,5] forest['scan_binned'] = pd.cut(forest['scan'], bins=bins, labels=labels)
bos.head()
Output:
Het gegevenstype converteren naar datumtype van tekenreeks of NumPy.
bos['acq_date'] = pd.to_datetime(forest['acq_date'])
Nu laten we de aftasten kolom en handvat datumtype data โ we kunnen nuttige informatie uit deze datatypen halen, net zoals we dat doen categorische data.
bos = bos.drop(['scan'], as = 1)
Een nieuw kolomjaar aanmaken met behulp van de kolom acq_date
bos['jaar'] = bos['acq_date'].dt.jaar bos.head()
Output:
Omdat we de jaarkolom op dezelfde manier hebben toegevoegd, zullen we deze toevoegen de maand en dag kolom
bos['maand'] = bos['acq_date'].dt.maand bos['dag'] = bos['acq_date'].dt.dag
De vorm van de dataset opnieuw controleren
bosvorm
Output:
(36011, 17)
Zoals we nu kunnen zien, zijn er nog twee kolommen toegevoegd, die een uitsplitsing zijn van de datumkolommen
Onze doelvariabele scheiden
y = bos['vertrouwen'] fin = forest.drop(['vertrouwen', 'acq_date', 'acq_time', 'bright_t31', 'type_0'], as = 1)
Nog een keer gekeken naar correlatie
plt.figure(figsize=(10, 10)) sns.heatmap(fin.corr(),annot=True,cmap='viridis',linewidths=.5)
Output:
Laten we nu onze opgeschoonde en gesorteerde dataset bekijken
fin.head()
Output:
Het opsplitsen van de schone gegevens in een trainings- en testdataset
Xtrain, Xtest, ytrain, ytest = train_test_split(fin.iloc[:, :500], y, test_size=0.2)
Model gebouw
RandomForestRegressor gebruiken voor het bouwen van modellen
random_model = RandomForestRegressor(n_estimators=300, willekeurige_status = 42, n_jobs = -1)
#Fit random_model.fit(Xtrain, ytrain) y_pred = random_model.predict(Xtest) #De nauwkeurigheid controleren willekeurige_model_nauwkeurigheid = round(random_model.score(Xtrain, ytrain)*100,2) print(round(random_model_accuracy, 2), '%')
Output:
95.32%
De nauwkeurigheid controleren
random_model_accuracy1 = round(random_model.score(Xtest, ytest)*100,2) print(round(random_model_accuracy1, 2), '%')
Output:
65.32%
Het model opslaan per pickle-module met behulp van het geserialiseerde formaat
importeer augurk opgeslagen_model = pickle.dump(random_model, open('ForestModelOld.pickle','wb'))
Modelafstemming
- De nauwkeurigheid is niet zo groot, en het model is overfitting
- Daarom gebruiken we RandomCV
Alle parameters uit het model ophalen
willekeurig_model.get_params()
Output:
{'bootstrap': True, 'ccp_alpha': 0.0, 'criterion': 'mse', 'max_ Depth': Geen, 'max_features': 'auto', 'max_leaf_nodes': Geen, 'max_samples': Geen, 'min_impurity_decrease' : 0.0, 'min_impurity_split': Geen, 'min_samples_leaf': 1, 'min_samples_split': 2, 'min_weight_fraction_leaf': 0.0, 'n_estimators': 300, 'n_jobs': -1, 'oob_score': False, 'random_state': 42, 'uitgebreid': 0, 'warme_start': False}
RadomizedSearchCV in actie zetten!
""" n_estimators = aantal bomen in het bos max_features = maximaal aantal functies dat in aanmerking wordt genomen voor het splitsen van een knooppunt max_diepte = maximaal aantal niveaus in elke beslissingsboom min_samples_split = minimaal aantal gegevenspunten dat in een knooppunt is geplaatst voordat het knooppunt wordt gesplitst min_samples_leaf = minimaal aantal toegestane gegevenspunten in een leaf-knooppunt bootstrap = methode voor het bemonsteren van gegevenspunten (met of zonder vervanging) """
van sklearn.model_selection import RandomizedSearchCV
Aantal bomen in willekeurig bos n_estimators = [int(x) voor x in np.linspace(start = 300, stop = 500, num = 20)] Aantal functies waarmee u bij elke splitsing rekening moet houden max_features = ['auto', 'sqrt'] Maximaal aantal niveaus in de boom max_diepte = [int(x) voor x in np.linspace(15, 35, num = 7)] max_diepte.append(Geen) Minimumaantal monsters dat nodig is om een โโknooppunt te splitsen min_samples_split = [2, 3, 5] Minimaal aantal monsters vereist bij elk bladknooppunt min_samples_leaf = [1, 2, 4] Maak het willekeurige raster random_grid = {'n_estimators': n_estimators, 'max_features': max_features, 'max_diepte': max_diepte, 'min_samples_split': min_samples_split, 'min_samples_leaf': min_samples_leaf, } afdrukken(willekeurig_raster)
Output:
{'n_schatters': [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_diepte': [15, 18, 21, 25, 28, 31, 35, Geen], 'min_samples_split': [2, 3, 5], 'min_samples_leaf': [ 1, 2, 4]}
- Een willekeurige zoektocht naar parameters, met behulp van drievoudige kruisvalidatie, zoeken in 3 verschillende combinaties en gebruik van alle beschikbare kernen
- n_iter, dat het aantal verschillende combinaties bepaalt dat moet worden geprobeerd, en cv, dat het aantal vouwen is dat moet worden gebruikt voor kruisvalidatie
rf_random = RandomizedSearchCV(schatter = willekeurig_model, param_distributies = willekeurig_raster, n_iter = 50, cv = 3, uitgebreid=2, willekeurige_status=42) # Pas het willekeurige zoekmodel aan rf_random.fit(Xtrain, ytrain)
Output:
Net als dit fragment zal dat er zijn talrijke vouwen in dit RandomizedSearchCV
Haal er de beste parameter uit
rf_random.best_params_
Output:
{'n_estimators': 394, 'min_samples_split': 2, 'min_samples_leaf': 1, 'max_features': 'sqrt', 'max_diepte': 25}
Een nieuw model maken met afgestemde parameters
random_new = RandomForestRegressor(n_estimators = 394, min_samples_split = 2, min_samples_leaf = 1, max_features = 'sqrt', max_diepte = 25, bootstrap = True)
#Fit willekeurige_nieuwe.fit(Xtrain, ytrain)
y_pred1 = willekeurig_nieuw.predict(Xtest)
#De nauwkeurigheid controleren random_model_accuracy1 = round(random_new.score(Xtrain, ytrain)*100,2) print(round(random_model_accuracy1, 2), '%')
Output:
95.31%
De nauwkeurigheid controleren
random_model_accuracy2 = round(random_new.score(Xtest, ytest)*100,2) print(round(random_model_accuracy2, 2), '%')
Output:
67.39%
Het afgestemde model opslaan via de pickle-module met behulp van het geserialiseerde formaat
opgeslagen_model = pickle.dump(random_new, open('ForestModel.pickle','wb'))
Het getunede ingelegde model laden
reg_from_pickle = augurk.load(saved_model)
bz2bestand
Hier komt de kers op de taart (bonus van dit artikel). Laten we begrijpen waar deze bz2file-module over gaat. Laten we beginnen!
Wat is bz2bestand
bz2file is een van de modules in Python die verantwoordelijk zijn voor de compressie en decompressie van bestanden, en kan daarom helpen bij het verkleinen van het geserialiseerde of gedeserialiseerde bestand naar een kleiner formaat, wat op de lange termijn zeer nuttig zal zijn als we grote datasets hebben
Hoe bz2file hier nuttig is?
Omdat we weten dat onze dataset 2.7+ MB is en ons Random forest-model maar liefst 700+ MB bedraagt, moeten we dat comprimeren zodat dat model niet leidend zal zijn als een hectische situatie voor opslag.
Hoe bz2file installeren?
- Jupyter-notitieboekje: !pip installeer bz2bestand
- Anaconda-prompt/CMD: pip installeer bz2bestand
Daarom heb ik bz2file geรฏnstalleerd, dat wordt gebruikt om gegevens te comprimeren. Dit is een levensreddend pakket voor degenen die weinig ruimte op hun schijf hebben, maar grote datasets willen opslaan of gebruiken. Nu was het ingelegde dossier voorbij 700 MB in grootte die bij gebruik bz2 comprimeerde tot een bestand van grootte 93 MB of minder.
importeer bz2 compressieniveau = 9 source_file = 'ForestModel.pickle' # dit bestand kan een ander formaat hebben, zoals .csv of andere... Destination_file = 'ForestModel.bz2' met open(source_file, 'rb') als gegevens: tarbz2contents = bz2.compress(data.read(), compressieniveau) fh = open(destination_file, "wb") fh.write(tarbz2inhoud) fh.close()
Deze code onderdrukt de grootte van het afgestemde augurkmodel.
Okรฉ, dus dat is een omslag van mijn kant!
eindnoten
Bedankt voor het lezen van mijn artikel ๐
Ik hoop dat jullie dit stap-voor-stap leren leuk zullen vinden bosbrandvoorspelling met behulp van machine learning. Een laatste ding dat ik wil vermelden is dat ik me heel goed bewust ben van het feit dat de nauwkeurigheid van het model niet zo goed is, maar het doel van het artikel is redelijk evenwichtig, dus jullie kunnen verschillende Ml-algoritmen uitproberen om te zoeken naar een betere nauwkeurigheid .
Hier is de repo link bij dit artikel.
Hier heeft u toegang tot mijn andere artikelen die zijn gepubliceerd op Analytics Vidhya als onderdeel van de Blogathon (link)
Als u vragen heeft, kunt u contact met mij opnemen op LinkedIn, raadpleeg dit link
Over mij
Groeten aan iedereen, ik ben momenteel aan het werk in TCS en voorheen werkte ik als Data Science Associate Analyst in Zorba Consulting India. Naast mijn fulltime werk heb ik een enorme interesse in hetzelfde vakgebied, dat wil zeggen Data Science samen met de andere subsets van kunstmatige intelligentie, zoals Computer Vision, Machine Learning en Deep Learning. Voel je vrij om met mij samen te werken aan elk project op de bovengenoemde domeinen (LinkedIn).
Afbeeldingsbron-
- Afbeelding 1 โ https://www.theleader.info/wp-content/uploads/2017/08/forest-fire.jpg
Bron: https://www.analyticsvidhya.com/blog/2021/10/forest-fire-prediction-using-machine-learning/
- "
- 100
- 116
- 39
- 420
- 7
- 9
- toegang
- algoritmen
- Alles
- analytics
- GEBIED
- dit artikel
- artikelen
- kunstmatige intelligentie
- auto
- BEST
- controleren
- Schoonmaak
- code
- Kolom
- Computer visie
- vertrouwen
- consulting
- Wij creรซren
- gegevens
- data science
- dag
- omgang
- beslissingsboom
- diepgaand leren
- Ontwikkeling
- domeinen
- Val
- etc
- exploratie
- Voordelen
- Brand
- Voornaam*
- geschikt
- formaat
- Gratis
- goed
- groot
- hoofd
- hier
- HTTPS
- Indiรซ
- informatie
- Intelligentie
- belang
- problemen
- IT
- labels
- Groot
- breedte
- leidend
- leren
- lang
- machine learning
- Media
- Metriek
- ML
- ML-algoritmen
- model
- Overige
- Overig
- planten
- voorspelling
- project
- Python
- reeks
- lezing
- lopen
- satelliet
- aftasten
- Wetenschap
- Ontdek
- het instellen van
- Eenvoudig
- Maat
- Klein
- So
- spleet
- begin
- mediaopslag
- shop
- doelwit
- Terra
- Testen
- niet de tijd of
- spoor
- Trainingen
- waarde
- visie
- WIE
- Mijn werk
- X
- jaar