{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "*Created by Petteri Nevavuori <>*\n", "\n", "---\n", "\n", "**CHIO & FREEMAN: MACHINE LEARNING & SECURITY (2018)**
\n", "*Otsikot kirjan mukaan, muutoin suomeksi.*" ] }, { "cell_type": "markdown", "metadata": { "toc": true }, "source": [ "

Sisällysluettelo

\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Malware Analysis\n", "\n", "Haittaohjelmien (*malware*) analyysillä tarkoitetaan niiden toiminnallisuuksien, tarkoituksen, lähteen ja vaikutusten tutkimusta. Perinteisesti se on vahvasti ihmiskeskeinen prosessi, jossa keskiössä on asiantuntemus ja kokemus. Datapohjaisilla menetelmillä ollaan saavutettu joitain lupaavia tuloksia, mutta haittaohjelmien vaikutusten juurisyiden eli tärkeiden ja informatiivisten piirteiden määrittäminen ja etsintä on ongelmana monimutkainen ja haastava. Tässä kappaleessa ei siksi keskitytä niinkään koneoppimismenetelmiin, vaan piirteiden suunnitteluun (*feature engineering*) haittaohjelmien kontekstissa data-analyysin ja koneoppimisen näkökulmasta.\n", "\n", "Luku on kahtiajaettu. Ensimmäisessä osiossa keskitytään haittaohjelmien ymmärtämiseen, niiden luokitteluunn haittaohjelmien ekonomiaan, ohjelmien suoritusmekanismeihin ja tyypilliseen käyttöön. Toisessa osassa keskitytään näihin pohjaten merkityksellisten piirteiden tuottamiseen bittitason datasta." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Understanding Malware\n", "\n", "Haittaohjelmat ovat täysverisesti ohjelmoituja sovelluksia - niiden kielien, suunnittelu- ja toteutustapojen kirjo on hyvin laaja riippuen kulloinkin ajatellusta kohteesta. Erona \"normaaleihin\" ohjelmistoihin on, että haittaohjelmat on suunniteltu toimiviksi ihmisen huomaamatta ja usein matalan tason binäärikooditasolla lähellä järjestelmän ydinprosesseja. Siitä syystä haittaohjelmien ymmärtämisessä on jossain määrin kyse takaisinmallinnuksesta (*reverse engineering*), jossa käännettyä matalan tason binäärikoodia pyritään tulkitsemaan ihmisen ymmärrettäväksi tulkkaamattomaksi korkeamman tason lähdekoodiksi. Tämä ei ole mahdollista, ellei tietoa ohjelman kääntämisessä käytetyistä tekijöistä ole saatavilla.\n", "\n", "Piirteiden suunnittelulla tarkoitetaan tässä kirjassa koko datan keruun ja käsittelyn prosessia, minkä lopputuote on algoritmille syötettävissä. Piirteiden louhinnalla (*feature extraction*) taas tarkoitetaan raakadatan jalostamista mielekkäiksi piirteiksi. Tämä tarkoittaa usein esimerkiksi dataa kuvaavien tilastollisten, raja-arvoihin sijoittumista ilmaisevien tai kategoristen arvojen olemassaolosta kertovien raakadataa rikastavien lisäpiirteiden muodostamista. \n", "\n", "Haittaohjelmien tapauksessa onnistunut piirteiden louhinta edellyttää syvää tietoa ohjelmistojen rakenteista ja siitä, mitä ohjelman toiminta kertoo sen rakenteesta, ominaisuuksista ja mahdollisista puutteista. Tästä on kyse takaisinmallinnuksessa, joka vaatii jatkuvaa harjaantumista ja kokemusta. Haittaohjelmat voidaan liittää osaksi moniin erilaisiin binäärimuotoihin (*.dll, .exe, .apk, ...*), joista jokainen eroaa toisistaan. Haittaohjelmat voivat olla myös piilotettuina muihin kuin binääritiedostoihin (*.pdf, .doc, ...*) makrojen ja dynaamisesti suoritettavien elementtien muodossa. Ne voivat tulla laajennosten (*plugin*) mukana. Jokaista tällaista formaattia ei käydä syvästi läpi, mutta merkityksellisimmät erot käydään jossain määrin seuraavaksi lävitse." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Defining Malware Classification\n", "\n", "Haittaohjelmat luokitellaan samankaltaisiksi niiden yhteisten piirteiden perusteella. Tällaisia piirteitä ovat esimerkiksi uhkataso, toimintatapa, vahinkopotentiaali tai muu vastaava. Alan perustapa on ryhmitellä haittaohjelmat perheisiin, mikä edesauttaa mm. uusien haittaohjelmien yhdistämistä aiempiin vastaavan kaltaisiin. Eräs tällainen perhe on Windowsiin kohdennettu Conficker-perhe, joka variaatioistaan huolimatta noudattaa tiettyä sille perheelle ominaista toimintatapaa. Perheen sisäiset erot voivat olla seurausta vaihtelevista kääntötavoista (*compilation*) ja muokatusta lähdekoodista. Joka tapauksessa kyse on erittäin vaativasta ja osin vaihtelevia tuloksiakin tuottavasta luokittelutavasta.\n", "\n", "Luokittelu voidaan ulottaa myös tavanomaisten ohjelmien piiriin, jolloin tavoitteena on pyrkiä erottamaan haittaohjelmat haitattomista. Tämä on antivirus-ohjelmien toiminnan ydintavoite, ja kyseessä on ohjattu tunnistus jo tunnettujen piirteiden pohjalta (*signature matching*). Menetelmä toimii niin pitkään, kuin ohjelmien toiminta ei perusteissaan juuri muutu. Vastavuoroisesti juuri tästä syystä uudet haittaohjelmat pyritään suunnittelemaan toimimaan tunnetusta poikkeavasti mm. binääriin vaikuttavan poly- ja metamorfian keinoin.\n", "\n", "Tässä koneoppimisella on yliote suhteessa staattisten haittaohjelmille tavanomaisten piirteiden havaitsemiseen keskittyviin menetelmiin. Ainakin seuraavat keinot ovat tässä hyödyksi:\n", "\n", " - **Sekava sovitus** (*fuzzy matching*): Koneoppimismenetelmät kykenevät tuottamaan raakojen kyllä-ei-tulosten sijasta luottamustasoja luokittelun tuloksesta. Likimääräinen luokittelu auttaa toisistaan poikkeavien mutta kuitenkin jossain määrin samankaltaisten havaintojen löytämisessä.\n", " - **Automatisoitu piirrevalinta**: Datapohjaiset menetelmät ytimessään pyrkivät erottelemaan ja painottamaan datan piirteet siten, että niitä käyttämällä tavoitetaan oikeita luokittelutuloksia. Näin menetelmät oppivat tyypillisesti sellaisia assosiaatioita, joihin ihmisymmärryksellä olisi haastavaa päästä käsiksi.\n", " - **Mukautuvuus**: Sekä hyökkäykset että niitä vastaan nostetut suojaukset kehittyvät alinomaa ja siksi myös tunnistusmenetelmien on myös kyettävä samaan. Koneoppimismenetelmiä on helppo rakentaa mukautuviksi siten, että ne painottavat viimeaikaisia havaintoja historiadataa enemmän.\n", " \n", "Vaikka haittaohjelmien jaottelu perhetasolla ei suoranaisesti auta yksittäisen haittaohjelman tunnistustehtävässä järjestelmää valvottaessa, se edesauttaa puolustavien asiantuntijoiden työtä tarjoamalla tietoa ohjelman mahdollisista lähtökohdista ja kontekstista. Ylipäätään koneoppimismenetelmien suuri vahvuus, suurten datamassojen pelkistäminen merkityksellisiin piirteisiin ja todennäköisyysjakaumiin, auttaa asiantuntijoita tekemään varmempia johtopäätöksiä jo valmiiksi vaativassa työssä." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Malware: Behind the Scenes\n", "\n", "Kuten kirjan alussa jo mainittiin, haittaohjelmien markkinat ovat vilkkaat sekä tarjonnan että kysynnän puolesta. Haittaohjelmia on saatavilla hyvinkin pienellä rahallisella panostuksella ja kehittyneet kauppapaikat takaavat ostojen ja ohjelmien toimituksen onnistumisen. Toisaalta, ohjelmilla saatavat tiedot, kuten käyttäjätiedot, ovat haluttua ja arvokasta edelleenmyytävää omaisuutta. Kehittäjät ovat usein joko itselleen tai jollekin organisaatiolle työskenteleviä kokeneita ammattilaisia, mutta jakelu hoidetaan välikäsien kautta. Keskinäisen kilpailun tai eriävien intressien vuoksi myös haittaohjelmien varastetaan ja muokataan omia tarpeita palvelevaksi, minkä vuoksi ohjelmat kehittyvät jopa alkuperäisestä kehittäjästä riippumatta.\n", "\n", "Haittaohjelmien hyväksikäyttöön ja luvattomaan toimintaan perustuva rahantuottologiikka ei ole sinänsä erikoinen verrattuna muuhun rikolliseen toimintaan, mutta pesäeron tekee lainvoimaisen valvonnan tehokas toteuttaminen. Digitaalisessa maailmassa tapahtuva toiminta, jota pyritään aktiivisesti salaamaan ja hämärtämään, jättää todelliset toimijat usein kiistattomien todisteiden ulkopuolelle eikä syyttävää sormea voida varmuudella osoittaa ketään yksilöä kohtaan.\n", "\n", "*Tässä vaiheessa kirjassa käydään hyvin konkreettinen ohjelmointiesimerkki haittaohjelmasta. Sen toisintaminen koettiin hyödyttömäksi ja siksi siitä kiinnostuneet voivat lukea sen kirjasta sivuilta 133-143.*\n", "\n", "Tutkiakseen ja luokitellakseen haittaohjelmia on tuntemus niiden toiminnasta ja toimittamisesta tarpeellista. Tyypillinen hyökkäys etenee pääpiirteittäin seuraavin askelin:\n", "\n", " 1. Tiedustelu (*reconnaissance*)\n", " 2. Soluttautuminen (*infiltration*)\n", " 3. Liike (*maneuver*)\n", " 4. Poteroituminen (*entrench*)\n", " 5. Tiedon välitys (*exfiltration*)\n", " 6. Jälkien siivous (*purge*).\n", " \n", "Ensimmäisessä vaiheessa (1-2) kohdejärjestelmää tiedustellaan epäsuorasti, minkä jälkeen järjestelmästä pyritään löytämään sopiva rako jalansijan saavuttamiseksi ja muuntamaan kohde uhriksi. Toisessa vaiheessa (3-4) pyritään tutkimaan uhrijärjestelmä sen sisältä käsin ja liikkumaan horisontaalisesti tärkeimpiin järjestelmään kytkettyihin alijärjestelmiin (pöytäkone, palvelin, tms.). Näiden löydyttyä saavutettu asema pyritään lujittamaan varmistamalla pääsy myös tulevaisuudessa. Viimeisessä vaiheessa (5-6) tapahtuu varsinainen vahinko, kun esimerkiksi arkaluontoiset tiedot kerätään, lähetetään hyökkääjälle ja murron jäljet pyritään peittämään mahdollisimman hyvin. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Feature Generation\n", "\n", "Dataa mallintaessa suurin osa ajasta kuluu datan käsittelyyn ja muokkaamiseen tavoitteita vastaavaan muotoon ja formaattiin. Itse mallien rakentamiseen kuluva aika on useimmiten tähän verrattuna huomattavasti pienemmässä osassa. Tämän luvun loppuosa käsitteleekin siksi piirteiden mallinnusta haittaohjelmien kontekstissa. Ensin aloitetaan kyseisen datan keruun haasteista, minkä jälkeen edetään haittaohjelmien luokittelussa hyödynnettävän datan keruuseen.\n", "\n", "Haittaohjelmien tapauksessa binääridata on kaikille toisistaan merkittävästikin poikkeaville ohjelmille yhteinen nimittäjä. Siksi haittaohjelmien tunnistuksessa keskitytään tässä kohdin binääridatasta muodostettavien piirteiden rakentamiseen ja käsittelyyn. Datan keruu on ylipäätään kaikkein merkittävin tekijä data-analyysissä ja datapohjaisessa mallinnuksessa. Suurimmat loikat suorituskyvyssä tulevat rikkaammasta ja kuvaavammasta datasta. Mikäli jokin malli ei suoriudu hyvin, on ensin varmistuttava datan riittävästä laadusta. Datan keruu vie aikaa ja vaatii vaivaa, eikä apukäsiä ole aina tarjolla. Siksi raakadatan käsittelykyky on olennainen osa datatietelijän työkalulaatikkoa." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Data Collection\n", "\n", "Domain-tuntemuksella tarkoitetaan datan kontekstiin liittyvää ymmärrystä - haittaohjelmien tapauksessa tämä on tietoturva-asiantuntijuutta, teknistä ymmärrystä matalalla tasolla ja eri toimintatapojen hallintaa ohjelmointityössä. Syvä kokemukseen pohjaava asiantuntijatietämys on erityisen tärkeää datan keruun alkuvaiheissa. Sitä hyödyntämällä saadaan tehokkaasti siivilöityä tarpeeton ja mallinnettavan ongelman näkökulmasta kohinaksikin luokiteltava pois ja voidaan keskittyä mallinnettavaan ilmiöön olennaisesti vaikuttaviin tekijöihin. Ilman asiantuntijan domain-tuntemusta tämä prosessi muodostuu yrityksen ja erehdyksen kautta eteneväksi siten, että riski merkityksekkään tiedon poisjäämiseen on huomattava.\n", "\n", "Koneoppimisalgoritmit vaativat dataa. Mitä enemmän sitä on, sitä paremmin sitä voidaan mallintaa. Riippumatta käsittelytarpeesta on datan keruu ja käsittely saatava automatisoitua mahdollisimman pitkälle siten, että datan keruu on skaalattavissa. Pelkkä datan keruu ei kuitenkaan vielä riitä, vaan kerätyn datan rajoitukset on myös pyrittävä tunnistamaan. Datan validoinnilla ja sen vääristymien tunnistamisella on merkittävä rooli sitä käyttävien mallien rajoitteiden ymmärtämisessä. Datan validointi nojaa puolestaan vahvasti domain-tuntemukseen siinä, että mallinnettavasta asiasta on olemassa aina edes joitain reunaehtoja, joita hyvälle datalle on asetettavissa. Haittaohjelmien tapauksessa esimerkiksi datajoukot tuppaavat ummehtumaan, sillä ohjelmat kehittyvät nopeasti ja täten havaintojenkin parasta-ennen-päiväykset ovat verraten lähellä keruuhetkeä.\n", "\n", "Koneoppimismallinnukseen liittyy olennaisesti iteratiivisuus. Tämä ei kuitenkaan koske vain mallinnusta, vaan se on myös ydintä datan keruussa. Kuten mallinnustakin, myös datan keruuta on tarkasteltava kriittisesti ja suostuttava myös keruuprosessin muokkaamiseen ja toistamiseen." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Generating Features\n", "\n", "Tässä aliluvussa piirteiden louhintaa lähestytään jälleen konkreettisella Android-binääriin keskittyvällä esimerkillä. Riippumatta siitä, minkälaista koneoppimistehtävää varten piirteitä muodostetaan, on mallinnuksen lopullinen päämäärä pidettävä aina kirkkaana mielessä piirteitäkin muodostettaessa. Esimerkiksi haittaohjelmia voitaisiin pyrkiä luokittelemaan esimerkiksi niiden perheiden, toiminnan tai haitallisuuden perusteella ja kullekin näistä tavoitteista on muodostettava omat, ongelman ratkaisua parhaiten helpottavat datasta louhittavat piirteensä. Kirjassa ei kuitenkaan keskitytä tässä kohdin mihinkään tiettyyn ongelmaan, vaan piirteiden louhintaa lähestytetään yleisemmältä tasolta.\n", "\n", "Käymällä läpi kohdejärjestelmän sovellusten rakennetta ja toimintalogiikkaa on mahdollista päästä selville tavoista, joilla Android-binäärejä voidaan takaisinmallintaa luokittelua helpottavien piirteiden louhimiseksi muutoin sekavasta binääridatasta. Yleisellä tasolla piirteiden muodostamisessa on tapana noudattaa huolellisuutta vaihtoehtoisten datan esitystapojen tarkastelussa. Matalapiirteisten ja vain muutamia arvoja sisältävien näytteiden kanssa on luonnollista käyttää dataa sellaisenaan, mutta näin ei ole esimerkiksi huomattavasti sisältörikkaampien ja monimutkaisempien ohjelmakoodien kanssa.\n", "\n", "Binääreistä piirteitä louhittauessa nojataan seuraaviin metodeihin:\n", "\n", " - Staattiset menetelmät, kuten rakenneanalyysi ja staattinen analyysi\n", " - Dynaamiset menetelmät, kuten käyttäytymisanalyysi, debuggaus ja dynaaminen instrumentointi\n", " \n", "Rakenneanalyysissä lähdetään liikkeelle siitä, että haitalliseksi havaitusta ohjelmasta käydään läpi siihen liittyvät tiedostot (mikäli niitä siis on). Vaikka tiedostoja olisi jossain määrin mahdollista tarkastella sellaisenaan, on usein otettava etenkin binääritiedostojen kohdalla käyttöön takaisinmallinnustyökaluja. Android-binäärin takaisinmallinnukseen löytyy *Apktool*-niminen työkalu, joka purkaa binääritiedostot ihmisluettavaan lähdekoodimaiseen muotoon. Tämän dekoodauksen jälkeen ohjelmakoodia on jo huomattavasti mielekkäämpää lähteä tarkastelemaan läpi. Esimerkiksi ohjelman käyttäjältä ja järjestelmältä pyytämät luvat ovat yksi indikaattori mahdollisesti haitallisesta ohjelmasta - yksinkertaisten sovellusten ei tulisi pyytää ydintoimintojensa vaatimukset ylittäviä oikeuksia. Toisin sanoen rakenneanalyysissä keskitytään siihen, mitä kaikkea paketoitu ohjelma pitää ylipäätään sisällään suhteessa sen suorittavaan järjestelmään yms. Rakenneanalyysissä koostettavia piirteitä voivat esimerkiksi olla ohjelman käyttöoikeuspyyntöjen määrä ja mahdollisten sertifikaattien tiedot.\n", "\n", "Staattisessa analyysissä pureudutaankin tarkemmin jo koodiin, joskin sitä vielä ajamatta. Mikäli lähdekoodi on saatavilla, on kyseessä suoraviivaisesti ohjelman toiminnan ymmärtäminen koodia tulkitsemalla. Tällöin päästään käsiksi esimerkiksi eri ohjelmointirajapintoihin (*application programmin interface, API*), joihin ohjelma muodostaa kutsuja. Näistä voidaan muodostaa esimerkiksi korkean riskin API-kutsujen lukumäärä yhdeksi esimerkkipiirteeksi. Myös ohjelman toimintaa voidaan tarkastella staattisesti esimerkiksi tutkimalla käännetyn ohjelman suorittamia järjestelmäkutsuja (*system calls, syscalls*) ja niiden muodostamia sekvenssejä. Näitä sekvenssejä voidaan käyttää myös piirteinä. Tyypillisesti esimerkiksi Android-pohjaisissa haittaohjelmissa on ainakin joitain seuraavista elementeistä, joita voidaan käytään binäärisinä piirteinä:\n", "\n", " - Haitallisen koodin piilotus hämäystekniikoilla (*obfuscation*).\n", " - Osoitteiden ja järjestelmätiedostojen kovakoodaus.\n", " - Suoritusympäristön tarkkailu emuloinnin varalta.\n", " - Oletetun käytön ylittävät käyttöoikeuspyynnöt.\n", " - PC-arkkitehtuuriin soveltumattomien kirjastojen käyttö.\n", " - Muokkaa, poistaa tai lisää tiedostoja odottamattomiin paikkoihin.\n", "\n", "Dynaaminen käyttäytymisanalyysi jatkaa siitä, mihin staattinen koodin ja toiminnan tarkastelu rajoittuu. Käytännössä ohjelman suorittaminen antaa suoraviivaisesti hyvin paljon tietoa ohjelmasta, sen käyttäytymisestä, toiminnasta ja tavotiteista. Tällöin tarkkailun kohteena ovat etenkin mielenkiintoiset ohjelman ajamisesta seuraavat sivuvaikutukset, joita voidaan tarkkailla riittävällä instrumentoinnilla ajamalla ohjelmaa eristetyssä ympäristössä. Yksi selkeimmistä sivuvaikutuksista on verkkoliikenne, sillä monet haittaohjelmat saavat toiminnalleen kriittisiä tietoja verkon ylitse. Kuten staattisessakin analyysissä, myös dynaamisessa analyysissä on hyvä tarkkailla haittaohjelman tekemiä järjestelmäkutsuja ja niiden sekvenssejä. Eräs paljon käytetty menetelmä riittävän kattavaan haittaohjelman analysointiin on ohjelmiston sumeutus (*software fuzzing*), jossa ohjelmalle syötetään satunnaisesti vaihtelevia ja odottamattomiakin syötteitä. Debuggaustyökalujen käyttö ohjelman ajamisessa voi myös auttaa sen toiminnan ymmärtämisessä ja merkittävien piirteiden muodostamisessa." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Feature Selection\n", "\n", "Monesti liian suuri määrä piirteitä ennemmin rampauttaa koneoppimismenetelmän kuin edesauttaa sen tarkkaa sovittumista dataan halutun ilmiön mallintamiseksi. Tässä kohdin ollaan tekemisissä piirteiden valinnan kanssa. Piirteitä voidaan aktiivisesti valita esimerkiksi perustuen asiantuntijuuteen tai tilastollisiin menetelmiin. Koneoppimispuolelta löytyy myös menetelmiä merkityksellisimpien piirteiden valintaan. Jotkut menetelmät tekevät piirteiden valinnan jossain määrin jopa automaattisesti, kuten vaikkapa syväoppivat menetelmät. Joka tapauksessa piirteitä louhiessa piirteiden valintaakin tapahtuu jo jossain määrin." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Supervised Feature Selection\n", "\n", "Tilastollisiin menetelmiin pohjaavat piirrevalintamenetelmät jaetaan kirjassa seuraavasti:\n", "\n", " - **Muuttuja-analyysi** (*univariate analysis*): Jokaista piirrettä tarkastellaan yksinään erillään muista tavoitteena selvittää, kuinka hyvin malli suoriutuu käyttämällä vain sitä. Näin saadaan yksittäin tarkasteluna raakattua esimerkiksi joukko parhaiten suoriutuvia piirteitä jatkoon.\n", " - **Rekursiivinen piirteiden poisto** (*recursive feature elimination, RFE*): Muuttuja-analyysille täysin päinvastaisesti RFE poistaa yksitellen piirteitä ja tarkastelee poistojen vaikutusta suorituskykyyn. Näin saadaan piirteistä karsittua parhaiten yhdessä suoriutuva joukko.\n", " - **Mallikohtainen piirrejärjestys**: Esimerkiksi lineaariregressio- ja puumallit tuottavat sivutuotteenaan piirteiden merkitysten paremmuusjärjestyksen, jota voidaa hyödyntää piirreavaruuden kaventamisessa." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Unsupervised Feature Learning and Deep Learning\n", "\n", "Syväoppivissa menetelmissä on olemassa merkityksellisimpien piirteiden oppimiseen keskittyvä autoenkooderien luokka. Menetelmä perustuu siihen, että oppii piirreavaruutta pienemmän koodausavaimen, joka hävittää mahdollisimman vähän alkuperäisestä informaation rikkaudesta - käytännössä kyse on piirreavaruuden kavennusmenetelmästä. Jos autoenkooderi tosin on syvä, alkuperäisten piirteiden vaikuttavuutta on haastava tavoittaa. Vaikka kirjassa tätä ei erikseen mainita, myös perinteiset myötäkytketyt verkotkin oppivat sivutuotteenaan painottamaan tiettyjä piirteitä muita enemmän ja tarvittaessa jättämään osan jopa kokonaan huomiotta osana optimointiprosessiaan." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### From Features to Classification\n", "\n", "Raakadatan muunnos kuvaavia piirteitä sisältäväksi datajoukoksi on prosessi, jonka automatisointi vaatii aina oman aikansa ja vaivansa - etenkin online-ratkaisuissa, joissa syötedata on saatava kulkemaan halutun mallin läpi ainakin lähes reaaliaikaisena staattisen datajoukon sijasta. Prosessin luonne konkreettisen ohjelmoinnin näkökulmasta on kuitenkin erittäin riippuvainen raakadatasta, haluttujen piirteiden muodostamiseen vaadittavista lisätyökaluista, mahdollisesta mallin ajoympäristöstä ja mallin implementaation viitekehyksen (*framework*) asettamista vaatimuksista. " ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.0" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": false, "sideBar": true, "skip_h1_title": false, "title_cell": "Sisällysluettelo", "title_sidebar": "Sisällysluettelo", "toc_cell": true, "toc_position": { "height": "1158px", "left": "278px", "top": "111.133px", "width": "338px" }, "toc_section_display": true, "toc_window_display": true } }, "nbformat": 4, "nbformat_minor": 2 }