AKADEMIA GÓRNICZO-HUTNICZA Wydział Elektrotechniki, Automatyki, Informatyki i Elektroniki

Podobne dokumenty
System Korekty Tekstu Polskiego

System Korekty Tekstu Polskiego

Nr Tytuł Przykład Str.

Części mowy - powtórzenie

Gramatyka. języka rosyjskiego z ćwiczeniami

Spis treści 5. Spis treści. Przedmowa Przedmowa do wydania II Część pierwsza MORFOLOGIA

NaCoBeZu na co będę zwracać uwagę. Nauka o języku

SPIS TREŚCI. Spis treści Wstęp Wykaz skrótów, symboli i terminów gramatycznych MIANOWNIK

SPIS TREŚCI WSTĘP... 11

4. Postęp arytmetyczny i geometryczny. Wartość bezwzględna, potęgowanie i pierwiastkowanie liczb rzeczywistych.

KRYTERIA OCEN Z JĘZYKA POLSKIEGO W KLASIE V

Tydzień 8 Podręcznik Zeszyt Ćwiczeń Funkcje Językowe Gramatyka Pisanie Poniedziałek Zeszyt Ćwiczeń Co lubisz robić? Czym się interesujesz?

43. Narzędnik Liczba mnoga

Zakres kształcenia językowego poziomy wymagań: podstawowy i ponadpodstawowy

KRYTERIA WYMAGAŃ EDUKACYJNYCH NA POSZCZEGÓLNE OCENY Z JĘZYKA FRANCUSKIEGO

WYMAGANIA EDUKACYJNE Z JĘZYKA FRANCUSKIEGO W TRZYLETNIM CYKLU KSZTAŁCENIA

Lekcja V I.3.7 I.3.8 I.3.9

5. WORD W POLSKIEJ WERSJI

Wymagania edukacyjne z języka polskiego w klasie VI Szkoły Podstawowej nr 1 im. Jana Pawła II w Czerwionce - Leszczynach

CZYTANIE CICHE ZE ZROZUMIENIEM

CZĘŚCI MOWY (Partes orationis) podstawowe kategorie wyrazów w języku

3a. Wstęp: Elementarne równania i nierówności

Kryteria oceniania z języka polskiego KLASA V

KRYTERIA OCEN Z JĘZYKA POLSKIEGO W KLASIE V

Zawartość. Wstęp. Moduł Rozbiórki. Wstęp Instalacja Konfiguracja Uruchomienie i praca z raportem... 6

KRYTERIA WYMAGAŃ EDUKACYJNYCH NA POSZCZEGÓLNE OCENY Z JĘZYKA FRANCUSKIEGO

operacje porównania, a jeśli jest to konieczne ze względu na złe uporządkowanie porównywanych liczb zmieniamy ich kolejność, czyli przestawiamy je.

Podstawy pracy z edytorem tekstu. na przykładzie Open Office

4. Zaimek wskazujący Zaimek względny Zaimek pytający Zaimek nieokreślony 55

WYMAGANIA EDUKACYJNE Z JĘZYKA POLSKIEGO KL. VI

Evolution plus 1 PLAN WYNIKOWY UNIT 1. Środki językowe. Umiejętności językowe wg NPP. Macmillan Polska 2014

Lokalizacja Oprogramowania

Lingwistyczny system definicyjny wykorzystujący korpusy tekstów oraz zasoby internetowe.

Niko 2 Przedmiotowy System Oceniania

Przekształcanie wykresów.

Urządzenia Techniki. Klasa I TI. System dwójkowy (binarny) -> BIN. Przykład zamiany liczby dziesiętnej na binarną (DEC -> BIN):

Maciej Piotr Jankowski

JĘZYK POLSKI WYMAGANIA EDUKACYJNE KLASA V

znalezienia elementu w zbiorze, gdy w nim jest; dołączenia nowego elementu w odpowiednie miejsce, aby zbiór pozostał nadal uporządkowany.

BUDOWA ZDANIA POJEDYNCZEGO

WYMAGANIA Z JĘZYKA NIEMIECKIEGO NA POSZCZEGÓLNE OCENY DLA KLASY I GIMNAZJUM /klasa Ia/ Wymagania zostały opracowane zgodnie z nową postawą programową

EGZAMIN W KLASIE TRZECIEJ GIMNAZJUM W ROKU SZKOLNYM 2018/2019

Załącznik nr 2 Wymagania programowe w klasie V

Wymagania edukacyjne na poszczególne oceny śródroczne z języka polskiego dla klasy VI

W jakim stopniu uczniowie opanowali umiejętność Wykorzystywania wiedzy w praktyce? Analiza zadań otwartych z arkusza Sprawdzian 2012

FUNKCJA LINIOWA - WYKRES

Przygotowanie materiału uczącego dla OCR w oparciu o aplikację Wycinanki.

gramatyka na 6+ liczebnik, spójnik, zaimek

Instrukcje dla zawodników

KRYTERIA OCENY ROCZNEJ Z JĘZYKA POLSKIEGO W KLASIE V

SPIS TREŚCI SPIS TREŚCI 1. WYMOWA NORWESKA 10

KRYTERIA WYMAGAŃ EDUKACYJNYCH NA POSZCZEGÓLNE OCENY Z JĘZYKA FRANCUSKIEGO

Przykłady zastosowań funkcji tekstowych w arkuszu kalkulacyjnym

Szkoła Podstawowa Nr 45 z Oddziałami Integracyjnymi im. Jana Pawła II w Białymstoku Przedmiotowy system oceniania JĘZYK ANGIELSKI

Sortowanie zewnętrzne

Kryteria oceniania z języka polskiego KLASA VI

SPRAWDZIAN W KLASIE VI SZKOŁY PODSTAWOWEJ W ROKU SZKOLNYM 2015/2016

EGZAMIN W KLASIE TRZECIEJ GIMNAZJUM W ROKU SZKOLNYM 2018/2019

SPIS TREŚCI

Języki programowania zasady ich tworzenia

Algorytmy i złożoności Wykład 5. Haszowanie (hashowanie, mieszanie)

Materiały dla finalistów

Klasyfikacja tradycyjna Klasyfikacja Zygmunta Saloniego Przykład analizy. Części mowy. Anna Kozłowska. Uniwersytet Kardynała Stefana Wyszyńskiego

- przyimek - spójnik - partykuła

Przedmiotowy System Oceniania z języka angielskiego

Następnie przypominamy (dla części studentów wprowadzamy) podstawowe pojęcia opisujące funkcje na poziomie rysunków i objaśnień.

NaCoBeZu na co będę zwracać uwagę. Wymagania do cyklu lekcji dotyczących składni

0 + 0 = 0, = 1, = 1, = 0.

EGZAMIN W KLASIE TRZECIEJ GIMNAZJUM W ROKU SZKOLNYM 2016/2017

Systemy liczbowe używane w technice komputerowej

PRZECZĄCYM 44 ROZKAZUJĄCYM ZAIMEK PRZYMIOTNY WSKAZUJĄCY (L'ADJECTIF DÉMONSTRATIF) 47 5

Wstęp do Informatyki zadania ze złożoności obliczeniowej z rozwiązaniami

WYMAGANIA EDUKACYJNE Z JĘZYKA POLSKIEGO DLA UCZNIÓW KLASY VI NA POSZCZEGÓLNE OCENY I OKRES OCENA CELUJĄCA

EGZAMIN W KLASIE TRZECIEJ GIMNAZJUM W ROKU SZKOLNYM 2016/2017

Budowa zdania pojedynczego BUDOWA ZDANIA POJEDYNCZEGO

2 Arytmetyka. d r 2 r + d r 1 2 r 1...d d 0 2 0,

Krój czcionki można wybrać na wstążce w zakładce Narzędzia główne w grupie przycisków Cz cionka.

EGZAMIN W KLASIE TRZECIEJ GIMNAZJUM W ROKU SZKOLNYM 2014/2015

KOŃCZĄCY KLASĘ SZÓSTĄ

Nazwa implementacji: Nauka języka Python wyrażenia warunkowe. Autor: Piotr Fiorek. Opis implementacji: Poznanie wyrażeń warunkowych if elif - else.

FUNKCJA LINIOWA - WYKRES. y = ax + b. a i b to współczynniki funkcji, które mają wartości liczbowe

Metoda Karnaugh. B A BC A

5.4. Tworzymy formularze

Polcode Code Contest PHP-10.09

KRYTERIA OCEN Z JĘZYKA POLSKIEGO W KLASIE IV

1 Układy równań liniowych

Elementy modelowania matematycznego

WYMAGANIA EDUKACYJNE Z JĘZYKA ANGIELSKIEGO KLASA IV. ocena

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania

Fleksja powtórzenie wiadomości

Szukanie rozwiązań funkcji uwikłanych (równań nieliniowych)

System oceniania z j. niemieckiego dla klasy I gimnazjum

Wymagania edukacyjne na poszczególne oceny w klasie 5 Teraz polski!

Praca Magisterska. Automatyczna kontekstowa korekta tekstów na podstawie Grafu Przyzwyczajeń. internetowego dla języka polskiego

(Przy rozwiązywaniu testu (28 pytań) masz prawo wykorzystać wszystkie dostępne aplikacje na Twoim komputerze), dostęp do Internetu jest zabroniony.

Księgarnia PWN: Albina Gołubiewa, Magdalena Kuratczyk - Gramatyka języka rosyjskiego z ćwiczeniami. Przedmowa CZASOWNIKI ( )

Programowanie celowe #1

Wydawnictwo Draco Plan wynikowy przygotowany na podstawie podręcznika C est parti 1 1

TABULATORY - DOKUMENTY BIUROWE

Transkrypt:

AKADEMIA GÓRNICZO-HUTNICZA Wydział Elektrotechniki, Automatyki, Informatyki i Elektroniki KATEDRA INFORMATYKI PRACA DYPLOMOWA MAGISTERSKA autor: promotor: Grzegorz Szuba dr inż. Marek Gajęcki Kraków 2008

Streszczenie W pracy przedstawiono problem korekty tekstu w języku polskim. Głównymi elementami wykonanego systemu są: zastosowanie metod rozpoznających kontekst wyrazu do wyboru poprawnego słowa; rozpoznawanie tematu tekstu w celu lepszego wyboru proponowanych słów; badanie czy proponowane słowa spełniają wybrane reguły gramatyki języka polskiego; cechą systemu jest jego dostosowanie do specyfiki języka a w szczególności uwzględnieniu rozszerzonego alfabetu oraz zjawiska błędów ortograficznych. W ramach pracy przeprowadzono badania skuteczności zrealizowanych metod osobno oraz jednocześnie, a także porównano uzyskane wyniki z innymi dostępnymi na rynku programami korygującymi tekst. 2/83

Spis treści 1. Wstęp...6 2. Metody inżynierii lingwistycznej...8 2.1. Odległość edycyjna...8 2.2. Prawo Zipfa...9 2.3. N-gramy...10 2.3.1. Prawdopodobieństwo warunkowe...10 2.3.2. Idealny model języka...10 3. Zagadnienia gramatyki języka polskiego...12 3.1. Fleksja...12 3.1.1. Czasowniki...12 3.1.2. Rzeczowniki...12 3.1.3. Przymiotniki...13 3.1.4. Liczebniki...13 3.1.5. Zaimki...14 3.1.6. Przysłówki...14 3.1.7. Przyimki...14 3.1.8. Spójniki...14 3.1.9. Wykrzykniki...14 3.1.10. Partykuły...15 3.2. Składnia...15 3.2.1. Podmiot...15 3.2.2. Orzeczenie...15 3.2.3. Dopełnienie...15 3.2.4. Przydawka...16 3.2.5. Okolicznik...16 3.3. Związki w zdaniu...17 3.3.1. Związek zgody...17 3.3.2. Związek rządu...17 3.3.3. Związek przynależności...18 3.3.4. Związki frazeologiczne...18 4. Opis algorytmu bezkontekstowego...19 4.1. Rodzaje błędów poprawiane przez algorytm...19 4.1.1. Brak polskiego znaku diakrytycznego przy literze...19 4.1.2. Błąd ortograficzny...20 4.1.3. Nadmiarowy znak diakrytyczny...20 4.1.4. Zamiana miejscami dwóch sąsiadujących liter...20 4.1.5. Nadmiarowa dowolna litera...20 4.1.6. Dowolna litera zamieniona na inną...21 4.1.6.1. Środkowe...21 4.1.7. Brak dowolnej litery...22 4.2. Stopień...22 4.3. Magazynowanie wyników...23 4.4. Słowa przypadkowo sklejone lub podzielone...24 4.4.1. Podział słowa na dwa...24 3/83

4.4.2. Sklejenie dwóch sąsiednich słów...24 4.4.3. Sklejenie więcej niż dwóch wyrazów lub podział na więcej niż dwa wyrazy...24 5. Opis algorytmu kontekstowego...26 5.1. Analiza częstości występowania pojedynczego wyrazu...26 5.1.1. Zebrane dane...27 5.1.2. Wpływ na wagi słów...27 5.2. Analiza częstości występowania dwóch wyrazów obok siebie (niezależnie od formy)...28 5.2.1. Zebrane dane...28 5.2.2. Wpływ na wagi słów...30 5.3. Analiza częstości występowania dwóch wyrazów obok siebie (z uwzględnieniem formy)...30 5.3.1. Zebrane dane...31 5.3.2. Wpływ na wagi słów...33 5.4. Analiza częstości występowania dwóch wyrazów w tym samym zdaniu...33 5.4.1. Zebrane dane...33 5.4.2. Wpływ na wagi słów...35 5.5. Analiza tematu tekstu...35 5.5.1. Wpływ na wagi słów...36 5.6. Analiza gramatyczna...36 5.6.1. Związek zgody...37 5.6.2. Wyrażenia przyimkowe...37 5.6.3. Wpływ na wagę słów...40 5.7. Podsumowanie metod...41 6. Testy algorytmu...42 6.1. Teksty źródłowe użyte do testowania algorytmu...42 6.1.1. Teksty z forum Onetu...42 6.1.2. Teksty z grup dyskusyjnych Usenetu...43 6.1.3. Rozmowy z komunikatora Gadu-Gadu...43 6.1.4. Zeskanowane teksty...44 6.1.5. Teksty wpisywane z klawiatury...45 6.1.6. Tekst bez polskich ogonków...46 6.1.7. Tekst z Gazety Wyborczej...46 6.1.8. Podsumowanie danych testowych...47 6.2. Porównanie stopni algorytmu...47 6.2.1. Wynik porównania...47 6.2.2. Wnioski z porównania...49 6.3. Porównanie z innymi programami...49 6.3.1. Wynik porównania...50 6.3.2. Wnioski z porównania...51 6.3.2.1. Ispell...51 6.3.2.2. Google Docs (Writely)...52 6.3.2.3. Word...54 6.3.2.4. Aspell...55 6.3.2.5. Podsumowanie...58 6.4. Porównanie różnych metod kontekstowych...59 6.4.1. Analiza tematu tekstu...64 4/83

6.4.2. Analiza gramatyczna...66 6.4.3. Analiza częstotliwościowa...68 6.4.4. Analiza par słów występujących jednocześnie w zdaniu...69 6.4.5. Analiza podstawowych form par sąsiadujących słów...70 6.4.6. Analiza par sąsiadujących słów z podziałem na formy słów...71 7. Algorytm w wersji dla języka hiszpańskiego...73 7.1. Algorytm bezkontekstowy...73 7.1.1. Znaki diakrytyczne...73 7.1.2. Błędy ortograficzne...73 7.2. Algorytm kontekstowy...74 7.3. Testy algorytmu...74 7.4. Porównanie wyników testów z wynikami algorytmu dla języka polskiego...76 8. Wnioski i propozycje kierunków dalszego rozwoju...77 8.1. Algorytm bezkontekstowy...77 8.1.1. Większa ilość predefiniowanych błędów ortograficznych...77 8.1.2. Wersja dla tekstów skanowanych...77 8.1.3. Dokładniejsze wagi błędów...78 8.2. Algorytm kontekstowy...78 8.2.1. Metoda gramatyczna...78 8.2.2. Rozpoznawanie tematu tekstu...78 8.2.3. Metody oparte na częstotliwości występowania słów i par słów w języku...78 9. Bibliografia...80 10. Spis tabel, wykresów i wzorów...82 10.1. Spis tabel...82 10.2. Spis wykresów...83 10.3. Spis wzorów...83 5/83

1. Wstęp Wraz z rozwojem komputerów, coraz więcej tekstów tworzonych jest nie ręcznie, ale maszynowo, przy pomocy klawiatury lub innych metod, na przykład skanowania. Posiadanie zapisu tekstu w postaci cyfrowej umożliwia stosowanie programów, których zadaniem jest odnajdowanie i korygowanie różnego rodzaju błędów. Możliwość ta jest o tyle cenniejsza, że równolegle z popularyzacją internetu, w społeczeństwie maleje umiejętność pisania w pełni poprawnie gramatycznie. Wpływ na to mają: niedbałość związana z pośpiechem przy pisaniu, związane (szczególnie dawniej) z problemami z konfiguracją programów pisanie bez polskich znaków diakrytycznych, swoista wśród pewnej grupy użytkowników moda na pisanie z premedytacją z błędami oraz wynikające z poprzedniego przywyknięcie do błędnych form wyrazów nawet wśród osób, które starają się pisać poprawnie. Wadą istniejących obecnie na rynku popularnych programów pozwalających na korektę błędów w pisowni, takich jak Microsoft Office, OpenOffice lub Aspell, jest to, że poprawiają one błędy traktując każdy wyraz osobno, nie patrząc na kontekst gramatyczny i znaczeniowy, w którym wyraz się znajduje. Dodatkowo część z nich jest algorytmami stworzonymi dla języka angielskiego z podmienionym tylko słownikiem zawierającym polskie wyrazy; inne mimo przeprowadzenia lokalizacji, nie radzą sobie poprawnie z charakterystycznymi dla języka polskiego błędami. Błędy w pisowni można podzielić na dwa rodzaje takie w wyniku których powstaje nieprawidłowe w danym języku słowo oraz takie, których efektem jest inny wyraz poprawny słownikowo (choć najczęściej niepoprawny w danym kontekście). Istniejące popularne programy z powodu tego, że poprawiają błędy w sposób bezkontekstowy, każdy wyraz istniejący w słowniku z założenia traktują jako prawidłowy, przez co w ogóle nie wychwytują drugiego rodzaju wymienionych wyżej błędów i zajmują się tylko pierwszym rodzajem błędów. Spośród istniejących na rynku programów, z wyżej wymienionymi wadami usiłuje sobie poradzić jedynie najnowsza wersja pakietu Microsoft Office z 2007 roku, przy pomocy testowego modułu gramatycznego, dostępnego tylko dla języków angielskiego, niemieckiego, hiszpańskiego i francuskiego [18]. Jednak nawet wśród użytkowników tych języków świadomość istnienia takiej możliwości jest niewielka, dlatego, że moduł wymaga przynajmniej 1 GB wolnej pamięci RAM i z tego powodu nie jest domyślnie aktywny. Celem powstania tej pracy było stworzenie systemu korekty tekstu polskiego. Zaproponowane rozwiązanie uwzględnia w algorytmie charakterystyczne cechy języka polskiego a w szczególności jego alfabet, zjawisko błędów ortograficznych i fleksyjność. W pracy przedstawiono badania wpływu na skuteczność znajdowania poprawnych wyrazów uwzględnienia rozwiązania obu wyżej wymienionych kwestii to jest badania kontekstu, zarówno syntaktycznego jak i semantycznego, w jakim znajdują się wyrazy oraz zbadania, czy możliwe jest wychwytywanie w tekście błędów w wyniku których powstają nowe, poprawne słownikowo słowa. Stworzony system będzie pierwszym na rynku polskim programem potrafiącym skutecznie radzić sobie z tego rodzaju problemami. Dodatkowym elementem pracy jest przeprowadzenie badań alternatywnych metod korekty tekstu. Metoda pierwsza oparta będzie na próbie rozpoznawania tematu tekstu. Metoda druga zajmie się analizą wybranych reguł gramatyki języka polskiego. W pierwszych rozdziałach pracy przedstawiono kilka zagadnień związanych z metodami inżynierii lingwistycznej, oraz przedstawię podstawowe zagadnienia gramatyki języka polskiego aby stworzyć teoretyczną bazę do dalszych rozważań. 6/83

W następnych rozdziałach omówiono stworzony algorytm bezkontekstowy oraz sześć różnych metod opierających się na uwzględnieniu kontekstu wyrazów. Aby poprawnie ocenić skuteczność stworzonego algorytmu niezależnie od stopnia trudności tekstu, wyniki przeprowadzonych testów zostaną skonfrontowane z wynikami osiągniętymi na tych samych tekstach źródłowych przez inne wiodące na rynku systemy korekty tekstu. Rezultaty i wnioski z testów zostaną przedstawione w rozdziale 6. Dodatkowo, w rozdziale 7, zaprezentowane zostanie rozszerzenie pracy, jakim jest przedstawienie na przykładzie języka hiszpańskiego, jak można dostosować algorytm do specyfiki innych języków oraz jak wygląda skuteczność opisywanych metod, jeśli się je zastosuje w trochę innych warunkach. Na końcu tej pracy przedstawiono podsumowanie stworzonych metod wraz z propozycjami dalszych kierunków rozwoju stworzonego systemu. 7/83

2. Metody inżynierii lingwistycznej 2.1. Odległość edycyjna W algorytmach poprawiających błędy cześć metod narzuca konieczność posiadania miary odmienności dwóch ciągów wyrazów, dzięki której można określać, które wyrazy i w jakim stopniu są podobne do analizowanego słowa. Najprostszą miarą jest wprowadzona przez Richarda Hamminga w 1950 roku odległość Hamminga, będąca miarą odmienności dwóch ciągów znaków o tej samej długości. Miara ta wyrażała, na ilu pozycjach należy dokonać zamiany znaku na inny, aby przeprowadzić jeden ciąg w drugi. Na potrzeby korekty tekstu ta miara jest jednak mało użyteczna, gdyż uwzględnia tylko jeden rodzaj możliwego do popełnienia błędu zamiany znaku na inny. Uogólnieniem tej metody jest zaproponowana przez Vladimira Levenshteina w 1965 roku odległość Levenshteina [8]. Metryka ta zdefiniowana jest jako najmniejsza liczba operacji prostych koniecznych do wykonania, aby zamienić jeden ciąg znaków w drugi. Działaniami prostymi są: zamiana znaku na inny (tak samo jak w odległości Hamminga), usunięcie znaku oraz wstawienie znaku. Dzięki temu uogólnieniu możliwe jest porównywanie dwóch ciągów znaków o różnej długości. Powyższa metryka ma jednak jedną poważną wadę, nie uwzględnia bowiem operacji polegającej na zamianie dwóch znaków miejscami. Dlatego pojawiło się rozszerzenie miary Levenshteina, nazwane odległością Damerau-Levenshteina, które uwzględnia te cztery podstawowe operacje edycyjne. Damerau w swojej pracy [4] twierdzi, że 80% popełnianych przez człowieka błędów znajduje się w odległości jednej jednostki edycyjnej od oryginalnego słowa według powyższej miary. Odległość Damerau-Levenshteina nie jest jednak idealną miarą. Po pierwsze traktuje słowa jako ciągi nieokreślonych znaków a nie jako zapis fonemów języka mówionego. Powoduje to, że słowa, które w języku mówionym różnią się nieznacznie lub wręcz są identyczne (jak na przykład morze i może ), traktowane są jak słowa znacząco różne, w podanym przykładzie posiadające odległość edycyjną równą dwóm jednostkom (usunięcie litery r i zamiana litery z na ż ). Drugim mankamentem jest traktowanie każdej z czterech podstawowych operacji jako możliwej do wystąpienia z równym prawdopodobieństwem. Potrzeba rozróżnienia pojawia się nie tylko pomiędzy różnymi operacjami, ale także w ramach jednej operacji, gdyż na przykład dla operacji zamiany litery na inną, odmiennie należy traktować zamianę na literę o podobnym kształcie (dla tekstów skanowanych) czy na literę znajdującą się blisko na klawiaturze (dla tekstów pisanych komputerowo) a odmiennie zamianę na literę całkowicie różną. Dodatkowo należałoby uwzględnić litery charakterystyczne dla danego języka, na których operacje także mogą wymagać odmiennego traktowania. Aby poszukiwać w słowniku słów najbardziej podobnych do szukanego wyrazu, można zastosować metodę polegającą na przeglądnięciu wszystkich poprawnych wyrazów w słowniku i dla każdego słowa wyznaczeniu jego odległości edycyjnej od badanego wyrazu a następnie podanie tych wyrazów, których odległość jest najmniejsza. Drugą metodą jest wykonywanie symulacji popełnionego błędu w odwrotną stronę to znaczy poszukiwanie wyrazów, dla których popełnienie zadanego błędu daje w rezultacie badane słowo. W tej metodzie wykonujemy operacje odwrotne (to znaczy na przykład dla operacji usunięcia litery operacją odwrotną jest dodanie litery, dla operacji 8/83

zamiany liter, operacja odwrotna jest tą samą operacją) i następnie sprawdzamy, czy dane słowo występuje w słowniku. Jeśli chcemy wyszukiwać wyrazy o odległości edycyjnej większej od jeden, musimy wykonać odpowiednio większą ilość operacji odwrotnych. W przypadku pierwszej metody należy pamiętać, że w słowniku języka polskiego znajduje się około 120 tysięcy wyrazów, a z uwzględnieniem wszystkich ich form, 1,2 miliona słów. Wyznaczenie odległości edycyjnej do każdego z nich zajmuje sporo czasu w porównaniu z metodą drugą (dla wyrazów o odległości edycyjnej mniejszej bądź równej dwa), metoda pierwsza działa wolniej. Ponieważ druga metoda jest także łatwiejsza do zastosowania, jeśli chce się uwzględnić poprawki na obie wady metryki Damerau-Levenshteina, dlatego postanowiłem zastosować ją w moim algorytmie. 2.2. Prawo Zipfa Metody statystyczne stają się niezbędne przy analizie języka w sytuacji gdy nie potrafimy przy pomocy gramatyk formalnych stworzyć wzoru na wyłącznie poprawne zdania języka naturalnego. Metody te, choć niedokładne, w większości przypadków są zgodne z tym, co opisują. Podstawowym prawem rządzącym metodami statystycznymi jest zasada Pareto, zwana też zasadą 80/20 na przykład 80% tekstu stanowią słowa składające się na 20% słownika. Zasada ta w lingwistyce została dokładniej przedstawiona przez George'a Kingsley'a Zipfa i nazwana później jego nazwiskiem [16]. Zasada ta mówi, że jeśli w policzymy jak często każde słowo występuje w odpowiednio dużym korpusie tekstów danego języka, a następnie posortujemy słowa malejąco względem częstości, możemy zauważyć, że częstość słowa jest odwrotnie proporcjonalna do jego pozycji w rankingu, innymi słowy, istnieje stała k, taka, że: częstość słowa pozycja na liście=k Wzór 1: Prawo Zipfa Fragment rankingu dla korpusu tekstów języka polskiego zawiera tabela 5 na stronie 27. Na jej podstawie utworzono poniższy wykres, ilustrujący prawo Zipfa. Wykres przedstawia zależność między pozycją w rankingu przedstawioną na osi X a częstością przedstawioną na osi Y, używając skali logarytmicznej. Punkty odpowiadają rankingowi i częstości słów z korpusu języka polskiego, linia przedstawia teoretyczną zależność między rankingiem a częstością wyliczoną na podstawie prawa Zipfa dla stałej k = 2 23 (patrz wzór 1): 9/83

1000000 100000 częstotliw ość 10000 1000 100 10 1 1 10 100 1000 10000 100000 1000000 pozycja w rankingu Wykres 1: Prawo Zipfa Z powodu ograniczenia narzędzia służącego do stworzenia wykresu (OpenOffice Calc), zostało uwzględnione tylko 65536 najczęściej występujących słów, co oznaczało pominięcie słów o częstości mniejszej niż 5. 2.3. N-gramy N-gram to sekwencja n elementów z danego ciągu. Elementami mogą być litery lub słowa. N-gram o rozmiarze jednego elementu nazywany jest unigramem, o rozmiarze dwóch elementów bigramem a o rozmiarze trzech elementów trigramem. Model n-gramów jest używany do przetwarzaniu języka naturalnego przy użyciu metod statystycznych. Model ten ilustruje pytanie: mając dany ciąg liter/słów, jakie jest prawdopodobieństwo następnego elementu? Na podstawie danych treningowych można otrzymać rozkład prawdopodobieństwa następnych elementów dla danego ciągu n-elementowego. 2.3.1. Prawdopodobieństwo warunkowe Z definicji prawdopodobieństwa warunkowego: P A B = P A B P B Wzór 2: Prawdopodobieństwo warunkowe 2.3.2. Idealny model języka Przyjmijmy notację W=(w 1, w 2, w 3,..., w d ), gdzie w 1, w 2,..., w d oznaczają poszczególne słowa a W oznacza stworzoną przez nie sekwencję. Zadajemy sobie pytanie, jakie jest 10/83

prawdopodobieństwo wystąpienia tej sekwencji, to znaczy ile wynosi P(W)? Dla dwóch wyrazów, A i B, korzystając ze wzoru 2 możemy wyliczyć: P w 1, w 2 = P w 1 P w 2 w 3 Wzór 3: Prawdopodobieństwo wystąpienia sekwencji dwóch wyrazów A następnie możemy uogólnić ten wzór na d składników: P W = P w 1, w 2,..., w d =P w 1 P w 2 w 1 P w 3 w 1, w 2... P w d w 1, w 2,..., w d 1 Wzór 4: Prawdopodobieństwo wystąpienia sekwencji d składników Powyższy wzór nie jest praktyczny, ponieważ zawiera zbyt dużo parametrów i przez to jego obliczanie jest kosztowne. Uproszczeniem tej metody jest ograniczenie się do tylko k poprzedników danego wyrazu, metoda ta zwana jest aproksymacją Markowa k-tego rzędu. W zależności od ilości poprzedników są to: aproksymacja 0-rzędu, powodująca powstanie 1-gramów (unigramów) aproksymacja 1-rzędu, powodująca powstanie 2-gramów (bigramów) aproksymacja 2-rzędu, powodująca powstanie 3-gramów (trigramów) Unigramy w wersji dla wyrazów zastosowano w metodzie opisanej w rozdziale 5.1, bigramy w metodach opisanych w rozdziałach 5.2, 5.3 i 5.4, natomiast trigramy (w przekształconej formie) zastosowałem dla pojedynczych liter w wyrazie w metodzie opisanej w paragrafie 4.1.6.1. 11/83

3. Zagadnienia gramatyki języka polskiego W mojej pracy będę często odwoływał się do pojęć z zakresu gramatyki, dlatego poniżej przedstawiam szereg przydatnych do zrozumienia problemu definicji: 3.1. Fleksja Części mowy dzielimy na odmienne i nieodmienne. Do tych pierwszych zaliczają się czasowniki, rzeczowniki, przymiotniki, liczebniki oraz zaimki rzeczowne, przymiotne i liczebne. Do tych drugich należą przysłówki, zaimki przysłowne, przyimki, spójniki, wykrzykniki i partykuły. Części mowy możemy także podzielić na samodzielne i niesamodzielne. Samodzielnymi są rzeczowniki, przymiotniki, liczebniki, czasowniki, zaimki, przysłówki i wykrzykniki. Niesamodzielne są przyimki, spójniki i partykuły. 3.1.1. Czasowniki Czasowniki to części mowy które odpowiadają na pytanie co robi?, co się z nim dzieje?, w jakim jest stanie?. Czasowniki odmieniają się przez osoby ( ja piszę, ty piszesz, on/ona/ono pisze ), przez liczby (pojedynczą ja piszę i mnogą my piszemy ), przez czasy (teraźniejszy piszę, przeszły pisałem i przyszły napiszę / będę pisał ), przez tryby (tryb orzekający ty rysujesz, tryb rozkazujący rysuj!, tryb przypuszczający ty rysowałbyś / ty rysowałabyś ) i przez strony (strona czynna ubiera, strona bierna jest ubierany, strona zwrotna ubiera się ). Stronę bierną posiadają tylko czasowniki przechodnie ( budować, robić itp.), czasowniki nieprzechodnie formy strony biernej nie posiadają (np. leżeć, wisieć ). Odmianę czasownika przez osoby, liczby, czasy, tryby i strony nazywamy koniugacją. W liczbie pojedynczej czasownik może wystąpić w trzech rodzajach: męskim ( on pisał ), żeńskim ( ona pisała ) i nijakim ( ono pisało ), a w liczbie mnogiej w dwóch: męskoosobowym ( oni pisali ) i niemęskoosobowym ( one pisały ). Czasowniki dzielimy także na niedokonane ( robiłem, robię, będę robił ) oraz dokonane ( zrobiłem, zrobię ). Te drugie nie występują w czasie teraźniejszym. Czasowniki występują w formach osobowych czyli takich jak przedstawione powyżej, które odmieniają się przez osoby, liczby, czasy tryby i strony. Oprócz tego występują formy nieosobowe: bezokolicznik ( czytać, jeść ), formy zakończone na -no, -to ( zrobiono, odkryto ) oraz imiesłowy. Imiesłowy mogą być przymiotnikowe: czynne ( myślący, dotykający ) oraz bierne ( odkryty, widziany ), albo przysłówkowe: współczesne ( rysując, niosąc ) oraz uprzednie ( zjadłszy, zobaczywszy ). 3.1.2. Rzeczowniki Rzeczowniki to części mowy, które odpowiadają na pytanie kto?, co?. Rzeczownik jest odmienną częścią mowy, odmienia się przez przypadki i osoby (pojedynczą i mnogą). Odmiana przez przypadki nazywa się deklinacja. Rzeczownik w liczbie pojedynczej może wystąpić w jednym z trzech rodzajów: męskim ( ten samochód ), żeńskim ( ta rzeka ) lub nijakim ( to okno ). W liczbie mnogiej rodzaje są dwa: męskoosobowy ( ci żeglarze ) i niemęskoosobowy ( te samochody ). Dodatkowo wprowadza się dwa podziały: na rzeczowniki własne ( Poznań, Jan, 12/83

Wenus ) i pospolite ( pies, wieś, parapet ), oraz na rzeczowniki żywotne ( kot, chłopiec, lew ) i nieżywotne ( dywan, chmura, kaloryfer ). przypadek przykłady odpow iada na pytania: liczba pojedyncza liczba mnoga mianownik kto? co? rycerz rycerze dopełniacz kogo? czego? rycerza rycerzy celownik komu? czemu? rycerzowi rycerzom biernik kogo? co? rycerza rycerzy narzędnik (z) kim? (z) czym? rycerzem rycerzami miejscownik (o/na/w ) kim? (o/na/w ) czym? rycerzu rycerzach wołacz - rycerzu! rycerze! Tabela 1: Odmiana rzeczownika przez przypadki 3.1.3. Przymiotniki Przymiotniki odpowiadają na pytanie jaki?, jaka?, jakie?, który?, która?, które?, czyj?, czyja?, czyje?. Przymiotnik odmienia się przez przypadki (takie same jak rzeczownik, patrz tabela 1), liczby (pojedynczą i mnogą) oraz rodzaje. Rodzajów jest pięć, trzy liczby pojedynczej (męski, żeński i nijaki) oraz dwa mnogiej (męskoosobowy i niemęskoosobowy). Dodatkowo w liczbie pojedynczej dla rodzaju męskiego istnieją różne formy biernika, w zależności od żywotności określanego tym przymiotnikiem rzeczownika. Umownie nazywa się te formy męską żywotną i męską nieżywotną. Przymiotnik podlega także stopniowaniu, tworząc formy stopnia równego ( mocny ), wyższego ( mocniejszy ) i najwyższego ( najmocniejszy ). przypadek przykłady liczba pojedyncza liczba mnoga rodzaj: męski żeński nijaki męskoosobowy niemęskoosobowy mianownik wysoki wysoka wysokie wysocy wysokie dopełniacz wysokiego wysokiej wysokiego wysokich wysokich celownik wysokiemu wysokiej wysokiemu wysokim wysokim biernik wysokiego/wysoki wysoką wysokie wysokich wysokie narzędnik wysokim wysoką wysokim wysokimi wysokimi miejscownik wysokim wysokiej wysokim wysokich wysokich wołacz wysoki! wysoka! wysokie! wysocy! wysokie! Tabela 2: Odmiana przymiotnika przez przypadki i rodzaje 3.1.4. Liczebniki Liczebnik odpowiada na pytania: ile?, który z kolei?. Odmienia się przez przypadki, liczby i rodzaje (analogicznie do przymiotnika, zobacz tabelę 2). 13/83

3.1.5. Zaimki Zaimki są częściami mowy, które zastępują inne, z czego wynika ich podstawowy podział na zaimki rzeczowne ( ty, ktoś ), przymiotne ( mój, ten, inny ), liczebne ( ile, tyle ) i przysłowne ( tam, skąd, kiedyś ). Ze względu na znaczenie zaimki dzielimy na: osobowe: ja, ty, on,... wskazujące: ten, tu, tędy,... pytające: kto?, kiedy?, jak?,... nieokreślone: coś, gdzieś, któryś,... przeczące: nic, nigdy, żaden,... względne: co, gdzie,... zwrotny: się ( siebie, sobie ) 3.1.6. Przysłówki Przysłówki są nieodmienną częścią mowy, odpowiadającą na pytania jak?, gdzie?, kiedy?. Podlegają tylko stopniowaniu; rozróżniamy stopień równy ( ładnie, dobrze ), stopień wyższy ( ładniej, lepiej ) i stopień najwyższy ( najładniej, najlepiej ). Przysłówki tworzy się najczęściej od przymiotnika ( wesoły wesoło, zgrabny zgrabnie ) ale istnieje grupa przysłówków, które nie mają takiego pochodzenia, na przykład bardzo, całkiem, wczoraj, wszędzie. 3.1.7. Przyimki Przyimek to nieodmienna i niesamodzielna część mowy. Dopiero w połączeniu z innym wyrazem (najczęściej rzeczownikiem) tworzy całość znaczeniową wyrażenie przyimkowe. Przyimki dzielimy na: proste: za, pod, bez, przy, mimo, ku,... złożone: zza, spod, pomimo, około,... 3.1.8. Spójniki Spójnik także jest nieodmienną i niesamodzielną częścią mowy. Służy do łączenia wyrazów w zdaniu lub zdań składowych w zdaniach złożonych. Spójniki dzielimy na: współrzędne: i, lub, jednak, dlatego, natomiast,... podrzędne: że, ponieważ, gdyby, zanim, choć,... 3.1.9. Wykrzykniki Wykrzyknik jest nieodmienną częścią mowy służącą do wyrażania uczuć, emocji, rozkazów, 14/83

woli mówiącego lub zawołań, na przykład: ach!, oj!, halo!, hop!, hej!, o!, hura!, ha!, bęc!, brzdęk! itp. 3.1.10. Partykuły Partykuła jest nieodmienną i niesamodzielną częścią mowy. Wyraża lub uwydatnia pytania, rozkazy, przeczenia, przypuszczenia albo życzenia. Przykładami partykuł są: bym, byśmy, czy, nie, niech, oby, chyba, no, -że ( chodźże ), -ż ( czyż ), -li ( znaszli ). 3.2. Składnia Rozróżniamy pięć części zdania: podmiot, orzeczenie, dopełnienie, przydawkę i okolicznik. 3.2.1. Podmiot Podmiot w zdaniu jest wykonawcą czynności. Podmiot może być wyrażony rzeczownikiem ( dzwonek ), zaimkiem rzeczownym ( oni ) oraz użytymi w znaczeniu rzeczownika: przymiotnikiem ( biali [ludzie] ), liczebnikiem ( szósta [godzina] ), imiesłowem przymiotnikowym czynnym ( walczący ), imiesłowem przymiotnikowym biernym ( uderzony ) lub bezokolicznikiem ( wygrywać [jest przyjemnie] ). Szczególnym przypadkiem jest podmiot szeregowy, składający się z wyrazów połączonych w stosunku współrzędnym ( ja i brat ) lub podrzędnym ( mężczyzna z psem ). Nie w każdym zdaniu pojawia się podmiot. Na przykład w zdaniu Piszę list podmiot ja jest domyślny. Istnieją też zdania bezpodmiotowe, na przykład Błyskało w oddali. 3.2.2. Orzeczenie Orzeczeniem najczęściej jest czasownik w formie osobowej, wtedy orzeczenie nazywamy czasownikowym ( rozegrałem, wracali itp.). Oprócz tego występują orzeczenia imienne, składające się z dwóch części: łącznika, będącego osobową formą czasowników być, zostać, stać się, oraz orzecznika, którym może być większość części mowy, na przykład: będę pilotem, był pierwszy, zostanie wykonany, staje się jasny. W zdaniach bezpodmiotowych funkcję orzeczenia może pełnić czasownik w formie nieosobowej zakończonej na -no/-to, na przykład Rozpoczęto polowanie na dzika. 3.2.3. Dopełnienie Dopełnienie w zdaniu pełni funkcję określenia czasownika. Może być wyrażone następującymi częściami mowy: rzeczownikiem (w dopełniaczu, celowniku, bierniku, narzędniku i miejscowniku): [pożyczył] koledze zaimkiem rzeczownym: [widzą] nas wyrażeniem przyimkowym: [spaceruję] z psem liczebnikiem: [dostałem] dwa przymiotnikiem: [pomagają] chorym 15/83

bezokolicznikiem: [pomógł] zanieść Dopełnienia dzielimy na bliższe i dalsze. Jeśli przy przekształceniu zdania ze strony czynnej na bierną dopełnienie stałoby się podmiotem, to jest to dopełnienie bliższe. Jeśli zachowałoby swoją funkcję składniową, to jest dopełnieniem dalszym. Przykładowo w zdaniu Malarz maluje obraz farbami., obraz jest dopełnieniem bliższym a farbami dopełnieniem dalszym, dlatego że po przekształceniu do strony biernej zdanie przyjmuje postać Obraz jest malowany farbami. 3.2.4. Przydawka Przydawka jest określeniem rzeczownika. Może być wyrażona następującymi częściami mowy: przymiotnikiem: duży [pies] zaimkiem przymiotnym: nasza [klasa] imiesłowem przymiotnikowym czynnym: płonący [budynek] imiesłowem przymiotnikowym biernym: napisany [list] liczebnikiem: pierwsze [dni] rzeczownikiem: [rzeka] Wisła Przydawka w zdaniu może być określeniem: podmiotu: Głośna muzyka przeszkadza sąsiadom w nocy. dopełnienia: Muzyka przeszkadza moim sąsiadom w nocy. okolicznika: Muzyka przeszkadza sąsiadom w środku nocy. 3.2.5. Okolicznik Okolicznik wskazuje na okoliczność wykonywania jakiejś czynności, w zdaniu jest określeniem czasownika. Może być wyrażony przy pomocy: przysłówka: [zachowuj się] grzecznie zaimka przysłownego: [poszli] tamtędy imiesłowu przysłówkowego współczesnego: [szedł] kulejąc wyrażenia przyimkowego: [wracali] do domu rzeczownika: [podróżowali] nocą Rozróżniamy następujące rodzaje okolicznika: miejsca: jadę (gdzie?) w góry, wracam (skąd) z gór 16/83

czasu: myślałem o tym (odkąd?) od wczoraj, wyjeżdżam (kiedy?) jutro celu: idę do sklepu (po co?) po chleb przyczyny: zawody odwołano (dlaczego?) z powodu niepogody sposobu: uczył się (jak?) pilnie przyzwolenia: ukończył bieg (mimo czego?) pomimo kontuzji warunku: odłożę wyjazd (pod jakim warunkiem?) w przypadku choroby 3.3. Związki w zdaniu Zespoły składniowe to łączące się gramatycznie i znaczeniowo wyrazy w zdaniu. Na przykład w zdaniu Drzewa i krzewy dawały przyjemny cień wyróżniamy następujące zespoły: drzewa i krzewy, drzewa i krzewy dawały, dawały cień, przyjemny cień. Związkiem składniowym są zespoły składniowe, w których jeden człon jest nadrzędny (określany) a drugi podrzędny (określający). Podmiot i orzeczenie tworzą związek główny (w powyższym przykładzie jest to <drzewa i krzewy><dawały> ), pozostałe związki składniowe są związkami pobocznymi. 3.3.1. Związek zgody W związku zgody wyraz nadrzędny (określany) i podrzędny (określający) zgadzają się pod względem formy, to znaczy występują w tym samym przypadku, liczbie i rodzaju. Związek zgody łączy: rzeczownik (podmiot) z czasownikiem (orzeczeniem): wilki śpią przymiotnik i rzeczownik: białą czekoladę zaimek przymiotny i rzeczownik: moimi przyjaciółmi liczebnik i rzeczownik: o czterech rowerach imiesłów przymiotnikowy czynny i rzeczownik: płynącej łodzi imiesłów przymiotnikowy bierny i rzeczownik: pobrudzone ubrania 3.3.2. Związek rządu W związku rządu wyraz nadrzędny decyduje o formie gramatycznej wyrazu podrzędnego. Związek rządu powstaje z: czasownika i rzeczownika w funkcji dopełnienia: pożyczam (co?) album, pożyczam (komu?) koledze czasownika i wyrażenia przyimkowego w funkcji dopełnienia: idziemy (z kim?) z bratem, rozmawiamy (o czym?) o filmie rzeczownika w mianowniku z rzeczownikiem w dopełniaczu: wiersz (czyj?) poety 17/83

rzeczownika i wyrażenia przyimkowego: dom (z czego?) z drewna przymiotnika i rzeczownika: godny (czego?) zaufania 3.3.3. Związek przynależności Związek przynależności łączy najczęściej orzeczenie z okolicznikiem. Wyraz podrzędny przeważnie jest wyrazem nieodmiennym. Związek przynależności powstaje z: czasownika i przysłówka w funkcji okolicznika: biegną (jak?) szybko czasownika i zaimka przysłownego w funkcji okolicznika: siadł (gdzie?) tam czasownika i imiesłowu przysłówkowego współczesnego w funkcji okolicznika: szedł (jak?) gwiżdżąc czasownika i wyrażenia przyimkowego w funkcji okolicznika: wracali (gdzie?) do domu czasownika i bezokolicznika w funkcji okolicznika: przyszli (po co?) podziękować 3.3.4. Związki frazeologiczne Frazeologizmy to utrwalone w użyciu połączenie kilku wyrazów, które ma często znaczenie nie będące prostą sumą znaczeń składowych wyrazów, na przykład biała flaga, wypić duszkiem. Związki frazeologiczne możemy dzielić według kryterium gramatycznego na wyrażenia, jeśli ośrodkiem frazeologizmu jest rzeczownik, przymiotnik, imiesłów przymiotnikowy lub (rzadziej) przysłówek, na przykład krokodyle łzy, rym częstochowski, krótko i węzłowato ; na zwroty, jeśli ośrodkiem frazeologizmu jest czasownik lub imiesłów przysłówkowy, na przykład iść w zaparte, wciskać kit ; oraz na frazy, jeśli frazeologizm jest całym zdaniem lub równoważnikiem zdania,na przykład kij ma dwa końce, człowiek człowiekowi wilkiem. Frazeologizmy dzielimy także pod względem semantycznym (znaczeniowym). Wyróżniamy kolokacje, czyli często używane zestawienia słów, w których znaczenie wynika wprost ze znaczeń składników, na przykład obrać jabłko, porąbać drewno. Na przeciwległym biegunie są idiomy, czyli wyrażenia złożone, których znaczenie jest odmienne od znaczenia jakie należałoby przypisać temu wyrażeniu biorąc pod uwagę poszczególne części składowe oraz reguły składni, na przykład urwanie głowy, flaki z olejem, grzeszyć rozumem. 18/83

4. Opis algorytmu bezkontekstowego Algorytm składa się z dwóch głównych części: algorytmu bezkontekstowego, który analizuje pojedyncze słowa, oraz algorytmu kontekstowego (patrz rozdział 5), który korzystając z wyników algorytmu bezkontekstowego, tworzy listy wyników analizując kontekst całego tekstu. Algorytm bezkontekstowy jest wywoływany dla pojedynczych wyrazów. Istnieje jeden parametr, stopień, określający głębokość przeszukiwania. Funkcja generuje listę słów analizując, jakie było pierwotne słowo jeśli po popełnieniu danego rodzaju błędów powstał aktualnie badany wyraz. Następnie na liście pozostawiane są te wyrazy, które tworzą poprawne słowa, posortowane od najbardziej do najmniej prawdopodobnych. Na potrzeby algorytmu kontekstowego istnieje wersja algorytmu, która oprócz samych słów zawraca też ich wagi, według których lista jest posortowana (im mniejsza waga, tym słowo jest bardziej prawdopodobne). Waga słowa jest iloczynem wag błędów, które powinny zostać popełnione na słowie, aby uzyskać analizowane słowo. Wagi błędów zostały wybrane arbitralnie na podstawie analizy szans wystąpienia danego błędu w tekście w języku polskim. Analizowane słowo może być poprawnym słowem, zostanie wtedy umieszczone na liście wyników, oprócz innych propozycji, jako słowo poprawione w zeru krokach (z wagą 1). 4.1. Rodzaje błędów poprawiane przez algorytm 4.1.1. Brak polskiego znaku diakrytycznego przy literze Dodawanie polskich znaków diakrytycznych jest dokonywane jednorazowo, na początku działania algorytmu, tworzone są od razu wszystkie możliwe kombinacje. Litery, które podlegają zmianie, przedstawia poniższa tabelka: litera nowa litera waga zmiany a ą 1,1 c ć 1,1 e ę 1,1 l ł 1,1 n ń 1,1 o ó 1,1 s ś 1,1 z ż 1,1 z ź 1,11 x ź 1,13 ż ź 1,18 ź ż 1,18 Tabela 3: Litery zmieniane przez funkcję dodającą polskie znaki diakrytyczne Rozważając literę ź postanowiłem uwzględnić zarówno intencjonalne pisanie bez polskich ogonków czyli możliwość pojawienia się litery z w miejsce ź jak i przypadkowe niewciśnięcie klawisza Alt skutkujące pojawieniem się litery x. Postanowiłem uwzględnić też (z mniejszą wagą) przypadki pomylenia ż z ź i na odwrót. 19/83

4.1.2. Błąd ortograficzny Funkcja symuluje popełnienie błędu ortograficznego. Uwzględnione zostały trzy najpopularniejsze błędy: zamiana u z ó, zamiana rz z ż i zamiana h z ch. Waga błędu wynosi 2. Ta i wszystkie następne funkcje proponują wyrazy zawierające tylko jedną poprawkę naraz. Aby uwzględnić w wyrazie więcej tego typu poprawek, algorytm musi zostać wywołany z odpowiednio większym parametrem określającym głębokość wyszukiwania. 4.1.3. Nadmiarowy znak diakrytyczny Funkcja jest niejako przeciwieństwem funkcji dodającej ogonki z rozdziału 4.1.1. Jeśli w wyrazie pojawia się litera z polskim ogonkiem, proponowane jest jego usunięcie. Waga tego błędu wynosi 3. Listę liter, które mogą zostać zamienione przedstawia poniższa tabelka: litera nowa litera ą a ć c ę e ł l ń n ó o ś s ż z ź z Tabela 4: Litery zmieniane przez funkcję usuwającą polskie znaki diakrytyczne 4.1.4. Zamiana miejscami dwóch sąsiadujących liter Zadaniem funkcji jest odtworzenie słowa przy założeniu, że popełnionym błędem było naciśnięcie w nieprawidłowej kolejności klawiszy na klawiaturze, co spowodowało zamianę kolejności liter w wyrazie. Waga błędu wynosi 4. 4.1.5. Nadmiarowa dowolna litera Błąd implementowany przez tę funkcję polega na pojawieniu się dodatkowej litery w wyrazie. Funkcja generuje możliwe pierwotne słowa usuwając jedną literę z analizowanego wyrazu. Obliczając wagę takich zmian, postanowiłem uwzględniać odległość między klawiszami na klawiaturze, tak aby promować błędy polegające na wciśnięciu klawisza sąsiadującego z zamierzonym względem zamiany na literę z odległego miejsca. Na przykład jeśli pojawi się wyraz mjcha i nie wiemy co jest bardziej prawdopodobne zamiana litery j na a ( macha ) czy j na u ( mucha ), to człowiek wystarczy, że rzuci okiem na wygląd klawiatury (patrz rysunek poniżej) i może zdecydować, że omyłkowe trafienie palcem w klawisz u znajdujący się zaraz obok klawisza j jest dużo bardziej prawdopodobne niż omyłkowe naciśnięcie znajdującego się na drugim końcu klawiatury klawisza a. 20/83

Zdecydowałem się taką umiejętność zaimplementować w moim algorytmie poprzez odpowiednie ustawianie wielkości wag błędów. Jeśli żadna z par <litera sąsiednia z lewej><nowa liter> ani <nowa litera><litera sąsiednia z prawej> nie są sąsiadami na klawiaturze, waga zmiany wynosi 8. Jeśli w którejś parze litery sąsiadują ze sobą, waga zależy od sposobu sąsiedztwa i zawiera się w przedziale od 5,1 do 5,5. Obecnie waga 5,1 jest przypisywana, gdy litery sąsiadują w poziomie a waga 5,5 gdy sąsiadują w pionie po ukosie. Jeśli układ używanej klawiatury jest inny (na przykład litery sąsiadują w pionie albo całym bokiem albo tylko rogiem) można zmodyfikować obliczanie wag poprzez modyfikację pliku opisującego układ klawiatury. 4.1.6. Dowolna litera zamieniona na inną Ten błąd polega na zamianie jednej z liter w słowie na jakąś inną. Próba wygenerowania wszystkich możliwych słów powodowałaby powstanie dużej liczby propozycji (ilość liter w wyrazie * 35 liter w alfabecie), dlatego skorzystałem z mechanizmu środkowych: 4.1.6.1. Środkowe Rysunek 1: Układ klawiatury Mechanizm środkowych opiera się na spostrzeżeniu, że jeśli będziemy rozpatrywać trigramy czyli n-gramy (patrz rozdział 2.3) o długości 3 liter, to nie każda ich kombinacja występuje w języku polskim (na przykład trójka liter bac jest często występującym n-gramem, a trójka acf nie występuje w ogóle). Tworząc algorytm stworzyłem listę wszystkich trigramów z liter występujących w języku polskim na podstawie listy wyrazów występujących w słowniku języka polskiego. Następnie przekształciłem wynik do postaci, w której dla każdej pary liter posiadamy listę liter, które mogą wystąpić między nimi (parę liter tworzą skrajne litery z trigramu a listę litery ze środkowej pozycji). Na przykład określenie parze liter <t><h> odpowiada lista <acouy> oznacza, że w języku polskim występują wyrazy, w których pojawia się trójka liter tah (na przykład w słowie wataha ), tch ( ketchup ), toh ( fotoheliograf ), tuh ( stuhektarowy ) lub tyh ( antyhitlerowski ). Uwzględnione zostały także początki i końce wyrazów, poprzez uwzględnienie par zawierających spacje (to znaczy, że określenie parze liter <ń><spacja> odpowiada lista <bc> oznacza, że w języku polskim występują wyrazy kończące się dwójką liter ńb ( na przykład słowo hańb ) lub ńc ( słońc ). W szczególności określenie parze liter <spacja><spacja> odpowiada lista <aiouwz> oznacza, że w języku polskim występują następujące jednoliterowe słowa: a, i, o, u, w i z ). 21/83

Średnia długość listy liter dla danej pary znaków wyniosła 9, co w porównaniu z 35 potencjalnie możliwymi (26 liter alfabetu łacińskiego + 9 polskich liter), oznacza średnio czterokrotne skrócenie listy. Algorytm zamieniający litery nie wstawia na miejsce danego znaku dowolnego innego, a jedynie te znaki, które mogą wystąpić w tym miejscu w słowie należącym do języka polskiego, czyli te, które występują na liście dla pary stworzonej z litery poprzedzającej i następującej po zmienianej literze zgodnie z mechanizmem środkowych opisanym powyżej. Dzięki temu ilość propozycji zmniejsza się z <długość wyrazu>*35 liter do <długość wyrazu>*9. Opisany mechanizm nie jest idealny. O ile dla słów zawierających tylko jeden błąd działa bezbłędnie, to jeśli w wyrazie pojawiły się dwa błędy polegające na zamianie litery na inną i do tego na sąsiednich pozycjach, to może się zdarzyć, że wyraz nie zostanie znaleziony. Przykładem może być wyraz wyghbd który powstał z wyrazu wygląd poprzez zamianę l na h i ą na b. Algorytm zamieniając litery na inne ani nie zamieni h na l (bo dla pary liter <g><b> litera l nie występuje nigdy między mini), ani nie zamieni b na ą (bo litera ą nie występuje pomiędzy literami <h> a <d>). Jednak szansa wystąpienia takiego zdarzenia jest niewielka, dlatego zdecydowałem, że wykorzystam ten mechanizm ze względu na przyspieszenie jakie daje algorytmowi poprzez mniejszą liczbę generowanych wyrazów. Dla tego błędu także uwzględniłem odległości liter na klawiaturze, analogicznie jak dla błędu opisane w punkcie 4.1.5). Różnica jest tylko w wysokości wag: w przypadku braku sąsiedztwa jest to 9, jeśli natomiast litery są sąsiadami, to waga należy do przedziału 6,1 6,5 w zależności od sposobu sąsiedztwa. 4.1.7. Brak dowolnej litery Błąd implementowany przez tę funkcję polega na pominięciu jednej z liter w wyrazie. Algorytm tworzy listę wyrazów poprzez dodawanie na każdej pozycji nowych liter. Aby ograniczyć liczbę tworzonych słów, podobnie jak dla błędu zamiany litery na inną (patrz rozdział 4.1.6) zastosowano mechanizm środkowych (punkt 4.1.6.1). Waga błędu wynosi 7. 4.2. Stopień Algorytmem bezkontekstowym możemy sterować poprzez jeden parametr, stopień, oznaczający głębokość poszukiwań poprawnego słowa. Stopień jest liczbą całkowitą, która może przyjmować następujące wartości: 0 (zero), oznacza tylko próbę dodania polskich znaków diakrytycznych (patrz 4.1.1) do badanego wyrazu dodatnie wartości parzyste algorytm zaproponuje słowa, w których znajduje się co najwyżej stopień/2 błędów (nie dotyczy to ogonków, których dodawana ilość jest ograniczona jedynie długością słowa) dodatnie wartości nieparzyste algorytm zaproponuje słowa, w których znajduje się co najwyżej (stopień+1)/2 błędów z tym, że ilość błędów polegających na zamianie (4.1.6) lub pominięciu (4.1.7) litery może być co najwyżej (stopień-1)/2. Innymi słowy dla stopnia 1 algorytm generuje słowa zawierające jeden z czterech rodzajów błędów (4.1.2-4.1.5), dla stopnia 2 generuje słowa zawierające jeden dowolny błąd. Dla stopnia 3 generuje słowa zawierające dwa 22/83

błędy, z czego co najwyżej jeden polega na zamianie lub pominięciu litery itd. Taka decyzja spowodowana była tym, że te dwa błędy są najbardziej czasochłonne i wydłużają czas pracy algorytmu. Dzięki temu możemy na przykład dla stopnia 3 szukać słów które zawierają po dwa błędy (ograniczenie do jednego błędu określonego typu nie jest dużą restrykcją) a z drugiej strony cieszyć się czasem działania porównywalnym z algorytmem znajdującym tylko jeden błąd w wyrazie. ujemne wartości ilość znajdowanych błędów jest analogiczna do wartości dodatnich z tym, że algorytm zatrzymuje się jak tylko znajdzie jakiekolwiek słowo występujące w słowniku, to znaczy zachowuje się jakby wywoływać funkcję kolejno z parametrem 0, 1, 2,..., stopień, tak długo aż któreś z wywołań zwróci niepustą listę wyników stopień 24 jest to hybrydowy stopień stworzony w wyniku analizy wyników testów; zachowuje się jakby funkcję wywołano ze stopniem 2 a jeśli w wyniku tego nie zostanie zaproponowane żadne słowo, ponownie wywołano ją z parametrem -4. Chciałem w ten sposób osiągnąć z jednej strony dla słów, które są całkowicie błędne, wyszukiwanie aż do dwóch dowolnych błędów w wyrazie, a z drugiej strony zagwarantowanie, że zawsze pojawią się na liście wyników (przekazywanej potem do algorytmu kontekstowego) wszystkie słowa, które różnią się do badanego jednym błędem; dzięki temu uniknąłem sytuacji, że jeśli w wyniku popełnienia błędu powstało inne poprawne słowo lub na przykład różniące się od jakiegoś poprawnego tylko znakiem diakrytycznym, prawidłowe słowo nie pojawiało się na liście wyników i algorytm kontekstowy, który sam z siebie nie dodaje nowych słów do listy a jedynie zamienia ich kolejność, nie mógł go zaproponować. 4.3. Magazynowanie wyników Jeżeli przetwarzamy dużą ilość tekstów a szczególnie jeśli wywołujemy funkcję algorytmu bezkontekstowego także dla słów które są poprawne słownikowo (przypuszczając że być może w rzeczywistości powinno się tam pojawić inne, podobne słowo), często będziemy wywoływali funkcję dla tego samego słowa i z tym samym parametrem stopnia. Taka sytuacja zaszła przy testach kontekstowych opisanych w rozdziale 6.4, gdzie testowałem algorytm z różnymi opcjami kontekstowymi ale na tej samej bazie tekstów i z tym samym stopniem algorytmu bezkontekstowego. Aby zmniejszyć czas działania algorytmu, można by w trakcie jego działania zapisywać każdą listę wyników w bazie danych i jeśli dojdzie do ponownego wywołania algorytmu dla tego samego słowa i z tym samym parametrem zamiast ponownie tworzyć listę propozycji słów, odczytać zachowany w bazie danych wynik i go zwrócić. Jako że w moich testach znałem na początku cały testowany zbiór tekstów, zastosowałem prostszą wersję tego rozwiązania przed właściwymi testami uruchomiłem algorytm dla każdego wyrazu i z każdym z testowanych stopni i stworzyłem tekstową bazę zawierającą wszystkie listy wyników. Następnie wykonując testy za każdym razem korzystałem już z tych danych. Jako że znałem już całość tekstów, z jednej strony miałem pewność, że szukany wynik jest w magazynie a z drugiej nie musiałem dodawać nowych list wyników do magazynu, co wiązałoby się z narzutem na jego przebudowę w celu optymalizacji czasu odczytu. Wyjątkiem były tylko testy czasu działania algorytmu, które wykonałem nie posługując się zmagazynowanymi danymi, gdyż nie miałoby to sensu wszystkie wyniki byłyby identyczne niezależnie od stopnia. 23/83

4.4. Słowa przypadkowo sklejone lub podzielone Sklejanie lub podział słów z formalnego punktu widzenia powinny być rozwiązywane przez algorytm bezkontekstowy. Jednak przyjęta przeze mnie strategia, według której algorytm bezkontekstowy pracuje na pojedynczych wyrazach, spowodowała, że mógłby on jedynie sprawdzać, czy dane słowo nie jest wynikiem sklejenia dwóch słów, natomiast nie potrafiłby stwierdzić, czy wraz z sąsiadującym słowem nie tworzy poprawnego wyrazu. Dlatego, aby zachować spójność, w algorytmie bezkontekstowym żadna z obu powyższych możliwości nie jest sprawdzana. Natomiast w przypadku, gdy uruchamiany jest algorytm kontekstowy, przed jego uruchomieniem lista propozycji jest rozszerzana. Dodawane są dwa rodzaje błędów: sklejenie dwóch sąsiednich słów i podział słowa na dwa. 4.4.1. Podział słowa na dwa Do listy propozycji dla każdego słowa doklejana jest lista tworzona według następujących zasad: tworzymy dwa nowe słowa, sklejając badane słowo ze słowem sąsiadującym po lewej oraz ze słowem sąsiadującym po prawej. Dla każdego z tych nowych słów uruchamiamy algorytm bezkontekstowy ze stopniem mniejszym o dwa co do wartości bezwzględnej (lub zero, jeśli wartość bezwzględna aktualnego stopnia jest mniejsza od dwóch). Następnie w tak uzyskanych listach propozycji uwzględniamy wagę błędu podziału, która wynosi 2,7 i dołączamy tę listę do wyników. 4.4.2. Sklejenie dwóch sąsiednich słów Podobnie jak w przypadku błędu podziału, także do listy propozycji dla danego słowa dołączamy nowe propozycje. Dla każdego słowa tworzymy wszystkie możliwe pary słów, powstałe poprzez podział badanego wyrazu. Następnie dla każdego słowa w parze uruchamiamy algorytm bezkontekstowy i łączymy listy wyników metodą każdy z każdym. Waga każdej nowej propozycji jest iloczynem wag obu łączonych propozycji i wagi błędu sklejenia, która wynosi 4,5. 4.4.3. Sklejenie więcej niż dwóch wyrazów lub podział na więcej niż dwa wyrazy Obecny algorytm nie próbuje znaleźć rozwiązań wymagających więcej niż dwóch podziałów lub sklejeń. Ograniczenie takie wprowadziłem, ponieważ takie sytuacje są rzadkie a dzięki temu mogłem znacznie ograniczyć czas działania algorytmu, dlatego, że ilość wszystkich możliwości podziału słowa na mniejsze wynosi 2 długość-1. Z kolei ilość potencjalnych połączeń z sąsiadami ograniczona jest tylko długością zdania, choć można też ograniczyć ją długością nowopowstałego ciągu znaków jeśli jest dłuższy niż pewna ustalona liczna znaków (rozsądnym ograniczeniem może być 25 znaków), to uznajemy, że w ten sposób już żadnego prawidłowego słowa nie stworzymy. Jeśli przyjmiemy, że oprócz sklejenia słów, w wyrazach nie było żadnych innych błędów (literówek, braku ogonków itp.), możemy także ograniczyć ilość możliwości podziału słowa. Jeśli prefiks badanego ciągu znaków nie tworzy prawidłowego słowa, to nie szukamy już podziałów w pozostałej części wyrazu. Jednak jeśli więcej niż jeden prefiks jest poprawnym wyrazem (np. w ciągu cofaniemy byłyby to słowa cofa i cofanie ) to i tak ilość możliwych podziałów jest duża. Dodatkową wadą szukania nieograniczonej liczby podziałów jest proponowanie podziału prawidłowego słowa na wiele mniejszych. Spowodowane to jest tym, że wiele wyrazów w języku 24/83

jest wyrazami pochodnymi od innych, powstałymi poprzez dodanie formantu (prefiksu lub sufiksu) do innego słowa, lub poprzez sklejenie kilku słów. Proponowane podziały mogą przebiegać też w poprzek rdzenia wyrazu tworząc (przypadkowo) dwa zupełnie nie powiązane słowa. Ilustracją tej sytuacji jest słowo bezokolicznik. Przeprowadzenie linii podziału między prefiksem a rdzeniem wyrazu powoduje powstanie dwóch poprawnych słów bez i okolicznik. Z kolei rdzeń okolicznik może podlec dalszym podziałom, na przykład na słowa oko i licznik a w przypadku posiadania w słowniku skrótu NIK także na dalsze mniejsze elementy: licz i nik. Jeszcze więcej przypadkowości w tworzonych propozycjach pojawiłoby się, gdybyśmy dopuścili w każdym wyrazie składowym możliwość popełnienia jakieś literówki. Jeśli nowopowstały wyraz miałby dwie litery, to zakładając możliwość jednej literówki w nim, tworzylibyśmy długą listę prawie dowolnych dwuliterówek. W szczególności, dzieląc badany ciąg znaków na każdą możliwą kombinację słów, z których każde ma długość co najwyżej dwa, tworzylibyśmy długie listy propozycji składające się z bezsensownych jedno- i dwuliterowych wyrazów. 25/83

5. Opis algorytmu kontekstowego Przed wywołaniem algorytmu kontekstowego, zawsze w pierwszej kolejności wywoływany jest algorytm bezkontekstowy (patrz rozdział 4), którego zadaniem jest dla każdego wyrazu, także słownikowo poprawnego, stworzenie listy propozycji słów wraz z wagami określającymi na podstawie rodzaju popełnionych błędów prawdopodobieństwo, że dane słowo jest poprawne. Działanie algorytmu kontekstowego polega na zamianie wag (a więc w konsekwencji także kolejności na liście) przypisanych poszczególnym propozycjom na podstawie różnych opisanych poniżej metod. Algorytm ani nie dodaje nowych słów do listy (operuje tylko na słowach zaproponowanych przez algorytm bezkontekstowy) ani nie usuwa słów (gdyż każde słowo choć z małym prawdopodobieństwem, ma szansę okazać się tym prawdziwym). Z drugiej strony prezentując użytkownikowi programu korygującemu tekst zbyt długiej listy wyników i tak nic nie daje, gdyż zwraca on uwagę tylko na początek listy ignorując dalsze propozycje i można by postępować tak jak twórcy programu Writely (patrz rozdział 6.3.2.2), którzy zawsze prezentują listę wyników składającą się maksymalnie z pięciu propozycji. Można by obcinając listę wyników kierować się też wartością wagi jeśli jest zbyt duża co oznacza małe prawdopodobieństwo wystąpienia błędu, to usuwać słowo z wyników. Algorytm analizuje nie tylko słowa, których nie znajdzie w słowniku. Dla każdego słowa, nawet pozornie poprawnego, tworzona jest lista propozycji w oparciu o algorytm bezkontekstowy. Oczywiście to poprawne słowo znajduje się na pierwszej pozycji listy wyników. Jednak algorytm kontekstowy (patrz niżej) może już uznać inne słowo za bardziej prawdopodobne i przesunąć je na pierwszą pozycję. Algorytm kontekstowy składa się z sześciu metod, z których każda jest niezależna od innych i może być uruchamiana zarówno sama jak i wspólnie z innymi metodami. 5.1. Analiza częstości występowania pojedynczego wyrazu Celem tej metody jest promowanie słów, które w języku polskim są popularne i występują w tekstach często kosztem słów rzadkich, gdyż mając dwa słowa do wyboru możemy domniemywać, że słowo generalnie w języku popularniejsze, także w danym miejscu ma większą szansę się pojawić. Oczywiście słowa rzadsze też się pojawiają w tekstach, ale patrząc statystycznie na błędy, wybierając zawsze słowo częstsze, w większości przypadków dokonamy prawidłowej decyzji. Pierwszym etapem tworzenia tego algorytmu było zgromadzenie danych opisujących częstość występowania wyrazów w języku polskim. Aby uzyskać wiarygodne wyniki potrzebowałem dużej ilości tekstów, na których mógłbym zebrać dane. Skorzystałem z korpusu polskich tekstów należącego do Grupy Lingwistyki Komputerowej z Katedry Informatyki na wydziale Elektrotechniki, Automatyki, Informatyki i Elektroniki na Akademii Górniczo-Hutniczej w Krakowie. W korpusie znajdowało się 3309 książek, gazet i innych tekstów w języku polskim. Postanowiłem także nie zapamiętywać częstości dla każdego słowa osobno, ale wspólnie dla wszystkich odmian wywodzących się z tej samej formy bazowej, aby nie dokonywać porównań, czy słowo nogą występuje częściej czy rzadziej od słowa nogę a jedynie porównywać różne wyrazy. Innym skutkiem tej decyzji było zmniejszenie ilości miejsca na dysku potrzebnego do zapisania tych danych. Odrzuciłem także wyrazy, które w całym korpusie pojawiły się co najwyżej jeden raz, uznając, że nie miałoby sensu porównywanie, że słowo, które pojawiło się w tekście dokładnie jeden raz jest generalnie w języku polskim częstsze od słowa, które nie pojawiło się ani razu, lecz raczej było to kwestia przypadku, że to słowo się pojawiło a inne akurat nie. 26/83