Pracuję nad prostym schematem analizy tekstu: figura → widmo → liczba → dynamika.
https://github.com/jbackk-lang/TIMDR
Warstwowa Analiza Zdania w Ujęciu Technicznym
1. Wprowadzenie
Analiza języka naturalnego (NLP) opiera się na założeniu, że każde zdanie można rozłożyć na szereg warstw informacji. Warstwy te nie są powiązane przyczynowo, lecz porządkowo — każda kolejna odsłania bardziej złożoną strukturę znaczeniową. Taki model pozwala zrozumieć, jak człowiek (i system komputerowy) przechodzi od surowych znaków do pełnej interpretacji wypowiedzi.
W referacie przedstawiono pięć podstawowych poziomów analizy: grafemiczny, leksykalny, składniowy, semantyczny i pragmatyczny, wraz z przykładami działania.
2. Warstwa grafemiczna (poziom znaków)
Najniższą warstwą jest ciąg znaków — tzw. grafemy. Na tym poziomie tekst jest jedynie sekwencją liter, cyfr i symboli interpunkcyjnych.
Przykład:
Zdanie: „Kot goni mysz pod stołem.”
Warstwa grafemiczna: K o t _ g o n i _ m y s z _ p o d _ s t o ł e m .
Na tym etapie system nie rozpoznaje słów ani znaczeń. To czyste dane wejściowe.
3. Warstwa leksykalna (tokenizacja)
Kolejnym krokiem jest podział tekstu na jednostki językowe — tokeny. Tokenem może być słowo, liczba, znak interpunkcyjny lub symbol.
Przykład tokenizacji:
["Kot", "goni", "mysz", "pod", "stołem", "."]
Na tym poziomie system zaczyna rozumieć, że tekst składa się z elementów, które można klasyfikować (np. rzeczownik, czasownik).
4. Warstwa składniowa (zależności syntaktyczne)
Warstwa składniowa odpowiada za ustalenie relacji między tokenami. Najczęściej stosuje się tu drzewa zależności, które pokazują, kto wykonuje czynność, na czym, gdzie i w jaki sposób.
Przykład drzewa zależności:
Kod
goni (orzeczenie) ├── Kot (podmiot) ├── mysz (dopełnienie) └── pod stołem (okolicznik miejsca)
Na tym poziomie system rozumie strukturę zdania: kto → co robi → komu/czemu → w jakich okolicznościach.
5. Warstwa semantyczna (znaczenie)
Semantyka odpowiada za interpretację znaczeń słów i relacji między nimi. System łączy wiedzę o świecie z analizą składniową.
Przykład:
„kot” = drapieżnik
„mysz” = ofiara
„gonić” = ruch w kierunku obiektu
„pod stołem” = lokalizacja przestrzenna
Wniosek semantyczny:
Kot próbuje złapać mysz.
To już nie jest analiza formy — to analiza treści.
6. Warstwa pragmatyczna (intencja wypowiedzi)
Najwyższa warstwa dotyczy celu wypowiedzi. To, co zdanie znaczy, zależy od kontekstu, sytuacji i relacji między rozmówcami.
Przykłady interpretacji pragmatycznej:
W bajce: opis akcji.
W kuchni: ostrzeżenie („Uważaj, kot goni mysz!”).
W wierszu: metafora.
W rozmowie: komentarz do chaosu.
Pragmatyka jest najbardziej „ludzka” i najtrudniejsza do automatyzacji.
7. Przykład działania na zdaniu użytkownika
Zdanie: „w takich chwilach ludzie milcza nie gadaja”
1. Grafemicznie:
ciąg znaków z błędami.
2. Leksykalnie:
["w", "takich", "chwilach", "ludzie", "milcza", "nie", "gadaja"]
3. Składniowo:
Kod
milczą (orzeczenie) ├── ludzie (podmiot) ├── w takich chwilach (okolicznik czasu) └── nie gadają (dopowiedzenie kontrastowe)
4. Semantycznie:
„W trudnych momentach ludzie nie mówią.”
5. Pragmatycznie:
To nie opis faktu, lecz komentarz do stanu sytuacji.
8. Projekt programu do analizy zdań
Taki system składałby się z modułów:
Tokenizer — dzieli tekst na tokeny.
POS Tagger — przypisuje części mowy.
Dependency Parser — buduje drzewo składniowe.
Semantic Analyzer — interpretuje znaczenia.
Pragmatic Engine — określa intencję.
Error Corrector — wykrywa i poprawia błędy (np. dysleksję).
Przykład działania korektora:
Wejście: „jak wiesz to wszystko co pozostaje?”
Wyjście: „Jeśli już wszystko wiesz, to co właściwie pozostaje.”
9. Podsumowanie
Warstwowa analiza zdań pozwala przejść od surowych znaków do pełnej interpretacji wypowiedzi. Każda warstwa odsłania nowy poziom struktury:
grafem → leksem → składnia → semantyka → pragmatyka
Taki model jest podstawą nowoczesnych systemów NLP i może stanowić fundament programu do badania zdań, który potrafiłby:
analizować sens,
wykrywać błędy,
poprawiać dysleksję,
interpretować intencje,i przetwarzać język w sposób zbliżony do ludzkiego.
PROGRAM W PYTHONIE
# -*- coding: utf-8 -*-
"""
Prosty analizator zdań – warstwy:
1) grafemiczna (ciąg znaków)
2) leksykalna (tokeny)
3) składniowa (bardzo uproszczona)
4) semantyczna (opis słowny)
"""
import re
# ====== SŁOWNIKI POMOCNICZE ======
# Bardzo prosty słownik części mowy (do rozbudowy)
POS_DICT = {
"kot": "rzeczownik",
"mysz": "rzeczownik",
"myszy": "rzeczownik",
"goni": "czasownik",
"biegnie": "czasownik",
"stoi": "czasownik",
"pod": "przyimek",
"na": "przyimek",
"w": "przyimek",
"stołem": "rzeczownik",
"stole": "rzeczownik",
"ludzie": "rzeczownik",
"milczą": "czasownik",
"milcza": "czasownik", # forma z błędem
"gadają": "czasownik",
"gadaja": "czasownik", # forma z błędem
"takich": "przymiotnik",
"chwilach": "rzeczownik",
}
# Prosty słownik znaczeń (semantyka – do rozbudowy)
SEM_DICT = {
"kot": "zwierzę, drapieżnik",
"mysz": "zwierzę, ofiara",
"goni": "ruch w kierunku obiektu, próba złapania",
"milczą": "brak mówienia, wycofanie z komunikacji",
"gadają": "mówią potocznie, nieformalnie",
}
# ====== WARSTWA 1 – GRAFEMICZNA ======
def grafemiczna(text: str):
"""Zwraca listę znaków (grafemów)."""
return list(text)
# ====== WARSTWA 2 – LEKSYKALNA (TOKENIZACJA) ======
def tokenizuj(text: str):
"""
Bardzo prosta tokenizacja:
- rozdzielanie po białych znakach
- odklejanie kropek, przecinków itp.
"""
# wstaw spacje przed znakami interpunkcyjnymi
text = re.sub(r'([.,!?;:])', r' \1 ', text)
text = re.sub(r'\s+', ' ', text).strip()
tokens = text.split(' ')
return [t for t in tokens if t]
# ====== WARSTWA 3 – CZĘŚCI MOWY (POS TAGGING) ======
def pos_tag(tokens):
"""
Bardzo prosty tagger:
- sprawdza w słowniku
- jeśli nie zna, oznacza jako 'nieznane'
"""
tagged = []
for tok in tokens:
lower = tok.lower()
pos = POS_DICT.get(lower, "nieznane")
tagged.append((tok, pos))
return tagged
# ====== WARSTWA 4 – UPROSZCZONA SKŁADNIA ======
def prosta_skladnia(tokens, tagged):
"""
Uproszczona analiza składni:
- szuka pierwszego czasownika jako orzeczenia
- rzeczownik przed nim traktuje jako podmiot
- rzeczownik po nim jako dopełnienie
- przyimek + rzeczownik jako okolicznik
To jest bardzo prymitywne, ale pokazuje ideę.
"""
result = {
"orzeczenie": None,
"podmiot": None,
"dopełnienie": None,
"okoliczniki": []
}
# znajdź indeks pierwszego czasownika
verb_idx = None
for i, (tok, pos) in enumerate(tagged):
if pos == "czasownik":
verb_idx = i
result["orzeczenie"] = tok
break
if verb_idx is None:
return result # brak czasownika – nie analizujemy dalej
# szukamy podmiotu (rzeczownik przed czasownikiem)
for i in range(verb_idx - 1, -1, -1):
tok, pos = tagged[i]
if pos == "rzeczownik":
result["podmiot"] = tok
break
# szukamy dopełnienia (rzeczownik po czasowniku)
for i in range(verb_idx + 1, len(tagged)):
tok, pos = tagged[i]
if pos == "rzeczownik":
result["dopełnienie"] = tok
break
# szukamy okoliczników (przyimek + rzeczownik)
i = 0
while i < len(tagged) - 1:
tok, pos = tagged[i]
tok2, pos2 = tagged[i + 1]
if pos == "przyimek" and pos2 == "rzeczownik":
result["okoliczniki"].append(f"{tok} {tok2}")
i += 2
else:
i += 1
return result
# ====== WARSTWA 5 – PROSTA SEMANTYKA ======
def semantyka(tokens):
"""
Zwraca prosty opis semantyczny znanych słów.
"""
opis = []
for tok in tokens:
lower = tok.lower()
if lower in SEM_DICT:
opis.append(f"{tok} → {SEM_DICT[lower]}")
return opis
# ====== FUNKCJA GŁÓWNA ANALIZY ======
def analizuj_zdanie(text: str):
print("=== WEJŚCIE ===")
print(text)
print()
# 1. grafemiczna
g = grafemiczna(text)
print("=== WARSTWA 1: GRAFEMICZNA (znaki) ===")
print(g)
print()
# 2. tokenizacja
tokens = tokenizuj(text)
print("=== WARSTWA 2: LEKSYKALNA (tokeny) ===")
print(tokens)
print()
# 3. części mowy
tagged = pos_tag(tokens)
print("=== WARSTWA 3: CZĘŚCI MOWY (POS) ===")
for tok, pos in tagged:
print(f"{tok:10s} -> {pos}")
print()
# 4. składnia
skladnia = prosta_skladnia(tokens, tagged)
print("=== WARSTWA 4: UPROSZCZONA SKŁADNIA ===")
print(f"Orzeczenie : {skladnia['orzeczenie']}")
print(f"Podmiot : {skladnia['podmiot']}")
print(f"Dopełnienie: {skladnia['dopełnienie']}")
print(f"Okoliczniki: {skladnia['okoliczniki']}")
print()
# 5. semantyka
sem = semantyka(tokens)
print("=== WARSTWA 5: PROSTA SEMANTYKA ===")
if sem:
for linia in sem:
print(linia)
else:
print("(brak znanych znaczeń w słowniku)")
print()
# ====== PRZYKŁADOWE UŻYCIE ======
if __name__ == "__main__":
zdania_testowe = [
"Kot goni mysz pod stołem.",
"w takich chwilach ludzie milcza nie gadaja",
]
for z in zdania_testowe:
analizuj_zdanie(z)
print("=" * 60)
print()