HUOM! Varsinkin ensimmäiset tehtävät on helppo ratkaista generatiivisen tekoälyn avulla. Koeta kuitenkin itse hahmotella ratkaisua ennen kuin turvaudut tekoälyyn. Myös tekoälyn avulla koodia tekevältä ohjelmoijalta vaaditaan koodin ymmärtämistä ja kykyä omaan ajatteluun.
Toteuta funktio collectFeed() joka kokoaa näppäimistöltä syöttämiäsi merkkejä merkkijonoon niin kauan kunnes syötät lopetusmerkin joka on #. Lopuksi merkkijono palautetaan, mutta ilman lopetusmerkkiä. Huomaa että merkkijonokin on tietorakenne, vähän kuin merkkejä sisältävä taulukko. Merkkijonolla (String) on JS-Api:ssa metodeja joista jotkin ovat samanlaisia mutta jotkin erilaisia kuin tavallisen taulukon metodit. Näppäimistösyötteen lukemiseen voit käyttää readline-sync -moduulia. Algoritmi on pääpiirteittäin seuraavanlainen:
Huomaa että koodia ei voi suorittaa VSCoden Code Runnerilla koska siinä käytetään näppäimistösyötettä, joten suorita se komennolla: node tiedostonnimi. Lopputuloksen pitäisi näyttää tältä. Tee funktio tähän projektiin jossa olevan testin tulee mennä läpi.
Tee edellisestä funktiosta toinen versio, collectFeedRec(str=''), jossa käytät rekursiota. Huomaa että parametri str='' on ns. oletusparametri. Eli jos jotain muuta argumenttia ei ole funktion kutsussa annettu, sisään menee tyhjä merkkijono. Algoritmi on pääpiirteittäin seuraavanlainen:
Lopputulos on sama kuin edellisessä tehtävässä. Tee funktio tähän projektiin jossa olevan testin
tulee mennä läpi.
Toteuta algoritmi jolla etsit taulukossa useimmin esiintyvän alkion. Voit olettaa että alkiot ovat numeroita. Tee algoritmi funktioon findMostFreqBrute(arr). Käytä brute force -menetelmää eli vertaa kaikkien alkioiden arvoja toisiinsa:
Yritä ensin tehdä algoritmi yllä olevan ohjeen avulla ja jos ei onnistu, niin katso mallia tästä. Algoritmin suorittaminen VSCoden Nodejs-debuggerilla helpottaa sen tekemistä ja ymmärtämistä huomattavasti.
Tee algoritmin testausta varten funktio createNumArr(n) joka palauttaa taulukon jossa on n kappaletta satunnaisesti arvottuja lukuja 1-9. Testaa algoritmia taulukoilla joissa on 100 ja 100000 alkiota. Miten suoritusnopeus muuttuu? Näet suoritusnopeuden konsolista kun ajat koodin VSCoden Code Runnerilla. Minkä arvelisit olevan algoritmin aikavaativuuden ja miksi?
Lopputulos voisi näyttää tältä. Tee funktiot tähän projektiin jossa olevien testien tulee mennä läpi.
Toteuta saman tuloksen tuottava algoritmi kuin edellisessä tehtävässä funktioon findMostFreq(arr), mutta nyt dynaamisella menetelmällä käyttäen apuna Map -tietorakennetta:
Testaa algoritmia taulukoilla joissa on 100 ja 100000 alkiota. Miten suoritusnopeus muuttuu? Minkä arvelisit olevan algoritmin aikavaativuuden ja miksi?
Voit käyttää samaa projektipohjaa kuin edellisessä tehtävässä. Jos ajat samat testit, muuta testeihin funktion nimi: findMostFreqBrute -> findMostFreq.
Toteuta algoritmi jolla etsit pisimmän yhteisen alimerkkijonon kahdesta merkkijonosta. Tee se funktioon findLcsBrute(s1, s2). Esim. sanojen "kameli" ja "karamelli" pisin yhteinen alamerkkijono on "amel". Tee algoritmi ensin brute force -tekniikalla:
Tee algoritmin testausta varten funktio genString(charset, n),
joka palauttaa merkkijonon jossa on n kappaletta satunnaisesti
arvottuja merkkejä, jotka arvotaan charset -merkkijonosta. Voit
käyttää merkkejä 'ATGC', jolloin etsit yhteisiä DNA-pätkiä
kahdesta DNA-rihmasta.
Testaa algoritmia merkkijonoilla, joissa on 4, 100 ja 10000 merkkiä. Miten suoritusnopeus muuttuu? Minkä arvelisit olevan algoritmin aikavaativuuden ja miksi?
Lopputulos voisi näyttää tältä.
Tee funktiot tähän projektiin
jossa olevien testien tulee mennä läpi.
Muunna edellisen tehtävän ratkaisua siten, että muutat kohdassa
1. tekemäsi kaksi alimerkkijonotaulukkoa ensin seteiksi ja sitten
teet seteille leikkauksen (intersection), josta etsit pisimmän
alimerkkijonon. Settien leikkaus on
eri tyyppinen, ja nopeampi operaatio, kuin tehtävän 5 kohdassa 2
tehty alimerkkijonotaulukoiden vertailu ja yhteisten alkioiden
poiminta uuteen taulukkoon.
Testaa algoritmia taulukoilla joissa on 4, 100 ja 10000 alkiota. Miten suoritusnopeus muuttuu?
Kehitetään pisimmän yhteisen alimerkkijonon etsivää algoritmia edelleen. Tehdään uusi algoritmi funktioon findLcs(s1, s2). Hyödynnetään nyt dynaamista algoritmin suunnittelua. Käytetään kaksiulotteista taulukkoa eli matriisia säilyttämään merkkijonojen vertailun tulokset ja katsotaan pisin yhteinen alimerkkijono matriisista:
Kokeile algoritmia samalla tavalla kuin edellisessä tehtävässä.
Miten suoritusnopeus muuttuu?. Minkä arvelisit olevan tämän
algoritmin aikavaativuuden ja miksi? Mitä sanoisit tämän
algoritmin muistivaativuudesta verrattuna tehtävien 5 ja 6
ratkaisuihin?
Voit testata tätä algoritmia edelleen tehtävän 5 testeillä jos
muokkaat testejä siten, että poistat getAllSubstrs -funktion
testit ja muutat pääfunktion nimeksi findLcs. Periaatteessa voisi
olla järkevää tehdä algoritmin osista omat funktionsa (esim.
createMatrix, compare ja calculateLcs),
joita kutsuttaisiin pääfunktiossa. Tämä helpottaisi testausta.
Tosin, jos funktiot eivät ole yleiskäyttöisiä, vaan vahvasti
sidottuja toisiinsa, on hyöty hieman kyseenalainen.
Bongobongon kansantasavallan väestö on kasvanut vuosina 1960-2010 seuraavasti:
1960: 2 miljoonaa
1970: 4 miljoonaa
1980: 6 miljoonaa
1990: 10 miljoonaa
2000: 18 miljoonaa
2010: 33 miljoonaa
Etsi npmjs.com:sta valmis regressioalgoritmi jolla voit arvioida mikä on väkiluku vuonna 2025, 2050 ja 2100 jos väestönkehitys jatkuu samanlaisena. Tee funktio joka ottaa kutsuttaessa argumentteina regressiotyypin ja vuosiluvun, ja palauttaa väkiluvun. Regression tyyppi on yksi tällä sivulla kohdassa 'Regression' esitellyistä regressiotyypeistä. Valitse oikea regressiotyyppi kokeilemalla ja/tai päättelemällä ja etsi tyyppiä vastaava algoritmi jolla ratkaiset tehtävän.
Toteuta kolmen muuttujan logistinen regressio. Henkilöistä on saatavilla seuraavanlaista harjoitusdataa: ikä, sukupuoli, vuositulot, onko ostanut hilavitkuttimen vai ei. Harjoitusdata voisi näyttää tältä, mutta voit itse keksiä sitä lisää. Henkilön ominaisuuksien perusteella ennustat ostokäyttäytymistä eli todennäköisyyttä sille ostaako hän hilavitkuttimen vai ei. Huomaa että dataa on hyvin vähän ja korrelaatio on heikkoa, joten mallin tuottamat tulokset ovat vain suuntaa-antavia.
Käytä ratkaisun pohjana yhden muuttujan logistisen regression esimerkkiä. Ratkaisu onnistuu tekemällä esimerkkiin pieniä muutoksia. Tämän laskurin avulla voit havainnollistaa myös usean muuttujan logistista regressiota.
Kokeile roskapostin havaitsemista Bayesin naiivin klassifikaation avulla. Käytä valmista algoritmia: bayes-classifier, jota harjoitat normaalilla postilla ja roskapostilla. Tutki algoritmin lähdekoodista ja web-lähteistä kuinka algoritmi pääpiirteissään toimii ja kirjoita kommentiksi sen toiminnan kuvaus. Miksi algoritmi on naiivi?
Kokeile tehtävän 9 ratkaisemista päättelypuun eli decision treen avulla: decision-tree. Kommentoi millä tavalla tämä algoritmi eroaa logistisesta regressiosta. Voit piirtää päättelypuun rakenteen pääpiirteissään ASCII-merkeillä, jolloin piirroksesta selviää sen toimintaperiaate. Huomaa että näin pienestä ja "ristiriitaisesta" data-aineistosta päättelypuu ennustaa vielä huonommin kuin logistinen regressio, joten ei kannata huolestua huonoista tuloksista.
Lopuksi täytä kurssipalaute Peppi-järjestelmässä. Kurssilta ei voi saada arvosanaa, ennen kuin kurssipalaute on annettu.