Praca wstawiona.
This commit is contained in:
parent
e0e7165f83
commit
2b1eedf4d1
10
abstract.tex
10
abstract.tex
@ -1,4 +1,10 @@
|
|||||||
\chapter*{Abstract}
|
\chapter*{Abstract}
|
||||||
todo
|
The thesis presents the process of creating a system for extracting information
|
||||||
|
about opening hours
|
||||||
|
of holy masses. The methods of collecting data of Polish parishes are being
|
||||||
|
described, especially the process of creating spiders. Then two methods are shown
|
||||||
|
for the extraction of opening hours of masses: a rule-based method and
|
||||||
|
machine learning-based method. More attention is devoted to machine
|
||||||
|
learning-based method that uses a text classifier.
|
||||||
|
|
||||||
\textbf{Key words:} information extraction
|
\textbf{Key words:} information extraction, web spidering, text classification
|
134
bibliografia.bib
134
bibliografia.bib
@ -1,66 +1,98 @@
|
|||||||
@ARTICLE{Bootstrap,
|
|
||||||
author = {Daniel Waegel},
|
|
||||||
title = {A Survey of Bootstrapping Techniques in Natural Language Processing},
|
|
||||||
journal = {Department of Computer Science,
|
|
||||||
University of Delaware, Literature Survey Reports},
|
|
||||||
year = {2013}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ARTICLE{Hearst,
|
|
||||||
author = {Marti Hearst },
|
|
||||||
title = {Automatic Acquisition of Hyponyms from Large Text Corpora.},
|
|
||||||
journal = {Proc. of the
|
|
||||||
Fourteenth International Conference on Computational Linguistics, Nantes, France.},
|
|
||||||
year = {1992}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@inproceedings{genetic,
|
|
||||||
title={Learning text patterns using separate-and-conquer genetic programming},
|
|
||||||
author={Bartoli, Alberto and De Lorenzo, Andrea and Medvet, Eric and Tarlao, Fabiano},
|
|
||||||
booktitle={European Conference on Genetic Programming},
|
|
||||||
pages={16--27},
|
|
||||||
year={2015},
|
|
||||||
organization={Springer}
|
|
||||||
}
|
|
||||||
|
|
||||||
@article{ramped,
|
|
||||||
title={Genetic programming as a means for programming computers by natural selection},
|
|
||||||
author={Koza, John R},
|
|
||||||
journal={Statistics and computing},
|
|
||||||
volume={4},
|
|
||||||
number={2},
|
|
||||||
pages={87--112},
|
|
||||||
year={1994},
|
|
||||||
publisher={Springer}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@article{gus,
|
@article{gus,
|
||||||
title={Rocznik statystyczny Rzeczypospolitej Polskiej 2017},
|
title={Rocznik statystyczny Rzeczypospolitej Polskiej 2017},
|
||||||
author={Dominik Rozkrut i in},
|
author={Dominik Rozkrut},
|
||||||
journal={GUS},
|
journal={GUS},
|
||||||
volume={T. LXXVII},
|
volume={T. LXXVII},
|
||||||
pages={194--195},
|
pages={194--195},
|
||||||
year={2016}
|
year={2017}
|
||||||
@Comment publisher={}
|
@Comment publisher={}
|
||||||
}
|
}
|
||||||
|
|
||||||
@misc{beautiful_soup,
|
@misc{beautiful_soup,
|
||||||
title = {BeautifulSoup},
|
title = {Strona internetowa {BeautifulSoup}},
|
||||||
note = {Crummy.org},
|
|
||||||
key = {BeautifulSoup},
|
key = {BeautifulSoup},
|
||||||
howpublished={\url{https://www.crummy.com/software/BeautifulSoup/}}
|
howpublished={\url{https://www.crummy.com/software/BeautifulSoup/}}
|
||||||
|
note = "Crummy.org [Online; dostęp 22.06.2018]"
|
||||||
}
|
}
|
||||||
@misc{expotential_backoff}
|
@misc{expotential_backoff,
|
||||||
@misc{google_api}
|
title = "Exponential backoff --- {Wikipedia}{,} The Free Encyclopedia",
|
||||||
@misc{text_search}
|
year = "2018",
|
||||||
@misc{place_detail}
|
howpublished = "\url{https://en.wikipedia.org/w/index.php?title=Exponential_backoff&oldid=830252246}",
|
||||||
@misc{jsonline}
|
note = "[Online; dostęp 22.06.2018]"
|
||||||
@misc{binaryornot}
|
}
|
||||||
@misc{html2text}
|
@misc{google_api,
|
||||||
@misc{markdown}
|
title = "{Google Places API}",
|
||||||
@misc{scrapy}
|
howpublished = "\url{https://developers.google.com/places/web-service/intro}",
|
||||||
|
note = "[Online; dostęp 22.06.2018]"
|
||||||
|
}
|
||||||
|
@misc{text_search,
|
||||||
|
title = "{Google Place Search}",
|
||||||
|
howpublished = "\url{https://developers.google.com/places/web-service/search}",
|
||||||
|
note = "[Online; dostęp 22.06.2018]"
|
||||||
|
}
|
||||||
|
@misc{place_detail,
|
||||||
|
title = "{Google Place Details}",
|
||||||
|
howpublished = "\url{https://developers.google.com/places/web-service/details}",
|
||||||
|
note = "[Online; dostęp 22.06.2018]"
|
||||||
|
}
|
||||||
|
@misc{jsonline,
|
||||||
|
title = "{Dokumentacja formatu JSON Lines}",
|
||||||
|
howpublished = "\url{jsonlines.org}",
|
||||||
|
note = "[Online; dostęp 22.06.2018]"
|
||||||
|
}
|
||||||
|
@misc{html2text,
|
||||||
|
title = "{Repozytorium html2text}",
|
||||||
|
howpublished = "\url{https://github.com/Alir3z4/html2text}",
|
||||||
|
note = "[Online; dostęp 22.06.2018]"
|
||||||
|
}
|
||||||
|
@techreport{markdown, author = {S. Leonard}, title = {The text/markdown Media Type}, howpublished = {Internet Requests for Comments}, type = {RFC}, number = {7763}, year = {2016}, month = {March}, issn = {2070-1721}, publisher = {RFC Editor}, institution = {RFC Editor}, }
|
||||||
|
|
||||||
|
@misc{fingerprintjs2,
|
||||||
|
title = "{Dokumentacja fingerprintjs2}",
|
||||||
|
howpublished = "\url{https://github.com/Valve/fingerprintjs2/blob/master/README.md}",
|
||||||
|
note = "[Online; dostęp 22.06.2018]"
|
||||||
|
}
|
||||||
|
@misc{softmax,
|
||||||
|
title = "Softmax function --- {Wikipedia}{,} The Free Encyclopedia",
|
||||||
|
year = "2018",
|
||||||
|
howpublished = "\url{https://en.wikipedia.org/w/index.php?title=Softmax_function&oldid=843761006}",
|
||||||
|
note = "[Online; dostęp 22.06.2018]"
|
||||||
|
}
|
||||||
|
@article{scrapy,
|
||||||
|
author = {Myers, Daniel and McGuffee, James W.},
|
||||||
|
title = {Choosing Scrapy},
|
||||||
|
journal = {J. Comput. Sci. Coll.},
|
||||||
|
issue_date = {October 2015},
|
||||||
|
volume = {31},
|
||||||
|
number = {1},
|
||||||
|
month = oct,
|
||||||
|
year = {2015},
|
||||||
|
issn = {1937-4771},
|
||||||
|
pages = {83--89},
|
||||||
|
numpages = {7},
|
||||||
|
url = {http://dl.acm.org/citation.cfm?id=2831373.2831387},
|
||||||
|
acmid = {2831387},
|
||||||
|
publisher = {Consortium for Computing Sciences in Colleges},
|
||||||
|
address = {USA},
|
||||||
|
}
|
||||||
|
@article{word2vec,
|
||||||
|
author = {Xin Rong},
|
||||||
|
title = {word2vec Parameter Learning Explained},
|
||||||
|
journal = {CoRR},
|
||||||
|
volume = {abs/1411.2738},
|
||||||
|
year = {2014},
|
||||||
|
url = {http://arxiv.org/abs/1411.2738},
|
||||||
|
archivePrefix = {arXiv},
|
||||||
|
eprint = {1411.2738},
|
||||||
|
timestamp = {Wed, 07 Jun 2017 14:43:03 +0200},
|
||||||
|
biburl = {https://dblp.org/rec/bib/journals/corr/Rong14},
|
||||||
|
bibsource = {dblp computer science bibliography, https://dblp.org}
|
||||||
|
}
|
||||||
|
@misc{fasttext,
|
||||||
|
Author = {Armand Joulin and Edouard Grave and Piotr Bojanowski and Tomas Mikolov},
|
||||||
|
Title = {Bag of Tricks for Efficient Text Classification},
|
||||||
|
Year = {2016},
|
||||||
|
Eprint = {arXiv:1607.01759},
|
||||||
@article{parallel,
|
@article{parallel,
|
||||||
title = {GNU Parallel - The Command-Line Power Tool},
|
title = {GNU Parallel - The Command-Line Power Tool},
|
||||||
author = {O. Tange},
|
author = {O. Tange},
|
||||||
|
@ -1 +1 @@
|
|||||||
<mxfile userAgent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36" version="8.7.10" editor="www.draw.io" type="device"><diagram id="cb6c6256-43c7-094e-4ab5-cf55f2e6a3c1" name="Page-1">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</diagram></mxfile>
|
<mxfile userAgent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36" version="8.7.10" editor="www.draw.io" type="device"><diagram id="cb6c6256-43c7-094e-4ab5-cf55f2e6a3c1" name="Page-1">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</diagram></mxfile>
|
19
master.tex
19
master.tex
@ -1,4 +1,4 @@
|
|||||||
\documentclass[a4paper, 12pt, twoside]{report}
|
\documentclass[a4paper, 12pt, twoside, reqno]{report}
|
||||||
\input{pakiety.tex}
|
\input{pakiety.tex}
|
||||||
\input{ustawienia.tex}
|
\input{ustawienia.tex}
|
||||||
|
|
||||||
@ -51,14 +51,19 @@
|
|||||||
\newpage\null\thispagestyle{empty}\newpage
|
\newpage\null\thispagestyle{empty}\newpage
|
||||||
|
|
||||||
% spis ilustracji:
|
% spis ilustracji:
|
||||||
%\newpage
|
\newpage
|
||||||
%\listoffigures
|
\listoffigures
|
||||||
%\addcontentsline{toc}{chapter}{Spis ilustracji}
|
\addcontentsline{toc}{chapter}{Spis rysunków}
|
||||||
|
|
||||||
|
% spis algorytmów:
|
||||||
|
\newpage
|
||||||
|
\listofalgorithms
|
||||||
|
\addcontentsline{toc}{chapter}{Spis algorytmów}
|
||||||
|
|
||||||
% spis tabel:
|
% spis tabel:
|
||||||
%\newpage
|
\newpage
|
||||||
%\listoftables
|
\listoftables
|
||||||
%\addcontentsline{toc}{chapter}{Spis tabel}
|
\addcontentsline{toc}{chapter}{Spis tabel}
|
||||||
|
|
||||||
|
|
||||||
%bibliografia
|
%bibliografia
|
||||||
|
@ -5,6 +5,12 @@
|
|||||||
\usepackage{makeidx} % indeks
|
\usepackage{makeidx} % indeks
|
||||||
\usepackage[pdftex]{graphicx} % zalaczanie grafiki
|
\usepackage[pdftex]{graphicx} % zalaczanie grafiki
|
||||||
\usepackage{tikz} % grafika wektorowa
|
\usepackage{tikz} % grafika wektorowa
|
||||||
|
\usepackage[
|
||||||
|
left = „,
|
||||||
|
right = ”,
|
||||||
|
leftsub = «,
|
||||||
|
rightsub = »
|
||||||
|
]{dirtytalk} % cudzysłówy dla różnych języków \say{nic} --> "nic"
|
||||||
|
|
||||||
\usepackage{setspace} % interlinia
|
\usepackage{setspace} % interlinia
|
||||||
|
|
||||||
@ -24,6 +30,7 @@
|
|||||||
\usepackage{floatflt} % ladne oplywanie obrazkow tekstem
|
\usepackage{floatflt} % ladne oplywanie obrazkow tekstem
|
||||||
\usepackage{url} % url w bibliografii
|
\usepackage{url} % url w bibliografii
|
||||||
\usepackage{amsmath}
|
\usepackage{amsmath}
|
||||||
|
\usepackage{mathtools}
|
||||||
\usepackage{amsthm}
|
\usepackage{amsthm}
|
||||||
\usepackage[section]{placeins} %wymusza by obrazek był w obrębie sekacji a nie poza nią
|
\usepackage[section]{placeins} %wymusza by obrazek był w obrębie sekacji a nie poza nią
|
||||||
|
|
||||||
|
566
rozdzial_3.tex
566
rozdzial_3.tex
@ -1,13 +1,12 @@
|
|||||||
\chapter{Podstawy teoretyczne i/lub spis pojęć}
|
|
||||||
\chapter{Ekstrakcja godzin rozpoczęcia mszy świętych}
|
\chapter{Ekstrakcja godzin rozpoczęcia mszy świętych}
|
||||||
\section{Ogólny zarys systemu}
|
\section{Ogólny zarys systemu}
|
||||||
Architektura systemu ekstrakcji godzin rozpoczęcia mszy świętych została
|
Architektura systemu ekstrakcji godzin rozpoczęcia mszy świętych została
|
||||||
przedstawiona na rysunku \ref{pic:architektura}. W tym podrozdziale zostanie ona
|
przedstawiona na rysunku \ref{pic:architektura}. W niniejszym podrozdziale zostanie ona
|
||||||
krótko opisana. Szczegółowy opis poszczególnych komponentów znajduje się w
|
krótko opisana. Szczegółowy opis poszczególnych komponentów znajduje się w
|
||||||
kolejnych podrozdziałach.
|
podrozdziałach \ref{sub:zbieranie_informacji} - \ref{sub:klasyfikacja}.
|
||||||
|
|
||||||
System zaczyna działanie od zebrania jak największej ilości danych (nazwa parafii, adres, diecezja
|
System zaczyna działanie od zebrania jak największej ilości danych (nazwa parafii, adres, diecezja
|
||||||
itd.) o polskich parafiach ze strony deon.pl. Następnie wysyła zapytania do interfejsu API
|
itd.) o polskich parafiach ze strony \url{deon.pl}. Następnie wysyła zapytania do interfejsu API
|
||||||
Google w
|
Google w
|
||||||
celu znalezienia adresów internetowych parafii.
|
celu znalezienia adresów internetowych parafii.
|
||||||
Dla każdej parafii, dla której udało się znaleźć adres URL, pobierane są wszystkie
|
Dla każdej parafii, dla której udało się znaleźć adres URL, pobierane są wszystkie
|
||||||
@ -16,7 +15,7 @@ podstrony w odległości\footnote{Zakładamy, że sieć jest grafem, zatem odleg
|
|||||||
|
|
||||||
Z dużej liczby stron parafialnych, za pomocą reguł wyodrębnione zostają
|
Z dużej liczby stron parafialnych, za pomocą reguł wyodrębnione zostają
|
||||||
te, na których z dużym prawdopodobieństwem znajdują się godziny mszy świętych.
|
te, na których z dużym prawdopodobieństwem znajdują się godziny mszy świętych.
|
||||||
Następnie godziny zostają wydobyte ekstraktorem
|
Następnie godziny zostają wydobyte ekstraktorem godzin
|
||||||
o bardzo niskiej precyzji i bardzo wysokiej wartości pokrycia.
|
o bardzo niskiej precyzji i bardzo wysokiej wartości pokrycia.
|
||||||
Każda godzina wraz z kontekstem, w jakim się znajduje, trafia do anotatora.
|
Każda godzina wraz z kontekstem, w jakim się znajduje, trafia do anotatora.
|
||||||
Tam jest oznaczana jako poprawna lub niepoprawna godzina mszy
|
Tam jest oznaczana jako poprawna lub niepoprawna godzina mszy
|
||||||
@ -24,8 +23,8 @@ Tam jest oznaczana jako poprawna lub niepoprawna godzina mszy
|
|||||||
godziny mszy świętych” rozumiemy godziny, które nie są
|
godziny mszy świętych” rozumiemy godziny, które nie są
|
||||||
godzinami rozpoczęcia mszy świętych.}.
|
godzinami rozpoczęcia mszy świętych.}.
|
||||||
Regułowy ekstraktor mszy świętych o bardzo wysokiej precyzji znajduje poprawne
|
Regułowy ekstraktor mszy świętych o bardzo wysokiej precyzji znajduje poprawne
|
||||||
godziny mszy świętych i dołącza je do zanotowanych danych.
|
godziny mszy świętych i dołącza je do zaanotowanych danych.
|
||||||
Dodatkowo w celu wyrównania
|
Co więcej, w celu wyrównania
|
||||||
klas z nieodfiltrowanego zbioru stron parafialnych wylosowane zostają niepoprawne godziny mszy świętych.
|
klas z nieodfiltrowanego zbioru stron parafialnych wylosowane zostają niepoprawne godziny mszy świętych.
|
||||||
Zebrane dane zostają użyte do wytrenowania klasyfikatora godzin opartego na
|
Zebrane dane zostają użyte do wytrenowania klasyfikatora godzin opartego na
|
||||||
płytkich sieciach neuronowych.
|
płytkich sieciach neuronowych.
|
||||||
@ -53,6 +52,7 @@ znalezionych przez ekstraktor godzin do następujących klas:
|
|||||||
\clearpage
|
\clearpage
|
||||||
|
|
||||||
\section{Zbieranie informacji o parafiach}
|
\section{Zbieranie informacji o parafiach}
|
||||||
|
\label{sub:zbieranie_informacji}
|
||||||
|
|
||||||
\begin{figure}[htb]
|
\begin{figure}[htb]
|
||||||
\center
|
\center
|
||||||
@ -61,10 +61,10 @@ znalezionych przez ekstraktor godzin do następujących klas:
|
|||||||
\label{pic:pajak_nazw_parafii}
|
\label{pic:pajak_nazw_parafii}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
Na rysunku \ref{pic:pajak_nazw_parafii} został przedstawiony fragment architektury
|
Na rysunku \ref{pic:pajak_nazw_parafii} został przedstawiony fragment architektury
|
||||||
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w tym podrozdziale.
|
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w niniejszym podrozdziale.
|
||||||
|
|
||||||
Dane zostały zebrane z serwisu internetowego deon.pl, który zawiera 10130 parafii.
|
Dane zostały zebrane z serwisu internetowego deon.pl, który zawiera 10130 parafii.
|
||||||
Jest to większość polskich parafii, ponieważ według
|
Są to prawie wszystkie polskie parafie, ponieważ według
|
||||||
danych statystycznych GUS\cite{gus} z 2016 roku w Polsce było
|
danych statystycznych GUS\cite{gus} z 2016 roku w Polsce było
|
||||||
10255 parafii.
|
10255 parafii.
|
||||||
|
|
||||||
@ -91,14 +91,14 @@ Dla każdej parafii zebrano:
|
|||||||
Św. Trójcy & Paszowice & Paszowic... & legnicka & Jawor & dolnośląskie\\
|
Św. Trójcy & Paszowice & Paszowic... & legnicka & Jawor & dolnośląskie\\
|
||||||
\\ [-1.5ex]
|
\\ [-1.5ex]
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\caption{Fragment zebranych danych.}
|
\caption{Fragment danych zebranych przez pająka nazw i adresów parafii.}
|
||||||
\label{dane_tab}
|
\label{dane_tab}
|
||||||
\end{table}
|
\end{table}
|
||||||
|
|
||||||
Do wydobycia danych użyto skryptu w języku Python, który korzystał z parsera
|
Do wydobycia danych użyto skryptu w języku Python, który korzystał z parsera
|
||||||
HTML z biblioteki \textit{Beautiful Soup}\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
|
algorytm \textit{Expotential Backoff}\cite{expotential_backoff}
|
||||||
przedstawia się następująco:
|
(patrz algorytm \ref{alg:backoff}).
|
||||||
|
|
||||||
\begin{algorithm}
|
\begin{algorithm}
|
||||||
\setstretch{1.2}
|
\setstretch{1.2}
|
||||||
@ -138,7 +138,7 @@ Dla każdej parafii zebrano:
|
|||||||
|
|
||||||
Algorytm \ref{alg:backoff} uodparnia skrypt na przejściowe problemy z połączeniem i
|
Algorytm \ref{alg:backoff} uodparnia skrypt na przejściowe problemy z połączeniem i
|
||||||
zapobiega zbyt częstemu wysyłaniu zapytań do serwisu. Dla przykładu załóżmy,
|
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ń.
|
że dany serwis jest obciążony i odpowiada na zapytanie z dużym opóźnieniem.
|
||||||
Wtedy algorytm \textit{Expotential Backoff} przy każdym kolejnym niepowodzeniu
|
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.
|
będzie niepotrzebnie obciążał serwisu.
|
||||||
@ -153,14 +153,14 @@ Dla każdej parafii zebrano:
|
|||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
Na rysunku \ref{pic:pajak_url} został przedstawiony fragment architektury
|
Na rysunku \ref{pic:pajak_url} został przedstawiony fragment architektury
|
||||||
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w tym podrozdziale.
|
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w niniejszym podrozdziale.
|
||||||
|
|
||||||
\subsubsection{Pierwsze próby}
|
\subsubsection{Pierwsze próby}
|
||||||
Do wyszukiwania adresów URL parafii próbowano wykorzystać wyszukiwarki takie jak
|
Do wyszukiwania adresów URL parafii próbowano wykorzystać wyszukiwarki takie jak
|
||||||
Google i DuckDuckGo. Automatycznie wysyłano zapytanie złożone z konkatenacji
|
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
|
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
|
zadowalające wyniki, jednak po kilkunastu zapytaniach blokowała adres IP.
|
||||||
dodatku w warunkach użytkowania serwisu i w pliku \textit{robots.txt} Google zabrania
|
Ponadto, w warunkach użytkowania serwisu i w pliku \textit{robots.txt} Google zabrania
|
||||||
korzystania z pająków na ich wyszukiwarce.
|
korzystania z pająków na ich wyszukiwarce.
|
||||||
Wyszukiwarka DuckDuckGo nie blokowała adresu IP, ale zabraniała indeksowania w pliku \textit{robots.txt} i słabo 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
|
zapytaniami. W obu przypadkach powyższa metoda stwarzała kolejny problem do
|
||||||
@ -171,12 +171,12 @@ Po wielokrotnych próbach poszukiwań znaleziono klucz do rozwiązania problemu
|
|||||||
wyszukiwania adresów URL, jakim jest
|
wyszukiwania adresów URL, jakim jest
|
||||||
\textit{Google Places API}\cite{google_api}. Serwis \textit{Text Search}\cite{text_search} pozwala na wyszukanie miejsca
|
\textit{Google Places API}\cite{google_api}. Serwis \textit{Text Search}\cite{text_search} pozwala na wyszukanie miejsca
|
||||||
danego obiektu na
|
danego obiektu na
|
||||||
podstawie jego nazwy. Ponadto mając już wyszukany dany obiekt i jego
|
podstawie jego nazwy. Ponadto, mając już wyszukany dany obiekt i jego
|
||||||
identyfikator można odpytać serwis \textit{Place Detail}\cite{place_detail}, aby wyciągnąć więcej
|
identyfikator można odpytać serwis \textit{Place Detail}\cite{place_detail}, aby wyciągnąć więcej
|
||||||
szczegółów o danym miejscu. Między innymi można otrzymać adres URL danego obiektu.
|
szczegółów o danym miejscu. Między innymi można otrzymać adres URL danego obiektu.
|
||||||
|
|
||||||
Jedynym minusem jest ograniczenie liczby zapytań do 1000 na 24 godziny. W
|
Jedynym minusem jest ograniczenie liczby zapytań do 1000 na 24 godziny. W
|
||||||
dodatku każde zapytanie do serwisu \textit{Text Search} traktowane jest jak 10
|
dodatku, każde zapytanie do serwisu \textit{Text Search} traktowane jest jak 10
|
||||||
zapytań. Podając swoją kartę płatniczą, można zwiększyć limit
|
zapytań. Podając swoją kartę płatniczą, można zwiększyć limit
|
||||||
zapytań do 150 000 na 24 godziny. Karta płatnicza jest potrzebna Google do
|
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
|
identyfikacji osoby. Żadna opłata nie jest pobierana za korzystanie z interfejsu
|
||||||
@ -193,10 +193,10 @@ 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
|
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}.
|
adres internetowy. Taki przypadek przedstawia rysunek \ref{pic:text_search}.
|
||||||
Serwis \textit{Text Search} zwraca dużo danych w formacie JSON, które
|
Serwis \textit{Text Search} zwraca dużo danych w formacie JSON, które
|
||||||
ciężko przedstawić w przejrzystej postaci.
|
trudno jest przedstawić w przejrzystej postaci.
|
||||||
Dla
|
Dla
|
||||||
czytelności na rysunku \ref{pic:text_search} pokazano zrzuty ekranu z wyszukiwarki \textit{Google Maps},
|
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
|
które odpowiadają rezultatowi, jaki otrzymano, korzystając z serwisu
|
||||||
\textit{Text Search}.
|
\textit{Text Search}.
|
||||||
|
|
||||||
\noindent Powyższą metodą udało się zebrać adresy URL dla ok. 5600 parafii.
|
\noindent Powyższą metodą udało się zebrać adresy URL dla ok. 5600 parafii.
|
||||||
@ -222,7 +222,7 @@ które odpowiadają rezultatowi, jaki otrzymano by, korzystając z serwisu
|
|||||||
|
|
||||||
|
|
||||||
Na rysunku \ref{pic:pajak_parafii_general} został przedstawiony fragment architektury
|
Na rysunku \ref{pic:pajak_parafii_general} został przedstawiony fragment architektury
|
||||||
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w tym podrozdziale.
|
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w niniejszym podrozdziale.
|
||||||
|
|
||||||
Pająk został napisany przy użyciu biblioteki \textit{Scrapy}\cite{scrapy}.
|
Pająk został napisany przy użyciu biblioteki \textit{Scrapy}\cite{scrapy}.
|
||||||
Punktem startowym jest pojedynczy adres URL parafii podawany na wejście
|
Punktem startowym jest pojedynczy adres URL parafii podawany na wejście
|
||||||
@ -235,17 +235,17 @@ asynchronicznie wysłać wiele zapytań do serwera i odbierać wiele odpowiedzi
|
|||||||
Pająk składa się z następujących komponentów:
|
Pająk składa się z następujących komponentów:
|
||||||
\begin{description}
|
\begin{description}
|
||||||
\item [Silnik] -- odpowiada za kontrolę przepływu danych i komunikację między komponentami.
|
\item [Silnik] -- odpowiada za kontrolę przepływu danych i komunikację między komponentami.
|
||||||
\item [Dyspozytor] -- otrzymuje żądania od silnika, kolejkuje je i na
|
\item [Dyspozytor] -- otrzymuje żądania od \textit{silnika}, kolejkuje je i na
|
||||||
prośbę silnika odsyła z powrotem.
|
prośbę \textit{silnika} odsyła z powrotem.
|
||||||
\item [Downloader] -- odpowiada za pobieranie stron parafialnych i
|
\item [Downloader] -- odpowiada za pobieranie stron parafialnych i
|
||||||
przekazywanie ich silnikowi.
|
przekazywanie ich \textit{silnikowi}.
|
||||||
\item [Procesor danych] -- zajmuje się końcową obróbką i zapisem danych.
|
\item [Procesor danych] -- zajmuje się końcową obróbką i zapisem danych.
|
||||||
\item [Spider]\footnote{Użyto angielskiej nazwy, aby rozróżnić
|
\item [Spider]\footnote{Użyto angielskiej nazwy, aby rozróżnić
|
||||||
\textit{spider'a} (komponent pająka), od pająka (cały program
|
\textit{spider'a} (komponent pająka), od pająka (cały program
|
||||||
odpowiedzialny za indeksowanie stron parafialnych).}
|
odpowiedzialny za indeksowanie stron parafialnych).}
|
||||||
- definiuje sposób, w jaki pobierać dane, między innymi jak parsować stronę i za jakimi
|
- definiuje sposób, w jaki pobierać dane, między innymi jak parsować stronę i za jakimi
|
||||||
linkami podążać.
|
linkami podążać.
|
||||||
\item [Spider middleware] -- programy pośredniczące między silnikiem, a
|
\item [Spider middleware] -- programy pośredniczące między \textit{silnikiem}, a
|
||||||
\textit{spider'em}. Odpowiedzialne są za dodatkowe przetwarzanie danych wyjściowych
|
\textit{spider'em}. Odpowiedzialne są za dodatkowe przetwarzanie danych wyjściowych
|
||||||
(dane parafialne i żądania) i wejściowych (odpowiedzi) \textit{spider'a}.
|
(dane parafialne i żądania) i wejściowych (odpowiedzi) \textit{spider'a}.
|
||||||
\item [Downloader middleware] -- programy pośredniczące między silnikiem, a
|
\item [Downloader middleware] -- programy pośredniczące między silnikiem, a
|
||||||
@ -256,7 +256,7 @@ Pająk składa się z następujących komponentów:
|
|||||||
\subsection{Przepływ danych}
|
\subsection{Przepływ danych}
|
||||||
|
|
||||||
Przepływ danych kontrolowany jest przez
|
Przepływ danych kontrolowany jest przez
|
||||||
silnik i wygląda następująco\footnote{Diagram i opis wzorowany jest na
|
\textit{silnik} i ma postać przedstawioną na rysunku \ref{pic:scrapy_data_flow}\footnote{Diagram i opis wzorowany jest na
|
||||||
dokumentacji znajdującej się pod linkiem https://doc.scrapy.org/en/latest/topics/architecture.html.}:
|
dokumentacji znajdującej się pod linkiem https://doc.scrapy.org/en/latest/topics/architecture.html.}:
|
||||||
|
|
||||||
\begin{figure}[tbh]
|
\begin{figure}[tbh]
|
||||||
@ -265,34 +265,33 @@ silnik i wygląda następująco\footnote{Diagram i opis wzorowany jest na
|
|||||||
\caption{Silnik kontrolujący przepływ danych przez komponenty pająka.}
|
\caption{Silnik kontrolujący przepływ danych przez komponenty pająka.}
|
||||||
\label{pic:scrapy_data_flow}
|
\label{pic:scrapy_data_flow}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
\begin{enumerate}
|
\begin{enumerate}
|
||||||
\item Silnik otrzymuje od \textit{spider'a} żądanie pobrania początkowej strony danej
|
\item \textit{Silnik} otrzymuje od \textit{spider'a} żądanie pobrania początkowej strony danej
|
||||||
parafii (najczęściej jest to strona główna parafii).
|
parafii (najczęściej jest to strona główna parafii).
|
||||||
\item Silnik oddaje żądania dyspozytorowi, który kolejkuje je do dalszego
|
\item \textit{Silnik} oddaje żądania \textit{dyspozytorowi}, który kolejkuje je do dalszego
|
||||||
przetwarzania oraz pyta dyspozytora o żądania gotowe do przekazania \textit{downloader'owi}.
|
przetwarzania oraz pyta \textit{dyspozytor} o żądania gotowe do przekazania \textit{downloader'owi}.
|
||||||
\item Dyspozytor zwraca silnikowi następne żądania.
|
\item \textit{Dyspozytor} zwraca \textit{silnikowi} następne żądania.
|
||||||
\item Silnik wysyła żądania do \textit{downloader'a}. Zanim żądania dotrą do
|
\item \textit{Silnik} wysyła żądania do \textit{downloader'a}. Zanim żądania dotrą do
|
||||||
\textit{downloader'a}, przetwarzane są przez \textit{downloader middleware}.
|
\textit{downloader'a}, przetwarzane są przez \textit{downloader middleware}.
|
||||||
\item \textit{Downloader} pobiera stronę parafialną i umieszcza ją w odpowiedzi, którą
|
\item \textit{Downloader} pobiera stronę parafialną i umieszcza ją w odpowiedzi, którą
|
||||||
przesyła silnikowi. Zanim odpowiedź dotrze do silnika, przetwarzana jest przez
|
przesyła \textit{silnikowi}. Zanim odpowiedź dotrze do \textit{silnika}, przetwarzana jest przez
|
||||||
\textit{downloader middleware}.
|
\textit{downloader middleware}.
|
||||||
\item Silnik otrzymuje odpowiedź od \textit{downloader'a} i przekazuje ją \textit{spider'owi} do
|
\item \textit{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
|
dalszego przetwarzania. Zanim odpowiedź trafi, do \textit{spider'a} przetwarzana jest
|
||||||
przez \textit{spider middleware}.
|
przez \textit{spider middleware}.
|
||||||
\item \textit{Spider} przerabia odpowiedź i zwraca dane strony parafialnej silnikowi. Zanim dane
|
\item \textit{Spider} przetwarza odpowiedź i zwraca dane strony parafialnej \textit{silnikowi}. Zanim dane
|
||||||
trafią, do silnika przechodzą przez \textit{spider middleware}. Dodatkowo \textit{spider}
|
trafią do \textit{silnika}, przechodzą przez \textit{spider middleware}. Dodatkowo \textit{spider}
|
||||||
wysyła żądania z nowymi stronami parafialnymi do pobrania.
|
wysyła żądania z nowymi stronami parafialnymi do pobrania.
|
||||||
\item Silnik wysyła zebrane dane do procesora danych, który zapisuje je do
|
\item \textit{Silnik} wysyła zebrane dane do \textit{procesora danych}, który zapisuje je do
|
||||||
pliku. Następnie przekazuje nowe żądania do zakolejkowania
|
pliku. Następnie przekazuje nowe żądania do zakolejkowania
|
||||||
dyspozytorowi.
|
\textit{dyspozytorowi}.
|
||||||
\end{enumerate}
|
\end{enumerate}
|
||||||
% \vspace*{-20mm}
|
% \vspace*{-20mm}
|
||||||
Cały proces trwa dopóty, dopóki są nowe żądania do przetworzenia.
|
Cały proces trwa dopóty, dopóki są nowe żądania do przetworzenia.
|
||||||
|
|
||||||
\subsection{Sprawdzanie typu odpowiedzi}
|
\subsection{Sprawdzanie typu odpowiedzi}
|
||||||
Podczas indeksowania ważne jest rozpoznawanie typu pobieranych danych. W przypadku
|
Podczas indeksowania ważne jest rozpoznawanie typu pobieranych danych. W przypadku
|
||||||
indeksowania stron parafialnych interesują nas wyłącznie dane tekstowe. Należy
|
indeksowania stron parafialnych przedmiotem zainteresowania są wyłącznie dane tekstowe. Należy
|
||||||
zatem zadbać o to, aby nie pobierać danych binarnych takich jak np. video, audio
|
zatem zadbać o to, aby nie pobierać danych binarnych takich jak np. video, audio
|
||||||
i obrazy.
|
i obrazy.
|
||||||
|
|
||||||
@ -306,12 +305,14 @@ następujących kryteriach:
|
|||||||
rozpoznać po nazwie pliku lub adresie URL).
|
rozpoznać po nazwie pliku lub adresie URL).
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
Powyższy schemat postępowania jest skuteczny, jeśli serwisy internetowe zwracają
|
Powyższy schemat postępowania jest skuteczny, jeśli serwisy internetowe zwracają
|
||||||
poprawne odpowiedzi. Niestety niektóre strony parafialne potrafią zwracać
|
poprawne odpowiedzi. Niestety, niektóre strony parafialne zwracają
|
||||||
odpowiedzi, które nie są zgodne z rozdziałem 3.1 z dokumentu RFC7231\cite{RFC7231}.
|
odpowiedzi, które nie są zgodne z rozdziałem 3.1 z dokumentu
|
||||||
|
RFC7231\cite{RFC7231}\footnote{RFC to zbiór technicznych dokumentów w formie
|
||||||
|
memorandum opisujących protokoły związane z Internetem i sieciami komputerowymi.}.
|
||||||
Dla przykładu strona potrafi zwrócić \mintinline{bash}{Content-Type: text/html}
|
Dla przykładu strona potrafi zwrócić \mintinline{bash}{Content-Type: text/html}
|
||||||
w nagłówku, a w ciele binarną
|
w nagłówku, a w ciele -- binarną
|
||||||
zawartość np. film. Tego rodzaju anomalie są wykrywane i eliminowane.
|
zawartość np. film. Tego rodzaju anomalie są wykrywane i eliminowane.
|
||||||
\enlargethispage{2\baselineskip}
|
\enlargethispage{3\baselineskip}
|
||||||
Stosując algorytm \ref{alg:binaryornot}, można określić typ zawartości
|
Stosując algorytm \ref{alg:binaryornot}, można określić typ zawartości
|
||||||
ciała odpowiedzi.
|
ciała odpowiedzi.
|
||||||
|
|
||||||
@ -355,7 +356,7 @@ ciała odpowiedzi.
|
|||||||
\end{algorithm}
|
\end{algorithm}
|
||||||
|
|
||||||
Algorytm \ref{alg:binaryornot} analizuje zawartość ciała odpowiedzi w celu
|
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
|
W linii 6 za znaki kontrolne uznano
|
||||||
wszystkie znaki kontrolne ze zbioru C0\footnote{C0 to znaki kontrolne z kodu
|
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
|
ASCII o kodach od 0 do 32 i o kodzie 127.} i C1\footnote{C1 to znaki kontrolne
|
||||||
@ -377,7 +378,8 @@ Warto zwrócić uwagę na linię 10. Współczynnik
|
|||||||
\mintinline{python}{control_char_ratio}
|
\mintinline{python}{control_char_ratio}
|
||||||
oznacza procent znaków kontrolnych w pierwszych 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ż
|
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
|
$0,3$, to plik jest uznawany za binarny. Wartość $0,3$ została przyjęta z
|
||||||
|
rozwiązania 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.}
|
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
|
ź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
|
binarnych. Natomiast współczynnik \mintinline{python}{high_ascii_ratio} oznacza
|
||||||
@ -414,7 +416,7 @@ Załóżmy, że serwer potrzebuje
|
|||||||
zdefiniowana w algorytmie \ref{alg:throttling}.} sekund, aby odpowiedzieć pająkowi. Jeśli pająk chce
|
zdefiniowana w algorytmie \ref{alg:throttling}.} sekund, aby odpowiedzieć pająkowi. Jeśli pająk chce
|
||||||
mieć przetworzone równolegle
|
mieć przetworzone równolegle
|
||||||
\mintinline{python}{target_concurrency}\footnote{Stała
|
\mintinline{python}{target_concurrency}\footnote{Stała
|
||||||
\mintinline{python}{target_concurrency} została zdefiniowana w algorytmie \ref{alg:throttling}.}zapytań to powinien
|
\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}
|
wysyłać każde zapytanie co \mintinline{python}{latency/target_concurrency}
|
||||||
sekund.
|
sekund.
|
||||||
|
|
||||||
@ -511,7 +513,7 @@ indeksowania stron parafialnych.
|
|||||||
\subsection{Organizacja danych}
|
\subsection{Organizacja danych}
|
||||||
|
|
||||||
\enlargethispage{1\baselineskip}
|
\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
|
Dane zbierane przez pająka zapisywane są do pliku w formacie JSONL\cite{jsonline}. Format JSONL charakteryzuje się tym, że w każdej linii pliku
|
||||||
znajduje się poprawny obiekt JSON.
|
znajduje się poprawny obiekt JSON.
|
||||||
Dla
|
Dla
|
||||||
każdej parafii pobrane dane zapisywane są w oddzielnym pliku. W każdej linii
|
każdej parafii pobrane dane zapisywane są w oddzielnym pliku. W każdej linii
|
||||||
@ -520,7 +522,7 @@ Taki sposób organizacji danych przynosi szereg korzyści takich jak:
|
|||||||
\begin{enumerate}
|
\begin{enumerate}
|
||||||
\item wygodne przetwarzanie równoległe,
|
\item wygodne przetwarzanie równoległe,
|
||||||
\item łatwa obróbka danych za pomocą narzędzi Uniksowych,
|
\item łatwa obróbka danych za pomocą narzędzi Uniksowych,
|
||||||
\item mniejszy rozmiar pliku w porównaniu do zwykłego formatu \textit{JSON}.
|
\item mniejszy rozmiar pliku w porównaniu do zwykłego formatu JSON.
|
||||||
\end{enumerate}
|
\end{enumerate}
|
||||||
|
|
||||||
\noindent Dla każdej strony parafialnej zapisywane są następujące informacje:
|
\noindent Dla każdej strony parafialnej zapisywane są następujące informacje:
|
||||||
@ -543,7 +545,7 @@ Taki sposób organizacji danych przynosi szereg korzyści takich jak:
|
|||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
Na rysunku \ref{pic:html2text} został przedstawiony fragment architektury
|
Na rysunku \ref{pic:html2text} został przedstawiony fragment architektury
|
||||||
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w tym podrozdziale.
|
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w niniejszym podrozdziale.
|
||||||
|
|
||||||
Do konwersji z formatu HTML na format tekstowy wykorzystano bibliotekę \mintinline{bash}{html2text}\cite{html2text}
|
Do konwersji z formatu HTML na format tekstowy wykorzystano bibliotekę \mintinline{bash}{html2text}\cite{html2text}
|
||||||
pierwotnie rozwijaną przez Aarona Schwartza.
|
pierwotnie rozwijaną przez Aarona Schwartza.
|
||||||
@ -570,7 +572,7 @@ konwersji i jest bardzo łatwa w modyfikacji.
|
|||||||
\label{pic:general_ekstraktor}
|
\label{pic:general_ekstraktor}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
Na rysunku \ref{pic:html2text} został przedstawiony fragment architektury
|
Na rysunku \ref{pic:html2text} został przedstawiony fragment architektury
|
||||||
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w tym podrozdziale.
|
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w niniejszym podrozdziale.
|
||||||
|
|
||||||
Ekstraktor godzin służy do znajdowania bardzo ogólnych ciągów znaków mogących
|
Ekstraktor godzin służy do znajdowania bardzo ogólnych ciągów znaków mogących
|
||||||
być godzinami rozpoczęcia mszy świętych. Został napisany z myślą, aby miał
|
być godzinami rozpoczęcia mszy świętych. Został napisany z myślą, aby miał
|
||||||
@ -603,7 +605,7 @@ Ekstraktor wraz
|
|||||||
\label{pic:filtrowanie}
|
\label{pic:filtrowanie}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
Na rysunku \ref{pic:filtrowanie} został przedstawiony fragment architektury
|
Na rysunku \ref{pic:filtrowanie} został przedstawiony fragment architektury
|
||||||
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w tym podrozdziale.
|
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w niniejszym 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
|
dużym prawdopodobieństwem znajdują się godziny mszy świętych. Taki zabieg jest
|
||||||
@ -687,6 +689,7 @@ W algorytmie \ref{alg:has_mass} warto zwrócić uwagę na wyrażenia regularne
|
|||||||
się tam wyrażenia takie jak „nabożeństwa czerwcowe” czy „nabożeństwa maryjne”.
|
się tam wyrażenia takie jak „nabożeństwa czerwcowe” czy „nabożeństwa maryjne”.
|
||||||
|
|
||||||
\section{Anotator danych}
|
\section{Anotator danych}
|
||||||
|
\label{sec:anotator}
|
||||||
|
|
||||||
|
|
||||||
\begin{figure}[tbh!]
|
\begin{figure}[tbh!]
|
||||||
@ -698,13 +701,21 @@ W algorytmie \ref{alg:has_mass} warto zwrócić uwagę na wyrażenia regularne
|
|||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
Na rysunku \ref{pic:anotator} został przedstawiony fragment architektury
|
Na rysunku \ref{pic:anotator} został przedstawiony fragment architektury
|
||||||
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w tym podrozdziale.
|
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w niniejszym podrozdziale.
|
||||||
|
|
||||||
\subsection{Ogólny zarys}
|
\subsection{Ogólny zarys}
|
||||||
|
\label{subsec:anotator}
|
||||||
|
\begin{figure}[tbh!]
|
||||||
|
\center
|
||||||
|
\includegraphics[width=0.4\hsize]{antoator.jpg}
|
||||||
|
\caption{Zrzut ekranu pokazujący interfejs anotatora na urządzeniu mobilnym.}
|
||||||
|
\label{pic:antoator}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
Anotator danych został stworzony w celu zebrania jak największej ilości
|
Anotator danych został stworzony w celu zebrania jak największej ilości
|
||||||
danych dla klasyfikatora przewidującego czy zaznaczony fragment jest godziną
|
danych dla klasyfikatora przewidującego czy zaznaczony fragment jest godziną
|
||||||
rozpoczęcia mszy świętej, czy nie.
|
rozpoczęcia mszy świętej, czy nie.
|
||||||
Aby osiągnąć zamierzony cel anotator został zaprojektowany w ten sposób aby:
|
Żeby osiągnąć zamierzony cel, anotator został zaprojektowany w ten sposób, aby:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item był szybki,
|
\item był szybki,
|
||||||
\item był dostępny na urządzeniach mobilnych i stacjonarnych,
|
\item był dostępny na urządzeniach mobilnych i stacjonarnych,
|
||||||
@ -712,60 +723,467 @@ Aby osiągnąć zamierzony cel anotator został zaprojektowany w ten sposób aby
|
|||||||
\item umożliwiał wykrywanie oszustów (osób intencjonalnie źle anotujących).
|
\item umożliwiał wykrywanie oszustów (osób intencjonalnie źle anotujących).
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
\noindent Anotator jest dostępny jako aplikacja internetowa pod adresem \url{msze.nsupdate.info}. Aplikacja jest
|
\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
|
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
|
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:
|
został pokazany na rysunku \ref{pic:antoator}. Jedyne akcje, jakie może wykonać użytkownik to:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item kliknąć „Tak” jeśli zaznaczono godzinę rozpoczęcia mszy,
|
\item kliknąć „Tak”, jeśli zaznaczono godzinę rozpoczęcia mszy,
|
||||||
\item kliknąć „Nie” jeśli zaznaczono inną godzinę,
|
\item kliknąć „Nie”, jeśli zaznaczono inną godzinę,
|
||||||
\item cofnąć się do poprzedniej anotacji,
|
\item cofnąć się do poprzedniej anotacji,
|
||||||
\item wyświetlić instrukcję obsługi.
|
\item wyświetlić instrukcję obsługi.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
Po naciśnięciu przycisku „Tak” lub „Nie” ekran jest automatycznie przewijany na
|
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
|
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ą
|
temu znajdują się one również zawsze w tym samym miejscu, co ułatwia szybką
|
||||||
anotację.
|
anotację.
|
||||||
Po naciśnięciu przycisku „Cofnij” ekran nie jest już przewijany na sam dół. W
|
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
|
ten sposób zapewniono wygodny dostęp do przycisku „Cofnij”. Jest to szczególnie
|
||||||
istotne w przypadku gdy
|
istotne w przypadku gdy
|
||||||
użytkownik zamierza cofać się wiele razy.
|
użytkownik zamierza cofać się wiele razy.
|
||||||
|
|
||||||
Aby zapewnić odpowiednią jakość anotacji przy pierwszym urchomieniu wyświetlana
|
Aby zapewnić odpowiednią jakość anotacji, przy pierwszym uruchomieniu wyświetlana
|
||||||
jest instrukcja obsługi. Opisuje ona sposób w jaki należy anotować godziny oraz
|
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ąć
|
przedstawia przykłady poprawnie zaanotowanych godzin. Instrukcję można zamknąć
|
||||||
dopiero po przewinięciu jej na sam dół.
|
dopiero po przewinięciu jej na sam dół.
|
||||||
|
|
||||||
Aplikacja nie wymaga logowania. Taka
|
Aplikacja nie wymaga logowania. Taka
|
||||||
decyzja została podjęta ze względu na fakt, że anotatorami są wolontariusze.
|
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
|
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
|
anotacji. Takie podejście wiąże się jednak z problemem identyfikacji
|
||||||
użytkowników. Identyfikacja jest niezbędna do prawidłowego funkcjonawania
|
użytkowników. Identyfikacja jest niezbędna do prawidłowego funkcjonowania
|
||||||
antotora. Chcielibyśmy wiedzieć, które godziny zostały zanotowane przez danego
|
antotora. Chcielibyśmy wiedzieć, które godziny zostały zaanotowane przez danego
|
||||||
użytkownika, aby między innymi nie dać mu tych samych godzin do anotacji.
|
użytkownika, aby między innymi nie dać mu tych samych godzin do anotacji.
|
||||||
|
|
||||||
\subsection{Identyfikacja urządzeń}
|
\subsection{Identyfikacja urządzeń}
|
||||||
Skuteczną identyfikację można przeprowadzić używając
|
\enlargethispage{3\baselineskip}
|
||||||
|
Skuteczną identyfikację można przeprowadzić, używając ciasteczek oraz pobierając różne informacje o urządzeniu.
|
||||||
|
Za pomocą biblioteki \mintinline{text}{fingerprintjs2} można między innymi zebrać następujące
|
||||||
|
dane o kliencie\cite{fingerprintjs2}:
|
||||||
|
\begin{enumerate}
|
||||||
|
\item wersję przeglądarki,
|
||||||
|
\item język,
|
||||||
|
\item głębię koloru,
|
||||||
|
\item rozdzielczość ekranu,
|
||||||
|
\item strefę czasową,
|
||||||
|
\item obsługę \textit{localStorage}\footnote{Obiekt przechowujący dane w
|
||||||
|
przeglądarce bez daty ważności.},
|
||||||
|
\item obsługę \textit{sessionStorage}\footnote{Obiekt przechowujący dane w
|
||||||
|
przeglądarce tylko na czas sesji (po zamknięciu przeglądarki dane są usuwane).},
|
||||||
|
\item wspieranie \textit{indexed DB}\footnote{Niskopoziomy interfejs API dla
|
||||||
|
transakcyjnej bazy danych do przechowywania ustrukturyzowanych danych.},
|
||||||
|
\item klasę CPU,
|
||||||
|
\item system operacyjny,
|
||||||
|
\item listę zainstalowanych czcionek,
|
||||||
|
\item listę zainstalowanych wtyczek,
|
||||||
|
\item \textit{Canvas fingerprint}\footnote{Mechanizm do tworzenia odcisków palca
|
||||||
|
przeglądarki na podstawie HTML5 Canvas. HTML5 Canvas to element języka HTML
|
||||||
|
służący do renderowania obrazów bitmapowych.},
|
||||||
|
\item \textit{WebGL fingerprint}\footnote{Mechanizm do tworzenia odcisków palca
|
||||||
|
przeglądarki na podstawie obrazków generowanych przez silnik do rysowania
|
||||||
|
grafiki \textit{WebGL}.},
|
||||||
|
\item \textit{Audio fingerprint}\footnote{Mechanizm do tworzenia odcisków palca
|
||||||
|
przeglądarki za pomocą analizy sygnału audio.},
|
||||||
|
\item \textit{Pixel ratio}\footnote{Jest to stosunek rozdzielczości logicznej do
|
||||||
|
rozdzielczości fizycznej.},
|
||||||
|
\item liczbę procesorów logicznych,
|
||||||
|
\item pojemność pamięci RAM.
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
\noindent Nadawanie identyfikatora nowemu urządzeniu, a potem jego identyfikacja przedstawia się następująco:
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Klient wysyła żądanie GET w celu załadowania anotatora.
|
||||||
|
\item Anotator ładuje się w przeglądarce i oblicza \textit{odcisk
|
||||||
|
palca}\footnote{Odcisk palca przeglądarki
|
||||||
|
to informacje zebrane w celu jej identyfikacji.}
|
||||||
|
przeglądarki za pomocą biblioteki \textit{fingerprintjs2}. Obliczony \textit{odcisk
|
||||||
|
palca} będzie dołączany do każdego kolejnego żądania.
|
||||||
|
\item Klient wysyła serwerowi nowe żądanie z prośbą wyświetlenia fragmentu z
|
||||||
|
godziną do anotacji. Wraz z żądaniem przesyłany jest \textit{odcisk palca} przeglądarki.
|
||||||
|
\item Serwer odbiera żądanie od klienta i oblicza unikalny identyfikator dla
|
||||||
|
klienta. Serwer zapisuje w bazie danych, że \textit{odciskowi palca} wysłanemu przez
|
||||||
|
klienta odpowiada wygenerowany identyfikator.
|
||||||
|
\item Serwer wysyła klientowi fragment do anotacji wraz z wcześniej
|
||||||
|
wygenerowanym identyfikatorem, który zostaje zapisany w nagłówku \textit{Set-Cookie}.
|
||||||
|
\item Klient odbiera fragment do anotacji. Zostaje on wyświetlony na ekranie
|
||||||
|
urządzenia. Identyfikator zawarty w nagłówku \textit{Set-Cookie} zostaje
|
||||||
|
zapisany w przeglądarce klienta. W tym momencie kończy się ładowanie anotatora.
|
||||||
|
\item Przy każdym kolejnym żądaniu ciasteczko z
|
||||||
|
identyfikatorem jest wysyłane do serwera. Na jego podstawie serwer
|
||||||
|
identyfikuje dane urządzenie. Jeśli użytkownik usunie ciasteczka z
|
||||||
|
urządzenia i wyśle kolejne zapytanie, to serwer zidentyfikuje użytkownika po
|
||||||
|
\textit{odcisku palca} przeglądarki i w nagłówku \textit{Set-Cookie} prześle
|
||||||
|
pierwotny identyfikator przydzielony danemu urządzeniu.
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
|
||||||
|
\enlargethispage{3\baselineskip}
|
||||||
\subsection{Architektura anotatora}
|
\subsection{Architektura anotatora}
|
||||||
Architektura
|
|
||||||
|
|
||||||
\subsection{Podsumowanie}
|
Architektura anotatora została przedstawiona na rysunku \ref{pic:anotator_detailed}.
|
||||||
|
Komunikacja między serwerem a klientem przedstawia się następująco:
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Klient wysyła żądanie do serwera.
|
||||||
|
\item Serwer \textit{nginx} odbiera żądanie od klienta i przekazuje je serwerowi
|
||||||
|
\textit{Gunicorn}.
|
||||||
|
\item Serwer \textit{Gunicorn} przekazuje żądanie wolnemu wątkowi roboczemu.
|
||||||
|
Jeśli każdy wątek roboczy jest zajęty, żądanie zostanie przekazane
|
||||||
|
pierwszemu wolnemu wątkowi roboczemu.
|
||||||
|
\item Aplikacja webowa \textit{Flask} przetwarza żądanie. W zależności od żądania odpowiednio
|
||||||
|
modyfikuje dane w bazie \textit{Redis}.
|
||||||
|
\item Aplikacja webowa \textit{Flask} zwraca kolejną godzinę do
|
||||||
|
anotacji z \textit{listy fragmentów do anotacji} i przekazuje ją w postaci
|
||||||
|
odpowiedzi do serwera \textit{Gunicorn}.
|
||||||
|
\item Serwer \textit{Gunicorn} odbiera odpowiedź i przekazuje ją serwerowi \textit{nginx}.
|
||||||
|
\item Serwer \textit{nginx} wysyła odpowiedź klientowi.
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
\clearpage
|
||||||
|
\begin{figure}[t]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=0.65\hsize]{annotator_detailed.png}
|
||||||
|
\caption{Architektura anotatora.}
|
||||||
|
\label{pic:anotator_detailed}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
\section{Regułowa ekstrakcja godzin mszy}
|
\section{Regułowa ekstrakcja godzin mszy}
|
||||||
Do napisania
|
\begin{figure}[tbh!]
|
||||||
\section{Klasyfikacja godzin}
|
\center
|
||||||
Do napisania
|
\includegraphics[width=0.6\hsize]{ekstraktor_regulowy.png}
|
||||||
\subsection{Model teoretyczny}
|
\caption{Fragment architektury systemu przedstawiający komponent odpowiedzialny
|
||||||
\subsection{FastText}
|
za ekstrakcję godzin rozpoczęcia mszy świętych.}
|
||||||
|
\label{pic:ekstraktor_regulowy}
|
||||||
|
\end{figure}
|
||||||
|
Na rysunku \ref{pic:ekstraktor_regulowy} został przedstawiony fragment architektury
|
||||||
|
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w niniejszym podrozdziale.
|
||||||
|
|
||||||
|
Ekstraktor regułowy oparty jest na wyrażeniach regularnych.
|
||||||
|
Wyróżniamy pięć kluczowych fragmentów wyszukiwanych przez ekstraktor godzin. Są
|
||||||
|
to:
|
||||||
|
\begin{description}[labelindent=15pt, style=multiline, leftmargin=5.5cm]
|
||||||
|
\item [główny nagłówek] -- nagłówek rozpoczynający spis godzin mszy świętych (np. \say{porządek mszy}) lub \say{msze
|
||||||
|
święte}. Jest on ekstrahowany przez wyrażenie regularne\footnote{Zakładamy
|
||||||
|
, że wyrażenia regularne ignorują wielkość liter.}\\
|
||||||
|
\mintinline[breaklines]{text}{'porządek mszy (świętych|św|św\.)|}\\
|
||||||
|
\mintinline[breaklines]{text}{msz[ea][\n]+([śs]wi[eę]t[ea]|św|św\.)'}
|
||||||
|
\item [nagłówek niedzielny] -- nagłówek, po którym występują niedzielne i świąteczne
|
||||||
|
godziny mszy (np. \say{porządek świąteczny}). Jest on ekstrahowany przez
|
||||||
|
wyrażenie regularne\\
|
||||||
|
\mintinline[breaklines]{text}{'niedziel[a|e][ \n]+i[ \n]+(dni[ \n]+}\\
|
||||||
|
\mintinline[breaklines]{text}{(świąteczne|św|św\.)|święta)|niedziel[ea]|}\\
|
||||||
|
\mintinline[breaklines]{text}{porządek świąteczny'}
|
||||||
|
\item [niedzielne godziny] -- niedzielne i świąteczne godziny mszy świętych.
|
||||||
|
Są one ekstrahowane przez wyrażenie regularne \\\mintinline[breaklines]{text}{'.*[^\d]\d{1,2}[^\d].*?''}
|
||||||
|
\item [nagłówek powszedni] -- nagłówek, po którym występują godziny mszy
|
||||||
|
świętych dla dni powszednich (np. \say{w tygodniu}). Jest on ekstrahowany
|
||||||
|
przez wyrażenie regularne \\\mintinline[breaklines]{text}{'dzień powszedni|dni powszednie|w tygodniu| porządek zwykły|od poniedziałku do soboty'}
|
||||||
|
\item [powszednie godziny] -- powszednie godziny mszy świętych. Są one
|
||||||
|
ekstrahowane przez wyrażenie regularne \\\mintinline[breaklines]{text}{'(.*?[^\d\n]?\d{1,2}[^\d\n]?.*?\n)+'}.
|
||||||
|
|
||||||
|
\end{description}
|
||||||
|
W dużym uproszczeniu ekstrakcja godzin przedstawia się następująco:
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Wyszukaj \textit{nagłówek główny}, \textit{nagłówek niedzielny} i
|
||||||
|
\textit{nagłówek powszedni} w taki sposób, aby:
|
||||||
|
\begin{itemize}
|
||||||
|
\item \textit{nagłówek niedzielny} był za \textit{nagłówkiem głównym}, ale
|
||||||
|
przed \textit{nagłówkiem powszednim}.
|
||||||
|
\item między \textit{nagłówkiem głównym} a \textit{nagłówkiem powszednim}
|
||||||
|
nie znajdował się żaden inny \textit{nagłówek} niż
|
||||||
|
\textit{nagłówek niedzielny}
|
||||||
|
\end{itemize}
|
||||||
|
\item Jeśli wyszukiwanie w kroku 2. się nie powiodło, szukaj na kolejnej stronie parafialnej.
|
||||||
|
\item Niedzielnymi i świątecznymi godzinami mszy świętych będą godziny między
|
||||||
|
\textit{nagłówkiem niedzielnym} a \textit{nagłówkiem powszednim} pasujące
|
||||||
|
do wyrażenia regularnego \textit{niedzielnych godzin}. Jeśli wyszukiwanie
|
||||||
|
się nie powiedzie, to rozpocznij szukanie od początku na kolejnej stronie parafialnej.
|
||||||
|
\item Godzinami powszednimi, będą godziny po \textit{nagłówku powszednim}
|
||||||
|
pasujące do wyrażenia regularnego \textit{powszednich godzin}. Jeśli wyszukiwanie
|
||||||
|
się nie powiedzie, to rozpocznij szukanie od początku na kolejnej stronie parafialnej.
|
||||||
|
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
\section{Klasyfikacja godzin}
|
||||||
|
\label{sub:klasyfikacja}
|
||||||
|
|
||||||
|
\begin{figure}[tbh!]
|
||||||
|
\center
|
||||||
|
\includegraphics[width=0.9\hsize]{klasyfikator.png}
|
||||||
|
\caption{Fragment architektury systemu przedstawiający komponent odpowiedzialny
|
||||||
|
za klasyfikację godzin.}
|
||||||
|
\label{pic:klasyfikator}
|
||||||
|
\end{figure}
|
||||||
|
Na rysunku \ref{pic:klasyfikator} został przedstawiony fragment architektury
|
||||||
|
systemu z rysunku \ref{pic:architektura}, który zostanie omówiony w niniejszym podrozdziale.
|
||||||
|
|
||||||
|
|
||||||
|
Klasyfikator opary jest na płytkich sieciach neuronowych optymalizowanych metodą
|
||||||
|
stochastycznego spadku wzdłuż gradientu z
|
||||||
|
liniowo malejącym współczynnikiem uczenia. Został on wykorzystany do klasyfikacji
|
||||||
|
godzin na te będące godzinami mszy świętych i na te nimi niebędące.
|
||||||
|
|
||||||
|
\subsection{Model teoretyczny}
|
||||||
|
\label{subsec:model_teoretyczny}
|
||||||
|
|
||||||
|
Podrozdział opiera się na artykule \textit{word2vec Parameter Learning
|
||||||
|
Explained}\cite{word2vec} i artykule \textit{Bag of Tricks for Efficient Text Classification}\cite{fasttext}.
|
||||||
|
\subsubsection{Notacja}
|
||||||
|
W podrozdziale \ref{subsec:model_teoretyczny} przyjęto poniższą notację.
|
||||||
|
\boldmath %\unboldmath
|
||||||
|
\begin{description}[labelindent=25pt, style=multiline, leftmargin=2.5cm]
|
||||||
|
|
||||||
|
\item[$X_{V\times N}$] -- macierz $X$ o $V$ wierszach i $N$ kolumnach.
|
||||||
|
\item [$X_{i,j}$] -- wartość w macierzy $X$ w wierszu $i$ i kolumnie $j$.
|
||||||
|
\item [$X_{i,*}$] -- wiersz $i$ w macierzy $X$.
|
||||||
|
\item [$X_{*,j}$] -- kolumna $j$ w macierzy $X$.
|
||||||
|
\item [$x_i$] -- $x_i$ wartość pod indeksem $i$ w wektorze $x$.
|
||||||
|
\item [$w_i$] -- wektor słowa o indeksie $i$.
|
||||||
|
\item [$w_{i,j}$] -- wartość pod indeksem $j$ w $i$-tym słowie.
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
\subsubsection{Architektura sieci}
|
||||||
|
|
||||||
|
\begin{figure}[tbh!]
|
||||||
|
\center
|
||||||
|
\includegraphics[width=0.6\hsize]{cbow.png}
|
||||||
|
\caption{Architektura sieci neuronowej.}
|
||||||
|
\label{pic:cbow}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
Rysunek \ref{pic:cbow}\footnote{Rysunek wzorowany jest na rysunku z artykułu \textit{word2vec Parameter Learning
|
||||||
|
Explained}\cite{word2vec}} przedstawia sieć neuronową, która służy do klasyfikacji
|
||||||
|
tekstu.
|
||||||
|
Wejście do sieci składa się z wektorów słów $w_1, \dots, w_C$, gdzie $w_1,
|
||||||
|
\dots, w_C$ to słowa z klasyfikowanego zdania. Wektory słów zakodowane
|
||||||
|
zostały za pomocą kodowania \textit{one-hot encoding}\footnote{Sposób kodowania
|
||||||
|
zwany jako \say{kod 1 z n}.}.
|
||||||
|
Na wejściu mamy $C$ wektorów słów o rozmiarze $V$, gdzie $V$ to rozmiar
|
||||||
|
słownika, a $C$ to liczba słów w zdaniu. Każdy wektor słów połączony jest z warstwą
|
||||||
|
ukrytą $h$ macierzą wag $W_{V\times N}$ (współdzielą tę samą macierz). Warstwa
|
||||||
|
ukryta $h$ jest rozmiaru $N$. Warstwa ukryta $h$ łączy się z warstwą wyjściową
|
||||||
|
macierzy $H_{N\times K}$. Warstwa wyjściowa $y$ jest rozmiaru $K$, gdzie $K$
|
||||||
|
to liczba klas.
|
||||||
|
Sieć klasyfikuje zdania do klas $k_1, \dots, k_K$.
|
||||||
|
|
||||||
|
\subsubsection{Propagacja w przód}
|
||||||
|
|
||||||
|
Warstwa ukryta jest wynikiem średniej z wektorów słów $w_1, \dots,
|
||||||
|
w_C$\footnote{Zakładamy, że wektory są wektorami wierszowymi.}
|
||||||
|
pomnożonych przez macierz $W_{V\times N}$ (patrz równanie \ref{eq:hidden}).
|
||||||
|
|
||||||
|
\begin{equation}
|
||||||
|
\label{eq:hidden}
|
||||||
|
h=\frac{1}{c} \sum_{i=1}^{C}{w_i W}=\frac{1}{c} (\sum_{i}^{C}{w_i }) \cdot W
|
||||||
|
\end{equation}
|
||||||
|
|
||||||
|
W warstwie wyjściowej jako funkcja aktywacji została zastosowana funkcja
|
||||||
|
\textit{softmax}\cite{softmax}. Wejście o indeksie $j$ do funkcji \textit{softmax} obliczane jest za pomocą równania \ref{eq:softmax_input}.
|
||||||
|
\begin{equation}
|
||||||
|
\label{eq:softmax_input}
|
||||||
|
u_j=h\cdot H_{*,j}
|
||||||
|
\end{equation}
|
||||||
|
|
||||||
|
$y_j$ w warstwie wyjściowej otrzymujemy używając funkcji \textit{softmax} zgodnie z równaniem \ref{eq:output_y}
|
||||||
|
\begin{equation}
|
||||||
|
\label{eq:output_y}
|
||||||
|
y_j = \frac{exp(u_j)}{\sum_{i=1}^{K}{exp(u_i)}}
|
||||||
|
\end{equation}
|
||||||
|
Funkcja \textit{softmax} normalizuje nam wektor wyjściowy. Dzięki niej na
|
||||||
|
wyjściu z sieci otrzymujemy rozkład prawdopobieństwa klas. Możemy zatem zapisać, że
|
||||||
|
\begin{equation}
|
||||||
|
\label{eq:probyj}
|
||||||
|
p(k_j|w_1,w_2, \dots, w_C) = y_j,
|
||||||
|
\end{equation}
|
||||||
|
gdzie $k_j$ to klasa o indeksie $j$.
|
||||||
|
|
||||||
|
\subsubsection{Proces uczenia sieci neuronowej}
|
||||||
|
Proces uczenia zaczynamy od zainicjalizowania macierzy $W_{V\times N}$ i
|
||||||
|
$H_{N\times K}$ losowymi wartościami. Następnie przeprowadzamy propagację w
|
||||||
|
przód i obliczamy błąd między aktualnym a oczekiwanym wyjściem. Następnie
|
||||||
|
obliczamy gradient funkcji kosztu i poprawiamy wartości macierzy $W$ i $H$ w
|
||||||
|
kierunku gradientu.
|
||||||
|
|
||||||
|
Celem jest maksymalizacja prawdopobieństwa $p(k_{j^*}|w_1, \dots w_C)$ (patrz równania \ref{eq:max_start} - \ref{eq:max_end}), gdzie $k_{j^*}$
|
||||||
|
to wyjściowa klasa o indeksie $j^*$.
|
||||||
|
\begin{align}
|
||||||
|
\label{eq:max_start}
|
||||||
|
max(p(k_{j^*}|w_1, \dots w_C)) &= max(\frac{exp(u_{j^*})}{\sum_{i=1}^{K}{exp(u_i)}}) &\text{z \ref{eq:probyj} i \ref{eq:output_y}}\\
|
||||||
|
&= max(log(\frac{exp(u_{j^*})}{\sum_{i=1}^{K}{exp(u_i)}}))\\
|
||||||
|
\label{eq:max_end}
|
||||||
|
&= max(u_{j^*} - log(\sum_{i=1}^{K}{exp(u_i)}))
|
||||||
|
\end{align}
|
||||||
|
Zatem funkcja kosztu (celem jest jej minimalizacja) będzie przedstawiała się tak
|
||||||
|
jak na równaniu \ref{eq:loss}.
|
||||||
|
|
||||||
|
\begin{align}
|
||||||
|
E&=-(u_{j^*} - log(\sum_{i=1}^{K}{exp(u_i)})) &\text{z \ref{eq:max_end}}\\
|
||||||
|
\label{eq:loss}
|
||||||
|
&=log(\sum_{i=1}^{K}{exp(u_i)}) -u_{j^*}
|
||||||
|
\end{align}
|
||||||
|
|
||||||
|
\subsubsection{Aktualizowanie wag macierzy $H_{N\times K}$}
|
||||||
|
Najpierw należy policzyć pochodną cząstkową funkcji kosztu $E$ względem wektora
|
||||||
|
$u$ (patrz równania \ref{eq:deu_start} - \ref{eq:deu_end}).
|
||||||
|
\begin{align}
|
||||||
|
\label{eq:deu_start}
|
||||||
|
\frac{\partial E}{\partial u_j} &= \frac{\partial(log(\sum_{i=1}^{K}{exp(u_i)}) -u_{j^*})}{\partial u_j}\\
|
||||||
|
&=\frac{\partial(log(\sum_{i=1}^{K}{exp(u_i)}))}{\partial u_j} - \frac{\partial u_{j^*}}{\partial u_{j}}\\
|
||||||
|
\shortintertext{Z reguły łańcuchowej otrzymujemy:}
|
||||||
|
&=\frac{\partial(\sum_{i=1}^{K}{exp(u_i)})}{\partial u_{j}} \cdot \frac{\partial(log(\sum_{i=1}^{K}{exp(u_i)}))}{\partial(\sum_{i=1}^{K}{exp(u_i)})} - \frac{\partial u_{j^*}}{\partial u_{j}}\\
|
||||||
|
&= exp(u_j) \cdot \frac{1}{\sum_{i=1}^{K}{exp(u_i)}} - \frac{\partial u_{j^*}}{\partial u_{j}}\\
|
||||||
|
&= y_j - \frac{\partial u_{j^*}}{\partial u_{j}} &\text{z \ref{eq:output_y}}\\ \shortintertext{Za $\frac{\partial u_{j^*}}{\partial u_{j}}$ podstawiamy $t_j$:}
|
||||||
|
\label{eq:deu_end}
|
||||||
|
&= y_j - t_j \vcentcolon= e_j\\\shortintertext{gdzie $t_j = 1$, gdy $j = j^*$, w przeciwnym wypadku $t_j = 0$.}\nonumber
|
||||||
|
\end{align}
|
||||||
|
|
||||||
|
Pochodna $e_j$ to błąd predykcji warstwy wyjściowej.
|
||||||
|
Gradient dla wag z macierzy $H$ otrzymamy, licząc pochodną cząstkową
|
||||||
|
funkcji kosztu $E$ względem wag macierzy $H$ (patrz równania \ref{eq:der_start} - \ref{eq:der_end}).
|
||||||
|
\begin{align}
|
||||||
|
\label{eq:der_start}
|
||||||
|
\frac{\partial E}{\partial H_{i,j}}&=\frac{\partial E}{\partial u_j} \cdot \frac{\partial u_j}{\partial H_{i,j}} &\text{z reguły łańcuchowej}\\
|
||||||
|
&= e_j \cdot \frac{\partial(h \cdot H_{*,j})}{\partial H_{i,j}} &\text{z \ref{eq:softmax_input}}\\
|
||||||
|
&= e_j \cdot \frac{\partial(\sum_{i'=1}^{N}{h_{i'} \cdot H_{i',j}})}{\partial H_{i,j}} &\text{z definicji mnożenia macierzy}\\
|
||||||
|
\label{eq:der_end}
|
||||||
|
&= e_j \cdot h_i
|
||||||
|
\end{align}
|
||||||
|
|
||||||
|
\noindent Aktualizowanie wag macierzy $H$ zostało przedstawione w równaniu \ref{eq:update_h}.
|
||||||
|
\begin{align}
|
||||||
|
\label{eq:update_h}
|
||||||
|
H_{i,j}^{nowe} = H_{i,j}^{stare} - \eta \cdot e_j \cdot h_i\\ \shortintertext{gdzie $\eta$ to liniowo malejący współczynnik uczenia.}\nonumber
|
||||||
|
\end{align}
|
||||||
|
\subsubsection{Aktualizowanie wag macierzy $W_{V\times N}$}
|
||||||
|
Najpierw należy policzyć pochodną cząstkową funkcji kosztu $E$ względem warstwy
|
||||||
|
ukrytej $h$ (patrz równania \ref{eq:sumder_start} - \ref{eq:sumder_end}).
|
||||||
|
\begin{align}
|
||||||
|
\label{eq:sumder_start}
|
||||||
|
\frac{\partial E}{\partial h_i} &= \sum_{j=1}^{K}{\frac{\partial E}{\partial u_j} \cdot \frac{\partial u_j}{\partial h_i}} &\text{z reguły łańcuchowej}\\
|
||||||
|
&= \sum_{j=1}^{K}{e_j \cdot \frac{\partial(h \cdot H_{*,j})}{\partial h_i}} &\text{z \ref{eq:softmax_input} i z \ref{eq:deu_start} - \ref{eq:deu_end}}\\
|
||||||
|
&= \sum_{j=1}^{K}{e_j \cdot \frac{\partial(\sum_{i'=1}^{N}{h_i' \cdot H_{i',j}})}{\partial h_i}} &\text{z definicji mnożenia macierzy}\\
|
||||||
|
\label{eq:sumder_end}
|
||||||
|
&= \sum_{j=1}^{K}{e_j \cdot H_{i,j}}
|
||||||
|
\end{align}
|
||||||
|
W równaniu \ref{eq:sumder_start} mamy do czynienia z sumą ze względu na fakt,
|
||||||
|
że neuron $h_i$ połączony jest z $K$ neuronami warstwy wyjściowej. Każdy błąd
|
||||||
|
predykcji powinien być uwzględniony.
|
||||||
|
|
||||||
|
Następnie należy policzyć pochodną cząstkową funkcji $E$ względem wag w macierzy
|
||||||
|
$W$ (patrz \ref{eq:last_der_start} - \ref{eq:last_der_end}).
|
||||||
|
\begin{align}
|
||||||
|
\label{eq:last_der_start}
|
||||||
|
\shortintertext{Z reguły łańcuchowej:}
|
||||||
|
\frac{\partial E}{\partial W_{k,i}} &= \frac{\partial E}{\partial h_i} \cdot \frac{\partial h_i}{\partial W_{k,i}}&\text{}\\
|
||||||
|
\shortintertext{Z \ref{eq:sumder_start} - \ref{eq:sumder_end} i z \ref{eq:hidden}:}
|
||||||
|
&= (\sum_{j=1}^{K}{e_j \cdot H_{i,j}}) \cdot \frac{\partial (\frac{1}{C}(\sum_{i'=1}^{C}{w_{i'}})W_{*,i})}{\partial W_{k,i}}\\
|
||||||
|
\shortintertext{Z definicji mnożenia macierzy:}
|
||||||
|
&=(\sum_{j=1}^{K}{e_j \cdot H_{i,j}}) \cdot \frac{\partial (\frac{1}{C}\sum_{l=1}^{V}((\sum_{i'=1}^{C}{w_{i',l}})W_{l,i}))}{\partial W_{k,i}}\\
|
||||||
|
&=(\sum_{j=1}^{K}{e_j \cdot H_{i,j}}) \cdot \frac{1}{C}\sum_{i'=1}^{C}{w_{i',k}}\\
|
||||||
|
\intertext{Zauważmy, że $\sum_{i'=1}^{C}{w_{i',k}}=1$, bo wektory słów zakodowane są kodowaniem \textit{one-hot encoding}. Innymi słowy jest tylko jeden wektor słowa, który ma wartość 1 pod indeksem $k$. Reszta wektorów słów ma pod indeksem $k$ wartość 0. Zatem otrzymujemy:}
|
||||||
|
&=\frac{1}{C}\sum_{j=1}^{K}{e_j \cdot H_{i,j}}
|
||||||
|
\label{eq:last_der_end}
|
||||||
|
\end{align}
|
||||||
|
|
||||||
|
\noindent Aktualizowanie wag macierzy $W$ zostało przedstawione w równaniu \ref{eq:final}.
|
||||||
|
\begin{equation}
|
||||||
|
\label{eq:final}
|
||||||
|
W_{i,j}^{nowe} = W_{i,j}^{stare} - \eta \frac{1}{C} \sum_{j=1}^{K}{e_j \cdot H_{i,j}}
|
||||||
|
\end{equation}
|
||||||
|
|
||||||
|
\subsection{FastText}
|
||||||
|
Autorzy biblioteki \textit{fastText} wskazują, że podstawowy model opisany w
|
||||||
|
podrozdziale \ref{subsec:model_teoretyczny} można usprawnić. Do modelu można
|
||||||
|
dodać dodatkowe cechy w postaci \textit{n-gramów}(w modelu z podrozdziału
|
||||||
|
\ref{subsec:model_teoretyczny} zostały zastosowane unigramy). Artykuł
|
||||||
|
\textit{Bag of Tricks for Efficient Text Classification}\cite{fasttext} pokazuje,
|
||||||
|
że dodanie bigramów poprawia wyniki klasyfikatora.
|
||||||
|
Ponadto, aby przyspieszyć trenowanie, można zastosować funkcję \textit{hierarchical
|
||||||
|
softmax}\cite{fasttext}, zamiast funkcji \textit{softmax}. Taka operacja jest korzystna w
|
||||||
|
przypadku dużej liczby klas \cite{fasttext}. W przypadku klasyfikacji godzin użyto funkcji
|
||||||
|
\textit{softmax} ze względu na małą liczbę klas.
|
||||||
|
Do klasyfikacji użyto biblioteki \textit{fastText} z domyślnymi parametrami.
|
||||||
|
Rezultaty zostały przedstawione w rozdziale \ref{ch:rezultaty}.
|
||||||
|
|
||||||
\chapter{Rezultaty}
|
\chapter{Rezultaty}
|
||||||
Do napisania
|
\label{ch:rezultaty}
|
||||||
% \section{Organizacja danych} % może zbyt inżynierskieby
|
W niniejszym rozdziale zebrane zostały wyniki, jakie osiągnął system ekstrakcji
|
||||||
|
informacji o godzinach rozpoczęcia mszy świętych.
|
||||||
|
|
||||||
|
\subsubsection{Dane parafii i ich adresy URL}
|
||||||
|
\noindent Udało się zebrać:
|
||||||
|
\begin{itemize}
|
||||||
|
\item \textbf{10130} nazw i adresów parafii,
|
||||||
|
\item \textbf{5600} adresów internetowych stron parafialnych,
|
||||||
|
\end{itemize}
|
||||||
|
Ręcznie na małej próbce adresów
|
||||||
|
URL stwierdzono, że
|
||||||
|
w ponad 90\% prowadzą one do poprawnych parafii.
|
||||||
|
|
||||||
|
Warto zaznaczyć, że w momencie oddania pracy do druku nie znaleziono
|
||||||
|
obszerniejszego zbioru adresów URL parafii. Serwisy internetowe zawierające
|
||||||
|
adresy URL parafii posiadały nie więcej niż 2500 tysiąca adresów URL parafii.
|
||||||
|
Większość z nich to były błędne adresy internetowe.
|
||||||
|
|
||||||
|
\subsubsection{Pająk}
|
||||||
|
Z \textbf{5600} adresów internetowych parafii pająk zaindeksował \textbf{5177} stron parafialnych.
|
||||||
|
W kilka dni pobrał około \textbf{3 000 000} stron HTML o łącznym rozmiarze \textbf{152G}. Po
|
||||||
|
konwersji stron parafialnych z formatu HTML do formatu tekstowego otrzymano \textbf{22G} tekstu.
|
||||||
|
|
||||||
|
\subsubsection{Anotator}
|
||||||
|
W dwa tygodnie od udostępnienia anotatora udało się:
|
||||||
|
\begin{itemize}
|
||||||
|
\item zebrać \textbf{10260} anotacji godzin,
|
||||||
|
\item zaanotować \textbf{9313}\footnote{Dopuszczane jest by jedna godzina była
|
||||||
|
anotowana przez wielu unikalnych użytkowników. Stąd rozbieżność między
|
||||||
|
liczbą anotacji a zaanotowanymi godzinami.} z \textbf{10920} godzin.
|
||||||
|
\end{itemize}
|
||||||
|
Dane anotowano z \textbf{177} unikalnych urządzeń.
|
||||||
|
Średni czas anotacji na urządzenie wyniósł \textbf{2,5} sekundy.
|
||||||
|
|
||||||
|
Liczba urządzeń, z których anotowano godziny mszy świętych świadczy o
|
||||||
|
zainteresowaniu społeczności katolickiej projektem automatycznego ekstraktora
|
||||||
|
godzin mszy świętych. Entuzjazm udzielał się również w komentarzach na
|
||||||
|
Facebook'u (komentarze pod postem z prośbą o anotowanie godzin mszy świętych).
|
||||||
|
Średni czas anotacji, jak i liczba zaangażowanych użytkowników potwierdzają cechy anotatora
|
||||||
|
wymienione
|
||||||
|
w podrozdziale \ref{subsec:anotator} (szybkość, dostępność i wygoda użytkowania).
|
||||||
|
\subsubsection{Regułowy ekstraktor danych}
|
||||||
|
Regułowy ekstraktor danych był w stanie znaleźć godziny mszy świętych dla około
|
||||||
|
\textbf{2600} parafii z \textbf{5177} parafii. Na małej próbce parafii ręcznie stwierdzono bardzo wysoką precyzję
|
||||||
|
ekstrahowanych danych.
|
||||||
|
|
||||||
|
\subsubsection{Klasyfikator godzin}
|
||||||
|
Do ewaluacji ekstraktora godzin wykorzystano dane zebrane przez anotator. Z 9313 zaanotowanych
|
||||||
|
godzin 80\% użyto do trenowania klasyfikatora, a 20\% do ewaluacji. Nie
|
||||||
|
przeprowadzono optymalizacji parametrów.
|
||||||
|
|
||||||
|
\noindent Otrzymano następujące wyniki:
|
||||||
|
\begin{itemize}
|
||||||
|
\item \makebox[3.8cm][l]{wartość pokrycia} $= 0,884$
|
||||||
|
\item \makebox[3.8cm][l]{precyzja} $= 0,850$
|
||||||
|
\item \makebox[3.8cm][l]{F1\footnote{F1 to średnia harmoniczna z wartości pokrycia i precyzji.}} $= 0,884$
|
||||||
|
\item \makebox[3.8cm][l]{dokładność} $= 0,858$
|
||||||
|
\end{itemize}
|
||||||
|
Wyniki są obiecujące i z pewnością można je w przyszłości znacznie poprawić.
|
||||||
|
%\textbf{9313} anotacji godzin w \textbf{dwa tygodnie} od udostępnienia anotatora,
|
||||||
\chapter{Podsumowanie}
|
\chapter{Podsumowanie}
|
||||||
Do napisania
|
W pracy opisany został zrobiony przeze mnie system do ekstrakcji informacji
|
||||||
|
godzin rozpoczęcia mszy świętych. Na początku przedstawiłem komponent
|
||||||
|
odpowiedzialny za zbieranie informacji o parafiach. Następnie przybliżyłem
|
||||||
|
metodę wyszukiwania adresów internetowych parafii. Potem dokładnie omówiłem
|
||||||
|
architekturę pająka do pobierania stron parafialnych.
|
||||||
|
W kolejnych rozdziałach krótko opisałem bibliotekę do konwersji tekstu,
|
||||||
|
ekstraktor godzin oraz wyszukiwanie stron, na których z dużym prawdopodobieństwem
|
||||||
|
znajdują się godziny mszy. Następnie omówiłem anotator służący do zbierania
|
||||||
|
danych do uczenia maszynowego. Anotator dostępny jest pod adresem
|
||||||
|
\url{msze.nsupdate.info}. Potem krótko opowiedziałem o regułowym ekstraktorze
|
||||||
|
danych. W kolejnym rozdziale przedstawiłem model teoretyczny klasyfikatora
|
||||||
|
godzin mszy. W szczególności wyprowadziłem równania na aktualizacje wag sieci
|
||||||
|
neuronowej.
|
||||||
|
Na końcu przedstawiłem informacje o wszystkich zebranych danych oraz wynikach
|
||||||
|
anotatora, ekstraktora godzin mszy świętych i klasyfikatora godzin. Otrzymane
|
||||||
|
rezultaty świadczą o sensowności projektu i zachęcają do jego dalszego rozwoju.
|
||||||
|
|
||||||
% \subsection{Ewaluacja wewnętrzna} %F1 score
|
% \subsection{Ewaluacja wewnętrzna} %F1 score
|
||||||
% \subsection{Ewaluacja zewnętrzna} % w systemie webowym, użytkownicy
|
% \subsection{Ewaluacja zewnętrzna} % w systemie webowym, użytkownicy
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
\chapter*{Streszczenie}
|
\chapter*{Streszczenie}
|
||||||
TODO
|
Praca przedstawia proces tworzenia systemu ekstrakcji informacji o godzinach
|
||||||
|
rozpoczęcia mszy świętych. Opisane zostają sposoby zbierania danych o polskich
|
||||||
|
parafiach, w szczególności proces tworzenia pająków. Następnie pokazane zostają
|
||||||
|
dwie metody ekstrakcji godzin rozpoczęcia mszy świętych: regułowa i oparta na
|
||||||
|
uczeniu maszynowym. Większa uwaga zostaje poświęcona metodzie opartej na uczeniu
|
||||||
|
maszynowym, która polega na wykorzystaniu klasyfikatora tekstu.
|
||||||
|
|
||||||
\textbf{Słowa kluczowe:} ekstrakcja informacji
|
\textbf{Słowa kluczowe:} ekstrakcja informacji, indeksowanie stron
|
||||||
|
internetowych, klasyfikacja tekstu
|
33
wstep.tex
33
wstep.tex
@ -1,2 +1,35 @@
|
|||||||
\markboth{Wstęp}{Wstęp}
|
\markboth{Wstęp}{Wstęp}
|
||||||
\addcontentsline{toc}{chapter}{Wstęp}
|
\addcontentsline{toc}{chapter}{Wstęp}
|
||||||
|
\chapter*{Wstęp}
|
||||||
|
Msza święta to najważniejsze duchowe wydarzenie w tygodniu chrześcijanina. Każdy wierzący katolik uczęszcza na niedzielną mszę świętą, a wielu również na msze święte w dni powszednie.
|
||||||
|
Ze względu na rangę tego wydarzenia powstało kilka serwisów, które umożliwiają
|
||||||
|
wyszukiwanie najbliższej godziny i miejsca mszy świętej. Z jednej strony
|
||||||
|
powstały wyszukiwarki ogólnopolskie takie jak \url{kiedymsza.pl} lub
|
||||||
|
\url{msze.info}. Wadą tych wyszukiwarek jest to, że wyświetlane godziny mszy
|
||||||
|
świętych bardzo często są albo błędne, albo już nieaktualne.
|
||||||
|
Z tego względu nie zdobyły one dużej popularności.
|
||||||
|
Z drugiej strony powstały wyszukiwarki lokalne jak na
|
||||||
|
przykład wyszukiwarka mszy świętych dla archidiecezji łódzkiej
|
||||||
|
\url{archidiecezja.lodz.pl/wyszukiwarka-mszy-swietych/} lub aplikacja mobilna Drogowskaz\footnote{\url{www.aplikacjadrogowskaz.pl}}
|
||||||
|
służąca do wyszukiwania mszy świętych w archidiecezji poznańskiej. Oczywistą
|
||||||
|
wadą tych wyszukiwarek jest to, że obejmują małą liczbę polskich parafii.
|
||||||
|
Oferują one za to bardzo wiarygodne informacje i są częściej aktualizowane.
|
||||||
|
Zarówno
|
||||||
|
ogólnopolskie, jak i lokalne wyszukiwarki mszy świętych zbierają swoje dane
|
||||||
|
manualnie. Dane wpisują albo internauci, albo autorzy wyszukiwarek. W celu
|
||||||
|
zasięgnięcia informacji dzwonią oni do parafii lub przepisują godziny mszy
|
||||||
|
świętych ze stron parafialnych. Takie postępowanie jest bardzo czasochłonne i kosztowne.
|
||||||
|
|
||||||
|
Niniejsza praca przedstawia system, który służy do automatycznego zbierania
|
||||||
|
informacji o godzinach rozpoczęcia mszy świętych. W pierwszym rozdziale dokładnie opisano system
|
||||||
|
ekstrakcji godzin mszy świętych. W drugim rozdziale przedstawiono osiągnięte
|
||||||
|
rezultaty. W trzecim rozdziale podsumowano pracę.
|
||||||
|
|
||||||
|
W momencie oddania pracy do druku system opisany w niniejszej pracy jest jedynym
|
||||||
|
w Polsce automatycznym system ekstrakcji godzin mszy świętych.
|
||||||
|
System przykuł uwagę jednego z
|
||||||
|
autorów Drogowskazu. Zostały przeprowadzone wstępne rozmowy i jeśli system się
|
||||||
|
sprawdzi, to być może będzie dostarczał dane dla aplikacji Drogwskaz.
|
||||||
|
%%% Local Variables:
|
||||||
|
%%% LaTeX-command: "latex -shell-escape"
|
||||||
|
%%% End:
|
Loading…
Reference in New Issue
Block a user