From ee9c7b4ab2d4d02b3328af4e3bff5b4d06fa1366 Mon Sep 17 00:00:00 2001 From: Dylan De Faoite Date: Wed, 15 Apr 2026 17:52:54 +0100 Subject: [PATCH] docs(report): finish evaluation & reflection --- report/img/gnatt.png | Bin 0 -> 51485 bytes report/main.tex | 101 +++++++++++++++++++++++++++++++++--------- report/references.bib | 36 +++++++++++++++ 3 files changed, 115 insertions(+), 22 deletions(-) create mode 100644 report/img/gnatt.png diff --git a/report/img/gnatt.png b/report/img/gnatt.png new file mode 100644 index 0000000000000000000000000000000000000000..742a10c0eaa4f9104eb15061dd1077d88a75df6f GIT binary patch literal 51485 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/status} allows the frontend to poll the state of a dataset. It returns the current status string and message stored in the \texttt{datasets} table, which the Celery worker updates at each stage of the pipeline, from \texttt{"fetching"} through \texttt{"processing"} to \texttt{"complete"} or \texttt{"error"}. \texttt{GET /dataset//all} returns the full raw event table for a dataset as a list of records, which powers the raw data viewer in the frontend. @@ -1141,9 +1128,6 @@ For each type of analysis, there is a corresponding endpoint, the base configura Each endpoint needs a JWT authorization header that corresponds to the user that owns that dataset, and the dataset ID is validated against the user's datasets to ensure they have access to it. The endpoint then fetches the entire dataset, and passes it through the global \texttt{StatGen} instance to generate statistics. The resulting statistics are returned as JSON to the frontend for visualisation. -\subsubsection{Access Control} -Endpoints are protected with Flask's \texttt{@jwt\_required()} decorator. This ensures that only authenticated users can access the protected endpoints. For dataset-specific endpoints, an additional ownership check is performed using \texttt{dataset\_manager.authorize\_user\_dataset()} to ensure that users can only access their own datasets. If a user attempts to access a dataset they do not own, a \texttt{403 Forbidden} response is returned. - \subsubsection{Error Handling} Each route handler wraps its logic in a \texttt{try/except} block that catches three categories of exception. \texttt{NotAuthorisedException} maps to a \texttt{403} response. \texttt{NonExistentDatasetException} maps to \texttt{404}. \texttt{ValueError}, which is raised by input validation in the manager layers, maps to \texttt{400}. @@ -1370,16 +1354,89 @@ In addition, ensuring a well-curated topic list that is specific to the dataset \subsection{Performance Benchmarks} The benchmarks for the performance of the system were measured in terms of the time taken for each stage of the data pipeline, including both fetching and NLP processing. The benchmarks were measured in many configurations, such as different dataset sizes, different numbers of sources for fetching, pre-gathered or auto-fetched. +It must be noted that this benchmark will be based on posts, and with each post comes a number of comments, so the total number of events (posts + comments) will be higher than the number of posts, and the performance will be affected by the total number of events rather than just the number of posts. Therefore, the benchmarks are based on the number of posts, as this is a more intuitive metric for users to understand when creating datasets. +Celery tasks return the time taken for a function to complete, so both the fetching and NLP processing times are recorded in the logs. This was tested on a machine with an AMD Ryzen 7 5800X3D, NVIDIA RTX 3070 Ti, 16GB of RAM and Arch Linux OS. \subsubsection{NLP Performance} +This section will outline the performance of the NLP processing, which is the process of enriching the dataset with the NLP models after the data has been fetched. The performance of this feature is measured in terms of the time taken to process a certain number of posts through the NLP pipeline, which includes both emotion classification and topic classification. The benchmarks are as follows: +\begin{itemize} + \item \textbf{10 posts}: 0.40s + \item \textbf{100 posts}: 6.73s + \item \textbf{1000 posts}: 67.12s +\end{itemize} + +Overall this tends to follow a linear trend, with the time taken increasing linearly with the number of posts. As noted above, the number of events the pipeline is processing is likely 10-20x the number of posts, due to comments, so the actual number of events being processed is likely around 1000 for the 100 post benchmark, and around 10,000 for the 1000 post benchmark. + +The 1000 posts benchmark for \texttt{boards.ie} took 312.83s for NLP processing, which is much higher than the other sources. This is likely due to the fact that \texttt{boards.ie} is a forum site, with long running conversations that can last years, therefore the number of comments per thread. is significantly higher than other sources. There is an average of around 900 comments per post in the \texttt{boards.ie} dataset, compared to ~30 comments per post in the Reddit and YouTube datasets, which explains the significant increase in NLP processing time for the \texttt{boards.ie} dataset. + \subsubsection{Auto-fetching Performance} +This section outlines the performance of the auto-fetching feature, which is the process of fetching data from the sources using the connectors. The performance of this feature is measured in terms of the time taken to fetch a certain number of posts from each source. The benchmarks are shown in Table \ref{tab:performance_benchmarks}. + +\begin{table}[!h] + \centering + \begin{tabular}{|c|c|c|c|} + \hline + \textbf{Size} & \textbf{Reddit} & \textbf{Boards.ie} & \textbf{YouTube} \\ + \hline + 10 posts & 3.25s & 103.28s & 2.08s \\ + 100 posts & 37.46s & 1182.71s & 12.52s \\ + 1000 posts & 482.87s & DNF & 74.80s \\ + \hline + \end{tabular} + \caption{Performance Benchmarks for Auto-fetching and NLP Processing} + \label{tab:performance_benchmarks} +\end{table} + \subsection{Limitations} +Several limitations of the system became apparent through development, evaluation and user testing. + +\subsubsection{NLP Accuracy} +As shown in the accuracy evaluation above, both emotion and topic classification only achieve accuracy within the 60-70\% range. This is ok for detecting patterns across the entire dataset, but on an individual level, it's quite inaccurate. The removal of the "neutral" class, while initially motivated by the desire to surface more meaningful emotional signals, introduced misclassification for genuinely neutral posts such as simple arithmetic or factual statements. + +\subsubsection{Temporal Coverage} +The system is designed to fetch only the most recent posts and comments from social media platforms, which means the dataset is limited to a relatively short time window, usually a few weeks at most. This limits the ability to perform true long-term temporal analysis or to study the evolution of a community over time. + +\subsubsection{Platform Coverage} +The system currently supports three data sources: Reddit, YouTube, and Boards.ie. It still excludes major platforms such as Twitter/X, Facebook, and TikTok, all of which would be valuable for ethnography, however their APIs are either extremely restrictive or non-existent for academic research. Should someone need to study communities on those platforms, they would need to upload their own datasets manually. + +\subsubsection{Boards.ie Scraping Fragility} +The Boards.ie connector relies on web scraping, which is very fragile and prone to breaking. The performance benchmarks for fetching from Boards.ie are significantly higher than the other sources. Fetching 100 posts from Boards.ie took around 20 minutes, which is much higher than the other sources. + +\subsubsection{English-Only Support} +Two of three NLP models used in the system are trained exclusively on English-language data. This means the system cannot accurately analyse datasets in other languages, which limits its usefulness for researchers working with non-English communities. This was noted as a specific concern by participants in the user feedback session, who work with both English and Turkish datasets. + +\subsubsection{Scalability} +While asynchronous processing via Celery and Redis mitigates blocking during NLP enrichment and data fetching, the system is not designed to scale horizontally. A single Celery worker handles all tasks sequentially, and the PostgreSQL database is not configured for high-availability or replication. For research use at small to medium scale this is fine, but the system would require significant infrastructure changes to support concurrent large-scale usage across many users. + \newpage \section{Conclusions} \subsection{Reflection} -\subsection{Future Work} +I have learned a lot through the process of building this system, both in terms of technical skills and personal growth. This project represented the most technically complex system I had built independently to date. Being able + +The analytical scope is the project's most visible limitation. Six analytical angles across many data sources sounds comprehensive, but with a single developer and a fixed timeline, the actual ethnographic depth achievable was modest. The decision between depth of ethnographic analysis and typical SaaS-type infrastructure and features was a tension throughout the project. Eventually a balance between the two was achieved, but there was some sacrafice in the analysis depth for the sake of building a more complete and polished system. + +Planning the project was a challenge, as generally I tend to work iteratively. I jump in and start building straight away, and I find that the process of building helps me to figure out what I actually want to build. This led to some awkward parts in the report where design and implementation often overlapped and were made in a non-linear fashion. Creating the design section was difficult when implementation had already started, and design was still changed throughout the implementation process. + +On a personal level, the project was a significant learning experience in terms of time management and project planning. The planning and implementation of the project was ambitious but easy to get carried away with, and I found myself spending a lot of time on features that were not essential to the core functionality of the system. The implementation was felt productive and visible in a way that the writing of a report was not, I found myself spending more time on the implementation than the report, and the report was pushed to the sidelines until the end of the project. + +\subsection{How the project was conducted} +\begin{figure}[!h] + \centering + \includegraphics[width=1\textwidth]{img/gnatt.png} + \caption{Gantt Chart of the Project Timeline} + \label{fig:gnatt_chart} +\end{figure} + +The project was maintained and developed using Git for version control, with the repository hosted on both Github and a self hosted Gitea instance. The project eventually began to use conventional commits to maintain a clean commit history, and commit messages contained rationale for non-obvious decisions. + +Starting in Novemeber, the project went through a few iterations of basic functionality such as data retreival and storage. Research was done on digital ethnography, the traditional metrics used, and how they're implemented in code. The design of the system was also iterated on, with the initial design being a very simple frontend that showed simple aggregates, into a more complex and feature-rich dashboard with multiple analytical perspectives and NLP enrichments. + +The majority of real development and implementation took place between January and April, with the final month of April being focused on testing, bug fixing, writing the report and preparation for the open day. The project was developed in an agile and iterative way, with new features being added and improved upon throughout the development process, rather than having a fixed plan for the entire project from the beginning. + +Git was as a changelog of decisions and rationale, to aid writing the report. But if this project were to be done again, I would maintain the report alongside the implementation from the beginning, as it would have made writing the report much easier and less stressful at the end. + \newpage \bibliography{references} diff --git a/report/references.bib b/report/references.bib index 434e8c3..db7fe26 100644 --- a/report/references.bib +++ b/report/references.bib @@ -68,3 +68,39 @@ year = {2024}, doi = {10.1016/j.nlp.2024.100059} } + +@article{coleman2010ethnographic, + ISSN = {00846570}, + URL = {http://www.jstor.org/stable/25735124}, + abstract = {This review surveys and divides the ethnographic corpus on digital media into three broad but overlapping categories: the cultural politics of digital media, the vernacular cultures of digital media, and the prosaics of digital media. Engaging these three categories of scholarship on digital media, I consider how ethnographers are exploring the complex relationships between the local practices and global implications of digital media, their materiality and politics, and thier banal, as well as profound, presence in cultural life and modes of communication. I consider the way these media have become central to the articulation of cherished beliefs, ritual practices, and modes of being in the world; the fact that digital media culturally matters is undeniable but showing how, where, and why it matters is necessary to push against peculiarly narrow presumptions about the universality of digital experience.}, + author = {E. Gabriella Coleman}, + journal = {Annual Review of Anthropology}, + pages = {487--505}, + publisher = {Annual Reviews}, + title = {Ethnographic Approaches to Digital Media}, + urldate = {2026-04-15}, + volume = {39}, + year = {2010} +} + +@article{shen2021stance, + author = {Shen, Qian and Tao, Yating}, + title = {Stance Markers in {English} Medical Research Articles and Newspaper Opinion Columns: A Comparative Corpus-Based Study}, + journal = {PLOS ONE}, + volume = {16}, + number = {3}, + pages = {e0247981}, + year = {2021}, + doi = {10.1371/journal.pone.0247981} +} + +@incollection{medvedev2019anatomy, + author = {Medvedev, Alexey N. and Lambiotte, Renaud and Delvenne, Jean-Charles}, + title = {The Anatomy of Reddit: An Overview of Academic Research}, + booktitle = {Dynamics On and Of Complex Networks III}, + series = {Springer Proceedings in Complexity}, + publisher = {Springer}, + year = {2019}, + pages = {183--204} +} +