2018-02-08 01:47:46 +01:00
|
|
|
|
|
2018-06-06 15:32:38 +02:00
|
|
|
|
\chapter{Ekstrakcja godzin rozpoczęcia mszy świętych}
|
|
|
|
|
\section{Ogólny zarys systemu}
|
|
|
|
|
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 odpytuje api Google'a w
|
|
|
|
|
celu znalezienia adresów internetowych parafii.
|
|
|
|
|
Dla każdej parafii dla której udało się znaleźć adres url pobierane są wszystkie
|
|
|
|
|
podstrony w odległości (sieć to graf) conajwyżej 3 od strony startowej.
|
|
|
|
|
|
|
|
|
|
Z dużej liczby stron parafialnych, za pomocą prostych reguł wyodrębnione zostają
|
|
|
|
|
te na których z dużym prawdopodbieństwem znajdują się godziny mszy świętych.
|
|
|
|
|
Każda godzina wraz z kontekstem w jakim się znajduje trafia do \textit{systemu
|
|
|
|
|
crowdsourcing'owego}, gdzie jest annotowana jako poprawna lub niepoprawna godzina mszy świętej.
|
|
|
|
|
Do zannotowanych danych zostają dołączone poprawne godziny mszy świętych
|
|
|
|
|
znalezione przez
|
|
|
|
|
regułowy ekstraktor mszy świętych o bardzo wysokiej precyzji. Dodatkowo w celu wyrównania
|
|
|
|
|
klas z nieodfiltrowanego zbioru stron parafialnych wylosowane zostają niepoprawne godziny mszy świętych.
|
|
|
|
|
Zebrane dane zostają użyte do wytrenowania klasyfikatora godzin opartego na
|
|
|
|
|
płytkich sieciach neuronowych.
|
|
|
|
|
|
|
|
|
|
Finalny ekstraktor godzin mszy świętych utworzony zostaje z połączenia
|
|
|
|
|
ekstraktora regułowego z ekstraktorem opartym na uczeniu maszynowym.
|
|
|
|
|
% \bigskip
|
|
|
|
|
|
|
|
|
|
% \newpage
|
|
|
|
|
\begin{figure}[tbh!]
|
|
|
|
|
\center
|
|
|
|
|
\includegraphics[width=1\hsize]{struktura_wyszukiwarki.png}
|
|
|
|
|
\caption{Struktura ekstraktora godzin mszy świętych.}
|
|
|
|
|
\label{struktura_pic}
|
|
|
|
|
\end{figure}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\newpage
|
2018-02-08 01:47:46 +01:00
|
|
|
|
\section{Zbieranie informacji o parafiach}
|
2018-06-06 15:32:38 +02:00
|
|
|
|
|
|
|
|
|
\begin{figure}[tbh!]
|
|
|
|
|
\center
|
|
|
|
|
\includegraphics[width=0.7\hsize]{crawler_adresow_trans.png}
|
|
|
|
|
\label{crawler_adresow_pic}
|
|
|
|
|
\end{figure}
|
|
|
|
|
Dane zostały zebrane z serwisu internetowego deon.pl, który zawiera 10130 parafii.
|
|
|
|
|
Warto zauważyć, że deon.pl posiada większość polskich parafii, ponieważ według
|
|
|
|
|
danych statystycznych GUS z 2016 roku w Polsce było
|
|
|
|
|
10255 parafii.
|
|
|
|
|
|
|
|
|
|
Dla każdej parafii zebrano:
|
|
|
|
|
\begin{itemize}
|
|
|
|
|
\item nazwę parafii,
|
|
|
|
|
\item miejscowość w której się znajduje,
|
|
|
|
|
\item województwo w którym się znajduje,
|
|
|
|
|
\item dokładny adres,
|
|
|
|
|
\item nazwę dekanatu do którego należy,
|
|
|
|
|
\item nazwę diecezji do której przynależy.
|
|
|
|
|
\end{itemize}
|
|
|
|
|
Do wydobycia danych został użyty skrypt w pythonie, który korzystał z parsera
|
|
|
|
|
html z biblioteki BeautifulSoup. Przy wysyłaniu zapytań do serwisu deon.pl zastosowano
|
|
|
|
|
algorym \textit{Expotential Backoff} REF, który prezentuje się następująco:
|
|
|
|
|
\begin{enumerate}
|
|
|
|
|
\item Wyślij zapytanie do serwisu.
|
|
|
|
|
\item Jeśli zapytanie się powiodło wróć do punktu nr 1, jeśli nie poczekaj 1.5s i wyślij kolejne zapytanie.
|
|
|
|
|
\item Jeśli zapytanie znów się nie powiodło odczekaj 2.25s i wyślij kolejne
|
|
|
|
|
zapytanie
|
|
|
|
|
\item W ogólności czekaj $1.5^t$ sekund zanim wyślesz kolejne zapytanie, gdzie
|
|
|
|
|
$t$ to liczba następujących po sobie nieudanych zapytań.
|
|
|
|
|
\end{enumerate}
|
|
|
|
|
Powyższy algorytm uodparnia skrypt na przejściowe problemy z połączeniem i
|
|
|
|
|
zapobiega zbyt częstemu odpytywaniu serwisu kiedy ten nie daje sobie rady ze
|
|
|
|
|
zbyt dużą liczbą zapytań.
|
|
|
|
|
|
|
|
|
|
\begin{table}
|
|
|
|
|
\centering
|
|
|
|
|
\def\arraystretch{1.1}
|
|
|
|
|
\begin{tabular}{ l l l l l l }
|
|
|
|
|
\textbf{Parafia} & \textbf{Miejscowość} & \textbf{Adres} & \textbf{Diecezja} & \textbf{Dekanat} & \textbf{Województwo} \\
|
|
|
|
|
\hline \\ [-2ex]
|
|
|
|
|
Bożego Ciała & Hel & ul. Gdań... & gdańska & Morski & pomorskie \\
|
|
|
|
|
Ducha Św. & Śrem & ul. Prym... & poznańska & Śrem & wielkopolskie\\
|
|
|
|
|
Św. Trójcy & Paszowice & Paszowic... & legnicka & Jawor & dolnośląskie\\
|
|
|
|
|
\\ [-1.5ex]
|
|
|
|
|
\end{tabular}
|
|
|
|
|
\caption{Fragment zebranych danych.}
|
|
|
|
|
\end{table}
|
|
|
|
|
|
2018-02-08 01:47:46 +01:00
|
|
|
|
\section{Wyszukiwanie stron internetowych parafii}
|
2018-06-06 15:32:38 +02:00
|
|
|
|
\begin{figure}[tbh!]
|
|
|
|
|
\center
|
|
|
|
|
\includegraphics[width=0.7\hsize]{crawler_url_trans.png}
|
|
|
|
|
\label{crawler_url_pic}
|
|
|
|
|
\end{figure}
|
|
|
|
|
\subsubsection{Pierwsze próby}
|
|
|
|
|
Do wyszukiwania adresów url parafii próbowano wykorzystać wyszukiwarki takie jak
|
|
|
|
|
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 robots.txt Google zabrania
|
|
|
|
|
korzystania z pająków na ich wyszukiwarce.
|
|
|
|
|
DuckDuckGo nie blokowało adresu ip, ale zabraniało \textit{crawlowania} w robots.txt i słabo radziło 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.
|
|
|
|
|
\subsubsection{Rozwiązanie}
|
|
|
|
|
Po wieleokrotnych próbach poszukiwań znaleziono klucz do rozwiązania problemu
|
|
|
|
|
wyszukiwania adresów url jakim jest
|
|
|
|
|
\textit{Google Places Api} REF. Serwis \textit{Text Search} REF pozwala na wyszukanie miejsca
|
|
|
|
|
danego obiektu na
|
|
|
|
|
podstawie jego nazwy. Ponadto mając już wyszukany dany obiekt i jego
|
|
|
|
|
identyfikator można odpytać serwis \textit{Place Detail} REF, aby wyciągnąć więcej
|
|
|
|
|
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
|
|
|
|
|
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ń do 150 000 na 24 godziny. Karta płatnicza jest potrzebna Google'owi do
|
|
|
|
|
identyfikacji osoby. Żadna opłata nie jest pobierana za korzystanie z 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
|
|
|
|
|
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 \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.
|
|
|
|
|
|
|
|
|
|
Powyższą metodą udało się zebrać adresy url dla ok. 5600 parafii.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\begin{figure}[tbh]
|
|
|
|
|
\center
|
|
|
|
|
\includegraphics[width=1\hsize]{amb_text_search.png}
|
|
|
|
|
\caption{Przykład dwóch obiektów zwróconych przez \textit{Text Search}, które
|
|
|
|
|
mają ten sam adres internetowy.}
|
|
|
|
|
\label{text_search_pic}
|
|
|
|
|
\end{figure}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section{\textit{Crawlowanie} stron parafialnych}
|
|
|
|
|
|
|
|
|
|
\begin{figure}[tbh]
|
|
|
|
|
\center
|
|
|
|
|
\includegraphics[width=0.7\hsize]{crawler_parafii_general.png}
|
|
|
|
|
\label{crawler_parafii_general_pic}
|
|
|
|
|
\end{figure}
|
|
|
|
|
Crawler został napisany przy użyciu biblioteki Scrapy.
|
|
|
|
|
Punktem startowym jest pojedynczy adres url parafii podawany na wejście
|
|
|
|
|
programu. Z początkowego adresu url wydobywana jest domena w obrębie której
|
|
|
|
|
porusza się pająk. Oznacza to, że jedna instancja pająka zajmuje się ściąganiem
|
|
|
|
|
tylko jedenej parafii. W ramach jednej parafii pająk jest w stanie
|
|
|
|
|
asynchronicznie wysłać wiele zapytań do serwera i odbierać wiele odpowiedzi od serwera.
|
|
|
|
|
|
|
|
|
|
\subsubsection{Komponenty crawler'a}
|
|
|
|
|
\subsubsection{Przepływ danych}
|
|
|
|
|
|
|
|
|
|
Przepływ danych kontrolowany jest przez
|
|
|
|
|
silnik i prezentuje się następująco:
|
|
|
|
|
|
|
|
|
|
\begin{figure}[tbh]
|
|
|
|
|
\center
|
|
|
|
|
\includegraphics[width=0.7\hsize]{scrapy_data_flow.png}
|
|
|
|
|
% \caption{100 crawlerów pracujących jednocześnie}
|
|
|
|
|
\label{scrapy_data_flow_pic}
|
|
|
|
|
\end{figure}
|
|
|
|
|
|
|
|
|
|
\begin{enumerate}
|
|
|
|
|
\item Silnik otrzymuje od pająka żądanie pobrania początkowej strony danej
|
|
|
|
|
parafii (najczęściej jest to strona główna parafii).
|
|
|
|
|
\item Silnik oddaje żądania dyspozytorowi, który kolejkuje je do dalszego
|
|
|
|
|
przetwarzania oraz pyta dyspozytora o żądania gotowe do przekazania downloader'owi.
|
|
|
|
|
\item Dyspozytor zwraca silnikowi następne żądania.
|
|
|
|
|
\item Silnik wysyła żądania do downloader'a. Zanim żądania dotrą do
|
|
|
|
|
downloader'a przetwarzane są przez middleware'y downloader'a.
|
|
|
|
|
\item Downloader ściąga stronę parafialną i umieszcza ją w odpowiedzi, którą
|
|
|
|
|
przesyła silnikowi. Zanim odpowiedź dotrze do silnka przetwarzana jest przez
|
|
|
|
|
middleware'y downloader'a.
|
|
|
|
|
\item Silnik otrzymuje odpowiedź od downloader'a i przekazuje ją pająkowi do
|
|
|
|
|
dalszego przetwarzania. Zanim odpowiedź trafi do pająka przetwarzana jest
|
|
|
|
|
przez middleware'y pająka.
|
|
|
|
|
\item Pająk przerabia odpowiedź i zwraca dane strony parafialnej silnikowi. Zanim dane
|
|
|
|
|
trafią do silnika przechodzą przez middleware'y pająka. Dodatkowo pająk
|
|
|
|
|
wysła żądania z nowymi stronami parafialnymi do pobrania.
|
|
|
|
|
\item Silnik wysyła zebrane dane do przetwarzacza danych, który zapisuje je w
|
|
|
|
|
pliku jsonline. Następnie przekazuje nowe żądania do zakolejkowania
|
|
|
|
|
dyspozytorowi.
|
|
|
|
|
\end{enumerate}
|
|
|
|
|
\vspace*{-20mm}
|
|
|
|
|
Cały proces trwa dopóty, dopóki są nowe żądania do przetworzenia.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\vspace*{20mm}
|
|
|
|
|
Z pomocą GNU parallel crawlowane jest jednocześnie 100 parafii.
|
|
|
|
|
|
|
|
|
|
\begin{figure}[tbh]
|
|
|
|
|
\center
|
|
|
|
|
\includegraphics[width=0.7\hsize]{crawler.png}
|
|
|
|
|
\caption{100 crawlerów pracujących jednocześnie}
|
|
|
|
|
\label{crawler_pic}
|
|
|
|
|
\end{figure}
|
|
|
|
|
|
2018-02-08 01:47:46 +01:00
|
|
|
|
\section{Organizacja danych} % może zbyt inżynierskieby
|
|
|
|
|
\section{Ekstrakcja godzin rozpoczęcia mszy świętych}
|
|
|
|
|
\subsection{Ogólny zarys}
|
|
|
|
|
\subsection{Named entity recognition}
|
|
|
|
|
\subsection{Słowa kluczowe}
|
|
|
|
|
\subsection{Reguły}
|
|
|
|
|
\subsection{Bootstraping}
|
|
|
|
|
\subsection{Otoczenia słów (ang. word embeddings)}
|
|
|
|
|
|
|
|
|
|
\chapter{Rezultaty}
|
|
|
|
|
\section{Wyrażenia regularne}
|
|
|
|
|
\section{Bootstraping}
|
|
|
|
|
\section{Autorska metoda}
|
|
|
|
|
|
|
|
|
|
\subsection{Ewaluacja wewnętrzna} %F1 score
|
|
|
|
|
\subsection{Ewaluacja zewnętrzna} % w systemie webowym, użytkownicy
|
|
|
|
|
\chapter{Wnioski}
|
2018-03-04 18:37:44 +01:00
|
|
|
|
\chapter{Perspektywy na przyszłość}
|