From e0e7165f83efd92ad8cf721004486125cf76b652 Mon Sep 17 00:00:00 2001 From: siulkilulki Date: Sun, 17 Jun 2018 18:54:39 +0200 Subject: [PATCH] REszta zrobiona. Robiny jest anotator. --- diagramy/crawler.xml | 2 +- img/crawler.png | Bin 21314 -> 21580 bytes rozdzial_3.tex | 163 +++++++++++++++++++++++++++++-------------- 3 files changed, 112 insertions(+), 53 deletions(-) diff --git a/diagramy/crawler.xml b/diagramy/crawler.xml index de19b88..eaac905 100644 --- a/diagramy/crawler.xml +++ b/diagramy/crawler.xml @@ -1 +1 @@ -7Vldj9soFP01kboPiWyDvx4n02b6sLuqNKq6fSSY2KjYuJiMk/n1CzGOP0imSZpO06rzkIELBnzO4V64noD7fPMgUJn9wxPCJp6TbCbg7cTzXBiG6p+2bBtLGAaNIRU0MZ06wyN9JsboGOuaJqQadJScM0nLoRHzoiBYDmxICF4Pu604G85aopRYhkeMmG39RBOZNdbIdzr7e0LTrJ3ZdUzLEuEvqeDrwsw38cBq99c056gdy/SvMpTwumcC7ybgXnAum1K+uSdMY9vC1jy3ONK6X7cghTzlAa954AmxtXl1lAhSbZVtLVgzFFpRalYrty1Cu3ckehRnAuZ1RiV5LBHWrbXShLJlMmeq5qriijJ2zxkXu2c1Ih7Gyl5Jwb+QXksSLAM/UC32e5hXeyJCkk3PZN7rgfCcSKEXblo9aDDettoy9bpj1G15yHpsBsaGjIjS/dAdkKpgsDyMK7Bwffj3o4GTMb1brohngki0OohngCOyXF0HTzDCc6/h18ATWnhigWpGxC8IJPyZwvQtIC0ESZHcaR+qapihqqJ4CBrZUPmfxnfmm9rntqVQq+k16epnw8RR4Cq+FpgM3JFEIiVysJNIMvDYNrg98PwD2LU2QRiS9Gno5w8Bamb4wKla71GnAuIRJ83bmKf6jnc8UDwaCI4GajCwBlLMoG2vW6k7VMcXDJyR2GLnxXXBl/urQrOCTmx7Dk7SX3CW/gpekGuITw25oHpNp0sR3roUgRPPIj90oWd+h7z5zswDkRP75hdeplM4miUexoBwNMsP0bB/YxoOjwejgCmS50tdSnXpTV3XM8SWKjg8p1ygWcn+snv9gkHM9Y/4r9cIYtGZBFT1FBXF7wP++Cj2quDHZ4L/vEQ1xZSwGRfp74G/D34i/u0d+UaPcMCOm+FNxc2x54LxhaHRG4UZCEcDXSn8jcMZcF8Of3uFHO7/3eHPtZMGNy7A6LYFGF56hxgL0BsNdESAl3BuJzTO5/wSZvs0xjdF43hbetGFNMLxftVH996ZG4CbcCv++MZ6bbdi53gsiVUZKnWR5rsEbl9dOnpTjNgdo2mhbJKXPevfaEnYB15RSbluXXIpea46MN0w32dth1lKnbcF891kd1XZJJq1WlFbWdGNPqjMzXreZlLqDPWdRsVb4KSAM4p5saLqQCNmWM3oLRIkkfqn7YqdBakqpXmK2BSV5VSpcOEGuheX05wLMs1JsZ5mNCFT14tmZZEe3SpnpEaj0FKcSQz19g6I7b3T2r7rAHNCDuoP0VchGrbfXTqiX41m74RzakszXgu2nQvFjvb13zrzdxeEpiaRIXsavxhLzrhgRUNf54Y2bvBQaBlH4IuAcw8A19yaVnznkTsEg69r3jZMq913NKVJx4Xlpmtsb1q7RHMzkFpDM1Z7B/vmrUwhJ4c0DK9YJlXXv48ZEzIbFSs+1C3R3sE5TRI9zUHeh7fBa3AbDnNYENqu7xC3F1Crqt2nvCYkdt9Lwbv/AQ== \ No newline at end of file +7Vldc5s4FP01ntl9sIcPgeHRduv0obuT2Uxnt48yyKCNQKyQg51fvxIIAwKnsUNdp9M8ONKVkMQ5R7q6l4m9SvZ3DGbxHzREZGIZ4X5if5hYlmcZ4lcaDpXBdUFliBgOK5PZGB7wM1JG9Vy0wyHKOx05pYTjrGsMaJqigHdskDFadLttKenOmsEI9QwPASR969845LF6Lcdo7J8QjuJ6ZtNQLRsYPEaM7lI138Syt+Vf1ZzAeizVP49hSIuWyf44sVeMUl6Vkv0KEQltDVv13PpE63HdDKX8NQ9Y1QNPkOzUq8OQofwgbF/++lwNBbcYq9XyQ41Q+Y5IjmJM7GURY44eMhjI1kJIQthinhBRM0VxiwlZUUJZ+axExAoCYc85o4+o1RK6G9dxRUv/PdSrPSHG0b5lUu91h2iCOJMLV60WUBgfam2petEwatY8xC02XWWDSkTRcegGSFFQWA7javdwvfvzi4KTELlZRsQzhMjbDuLpBh7abEVLCPO4HN1UlXvIOWJpabEMcxzIbQ3yo8yvATnoQZ7BfycrMPGcx2vDPQKW4EfK1+lh2UMQpeFCnrSiFhCY5zjogob2mP8j8Z05qva1bknFalpNsvpVMfEWneZ0xwLUOdc4ZBHinS2Jws7R38e/ha8zAG9tY4hAjp+6DmMIczXDPcVivSdPJ9vXaKveRj3VPsH1gXxtIKANVGHQG0iQBw+tbpnskJ9esG1oevSNF9cFXu4vCtUKGj0eOXiVRN2zJJrSFI2hTzHkGss1japWcOtqtQ1/5jlzE1jqt0utY8ws2zN8R/2Cy6QMtFn8rjOZa7N8F5k7Nybz+YtezSWC5+WGiVIkS78VRTGDZCO8zHNEGZxl5Pd+r3foDU3nxCl3DW/onc9BXkxhmv48+Os3u6vi75+P//MGFjjAiMwoi34OChz7B1JQB+bv90Zo933s/KZ8rH7EAf9CN2ppLgkAbaCRXKXu+mzzZVd5FNFw/ze7SrOfzHj/GvVuW6PzS6MWXaOWNtAJjV4ii34u5nxZfCfy20z7N8W0vrkt70Kmgb7rZbDQuuXb9k0cTo4eRo99OPXTUz0V5jHMZBEnZXq6LUB5TcABJAuCI6ksTrOW9TPcIHJPc8wxla0byjlNRAciG5bHnHQ3Byuz0vaynGyRZ1UaXQoa1pUt3kthL9V6PsScy/z7QqJirYMwBTMc0HSLxc2JzQIxo7UOIYfin7QLdtYoz4XmMSRTmGVTocK16cpelE8TytA0QeluGuMQTU3Lm2VpdHKrnJH49eY9xamEVmvv2H5/79S2N92UXpE7+0X0KESDuasTfTWarVdciGuagx0jhyUT7Miz/lvBRROJVDUOFdlT3xgpmPO6Z5057+MGhlyL7qQvAs4cAK4Kz7a0PJEbBN3/drRumOblV8KFdKkg2zeNdUhXJsirgcQaqrHqYO+b4Z9Ajndp6MZyKn/YDvyUCaqNGgg+EBvYwQkOQznNIO/dsHMMbufdrBkA/aNviNsLqBXV5kNl5RKbj8H2x/8B \ No newline at end of file diff --git a/img/crawler.png b/img/crawler.png index d88e852d3f1d1eeba4167a0ca35311a75711a120..7db0c887816c0ec46d70593f2ee0aaec0c2e0fa1 100644 GIT binary patch literal 21580 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
  • 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 diff --git a/rozdzial_3.tex b/rozdzial_3.tex index 9ae0be9..b1e1d85 100644 --- a/rozdzial_3.tex +++ b/rozdzial_3.tex @@ -1,4 +1,4 @@ -\chapter{Podstawy teoretyczne/spis pojęć} +\chapter{Podstawy teoretyczne i/lub spis pojęć} \chapter{Ekstrakcja godzin rozpoczęcia mszy świętych} \section{Ogólny zarys systemu} Architektura systemu ekstrakcji godzin rozpoczęcia mszy świętych została @@ -30,7 +30,7 @@ klas z nieodfiltrowanego zbioru stron parafialnych wylosowane zostają niepopraw Zebrane dane zostają użyte do wytrenowania klasyfikatora godzin opartego na płytkich sieciach neuronowych. -Klasyfikator używany jest do klasyfikacji godzin +Klasyfikator używany jest do przyporządkowania godzin znalezionych przez ekstraktor godzin do następujących klas: \begin{itemize} \item poprawne godziny mszy świętych, @@ -96,7 +96,7 @@ Dla każdej parafii zebrano: \end{table} Do wydobycia danych użyto skryptu w języku Python, który korzystał z parsera - HTML z biblioteki \textit{BeautifulSoup}\cite{beautiful_soup}. Przy wysyłaniu zapytań do serwisu deon.pl zastosowano + HTML z biblioteki \textit{Beautiful Soup}\cite{beautiful_soup}. Przy wysyłaniu zapytań do serwisu deon.pl zastosowano algorytm \textit{Expotential Backoff}\cite{expotential_backoff}, który przedstawia się następująco: @@ -140,7 +140,7 @@ Dla każdej parafii zebrano: zapobiega zbyt częstemu wysyłaniu zapytań do serwisu. Dla przykładu załóżmy, że dany serwis jest obciążony i nie daje sobie rady z przetwarzaniem zapytań. Wtedy algorytm \textit{Expotential Backoff} przy każdym kolejnym niepowodzeniu - będzie czekał coraz dłużej zanim wyśle kolejne zapytanie. W ten sposób nie + będzie czekał coraz dłużej, zanim wyśle kolejne zapytanie. W ten sposób nie będzie niepotrzebnie obciążał serwisu. \section{Wyszukiwanie adresów URL parafii} @@ -160,9 +160,9 @@ Do wyszukiwania adresów URL parafii próbowano wykorzystać wyszukiwarki takie Google i DuckDuckGo. Automatycznie wysyłano zapytanie złożone z konkatenacji nazwy parafii, jej miejscowości i ulicy, na której się znajduje. Wyszukiwarka Google dawała zadowalające wyniki, jednak po kilkunastu zapytaniach blokowała adres IP. W -dodatku w warunkach użytkowania serwisu i w pliku robots.txt Google zabrania +dodatku w warunkach użytkowania serwisu i w pliku \textit{robots.txt} Google zabrania korzystania z pająków na ich wyszukiwarce. -Wyszukiwarka DuckDuckGo nie blokowała adresu IP, ale zabraniała indeksowania w pliku robots.txt i słaba radziła sobie z polskimi +Wyszukiwarka DuckDuckGo nie blokowała adresu IP, ale zabraniała indeksowania w pliku \textit{robots.txt} i słabo radziła sobie z polskimi zapytaniami. W obu przypadkach powyższa metoda stwarzała kolejny problem do rozwiązania -- z wielu wyników wyszukiwania trzeba było wybrać ten, który zawierał adres URL parafii. @@ -182,19 +182,21 @@ zapytań do 150 000 na 24 godziny. Karta płatnicza jest potrzebna Google do identyfikacji osoby. Żadna opłata nie jest pobierana za korzystanie z interfejsu API. -Dla każdej parafii wykonywane jest zapytanie do serwisu \textit{Text Search} -składające się z konkatenacji nazwy, parafii, jej miejscowości i ulicy, na której +Dla każdej parafii wykonywane jest zapytanie do serwisu \textit{Text Search}. +Składa się ono z konkatenacji nazwy parafii, jej miejscowości i ulicy, na której się znajduje. Jeśli nie zostanie znaleziony żaden obiekt, wysyłane jest powtórne zapytanie, lecz tym razem składające się tylko z nazwy parafii i jej -miejscowości. Zdarza się, że serwis \textit{Text Search} zwraca kilka obiektów. W takim +miejscowości. + +Zdarza się, że serwis \textit{Text Search} zwraca kilka obiektów. W takim przypadku brany jest adres URL pierwszego obiektu z listy wyników. Najczęściej jednak oba obiekty należą do tej samej parafii, więc mają taki sam adres internetowy. Taki przypadek przedstawia rysunek \ref{pic:text_search}. -Serwis \textit{Text Search} zwraca dużo danych w formacie \textit{json}, które +Serwis \textit{Text Search} zwraca dużo danych w formacie JSON, które ciężko przedstawić w przejrzystej postaci. Dla -czytelności na rysunku \ref{pic:text_search} pokazano zrzuty z wyszukiwarki \textit{Google Maps}, -które odpowiadają rezultatowi jaki otrzymanoby korzystając z serwisu +czytelności na rysunku \ref{pic:text_search} pokazano zrzuty ekranu z wyszukiwarki \textit{Google Maps}, +które odpowiadają rezultatowi, jaki otrzymano by, korzystając z serwisu \textit{Text Search}. \noindent Powyższą metodą udało się zebrać adresy URL dla ok. 5600 parafii. @@ -275,14 +277,14 @@ silnik i wygląda następująco\footnote{Diagram i opis wzorowany jest na \item \textit{Downloader} pobiera stronę parafialną i umieszcza ją w odpowiedzi, którą przesyła silnikowi. Zanim odpowiedź dotrze do silnika, przetwarzana jest przez \textit{downloader middleware}. - \item Silnik otrzymuje odpowiedź od \textit{downloader'a}i przekazuje ją \textit{spider'owi} do + \item Silnik otrzymuje odpowiedź od \textit{downloader'a} i przekazuje ją \textit{spider'owi} do dalszego przetwarzania. Zanim odpowiedź trafi, do \textit{spider'a} przetwarzana jest przez \textit{spider middleware}. \item \textit{Spider} przerabia odpowiedź i zwraca dane strony parafialnej silnikowi. Zanim dane trafią, do silnika przechodzą przez \textit{spider middleware}. Dodatkowo \textit{spider} wysyła żądania z nowymi stronami parafialnymi do pobrania. \item Silnik wysyła zebrane dane do procesora danych, który zapisuje je do - pliku.. Następnie przekazuje nowe żądania do zakolejkowania + pliku. Następnie przekazuje nowe żądania do zakolejkowania dyspozytorowi. \end{enumerate} % \vspace*{-20mm} @@ -297,15 +299,15 @@ i obrazy. Biblioteka \textit{Scrapy} obsługuje rozpoznawanie typu zawartości odpowiedzi, bazując na następujących kryteriach: \begin{itemize} -\item wartości \mintinline{bash}{Content-type}\cite{RFC2045}, \mintinline{bash}{Content-Encoding}\cite{RFC7231} i \mintinline{bash}{Content-Disposition}\cite{RFC6266} w nagłówku odpowiedzi, -\item nazwie pliku lub adresie URL (jeśli nie udało się rozpoznać po nagłówku), +\item wartości \mintinline{bash}{Content-type}\cite{RFC2045}, \mintinline{bash}{Content-Encoding}\cite{RFC7231} i \mintinline{bash}{Content-Disposition}\cite{RFC6266} w nagłówku odpowiedzi; +\item nazwie pliku lub adresie URL (jeśli nie udało się rozpoznać po nagłówku); \item obecności znaków kontrolnych w pierwszych 5000 bajtów odpowiedzi (jeśli nie udało się rozpoznać po nazwie pliku lub adresie URL). \end{itemize} Powyższy schemat postępowania jest skuteczny, jeśli serwisy internetowe zwracają poprawne odpowiedzi. Niestety niektóre strony parafialne potrafią zwracać -odpowiedzi, które nie są zgodne z rozdziałem 3.1 z RFC7231\cite{RFC7231}. +odpowiedzi, które nie są zgodne z rozdziałem 3.1 z dokumentu RFC7231\cite{RFC7231}. Dla przykładu strona potrafi zwrócić \mintinline{bash}{Content-Type: text/html} w nagłówku, a w ciele binarną zawartość np. film. Tego rodzaju anomalie są wykrywane i eliminowane. @@ -353,7 +355,7 @@ ciała odpowiedzi. \end{algorithm} Algorytm \ref{alg:binaryornot} analizuje zawartość ciała odpowiedzi w celu -stwierdzenia czy jest ona binarna czy nie. +stwierdzenia czy jest ona binarna, czy nie. W linii 6 za znaki kontrolne uznano wszystkie znaki kontrolne ze zbioru C0\footnote{C0 to znaki kontrolne z kodu ASCII o kodach od 0 do 32 i o kodzie 127.} i C1\footnote{C1 to znaki kontrolne @@ -373,21 +375,21 @@ Powyższe znaki zostały wykluczone, ponieważ często występują w plikach tek Warto zwrócić uwagę na linię 10. Współczynnik \mintinline{python}{control_char_ratio} -oznacza procent znaków kontrolnych w pierszych 1024 bajtach pliku. +oznacza procent znaków kontrolnych w pierwszych 1024 bajtach pliku. Jeśli współczynnik \mintinline{python}{control_char_ratio} jest większy niż -$0.3$ to plik jest uznawany za binarny. Wartość $0.3$ została wzięta z -kodu\footnote{Kod znajduje się pod linkiem \url{https://github.com/Perl/perl5/blob/v5.27.11/pp\_sys.c\#L3605-L3665}. Wartość 0.3 występuje w linii 3661.} +$0,3$, to plik jest uznawany za binarny. Wartość $0,3$ została wzięta z +kodu\footnote{Kod znajduje się pod linkiem \url{https://github.com/Perl/perl5/blob/v5.27.11/pp\_sys.c\#L3605-L3665}. Wartość 0,3 występuje w linii 3661.} źródłowego języka Perl, który między innymi zajmuje się rozpoznawaniem plików binarnych. Natomiast współczynnik \mintinline{python}{high_ascii_ratio} oznacza procent znaków EASCII\footnote{EASCII - oznacza rozszerzone kodowanie ASCII. Przykładowe rozszrzenia to systemy + oznacza rozszerzone kodowanie ASCII. Przykładowe rozszerzenia to systemy kodowania ISO 8859 lub UTF-8.} o kodach od 160 do 255. Reprezentacja tych znaków zależy od rozszerzenia ASCII. Najczęściej jednak są to znaki drukowalne, które rzadko występują w tekście. -Jeśli współczynnik \mintinline{python}{high_ascii_ratio} jest większy niż $0.7$ +Jeśli współczynnik \mintinline{python}{high_ascii_ratio} jest większy niż $0,7$, to plik jest uznawany za binarny. -Wartośc $0.7$ została dobrana na podstawie następujących obserwacji: +Wartość $0,7$ została dobrana na podstawie następujących obserwacji: \begin{enumerate} \item Zdarzają się pliki binarne, które mają dużo znaków \mintinline{python}{high_ascii}. Przykładem jest plik z katalogu @@ -396,15 +398,15 @@ Wartośc $0.7$ została dobrana na podstawie następujących obserwacji: zawiera bardzo dużo znaków o kodzie 255 w początkowych bajtach. \item Mało prawdopodobne jest, aby plik tekstowy miał w pierwszych 1024 bajtach więcej niż 70\% znaków \mintinline{python}{high_ascii}. Nawet jeśli pająk - natrafiłby na taki plik to z dużym prawdopodbieństwem nie zawierałby on + natrafiłby na taki plik, to z dużym prawdopodobieństwem nie zawierałby on informacji parafialnych. \end{enumerate} \subsection{Automatyczna regulacja częstości zapytań} Biblioteka \textit{Scrapy} zawiera przydatne rozszerzenie, które potrafi automatycznie -regulować częstość zapytań w zależności od obciążenia pająka i strony internetowej. +regulować częstość zapytań w zależności od obciążenia pająka i serwera. -Algorytm \ref{alg:throttling} przedstawia sposób postępowania w jaki pająk +Algorytm \ref{alg:throttling} przedstawia sposób postępowania, w jaki pająk automatycznie reguluje częstość zapytań. Idea algorytmu jest następująca. Załóżmy, że serwer potrzebuje \mintinline{python}{latency}\footnote{Zmienna \mintinline{python}{latency} @@ -412,7 +414,7 @@ Załóżmy, że serwer potrzebuje zdefiniowana w algorytmie \ref{alg:throttling}.} sekund, aby odpowiedzieć pająkowi. Jeśli pająk chce mieć przetworzone równolegle \mintinline{python}{target_concurrency}\footnote{Stała - \mintinline{python}{target_concurrency} została zdefiniowana w algorytmie \ref{alg:throttling}.}zapytań to powinnien + \mintinline{python}{target_concurrency} została zdefiniowana w algorytmie \ref{alg:throttling}.}zapytań to powinien wysyłać każde zapytanie co \mintinline{python}{latency/target_concurrency} sekund. @@ -507,17 +509,18 @@ maksymalnie wykorzystać łącze internetowe, które było wąskim gardłem w pr indeksowania stron parafialnych. \subsection{Organizacja danych} -Dane zbierane przez pająka zapisywane są do pliku w formacie \textit{JSON - Lines}. Format \textit{JSON Lines} charakteryzuje się tym, że w każdej linii pliku -znajduje się poprawny obiekt \textit{json}. + +\enlargethispage{1\baselineskip} +Dane zbierane przez pająka zapisywane są do pliku w formacie JSONL. Format JSONL charakteryzuje się tym, że w każdej linii pliku +znajduje się poprawny obiekt JSON. Dla każdej parafii pobrane dane zapisywane są w oddzielnym pliku. W każdej linii -pliku znajduje się strona parafialna zapisana w formacie \textit{json}. -Zapis w formacie \textit{JSON Lines} i traktowanie każdej linii jako strony parafialnej niesie szereg korzyści takich jak: +pliku znajduje się strona parafialna zapisana w formacie JSON. +Taki sposób organizacji danych przynosi szereg korzyści takich jak: \begin{enumerate} \item wygodne przetwarzanie równoległe, -\item łatwa obróbka danych za pomocą narzędzi Unixowych, -\item mniejszy rozmiar pliku w porównaniu do zwykłego formatu \textit{json}. +\item łatwa obróbka danych za pomocą narzędzi Uniksowych, +\item mniejszy rozmiar pliku w porównaniu do zwykłego formatu \textit{JSON}. \end{enumerate} \noindent Dla każdej strony parafialnej zapisywane są następujące informacje: @@ -574,8 +577,7 @@ być godzinami rozpoczęcia mszy świętych. Został napisany z myślą, aby mia bardzo wysoką wartość pokrycia, ale już niekoniecznie wysoką precyzję. Celem jest, aby w zbiorze wyekstrahowanych godzin znalazło się jak najwięcej godzin - rozpoczęcia mszy, bez względu na to, jak duży jest ten zbiór. Ekstraktor wraz - ze znalezioną godziną zapisuje kontekst w jakim ta godzina się znalazła. + rozpoczęcia mszy, bez względu na to, jak duży jest ten zbiór. Do osiągnięcia tego celu zastosowano następujące reguły. Ciąg znaków oznaczony jako \mintinline{bash}{hour} zostanie wyekstrahowany, jeśli @@ -589,6 +591,8 @@ zajdzie każdy z poniższych warunków: \item Jeśli znak przed \mintinline{bash}{hour} równa się \mintinline{python}{'('}, to znak po \mintinline{bash}{hour} jest różny od \mintinline{bash}{')'}. \end{enumerate} +Ekstraktor wraz + ze znalezioną godziną zapisuje kontekst, w jakim ta godzina się znalazła. \section{Filtrowanie stron} \begin{figure}[tbh!] @@ -601,16 +605,17 @@ zajdzie każdy z poniższych warunków: Na rysunku \ref{pic:filtrowanie} został przedstawiony fragment architektury systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w tym podrozdziale. -Filtr stron parafialnych ma za zadanie odnaleźć strony parafialne na których z +Filtr stron parafialnych ma za zadanie odnaleźć strony parafialne, na których z dużym prawdopodobieństwem znajdują się godziny mszy świętych. Taki zabieg jest potrzebny, aby ograniczyć liczbę godzin, które trafią do anotatora. Gdyby nie zastosowano -filtru stron parafialnych ekstraktor godzin wśród wszystkich stron parafialnych +filtru stron parafialnych, ekstraktor godzin wśród wszystkich stron parafialnych znalazłby ponad 3 miliony godzin. Po zaaplikowaniu filtru stron i przetworzeniu ich przez ekstraktor godzin otrzymano 10920 godzin. Później godziny wraz z -kontekstami poddawane są anotacji. Etap ten będzie dokładniej opisany w kolejnym podrozdziale. +kontekstami poddawane są anotacji. Etap ten będzie dokładniej opisany w +podrozdziale \ref{sec:anotator}. Reguły zastosowane do zadecydowania czy dana strona zawiera godziny mszy -świętych zostały przedstawione w +świętych, zostały przedstawione w algorytmie \ref{alg:has_mass}. \begin{algorithm} \setstretch{1.2} @@ -621,7 +626,7 @@ algorytmie \ref{alg:has_mass}. if}{\nl else}{\nl end if}% \SetKwIF{If}{ElseIf}{Else}{if}{then}{else if}{else}{\nl end if}% \SetAlgoLined -\SetKwData{url}{url} +\SetKwData{link}{url} \SetKwData{bText}{btn\_text} \SetKwData{False}{False} \SetKwData{True}{True} @@ -629,7 +634,7 @@ algorytmie \ref{alg:has_mass}. \SetKwInput{kwOutput}{Wyjście} \kwInput{\\ \vspace{-0.5mm} - \Indp\url $\leftarrow$ adres internetowy analizowanej strony,\\ + \Indp\link $\leftarrow$ adres internetowy analizowanej strony,\\ \bText $\leftarrow$ tekst na przycisku, który doprowadził do analizowanej \phantom{\bText $\leftarrow$} strony. } @@ -657,7 +662,7 @@ algorytmie \ref{alg:has_mass}. \nl $\badreg \leftarrow$ \mintinline[breaklines]{python}{'nabo[zż]e[nń]stwa.(majowe|wielk|czerwcowe |maryjne|pasyjne|pokutne|fatimskie|do|ro[żz]a|czterdzie|w.wielk)'} -\nl$\suf \leftarrow$ ciąg znaków w \url po ostatnim wystąpieniu \slash\; +\nl$\suf \leftarrow$ ciąg znaków w \link po ostatnim wystąpieniu \slash\; \nl\uIfM{\begin{tabular}{@{\hspace*{-3.8pt}}l@{}} \nl \hspace*{1.2em} @@ -671,31 +676,85 @@ algorytmie \ref{alg:has_mass}. } \end{algorithm} -W algorytmie \ref{alg:has_mass} warto zwórcić uwagę na wyrażenia regularne +W algorytmie \ref{alg:has_mass} warto zwrócić uwagę na wyrażenia regularne \mintinline{text}{ok_regex} i \mintinline{text}{bad_regex}. Wyrażenie regularne \mintinline{text}{ok_regex} ma za zadanie dopasować się do słów, które są powiązane z porządkiem mszy świętych. Stąd też pojawiają się tam - wyrażenia takiej jak rozkład mszy lub porządek liturgii. + wyrażenia takie jak „rozkład mszy” lub „porządek liturgii”. Wyrażenie regularne \mintinline{text}{bad_regex} ma za zadanie dopasować się do - słów, które są powiązane z innymi nabożeństami niż msze święte. Stąd pojawiają - się tam wyrażenia takie jak nabożeństwa czerwcowe czy nabożeństwa maryjne. + słów, które są powiązane z innymi nabożeństwami niż msze święte. Stąd pojawiają + się tam wyrażenia takie jak „nabożeństwa czerwcowe” czy „nabożeństwa maryjne”. \section{Anotator danych} + + \begin{figure}[tbh!] \center \includegraphics[width=0.6\hsize]{annotator.png} -\label{anotator_pic} +\caption{Fragment architektury systemu przedstawiający komponent odpowiedzialny + za anotację danych.} +\label{pic:anotator} \end{figure} + +Na rysunku \ref{pic:anotator} został przedstawiony fragment architektury +systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w tym podrozdziale. + +\subsection{Ogólny zarys} Anotator danych został stworzony w celu zebrania jak największej ilości danych dla klasyfikatora przewidującego czy zaznaczony fragment jest godziną rozpoczęcia mszy świętej, czy nie. +Aby osiągnąć zamierzony cel anotator został zaprojektowany w ten sposób aby: +\begin{itemize} +\item był szybki, +\item był dostępny na urządzeniach mobilnych i stacjonarnych, +\item był prosty i wygodny w użyciu, +\item umożliwiał wykrywanie oszustów (osób intencjonalnie źle anotujących). +\end{itemize} -Do dokończenia +\noindent Anotator jest dostępny jako aplikacja internetowa pod adresem \url{msze.nsupdate.info}. Aplikacja jest +responsywna, więc można z niej wygodnie korzystać na każdym urządzeniu +wyposażonym w co najmniej 4 calowy wyświetlacz. Interfejs jest przejrzysty i +został pokazany na rysunku X. Jedyne akcje jakie może wykonać użytkownik to: +\begin{itemize} +\item kliknąć „Tak” jeśli zaznaczono godzinę rozpoczęcia mszy, +\item kliknąć „Nie” jeśli zaznaczono inną godzinę, +\item cofnąć się do poprzedniej anotacji, +\item wyświetlić instrukcję obsługi. +\end{itemize} +Po naciśnięciu przycisku „Tak” lub „Nie” ekran jest automatycznie przewijany na +sam dół. Taka operacja zapewnia łatwy dostęp do przycisków odpowiedzialnych za anotację. Dzięki +temu znajdują się one również zawsze w tym samym miejscu co ułatwia szybką +anotację. +Po naciśnięciu przycisku „Cofnij” ekran nie jest już przewijany na sam dół. W +ten sposób zapewniono wygodny dostęp do przycisku „Cofnij”. Jest to szczególnie +istotne w przypadku gdy +użytkownik zamierza cofać się wiele razy. -\section{Regułowy ekstraktor godzin mszy} +Aby zapewnić odpowiednią jakość anotacji przy pierwszym urchomieniu wyświetlana +jest instrukcja obsługi. Opisuje ona sposób w jaki należy anotować godziny oraz +przedstawia przykłady poprawnie zanotowanych godzin. Intrukcję można zamknąć +dopiero po przewinięciu jej na sam dół. + +Aplikacja nie wymaga logowania. Taka +decyzja została podjęta ze względu na fakt, że anotatorami są wolontariusze. +Wymóg rejestracji i logowania spowodowałby zmniejszenie liczby osób chętnych do +anotacji. Takie podejście wiąże się jednak z problemem identyfikacji +użytkowników. Identyfikacja jest niezbędna do prawidłowego funkcjonawania +antotora. Chcielibyśmy wiedzieć, które godziny zostały zanotowane przez danego +użytkownika, aby między innymi nie dać mu tych samych godzin do anotacji. + +\subsection{Identyfikacja urządzeń} +Skuteczną identyfikację można przeprowadzić używając + + +\subsection{Architektura anotatora} +Architektura + +\subsection{Podsumowanie} +\section{Regułowa ekstrakcja godzin mszy} Do napisania -\section{Ekstraktor godzin mszy oparty na uczeniu maszynowym} +\section{Klasyfikacja godzin} Do napisania \subsection{Model teoretyczny} \subsection{FastText}