Tekoälyllä voi myös rakenteellistaa dataa
Innostus generatiivisten kielimallien kanssa leikkimiseen valtasi maailman reilu vuosi sitten, kun ChatGPT julkaistiin. Sanon leikkimiseen, koska suuri osa käytöstä on ollut huumorilla höystettyä kokeilua.
Fonzit Oy on laajentanut liiketoimintaansa loma-asuntobisnekseen ja rakennuttanut kokonaisen vuokramökkikylän Etelä-Suomeen. Koska data ja tekoäly liiketoiminnassa on Fonzitin ydinosaamista, käytämme tietenkin mökkikylästä kertyvää mittausdataa hyödyksi.
Tämä työkirja havainnollistaa kuvitteellisen mökkikylän energiankulutuksen tarkkailua koneoppimisen avulla. Käytössä on viikkokohtaista dataa mökkien energiankulutuksesta, ulkolämpötilasta sekä varauksista. Datasta pyritään havaitsemaan laitevikoja ja muita häiriötilanteita.
Mahdollisia datasta löytyviä vikatilanteita:
Demo käyttää Python-datatieteilijän perustyökaluja NumPy, Matplotlib ja Scikit-learn. Tuodaan ne sisään.
import numpy as np
import numpy.typing as npt
import matplotlib.pyplot as plt
import matplotlib as mpl
from sklearn.cluster import DBSCAN
import pandas as pd
Mökkikylästä on kerätty vuosien varrella dataa noin sadan datapisteen verran. Yksi piste vastaa yhtä viikkoa ja mökkiä. Kaikki mökit ovat samanlaisia.
Datapisteen sisältämät tiedot ovat ulkolämpötila, mökin energiankulutus sekä asuttu/tyhjä-tieto. Data on siis kolmiulotteista, vaikka tässä työkirjassa piirrämme siitä vain kaksiulotteisia kuvia.
Luetaan data csv-tiedostosta.
data = np.loadtxt('mokkidata.csv', delimiter=',', skiprows=1)
def piirra_mokkidata(data: npt.NDArray) -> plt.Axes:
"""Piirtää kuvan mökkien energiankulutusdatasta. Input-datan
tulee sisältää sarakkeet ulkolämpötila, energiankulutus ja asuttu/tyhjä.
Palauttaa Axes-olion, jonka avulla kuvaa voi muokata.
Args:
data (npt.NDArray): Nx3-data.
Returns:
plt.Axes: Olio, joka sisältää kuvan.
"""
mpl.rcParams["lines.markersize"] = 12
mpl.rcParams["lines.marker"] = "."
mpl.rcParams["lines.linestyle"] = "None"
akseli = plt.axes()
asuttu_maski = data[:, 2] > 0
akseli.plot(data[asuttu_maski, 0], data[asuttu_maski, 1], label="Mökki asuttu")
akseli.plot(data[~asuttu_maski, 0], data[~asuttu_maski, 1], label="Mökki tyhjä")
akseli.set_title("Mökkien energiankulutus ulkolämpötilan suhteen")
akseli.legend()
akseli.set_xlabel("Ulkolämpötila")
akseli.set_ylabel("Energiankulutus viikossa")
return akseli
Alla olevassa kuvassa on piirretty energiankulutus ulkolämpötilan suhteen. Asutut ja tyhjät viikot on eroteltu väreillä. (Ne voisi erotella myös piirtämällä kolmiulotteisen kuvan, mutta se olisi luultavasti epäselvempi.)
Tyhjä mökki pidetään viileämpänä, siksi kuvassa näkyy selvästi tyhjän mökin matalampi kulutus. Lisäksi näkyy totta kai kylmän vuodenajan korkea lämmityskulu. Kesähelteillä asuttua mökkiä viilennetään, mikä aiheuttaa sinisen pistejoukon kääntymisen lievään kasvuun yli +20 asteen säillä. Asutun mökin energiankulutuksessa on enemmän vaihtelua kuin tyhjän, koska asukkaiden määrä ja kulutus vaihtelee.
_ = piirra_mokkidata(data)
def piirra_klusterointitulos(data: npt.NDArray, klusterointi: DBSCAN):
"""Piirtää kuvan mökkien energiankulutusdatasta ja lisää siihen
klusteroinnin havaitsemat poikkeamat.
Args:
data (npt.NDArray): Nx3-data (ks. piirra_mokkidata).
klusterointi (DBSCAN): sklearn.cluster.DBSCANin palauttama tulos.
"""
poikkeamien_indeksit = np.flatnonzero(klusterointi.labels_ == -1)
akseli = piirra_mokkidata(data)
juokseva_numero = 1
for i in poikkeamien_indeksit:
paikka = (data[i, 0], data[i, 1])
akseli.plot(
paikka[0],
paikka[1],
"ro",
markerfacecolor="None",
markersize=10,
label="Poikkeama",
)
akseli.annotate(
juokseva_numero, paikka, xytext=(10, -3), textcoords="offset points"
)
juokseva_numero += 1
kahvat, nimikkeet = akseli.get_legend_handles_labels()
_ = akseli.legend(kahvat[0:3], nimikkeet[0:3])
Klusterointi kuuluu ohjaamattoman koneoppimisen menetelmiin, ja se sopii mainiosti juuri poikkeamien (anomalioiden) etsimiseen, kun varsinaista opetusdataa ei ole.
Etsitään mökkidatasta poikkeamia DBSCAN-klusterointialgoritmilla. Se liittää yhteen datapisteitä, joiden lähellä on riittävästi muita pisteitä, kun taas yksinäiset pisteet jäävät poikkeamiksi.
Huomaa, että itse koneoppiminen on tässä kokonaisuudessa yksi ainoa koodirivi, koska algoritmi on valmiiksi koodattuna Scikit-learn-kirjastossa. Toki datatieteilijän on syytä tuntea algoritmin toiminta samoin kuin sen vaatimat parametrit.
klusterointi = DBSCAN(eps=8, min_samples=3).fit(data)
piirra_klusterointitulos(data, klusterointi)
Yllä olevassa kuvassa on sama data kuin edellisessäkin, nyt vain on poikkeamat löydetty. Kuvaan merkityt ja numeroidut poikkeamat voivat johtua seuraavista syistä:
Innostus generatiivisten kielimallien kanssa leikkimiseen valtasi maailman reilu vuosi sitten, kun ChatGPT julkaistiin. Sanon leikkimiseen, koska suuri osa käytöstä on ollut huumorilla höystettyä kokeilua.
Autonomiset koneet on Fonzitin käyttämässä jaottelussa yksi tekoälyn sovelluskohde. Autonomisia koneita ovat esim. autonomiset autot, teollisuusrobotit ja ihmisen kaltaiset robotit eli humanoidirobotit.
Hahmottelimme Fonzitille tekoälyprojektin mallin. Monissa lähteissä tekoälyprojekti esitetään syklisenä kehänä, jossa lopusta palataan takaisin alkuun. Esikuvana on luultavasti ollut 1990-luvun lopulla luotu tiedonlouhinnan