Luonnollinen kieli
Tietojenkäsittelytieteissä luonnollisella kielellä tarkoitetaan kieliä kuten suomi, englanti, ranska tai japani, joita ihmiset käyttävät päivittäisessä viestinnässään. Tämä on vastakohta keinotekoisille kielille, kuten ohjelmointikielille (esim. Python, Java) tai merkintäkielille (esim. HTML, XML). Merkittävä ero näiden välillä on, että koneelle tarkoitetut kielet ovat tehty insinöörinäkökulmasta siten, että formaalit säännöt ovat muodostettu ensin. Konekieli on käyttökelpoinen vasta kun säännöt ovat tarkoin määritelty. Ihmisten käyttämät kielet ovat syntyneet päinvastoin: käyttö ensin, säännöt myöhemmin. 1
"As a result, while machine-readable language is highly structured and rigorous, natural language is messy—ambiguous, chaotic, sprawling, and constantly in flux."
– François Chollet ja Matt Watson 1
Termi ambiguous tarkoittaa, että luonnollisessa kielessä samalle asialle voi olla useita merkityksiä tai tulkintoja. Suomalaisittain kuuluisa esimerkki tästä on lyhyt lause: "Kuusi palaa" (engl. the spruce is on fire / spruce returns / the number six is on fire / ... / six pieces). Entäpä kuinka tulkitaan seuraava uutisotsikko:
"Susi hyökkäsi omistajansa kanssa pyörälenkillä olleen koiran kimppuun keskellä asutusta Raahessa"
– Pyhäjokiseutu 02.10.2024

Kuva 1: Kirjaimellisesti tulkittu otsikko: "Susi hyökkäsi omistajansa kanssa pyörälenkillä olleen koiran kimppuun keskellä asutusta Raahessa.". Kuva luotu Gemini Nano Banana mallilla.
Onko tilanne kenties ollut Kuvan 1 mukainen: susi ja hänen omistajansa olivat hyökkääjät, kun koiraraukka yritti pyöräillä karkuun? Vastaavia monitulkintaisia lauseita on Suomen Kuvalehden Jyvät & Akanat -palstalla viikoittain. Tässä kaksi tuoretta esimerkkiä lisäviihteenä 5/2026 numerosta:
"Nikotiinipussit muuttavat aivoja – kokenut lääkäri kertoo, miten pääset niistä pysyvästi eroon"
– Iltasanomat 5.1.2026
"Varkaudessa anastettiin omaisuutta marraskuussa"
– Iltasanomat 7.1.2026
Täten lienee selvä, että koneellinen kielen käsittely haastavaa, mutta koska kieli on ihmisten pääasiallinen viestintäväline, on luonnollisen kielen käsittely (Natural Language Processing, NLP) keskeinen osa tietojenkäsittelyä ja tekoälyä. Käytännön sovelluksia ovat esimerkiksi tekstin luokittelu (spam, no spam), konekäännökset (ranska → suomi), hakukoneet ja tekstin generointi ("Olipa kerran... ?"). Näiden haastavien tehtävien suhteen suuret läpimurrot ovat varsin tuoreita, mutta yritystä on kuitenkin ollut viimeisen yli 60 vuoden ajan. 1
Historia
Nykyisten chatbottien suuret merkkipaalut ovat syntyneet lähitulevaisuudessa, mutta NLP:llä on pitkä historia. Historia voidaan jakaa kolmeen pääkauteen: säännöpohjainen (rule-based), tilastollinen (statistical) ja syväoppimiseen perustuva (deep learning-based) NLP – joka toki on myös tilastollista.
Turingin koe
Kaiken luonnollisen kielen käsittelyn päämäärä ei ole välttämättä matkia ihmisen älykkyyttä, mutta tämä ajatus on kulkenut matkassa alusta asti – aivan kuten muussakin tekoälyn historiassa. Alan Turing julkaisi 1950 paperin otsikolla "Computing Machinery and Intelligence", jossa hän esitteli ajatuksen Turingin kokeesta nimellä "The Imitation Game" 2. Peli perustuu vanhaan seurapeliin, jolla salongissa on voinut viihdyttää vieraita: henkilöt A ja B istuvat erillään toisistaan, ja kolmas henkilö C esittää kysymyksiä kummallekin. A ja B ovat mies ja nainen, ja henkilön C tehtävä on päätellä kirjoitetun viestin perusteella, kumpi on kumpi. Turingin koe on sama asetelma, mutta A ja B ovat kone ja ihminen. Jos C ei pysty luotettavasti erottamaan konetta ihmisestä, voidaan sanoa, että kone on läpäissyt Turingin kokeen. 3
Löydät internetistä helposti tätä koetta kritisoivaa sisältöä, ja myös väitteitä, että eri mallit ovat läpäisseet kokeen. Jos haluat tutustua aihepiiriin, kannattanee tutustua vuoden 2025 artikkeliin otsikolla Large Language Models Pass the Turing Test, jossa on vertailtu niin ELIZAa kuin tuoreita GPT-4.5-malleja. 4
ELIZA
Tunnetuin varhaisista chatterbot-sovelluksista on ELIZA, erityisesti skripti DOCTOR, joka kehitettiin 1960-luvulla MIT:ssä. Sen loi Joseph Weizenbaum, ja se simuloitsi Carl Rogerin asiakaskeskeistä psykoterapiaa. Ohjelma on nimetty fiktiivisen Eliza Doolittle hahmon mukaan, joka esiintyy George Bernard Shaw'n näytelmässä "Pygmalion" (ja myöhemmin musikaalissa "My Fair Lady"). ELIZA käytti yksinkertaisia sääntöjä ja avainsanojen tunnistusta vastatakseen käyttäjän syötteisiin, luoden vaikutelman ymmärryksestä. Kyseessä on siis pattern-matching-järjestelmä. 5
"There are even accounts of ELIZA’s responses being so human-like that it evoked emotional responses from people who forgot they were interacting with a computer, including Weizenbaum’s own secretary. This led to much discussion about ELIZA’s potential to pass the Turing Test, although there are no known accounts of ELIZA actually doing this."
– Robert Barton ja Jerome Henry 5
Kokeile!
ELIZA:sta löytyy JavaScript-toteutuksia, mutta yksi näppärä tapa saada pääsy siihen on APT-paketinhallinnasta löytyvä PERL-toteutus. Sen saat käyttöön näin:
- Luo Dockerfile. Katso sisältö alta.
- Aja
docker build -t eliza . - Aja
docker run -it --rm eliza
Dockerfile
FROM ubuntu:latest
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get install -y --no-install-recommends \
perl \
libchatbot-eliza-perl && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
RUN cat > eliza.pl << 'EOF'
#!/usr/bin/perl
use strict;
use warnings;
use Chatbot::Eliza;
my $eliza = Chatbot::Eliza->new;
print "Eliza: Hello. How can I help you today?\n";
while (1) {
print "You: ";
my $input = <STDIN>;
last unless defined $input;
my $response = $eliza->transform($input);
chomp $response;
print "Eliza: $response\n";
}
EOF
RUN chmod +x /app/eliza.pl
ENTRYPOINT ["/app/eliza.pl"]

Kuva 2: ELIZA vastailee opettajan murheisiin.
ELIZA herätti yleisön mielenkiinnon ja sen ympärille syntyi hypeä. Weizenbaum päätyi itse taistelemaan tätä hypeä vastaan, aloittaen ikään kuin ristiretken omaa ohjelmaansa vastaan. ELIZA ei tiennyt mitään psykologiasta ja oli pikemminkin Carl Rogerin terapian karikatyyri tai parodia, joka lähinnä heijastaa kysymykset takaisin käyttäjälle. 6
PARRY
Toinen varhainen chatbot on PARRY, joka kehitettiin 1970-luvulla psykiatri Kenneth Colbyn Stanfordissa. Applikaatio pyrki simuloimaan skitsofreniaa sairastavan potilaan puhetta. PARRY käytti monimutkaisempia sääntöjä ja malleja kuin ELIZA, pyrkien jäljittelemään skitsofrenian oireita, kuten vainoharhaisuutta ja epäjohdonmukaista ajattelua. 5 Ohjelman LISP-koodi on linkitettynä Wikipedia-artikkelissa ja löytyy Carnegie Mellonin arkistosta. Sen ajaminen modernilla koneella olisi haastellista, joten tyydytään kurkkaamaan ELIZA:n (DOCTOR) ja PARRY:n keskustelua, joka on dokumentoitu vuonna 1972. Keskustelun alku muotoiltuna alla: 7
DOCTOR: Good Evening. Tell me your problems. Please terminate input with a period or a question mark.
PARRY: People get on my nerves sometimes.
DOCTOR: I am not sure I understand you fully.
PARRY: You should pay more attention.
DOCTOR: Suppose you should pay more attention.
PARRY: You're entitled to your own opinion.
DOCTOR: What makes you think I am entitled to my own opinion?
Myöhemmät kehitysvaiheet
| Nimi | Kehittäjä | Vuosi | Huomioitavaa |
|---|---|---|---|
| ELIZA | Joseph Weizenbaum | 1966 | Simuloi psykoterapeuttia |
| PARRY | Kenneth Colby | 1972 | Simuloi skitsofreenikkoa |
| Jabberwacky | Rollo Carpenter | 1988 | Online-julkaisu 1997 |
| MS Word AutoCorrect | Microsoft | 1993 | Yksinkertainen sääntöpohjainen |
| ALICE | Richard Wallace | 1995 | Käyttää AIML-skriptauskieltä |
| MedSpeak | IBM | 1996 | Lääketieteellinen litterointi |
| VAL | BellSouth | 1996 | Puheentunnistus ja vastaus |
| SmarterChild | Robert Hoffer | 2001 | Agentti AOL ja Messengerissä |
| Cleverbot | Rollo Carpenter | 2008 | Jabberwackyn seuraaja |
| Siri | Adam Cheyer | 2011 | Assistentti |
| Xiaoice | Microsoft | 2014 | Empaattinen chatbot |
| Alexa | Amazon | 2014 | Assistentti |
| Melody | Andrew Ng | 2015 | Lääketieteellinen assistentti |
Taulukko on koostettu kirjoista Conversational Artificial Intelligence 8 ja The Invisible Brand: Marketing in the Age of Automation, Big Data, and Machine Learning. 3
Asiantuntijajärjestelmät (Expert Systems)
Heti alkuun suosittelen, että kannattaa silmäillä seuraavia videoita. Sinun ei välttämättä tarvitse katsoa pitkiä videoita kokonaan, mutta silmäilemällä näet, miten niissä käsitellyt asiantuntijajärjestelmät toimivat:
- MIT: 3. Reasoning: Goal Trees and Rule-Based Expert Systems. 50-minuuttinen ideo, jossa Patrick Winston esittelee Genesis-ryhmän tuottamaa Genesis-ohjelmaa, joka kykenee selostaa Macbeth-kirjan tapahtumia (aivan videon lopussa). Edeltävässä osio on pohjustavaa teoriaa.
- URBS: Lecture 13: Building an Expert System and PyKE. 50-minuuttinen luento, jossa esitellään PyKE-kirjasto ja rakennetaan asiantuntijajärjestelmä. Pitääkö ottaa sateenvarjo mukaan vai ei?
Asiantuntijajärjestelmät ovat säännöpohjaisia järjestelmiä, jotka käyttävät tietokantaa sääntöjä ja faktoja päätöksenteon tai ongelmanratkaisun tukena.
"Expert systems are computer programs designed to mimic the decision-making abilities of human experts by leveraging predefined rules and knowledge bases."
– Vijay Kanabar ja Jason Wong 9
Jos asiantuntijajärjestelmällä haluaa analysoida tekstin tapahtumia, tulee käyttää jonkin sortin semantic parser -ohjelmaa, joka muuttaa luonnollisen kielen lauseet koneen ymmärtämään muotoon. Genesiksen kohdalla tämä on START-niminen ohjelma, joka kääntää englantia Genesiksen sisäiseen esitysmuotoon. Tämä selitetään A Commonsense Approach to Story Understanding-artikkelissa 10. START itsessään on Boris Katz:n ja InfoLab:n (MIT) kehittämä kysymyksiin vastaava hakukone, mutta Genesis käyttää sitä vain parsijana. Sisäinen kieli sisältää entiteettejä (substantiiveja), suhteita (henkilö A verbi henkilö B), funktioita ja sekvenssejä. Genesis käyttää apunaan ConceptNet-tietokantaa, knowledge graph:ia, jonka avulla voit esimerkiksi tutkia sanan dog suhteita muihin käsitteisiin. Näiden päälle voi käyttäjä rakentaa sääntöjä, kuten if XX harms YY, YY becomes angry tai if XX eats food, XX becomes full. Jatkossa, lause Matt eats an apple istuu tähän sääntöön, koska ConceptNet yhdistää apple-sanan food-käsitteeseen (is type of edible fruit).
Toivon mukaan on tässä vaiheessa selvää, että olisi äärimmäisen haastavaa luoda modernin suuren kielimallin tasoinen asiantuntijajärjestelmä. Asiantuntijajärjestelmät olivat kovinta huutoa 80-luvulla. Modernien kielimallien kohdalla tulet kuitenkin törmäämään termeihin knowledge graph ja ontology.
Haasteita vs. MLP
90-luvulta alkoi selkeä siirtymä tilastollisiin menetelmiin ja perinteiseen koneoppimiseen. Tämän kurssin osalta tämä aihepiiri alkaa FC-MLP-verkoista (fully connected multilayer perceptron). Kuten on jo opittu, MLP-versiot eivät kykene tunnistamaan spatiaalisuutta. Tähän käytimme kuvien (ja äänen) kanssa konvoluutioverkkoja aiemmissa luvuissa. Lauseen voi kuvitella 1-D -spatiaaliseksi dataksi, jossa sanat ovat "pikseleitä" peräkkäin. Näin Conv1D-kerrokset soveltuvat tekstin käsittelyyn ainakin paperilla, ja niitä on siihen myös käytetty. Ongelmia, joita Conv1D-kerrokset eivät kuitenkaan ratkaise, ovat mm.:
- Sanat eivät ole lukuja. Kuvissa pikselit ovat numeerisia arvoja (esim. 0–255), mutta sanat ovat kategorisia muuttujia. On ensin keksittävä tapa kääntää lauseet listaksi numeroita.
- Lauseiden pituudet vaihtelevat. Yksi lause voi olla "Kissa istuu matolla." ja toinen "Kissa matolla istui olevaista pohtien." Konvoluutioverkot olettivat kiinteän syötteen pituuden.
- Pitkäaikaiset riippuvuudet. Conv1D-kerrokset havaitsevat paikallisia kuvioita hyvin (esim. 2–5 peräkkäistä sanaa), mutta niiden on vaikea mallintaa pitkän kantaman riippuvuuksia. Kuvittele teos, joka alkaa sanoilla: "Seuraavat 100 asiaa eivät ole totta: (1) ...".
- Konteksti ja monet merkitykset. Sanat voivat saada merkityksensä kontekstin perusteella. Muista: "kuusi palaa".
- Taivutusmuodot. Monet kielet sallivat sanojen taivuttamisen, eli ovat jossain määrin morphologically rich. Mitenpä suomen "epäjärjestelmällistyttämättömyydellänsäkäänköhän" ja "epäjärjestelmällinen" liittyvät toisiinsa?
Todella, todella naiivi ratkaisu yllä oleviin ongelmiin keittiöfilosofin pohdinnalla olisi:
- ✅ Tee sanoista lukuja One-Hot Encoding -menetelmällä.
- ✅ Täytä lauseet nollilla (padding) niin, että kaikilla on sama pituus.
- ⛔ ???
- ⛔ ???
- ⛔ ???
Kolme viimeisintä jäisivät siis tyystin ratkaisematta – ainakin opettajan keittiöfilosofian taidoilla. Näihin ongelmiin onneksi löytyy parempia ratkaisuja, joihin pureudutaan tässä ja seuraavissa luvuissa.
NLP:n perusteet
Tekstin esikäsittely: SpaCy
Modernissa NLP:ssä esikäsittely on usein virtaviivaistettu valmiiden kirjastojen, kuten SpaCy:n, avulla. SpaCy ei ole ainut. Vaihtoehtoja olisivat esimerkiksi NLTK ja Gensim. SpaCy on kuitenkin suorituskykyinen ja helppokäyttöinen, joten keskitymme siihen.
Kun syötät tekstiä SpaCy-putkeen (engl. pipeline), se suorittaa taustalla automaattisesti useita komponentteja. Tämä ei ole kielen käsittelyn kurssi, joten keskitymme pääasiassa käyttämään valmiita putkia. Yksi valmiiksi koulutettu putki on en_core_web_sm. Kyseessä ei ole yksittäinen tilastollinen malli, vaan joukko NLP-komponentteja, jotka on ketjutettu yhteen. Alla on taulukko, jossa nämä ovat selitettynä auki linkkeineen, sekä tieto siitä, onko kyseinen komponentti koulutetttava tilastollinen (lue: koneoppimiseen perustuva) malli vai sääntöpohjainen menetelmä (lue: pattern matching).
| Komponentti | Tyyppi | Tunnistaa | Esim | Mistä löytyy tulos? |
|---|---|---|---|---|
| Tokenizer | Rule | N/A | Doc itsessään |
|
| tok2vec | ML | N/A | Doc.tensor tai Doc[i].vector |
|
| tagger | ML | Sanaluokat | NN (noun; apple), PRP (pronoun; they), JJ (adj; big) | Doc[i].tag_ |
| parser | ML | Sanojen keskinäiset riippuvuudet | nsubj (subject; she), prep (prep modifier; on) | Doc[i].dep_ |
| ner | ML | Erisnimet | ORG (organization; Google) | Doc[i].ent_type_ |
| attributeruler | Rule | Poikkeussäännöt esim. sanaluokille | N/A | |
| lemmatizer | Rule | Sanan perusmuoto | Doc.lemmas |
Tip
Jos haluat tietää, mitä vaikkapa PRP tarkoittaa, voit tarkistaa sen explain()-metodilla.
Tip
Kannattaa tutustua dokumentaatiosta sivuihin:
- SpaCy Linguistic Features. Siellä käsitellään tarkemmin se, mikä on alla vain listattuna yhden esimerkin avulla.
- SpaCy Library Architecture. Tämä auttaa yllä olevan taulukon ymmärtämisessä visuaalisesti.
- SpaCy Training Pipelines & Models. Tämä dokumentti selittää, miten SpaCy-mallit on koulutettu, ja paljastaa, mikä syväoppimiskirjasto sillä on käytössä konepellin alla.
Jos haluaisit opetella SpaCyn syvällisemmin, kuten tehdä itse omia komponentteja putkeen, voisit aloittaa kurssin Advanced NLP with spaCy. Todennäköisesti haluaisit tutustua myös YouTube: ExplosionAI-kanavaan, joka on SpaCyn kehittäjän kanava, sisältäen videoita sekä SpaCyn että Prodigyn käytöstä.
Kuinka ajaa alla olevat snippetit?
Sinulla pitää luonnollisesti olla SpaCy asennettuna (uv add spacy). Lisäksi sinun pitää ladata malli. Aja terminaalissa seuraava komento:
uv add "fi-core-news-sm @ https://github.com/explosion/spacy-models/releases/download/fi_core_news_sm-3.8.0/fi_core_news_sm-3.8.0-py3-none-any.whl"
Tämän jälkeen käynnistä Marimo, luo uusi Notebook, ja ota malli käyttöön:
Tokenisointi
Tekstin pilkkominen pienempiin yksiköihin, tokeneihin (sanat, välimerkit, erikoismerkit). Toisin kuin yksinkertainen split(" "), älykäs tokenisoija ymmärtää esimerkiksi välimerkkien erottamisen sanoista.
tokenized = nlp.make_doc("Kissa, se on eläin?!")
for tok in tokenized:
print(tok, end="|")
# Kissa|,|se| |on|eläin|?|!|
Perusmuotoistaminen (Lemmatization)
Sanojen palauttaminen niiden sanakirjamuotoon eli perusmuotoon (esim. "juoksi" → "juosta", "kissojen" → "kissa"). Tämä on erityisen kriittistä suomen kielen kaltaisissa morfologisesti rikkaissa kielissä sanaston koon hallitsemiseksi.
doc = nlp("Pienet pyöreät pippurit hyppivät")
for token in doc:
print(token.lemma_, end=" ")
# pieni pyöreä pippuri hyppiä
Sanaluokat (POS)
Jokaiselle tokenille ennustetaan sen sanaluokka (esim. substantiivi, verbi, adjektiivi). Onko kuusi numero vai mikä? Muuttuuko sanaluokka, jos annat lauseessa kontekstia, kuten kertomalla että taskussani on kuusi pientä palaa kakkua.
doc = nlp("Kuusi palaa.")
for token in doc:
print(f"{token.text} {token.pos_}")
# Kuusi NUM
# palaa VERB
Riippuvuussuhteet
Sanojen välisten syntaktisten suhteiden analysointi (engl. syntactic dependency parsing) – kuka tekee, mitä tekee, kenelle tekee. Tämä auttaa ymmärtämään lauseen rakennetta pintaa syvemmältä. Tähän löytyy jopa oma visualisointityökalu:
from spacy import displacy
doc = nlp("Susi hyökkäsi omistajansa kanssa pyörälenkillä "
+ "olleen koiran kimppuun keskellä asutusta Raahessa")
mo.Html(displacy.render(doc, style="dep"))

Kuva 3: Riippuvuussuhteiden visualisointi SpaCy:llä.
Nimettyjen entiteettien tunnistus (NER)
Errisnimien, organisaatioiden, paikkojen, päivämäärien ja rahasummien automaattinen tunnistus tekstivirrasta.
doc = nlp("microsoft Microsoft MiCrOSofT MICROSOFT macrohard")
for token in doc:
print(token.text, "==", token.ent_type_)
# microsoft == ORG
# Microsoft == ORG
# MiCrOSofT ==
# MICROSOFT ==
# macrohard ==
Morfologinen analyysi
Tunnistaa taivutusmuotoja.
doc = nlp("Pöydällä")
doc[0].morph
# Case=Ade|Number=Sing
# eli adessiivi
doc = nlp("Pöydillä")
doc[0].morph
# Case=Ade|Number=Plur
# eli monikon adessiivi
Hukkasanat (Stop Words)
Hyvin yleisten ja usein merkitykseltään vähäisten sanojen (kuten "ja", "on", "että") suodattaminen pois, jotta malli voi keskittyä oleelliseen sisältöön.
doc = nlp("Minua rassaa kun tuon niille jäätelöä, mutta kukaan ei niinku edes hymyile.")
for token in doc:
print(token, end=" ") if not token.is_stop else print("---", end=" ")
# --- rassaa --- --- tuon --- jäätelöä , --- --- --- hymyile .
Sanavektorit
Määritelmät
- Embedding: Yleinen termi, joka viittaa mihin tahansa tiheään numeeriseen esitykseen, joka säilyttää tietyn rakenteen tai suhteet alkuperäisessä datassa. Raschka:n mukaan se on "a mapping from discrete objects, such as words, images, or even entire documents, to points in a continuous vector space" 11. Tähän liittyy ainakin satavuotinen historia, sisältäen klassiset PCA:t (Principal Component Analysis) sekä modernit ongelmat/ratkaisut kuten MDE (MinimumDistortion Embedding) sekä tietenkin alla esiteltävät neuroverkkopohjaiset menetelmät. 12
- Word Embedding: Erityisesti sanojen tiheä numeerinen esitys, joka säilyttää semanttisia suhteita sanojen välillä. Esimerkiksi Word2Vec ja GloVe ovat menetelmiä, jotka luovat sanavektoreita. 11
- Word Vector eli sanavektori: Sama kuin aiempi, mutta korostaa sen vektoriluonnetta matemaattisena objektina.
Huomaa, että on siis muitakin embedding-tyyppejä, kuten lause- tai osasana- (engl. subword) embeddingit. Pahoittelut finglishistä: en löydä hyvää käännöstä embedding-sanalle.
SpaCy laskee sanavektoreita, joten kurkataan, kuinka niihin pääsee käsiksi. SpaCy:n suomenkielisen pipelinen tapauksessa vektori on 96-ulotteinen. Esimerkiksi sanaa Pizza kuvaa 96 featurea. Nämä featuret on opittu tilastollisesti valtavasta määrästä tekstiä.
doc = nlp("Pizza on ravitsevaa.")
for token in doc:
print(f"{token.text:>12}: ", end="")
for value in token.vector[:3]:
print(f"{value:>5.2f}", end=" | ")
print(f"... | {value:>5.2f}")
Output:
Pizza: 0.49 | -5.49 | -3.25 | ... | -3.25
on: 5.62 | -1.54 | -0.35 | ... | -0.35
ravitsevaa: 4.88 | 3.93 | 0.55 | ... | 0.55
.: -0.65 | -0.54 | 6.29 | ... | 6.29
Löydät vastaavan rakenteen myös doc.tensor-attribuutista, joka sisältää koko lauseen vektoritensorin, jonka muoto olisi tässä tapauksessa (4, 96). PyTorchissa tulet käsittelemään niitä yleisimmin tensoreina kokoa: (batch_size, seq_len, embedding_dim).
Mutta kuinka tähän outoon vektoriin ollaan päädytty? Tutustutaan alla eri menetelmiin, aloittaen Johdatus koneoppimiseen -kurssilta tutuksi tulleesta One-Hot Encoding -menetelmästä, edeten tiheisiin vektoreihin, joiden piirteet on opittu tilastollisesti. Seuraavassa luvussa tutustumme suurten kielimallien käyttämiin kontekstisidonnaisiin sanavektoreihin. Niiden ymmärtäminen on helpompaa, jos aloitetaan perusasioista.
⛔ One-Hot Encoding
Tämän pitäisi olla sinulle tuttu konsepti Johdatus koneoppimiseen -kurssilta. Yksinkertaisesti sanottuna, One-Hot Encodin muuntaa jokaisen sanan vektoriksi, jossa on yhtä monta ulottuvuutta kuin sanakirjassa on sanoja. Vektorin arvo on 1 siinä ulottuvuudessa, joka vastaa kyseistä sanaa, ja 0 muualla. Eli siis, jos meillä on 6 sanan sanasto (engl. corpus): ["kissa", "koira", "auto", "talo", "puu", "vene"], niin koko sanasto olisi enkoodattuna:
vocab = {
"kissa": [1, 0, 0, 0, 0, 0],
"koira": [0, 1, 0, 0, 0, 0],
"auto": [0, 0, 1, 0, 0, 0],
"talo": [0, 0, 0, 1, 0, 0],
"puu": [0, 0, 0, 0, 1, 0],
"vene": [0, 0, 0, 0, 0, 1],
"UNK": [0, 0, 0, 0, 0, 0], # Tuntematon sana
}
Jos koko sanasto on siis \(400\,000\) sanaa, jokainen sana esitetään \(400\,000\)-ulotteisena vektorina, jossa vain yksi arvo on 1 ja loput \(399\,999\) ovat 0. Tämä johtaa erittäin harvaan (sparse) esitykseen. Kukin vektori on orthogonaalinen toisiinsa nähden, mikä tarkoittaa, että sanojen välillä ei ole lainkaan semanttista yhteyttä. Esimerkiksi "kissa" ja "koira" ovat yhtä kaukana toisistaan kuin "kissa" ja "auto", vaikka ne ovat semanttisesti lähempänä toisiaan. Tämä metodi oli käytössä 1990-luvulla, mutta nykyisten kielimallien kohdalla sen voi unohtaa tyystin. 13
Tiheät vektorit
Naiivi harva esitys on siis ongelmallinen. Seuraavaksi yksinkertaisin lähestymsistapa on käyttää tiheitä vektoreita, joissa jokainen sana esitetään matalammassa ulottuvuudessa (esim. 100 tai 300 ulottuvuutta). Tällaiset vektorit oppivat säilyttämään sanojen semanttisia suhteita, kuten synonyymit ja analogiat. Useita menetelmiä on kehitetty tällaisten sanavektorien luomiseksi, joista hyvät esimerkit ovat Word2Vec, GloVe ja fastText. 13
Word2Vec ei itsessään ole algoritmi vaan pikemminkin joukko malleja, jotka oppivat sanavektoreita tilastollisesti. Mikolov esitteli alkuperäisessä artikkelissaan kaksi päämallia: Continuous Bag of Words (CBOW) ja Skip-Gram. 14 Tutustumme erityisesti CBOW:iin alla.
Ennen Mikolovin artikkelia oli tyypillistä, että kukin NLP-tutkija kehitti/koulutti oman sanavektorimallinsa omaan käyttöönsä. Word2Vec:n mallit mullistivat tätä siten, että jatkossa tutkijat pystyivät hyödyntämään valmiiksi koulutettuja sanavektoreita, pretrained word embeddings, jotka oli koulutettu valtavilla tekstikorpuksilla (esim. Google News, Wikipedia). Näin sanavektorit muuttuivat standardoiduiksi resursseiksi, joita voitiin jakaa ja käyttää eri NLP-tehtävissä. 13
Word2Vec
Warning
Vältä sekaannusta Bag of Words (BoW) -menetelmän kanssa, joka on eri asia kuin Continuous Bag of Words (CBOW). BOW on Naive Bayesin ja muiden perinteisten mallien esikäsittelymenetelmä, jossa lause esitetään sanakirjassa esiintyvien sanojen frekvensseinä ilman järjestystä.
- BoW:
- Dokumentti-tason esitys, jossa lasketaan kunkin sanaston sanan esiintymiskerrat (tai muita tilastollisia esiintymisiä, kuten TF-IDF).
- Ei vaadi minkään sortin koulutusta.
- CBOW:
- Sanatason esitys.
- Koulutetaan ennustamaan sanaa sen kontekstin perusteella.
Continuous Bag of Words (CBOW) -malli ennustaa keskimmäisen sanan ympäröivien sanojen perusteella. 14 Käydään algoritmi läpi esimerkin avulla. Kuvitellaan lause: "Train will arrive at five". Meidän ikkunakoko on 2, eli otamme kaksi sanaa kummaltakin puolelta keskimmäistä sanaa. Meidän haluttu embedding ulottuvuus on 3. Täten input ja target ovat esikäsittelyn jälkeen:
n = len(rest_of_vocab)
X = [
[1,0,0,0,0] + [0]*n, # train
[0,1,0,0,0] + [0]*n, # will
[0,0,0,1,0] + [0]*n, # at
[0,0,0,0,1] + [0]*n # five
]
y = [0,0,1,0,0] + [0]*n # arrive
Näiden johdosta meillä on Nx3-kokoinen embedding matrix W (N sanaa sanastossa, 3 ulottuvuutta). Tämän matriisin jokainen rivi on sanan vektoriesitys. Tämä vektori on siis embedding matrix. Koulutuksen jälkeen tämä on se, mitä me haluamme käyttää sanavektoreina. Aluksi nämä arvot ovat satunnaisia. Syöte käytännössä valitsee W:stä neljä riviä (operaatiolla X @ W), jotka vastaavat tässä tapauksessa sanoja train, will, at ja five. Tämä valinta tapahtuu siten, että matriisin muut arvot saavat arvon nolla, jolloin vain näiden neljän sanan rivit vaikuttavat lopputulokseen.
Tämä operaatio kääritään vielä summan tai keskiarvon sisään, h = torch.sum(X @ W, dim=0), jolloin saadaan kolmeulotteinen vektori h, joka on näiden neljän sanan vektoreiden summa. Tämän jälkeen lasketaan h @ W2, jossa W2 on toinen painomatriisi, joka muuntaa takaisin sanatilaan. Alla olevassa kuvassa tämä on nimeltään \(W'\). Tulos on vektori, jossa on N ulottuvuutta. Lopuksi käytetään softmaxia ja lasketaan tappio (loss) verraten ennustettua sanaa y:tä vastaan. Koko prosessi toistetaan valtavalla määrällä lauseita, jolloin W oppii säilyttämään sanojen semanttisia suhteita.

Kuva 4: Continuous Bag of Words (CBOW) -mallin arkkitehtuuri. Kuva on mukailtu Mikolov:n alkuperäisestä artikkelista, mutta avattu yllä olevan tekstiesimerkin mukaiseksi.
Seuraavaksi voisimme liu'uttaa tätä ikkunaa eteenpäin lauseessa, jolloin saamme lisää input- ja target-pareja. Seuraava ikkuna voisi olla: "will arrive at five o'clock", jolloin y olisi at. Näin jatketaan koko korpuksen läpi useita kertoja.
CBOW ei suinkaan ole täydellinen, vaan siinä on seuraavat heikkoudet 13:
- Pieni ikkuna. CBOW käyttää kiinteän kokoista liukuvaa ikkunaa, joka rajoittaa kontekstin määrää. Pitkän kantaman riippuvuudet jäävät huomiotta.
- Subword-tieto puuttuu. CBOW käsittelee sanat kokonaisina yksikköinä. Esimerkiksi substansiitivsta muodostetun adjektiivin kantasanan yhteys jää huomiotta (
vaaravs.vaarallinentaiintelligentvs.intelligence). - Out of Vocabulary (OOV). CBOW ei pysty käsittelemään sanoja, joita ei ole nähty koulutuksen aikana. Tämä on ongelma harvinaisille sanoille tai kirjoitusvirheille.
- Staattisuus. Jokaisella sanalla on yksi kiinteä vektoriesitys, joka ei muutu kontekstin mukaan. Onko se kuusi nyt sitten numero vai puu?
Entä Skip-gram?
Skip-gram toimii päinvastoin kuin CBOW: se ennustaa kontekstisanoja annetun sanan perusteella. Eli jos meillä on sana arrive, Skip-gram yrittää ennustaa sanat train, will, at ja five. Arkkitehtuuri on muuten samanlainen, mutta syöte ja tavoite ovat vaihtaneet paikkaa 14. Skip-gram toimii erityisen hyvin harvinaisten sanojen kanssa, koska se keskittyy yksittäisiin sanoihin ja niiden konteksteihin. 15
GloVe
GloVe julkaistiin 2014 Stanfordissa, vuosi Word2Vec:n jälkeen. GloVe korjaa CBOW:n ensimmäisenä puutteen (ks. yltä) hyödyntämällä koko korpuksen globaaleja yhteisesiintymistilastoja (engl. co-occurrence matrix) pelkän lokaalin ikkunan sijaan. GloVe rakentaa sanavektorit siten, että sanojen vektoreiden välinen etäisyys heijastaa niiden yhteisesiintymistiheyttä koko korpuksessa: tämä tehdään tekemällä dimensiovähennys yhteisesiintymismatriisille 13.
Emme käsittele algoritmia tässä tarkemmin, mutta voit tutua sen verkkosivuihin GloVe: Global Vectors for Word Representation. Sivuilta löytyy sekä julkaisu, kivoja kuvia, että linkki GitHub-koodiin (C-kieltä).
fastText
Facebook julkaisi fastText-algoritmin vuonna 2016. Kuten sen artikkelin otsikosta, "Enriching Word Vectors with Subword Information", voi päätellä, fastText ottaa huomioon sanojen sisäiset osat (subwords), kuten n-grammit. Tämä auttaa käsittelemään harvinaisia sanoja ja morfologisesti rikkaita kieliä paremmin kuin Word2Vec tai GloVe. fastText edustaa kutakuinkin seuraavaa evoluutiovaihetta sanavektoreissa 16.
Emme käsittele myöskään tätä algoritmia tarkemmin. Voit tutustua sen verkkosivuihin fastText: Library for Efficient Text Classification and Representation Learning. Sivuilta löytyy Explain Like I'm Five -video, linkki koodiin ja muuta hyödyllistä.
Se, mikä meitä kiinnostaa, on että mitkä CBOW:n heikkouksista on nyt korjattu 13:
- ⛔ Pieni ikkuna. fastText käyttää edelleen kiinteän kokoista ikkunaa.
- ✅ Subword-tieto. fastText jakaa sanat n-grammeihin.
- ✅ Out of Vocabulary (OOV). fastText voi luoda vektoreita tuntemattomille sanoille niiden n-grammien perusteella.
- ⛔ Staattisuus. fastTextin sanavektorit ovat edelleen staattisia.
Vektorien vertailu
Vektorien analogiat
"We now evaluate our approach on word analogy questions, of the form A is to B as C is to D, where D must be predicted by the models."
— Mikolov et al., 2013 14
Koska embedding on piirrovektori, voidaan laskea vektoreiden välisiä eroja ja summia. Tämä mahdollistaa semanttisten analogioiden löytämisen. Esimerkiksi, jos meillä on sanat king, man ja woman, voimme tehdä seuraavanlaista matematiikkaa:
import numpy as np
king_vector = nlp("king").vector
man_vector = nlp("man").vector
woman_vector = nlp("woman").vector
queen_vector = king_vector - man_vector + woman_vector
Samankaltaisuus numerona
Johdatus koneoppimiseen -kurssilta sinulle pitäisi olla tuttu käsite euklidinen etäisyys, joka mittaa suoraa etäisyyttä kahden vektorin välillä. Kyseessä on linnuntie-etäisyys. Piirrevektorin kohdalla tämä ei kuitenkaan ole paras tapa mitata samankaltaisuutta, koska se on herkkä vektoreiden normille eli pituudelle. Siksi käytetään usein kosinista samankaltaisuutta, joka mittaa vektoreiden välistä kulmaa, eikä niinkään etäisyyttä. 17 Ajatus itsessään on hyvin vanha. Ainakin itse sen esittelijöistä on Zellig Harris julkaisussa "Distributional Structure" vuodelta 1954. 18 PsycNetin tiivistelmä on seuraava: "Harris maintains that it is possible to define a linguistic structure solely in terms of the "distributions" (= patterns of co-occurrences) of its elements. There is no parallel meaning-structure which can aid in describing formal structure. Meaning is partly a function of distribution." 19
Tämä cosine similarity on pistetulon normalisoitu versio. Se vastaa kahden vektorin välisen kulman kosinia, mistä nimi kosininen samankaltaisuus 17:
Kosinilla on hyödyllisiä ominaisuuksia skaalainvarianssin lisäksi 17:
- Se on välillä -1 ja 1.
- Vastakkaiset: -1
- Ortogonaaliset: 0
- Samansuuntaiset: 1
- Se on nopea ja edullinen laskea.
- Se on vähemmän herkkä sanojen esiintymistiheydelle ja siten kestävämpi poikkeuksille (engl. outliers)
- Koska se on normalisoitu, sitä voidaan käyttää myös korkeaulotteisen datan kanssa.

Kuva 5: Havainnekuva kosinisen samankaltaisuuden arvoista eri ryppäiden välillä. Punainen kolmio edustaa kahden ryppään välistä kosinikulmaa.
Yllä olevassa kuvassa pisteet edustavat sanoja tai N-grammeja eli yleensä yhdessä esiintyvistä sanoista koostettuja kokonaisuuksia. Pisteparven x-akseli on individual—social ja y on physical—digital.
Siniset sanat ovat vahvan digitaalisia, lähes neutraaleja sosiaalisuudeltaan, kuten:
cloud_storage,database,encryption.Keltaiset sanat ovat vähemmän digitaalisia, enemmän sosiaalisia, kuten:
social_media_app,group_chat,wikipedia.Violetit sanat ovat miedosti fyysisen puolella ja yksilöllisiä, kuten:
map,board_game_rulebook,print.
Jos valitsemme kustakin ryppäästä yhden sanan, voimme laskea etäisyyksiä. Saamme cosine(yellow, blue) ≈ 0.5. Sen sijaan cosine(yellow, purple) ≈ -1.0. Huomaa, että jos käyttäisimme euklidista etäisyyttä, tulos olisi hyvin eri: euclid(yellow, blue) > euclid(yellow, purple). Yksinkertaisessa 2-ulotteisessa kuvaajassa tämä on silmämääräisesti todistettavissa: muista, että sanavektori on esimerkiksi 300-ulotteinen vektori.
Yhteenveto
Tiivistetään yllä löydetty, ELIZA:aa ja PARRY:ä seuraava historia lyhyesti väitteisiin vuosikymmenittäin:
1990-luku
- Esiprosessointi ja sanojen tokenisointi. Tilastolliset menetelmät ovat hyvin hauraita syötteen suhteen, joten sananmuodot, hukkasanat ja muut on käsiteltävä huolellisesti. Tiedät tämän Johdatus koneoppimiseen -kurssilta. Naive Bayes luulee esimerkiksi että
Kissajakissaovat eri sanoja, ellet erikseen käsittele datasettiä. - One-Hot & BoW. Sanat esitettiin eristettyinä indekseinä tai frekvensseinä sanakirjassa, jossa esiintyy aivan jokainen mallin tuntema sana. 13
- N-Gram. Ainut tapa mallintaa kontekstia oli tarkastella peräkkäisten sanojen yhdistelmiä. Kärjistetysti tietyistä sanapareista (bigram) tai -kolmikoista (trigram) laskettiin todennäköisyydet, eli vaikkapa
new yorkon yksi token. - RNN ja LSTM. RNN oli 90-luvulla akateeminen kuriositeetti. Laskentatehoa oli todella vähän ja saatavat datasetit pieniä. Wikipediaa tai näytönohjaimia ei ollut olemassa.
2000-luku
- Word Embeddings. Bengio ja kollegat esittelivät sanavektorit kielimallinnukseen (tai käännöstyöhön). Sanavektori sisältää tietoa kontekstista, kuten sanojen
dogjacatsamankaltaisuudesta. 20
2010-luku
- Word2Vec. Mikolov ja kollegat Googlessa esittelivät Word2Vecin (CBOW ja Skip-Gram), joka mahdollisti erittäin tehokkaan tavan oppia sanavektoreita suurista tekstikorpuksista. Huomaa sana efficient julkaisun otsikossa. Tämä jatkoi Bengion kehitystä. 14
- Kontekstisidonnaiset sanavektorit. Sanavektorit eivät ole enää staattisia, vaan ne riippuvat lauseen kontekstista.
- Subword-tokenisointi. Koko sanan käyttö tokenina on naiivi ratkaisu. Yksittäisen kirjaimen käyttö tokenina sisältää enemmän informaatiota, mutta on epätehokas ratkaisu. Välistä löytynee siis hyvä balanssi? Byte-Pair Encoding (BPE) ja vastaavat menetelmät pyrkivät muodostamaan tokenit dynaamisesti yleisimmistä osasanoista. 21
- Seq2Seq. Sutskever ja kollegat esittelivät encoder-decoder-arkkitehtuurin konekäännökseen, jossa RNN-verkko koodaa syötteen ja toinen RNN dekoodaa sen toiselle kielelle. Enkooderin ja dekooderin välissä on kiinteämittainen vektori, joka pyrkii sisältämään kaiken syötteen merkityksen. 22 Tästä jatketaan tarkemmin RNN ja jälkeläiset-luvussa.
- Attention. Bahdanau ja kollegat esittelivät attention-mekanismin, joka sallii dekooderin keskittyä eri osiin syötettä eri aikoina, parantaen merkittävästi käännösten laatua. 23
- Transformers. Tästä jatketaan tarkemmin Transformers-luvussa.
Tehtävät
Tehtävä: Embeddings
Avaa Marimo Notebook 700_embeddings.py ja tutustu koodiin. Suorita koodi ja tarkastele tuloksia. Kokeile muuttaa sanoja ja nähdä, miten vektorit muuttuvat. Notebookissa muun muassa:
- Vertaillaan sanaparien etäisyyksiä (esim.
sieluvs.teräs) - Tutustutaan 1000 yleisimmän suomenkielisen sanan keskinäisiin etäisyyksiin: mitkä ovat lähimmät ja kaukaisimmat sanat?
- Tarkastellaan 2-ulotteiseen koordinaatistoon projisoituja sanavektoreita (PCA- ja t-SNE-menetelmillä)
Tehtävä: SpaCY Playground
Tämä tehtävä on vapaaehtoinen: tee, jos se auttaa sinua ymmmärtämään konseptit yltä.
Käytä 701_spacy_playground.py-notebookia apuna esimerkiksi yllä olevan tekstin ymmärtämiseen. Voit kopioida ja liittää koodinpätkät ja kokeilla niitä itse. Notebookissa on lähinnä vain import ja mallin lataus valmiina.
Tehtävä: Sanavektorien vertailu
Tämä tehtävä on vapaaehtoinen. Se vaatii suurehkon tiedoston lataamisen netistä, mikä voi olla rajoite joillekin.
Avaa 702_nvidia_pretrained_glove.py-notebook ja tutustu koodiin. Suorita koodi ja tarkastele tuloksia. Tämä on oiva tapa tutustua suurella datalla koulutettuihin sanavektoreihin.
Lähteet
-
Watson, M & Chollet, F. Deep Learning with Python, Third Edition. Manning. 2025. ↩↩↩
-
Turing, A. M. Computing Machinery and Intelligence. Mind. 1950. https://courses.cs.umbc.edu/471/papers/turing.pdf ↩
-
Ammerman, W. The Invisible Brand: Marketing in the Age of Automation, Big Data, and Machine Learning. McGraw-Hill. 2024. ↩↩
-
Jones, C.R. & Benjamin, B. Large Language Models Pass the Turing Test. 2025. https://arxiv.org/abs/2503.23674 ↩
-
Barton, R. & Henry, J. Demystifying Generative AI: A Practical and Intuitive Introduction. Addison-Wesley Professional. 2026. ↩↩↩
-
Lew, G. & Schumacher, R. AI and UX: Why Artificial Intelligence Needs User Experience. Apress. 2020. ↩
-
Unknown. PARRY Encounters the DOCTOR. 1973. https://www.rfc-editor.org/rfc/rfc439.html ↩
-
Rawat, R. et. al. Conversational Artificial Intelligence. Wiley-Scrivener. 2024. ↩
-
Kanabar, V. & Wong, J. The AI Revolution in Project Management: Elevating Productivity with Generative AI*. Pearson. 2023. ↩
-
Williams, B. A Commonsense Approach to Story Understanding. MIT. 2016. https://groups.csail.mit.edu/genesis/papers/2017%20Bryan%20Williams.pdf ↩
-
Raschka, S. Build a Large Language Model (From Scratch). Manning. 2024. ↩↩
-
Akshay and pymde contributors. What is an embedding?. pymde docs. https://pymde.org/getting_started/#what-is-an-embedding ↩
-
Patel, A & Arasanipalai, A. Applied Natural Language Processing in the Enterprise. O'Reilly. 2021. ↩↩↩↩↩↩↩
-
Mikolov, T. et. al. Efficient Estimation of Word Representations in Vector Space. 2013. https://arxiv.org/abs/1301.3781 ↩↩↩↩↩
-
Kulshreshta, R. NLP 101: Word2Vec — Skip-gram and CBOW. Toward Data Science. 2019. https://medium.com/data-science/nlp-101-word2vec-skip-gram-and-cbow-93512ee24314 ↩
-
Bojanowski, P. et. al. Enriching Word Vectors with Subword Information. 2016. https://arxiv.org/pdf/1607.04606 ↩
-
Raieli, S. & Iuculano, G. Building AI Agents with LLMs, RAG, and Knowledge Graphs. Packt. 2025. ↩↩↩
-
Harris, Z. Distributional Structure. Word. 1954. https://www.its.caltech.edu/~matilde/ZelligHarrisDistributionalStructure1954.pdf ↩
-
APA PsycNet. Distributional Structure. PsycINFO Database Record. 2016. https://psycnet.apa.org/record/1956-02807-001 ↩
-
Bengio, Y. et. al. A Neural Probabilistic Language Model. Journal of Machine Learning Research. 2003. https://www.jmlr.org/papers/volume3/bengio03a/bengio03a.pdf ↩
-
Sennrich, R. et. al. Neural Machine Translation of Rare Words with Subword Units. 2016. https://arxiv.org/abs/1508.07909 ↩
-
Sutskever, I. et. al. Sequence to Sequence Learning with Neural Networks. 2014. https://arxiv.org/abs/1409.3215 ↩
-
Bahdanau, D. et. al. Neural Machine Translation by Jointly Learning to Align and Translate. 2015. https://arxiv.org/abs/1409.0473 ↩