<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dimitrios Ioannidis</title>
    <description>The latest articles on DEV Community by Dimitrios Ioannidis (@dmitrisgr).</description>
    <link>https://dev.to/dmitrisgr</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4190329%2F9da4f14e-f749-4e1b-8086-7ac859ccf6ff.png</url>
      <title>DEV Community: Dimitrios Ioannidis</title>
      <link>https://dev.to/dmitrisgr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dmitrisgr"/>
    <language>en</language>
    <item>
      <title>ROC-AUC vs PR-AUC: Why Rare Events Need More Than One Metric</title>
      <dc:creator>Dimitrios Ioannidis</dc:creator>
      <pubDate>Mon, 19 Oct 2026 11:03:51 +0000</pubDate>
      <link>https://dev.to/dmitrisgr/roc-auc-vs-pr-auc-why-rare-events-need-more-than-one-metric-1ldn</link>
      <guid>https://dev.to/dmitrisgr/roc-auc-vs-pr-auc-why-rare-events-need-more-than-one-metric-1ldn</guid>
      <description>&lt;p&gt;Imagine you are building a system to monitor social media during a wildfire.&lt;/p&gt;

&lt;p&gt;Thousands of posts appear every hour. Most are ordinary discussions, but a small number may contain important information about an evacuation, a blocked road, or an emerging hazard.&lt;/p&gt;

&lt;p&gt;Your classifier is designed to flag potentially relevant posts for further review.&lt;/p&gt;

&lt;p&gt;You evaluate it and obtain a ROC-AUC of 0.95.&lt;/p&gt;

&lt;p&gt;That sounds excellent.&lt;/p&gt;

&lt;p&gt;But when you examine the alerts, you discover that most of the flagged posts are irrelevant.&lt;/p&gt;

&lt;p&gt;How can a model have a high ROC-AUC and still generate so many false alarms?&lt;/p&gt;

&lt;p&gt;The answer becomes clearer when we compare ROC-AUC with precision-recall metrics, especially when the positive class is rare.&lt;/p&gt;

&lt;p&gt;In this tutorial, we will construct a small, reproducible Python example, calculate both metrics, and explore what they tell us about the same classifier.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The problem with rare events&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consider a dataset containing 10,000 social media posts.&lt;/p&gt;

&lt;p&gt;Only 100 contain the event we want to identify. The remaining 9,900 do not.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Class&lt;/th&gt;
&lt;th&gt;Number of posts&lt;/th&gt;
&lt;th&gt;Percentage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Relevant events&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Other posts&lt;/td&gt;
&lt;td&gt;9,900&lt;/td&gt;
&lt;td&gt;99%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total&lt;/td&gt;
&lt;td&gt;10,000&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is an imbalanced classification problem.&lt;/p&gt;

&lt;p&gt;The positive class is the event we want to detect. It represents only 1% of the dataset.&lt;/p&gt;

&lt;p&gt;This situation appears in a plethora of applications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fraud detection, where fraudulent transactions are uncommon.&lt;/li&gt;
&lt;li&gt;Security monitoring, where genuine attacks are rare.&lt;/li&gt;
&lt;li&gt;Predictive maintenance, where equipment failures occur infrequently.&lt;/li&gt;
&lt;li&gt;Crisis monitoring, where important event reports are a small fraction of all posts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A model can achieve 99% accuracy simply by predicting that every post is negative.&lt;/p&gt;

&lt;p&gt;It would identify none of the 100 relevant events.&lt;/p&gt;

&lt;p&gt;This illustrates an important lesson: &lt;strong&gt;a metric is only useful when it reflects the problem we are trying to solve.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What do ROC-AUC and PR-AUC measure?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before writing code, let us distinguish the metrics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ROC-AUC: How well does the model rank positive examples?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Receiver Operating Characteristic (ROC) curve plots:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;True Positive Rate (TPR):&lt;/strong&gt; the proportion of positive examples correctly identified.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;False Positive Rate (FPR):&lt;/strong&gt; the proportion of negative examples incorrectly flagged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The true positive rate is also called recall or sensitivity.&lt;/p&gt;

&lt;p&gt;The true positive rate is also called recall or sensitivity:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TPR&lt;/strong&gt; = TP / (TP + FN)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FPR&lt;/strong&gt; = FP / (FP + TN)&lt;/p&gt;

&lt;p&gt;ROC-AUC summarizes the ROC curve across classification thresholds. It measures how well the model ranks positive examples above negative examples.&lt;/p&gt;

&lt;p&gt;A score of 1.0 represents perfect ranking; a score near 0.5 indicates performance similar to a random ranking under the usual binary-classification interpretation.&lt;/p&gt;

&lt;p&gt;However, the false positive rate uses &lt;em&gt;all negative examples&lt;/em&gt; as its denominator. When there are thousands of negatives, a seemingly small rate can still produce a large number of false alarms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Precision-recall: How useful are the positive predictions?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A precision-recall (PR) curve plots precision against recall at different thresholds.&lt;/p&gt;

&lt;p&gt;Precision answers the question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Of all the posts flagged by the model, how many are actually relevant?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Precision&lt;/strong&gt; = TP / (TP + FP)&lt;/p&gt;

&lt;p&gt;Recall answers a different question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Of all the relevant posts, how many did the model find?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Recall&lt;/strong&gt; = TP / (TP + FN)&lt;/p&gt;

&lt;p&gt;The area under the precision-recall curve summarizes the trade-off between these two quantities.&lt;/p&gt;

&lt;p&gt;In scikit-learn, we will use Average Precision (AP) as our summary of the PR curve. AP is a common PR-curve summary, but it is not the same as calculating the trapezoidal area under the curve.&lt;/p&gt;

&lt;p&gt;For imbalanced datasets, precision-recall analysis often reveals the practical consequences of false positives more clearly than ROC analysis alone (Saito &amp;amp; Rehmsmeier, 2015).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Build a deliberately simple example&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of training a complicated model, let us construct a synthetic dataset with known outcomes.&lt;/p&gt;

&lt;p&gt;This is intentional: the goal is to isolate the behaviour of the metrics, not to claim that we have built a production-ready detector.&lt;/p&gt;

&lt;p&gt;Our classifier assigns the following scores:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Actual class&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;Number of posts&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Negative&lt;/td&gt;
&lt;td&gt;0.90&lt;/td&gt;
&lt;td&gt;495&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Positive&lt;/td&gt;
&lt;td&gt;0.80&lt;/td&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Positive&lt;/td&gt;
&lt;td&gt;0.60&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Negative&lt;/td&gt;
&lt;td&gt;0.10&lt;/td&gt;
&lt;td&gt;9,405&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Higher scores indicate that the model considers a post more likely to be positive.&lt;/p&gt;

&lt;p&gt;Notice something interesting: the 495 negative posts with the highest scores rank ahead of the positive posts.&lt;/p&gt;

&lt;p&gt;This is a useful teaching example because it lets us see how a low false positive rate can coexist with a substantial number of false alerts.&lt;/p&gt;

&lt;p&gt;Let us implement it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.metrics&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;average_precision_score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;confusion_matrix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;precision_score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;recall_score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;roc_auc_score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 10,000 posts: 100 positive and 9,900 negative.
&lt;/span&gt;&lt;span class="n"&gt;y_true&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concatenate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zeros&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9_900&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ones&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# Scores aligned with the labels above.
# Negative posts: 495 high scores, then 9,405 low scores.
# Positive posts: 80 medium-high scores, then 20 lower scores.
&lt;/span&gt;&lt;span class="n"&gt;y_score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concatenate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;495&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.90&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9_405&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.80&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.60&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# Threshold for converting scores into binary decisions.
&lt;/span&gt;&lt;span class="n"&gt;threshold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.50&lt;/span&gt;
&lt;span class="n"&gt;y_pred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Ranking metrics.
&lt;/span&gt;&lt;span class="n"&gt;roc_auc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;roc_auc_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;average_precision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;average_precision_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Metrics at the selected threshold.
&lt;/span&gt;&lt;span class="n"&gt;precision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;precision_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_pred&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zero_division&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;recall&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;recall_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_pred&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zero_division&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;tn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;confusion_matrix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;y_true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_pred&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;labels&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ravel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;accuracy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ROC-AUC: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;roc_auc&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Average Precision: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;average_precision&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Precision at threshold &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;precision&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Recall at threshold &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;recall&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Accuracy at threshold &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;accuracy&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;True positives: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tp&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;False positives: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;True negatives: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tn&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;False negatives: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The expected output is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ROC-AUC: 0.9500
Average Precision: 0.1449
Precision at threshold 0.5: 0.1681
Recall at threshold 0.5: 1.0000
Accuracy at threshold 0.5: 0.9505

True positives: 100
False positives: 495
True negatives: 9405
False negatives: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The contrast is striking.&lt;/p&gt;

&lt;p&gt;The ROC-AUC is 0.95, which indicates strong overall ranking performance on this synthetic dataset. Yet the average precision is only about 0.145, and at the selected threshold, fewer than 17% of flagged posts are genuinely positive.&lt;/p&gt;

&lt;p&gt;The example demonstrates why these metrics answer different questions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Predicted positive&lt;/th&gt;
&lt;th&gt;Predicted negative&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Actually positive&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Actually negative&lt;/td&gt;
&lt;td&gt;495&lt;/td&gt;
&lt;td&gt;9,405&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We found every positive case.&lt;/p&gt;

&lt;p&gt;That gives us 100% recall.&lt;/p&gt;

&lt;p&gt;But we also flagged 495 negative posts.&lt;/p&gt;

&lt;p&gt;Our precision is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Precision:&lt;/strong&gt; = 100 (100 + 495), approx 0.1681&lt;/p&gt;

&lt;p&gt;In other words, out of 595 flagged posts, only 100 are positive.&lt;/p&gt;

&lt;p&gt;The model has achieved perfect recall at this threshold, but the alert workload is substantial.&lt;/p&gt;

&lt;p&gt;Imagine a crisis-response team that must manually investigate every alert. Reviewing 595 posts to find 100 relevant ones could be expensive, especially if the system operates continuously.&lt;/p&gt;

&lt;p&gt;That is the operational side of the metric.&lt;/p&gt;

&lt;p&gt;ROC-AUC tells us about ranking across thresholds. Precision tells us how much confidence we should place in the positive predictions produced at a particular threshold.&lt;/p&gt;

&lt;p&gt;Neither should be interpreted in isolation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Visualize both curves&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.metrics&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;average_precision_score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;precision_recall_curve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;roc_auc_score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;roc_curve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# ROC curve.
&lt;/span&gt;&lt;span class="n"&gt;fpr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tpr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;roc_curve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Precision-recall curve.
&lt;/span&gt;&lt;span class="n"&gt;precision_values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;recall_values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;precision_recall_curve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;y_true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_score&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;roc_auc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;roc_auc_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;average_precision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;average_precision_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;prevalence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y_true&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ax_roc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ax_pr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subplots&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# Left: ROC.
&lt;/span&gt;&lt;span class="n"&gt;ax_roc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fpr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tpr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ROC-AUC = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;roc_auc&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax_roc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Random ranking&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax_roc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_xlabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;False Positive Rate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax_roc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_ylabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;True Positive Rate (Recall)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax_roc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ROC Curve&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax_roc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;ax_roc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Right: Precision-recall.
&lt;/span&gt;&lt;span class="n"&gt;ax_pr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;recall_values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;precision_values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Average Precision = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;average_precision&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax_pr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;axhline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;prevalence&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;linestyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Positive prevalence = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;prevalence&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax_pr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_xlabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Recall&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax_pr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_ylabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Precision&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax_pr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Precision-Recall Curve&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax_pr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;ax_pr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tight_layout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmex1ufkyc69xjdsylfp4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmex1ufkyc69xjdsylfp4.png" alt=" " width="799" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The ROC curve shows strong overall ranking performance, with a ROC-AUC of 0.95. &lt;/p&gt;

&lt;p&gt;However, this metric can obscure the impact of false positives when the dataset is highly imbalanced.&lt;/p&gt;

&lt;p&gt;The precision-recall curve highlights this issue: 495 negative posts receive higher scores than all the positive posts, reducing precision despite the high ROC-AUC.&lt;/p&gt;

&lt;p&gt;The dashed line in the PR plot represents positive-class prevalence. With random rankings, expected Average Precision is approximately equal to this prevalence, or 0.01 (1%) in this example.&lt;/p&gt;

&lt;p&gt;One caution: this dataset uses intentionally constructed score groups. Real models typically produce different score distributions, so their curves may have different shapes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Does Pr-AUC always matter more?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not necessarily.&lt;/p&gt;

&lt;p&gt;ROC-AUC remains useful when comparing ranking behaviour across thresholds, and it may be particularly valuable when both classes matter to the task.&lt;/p&gt;

&lt;p&gt;Precision-recall metrics are especially informative when the positive class is rare, and the quality of positive predictions matters operationally. This is why they are widely considered alongside ROC analysis in imbalanced classification research (Davis &amp;amp; Goadrich, 2006; Saito &amp;amp; Rehmsmeier, 2015).&lt;/p&gt;

&lt;p&gt;The choice ultimately depends on the cost of the errors.&lt;/p&gt;

&lt;p&gt;Consider two scenarios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario A: Missing an event is extremely costly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In early crisis detection, you may prefer a lower threshold to capture as many potentially important posts as possible. This increases recall but can also increase the number of false alarms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario B: Human review capacity is limited.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If a small team can inspect only a limited number of posts, precision and precision-recall behaviour become particularly important. A model that flags too many irrelevant posts may overwhelm the people who are supposed to investigate them.&lt;/p&gt;

&lt;p&gt;The threshold should therefore reflect the task, available resources, and relative cost of false positives and false negatives.&lt;/p&gt;

&lt;p&gt;AUC values alone do not choose the threshold for you.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;How should we apply this to anomaly detection and fact-checking?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This distinction is especially important in social-media analysis during emergencies.&lt;/p&gt;

&lt;p&gt;An anomaly detector might identify an unusual cluster of posts, a sudden change in message volume, or content that differs from typical patterns.&lt;/p&gt;

&lt;p&gt;That output is a signal for further investigation. It is not evidence that a post is false.&lt;/p&gt;

&lt;p&gt;The system still needs to examine the claim, assess available evidence, and account for uncertainty.&lt;/p&gt;

&lt;p&gt;Evaluation should reflect those separate responsibilities. Anomaly detection should be tested for its ability to prioritize relevant cases, while verification should be evaluated against suitable reference evidence and labels.&lt;/p&gt;

&lt;p&gt;This is one of the design principles I explored in my MSc thesis on anomaly detection and fact-checking of social-media data in crisis management: unusual content should be prioritized for analysis without automatically treating it as misinformation.&lt;/p&gt;

&lt;p&gt;The distinction between detection and verification is not merely philosophical. It changes what the system measures, how its outputs are interpreted, and which errors matter.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When positive cases are rare, a model can look impressive under one metric while exposing weaknesses under another.&lt;/p&gt;

&lt;p&gt;ROC-AUC summarizes ranking behaviour across thresholds. Precision-recall analysis makes the relationship between retrieved positives and false alarms more visible. Precision, recall, and the confusion matrix then help us understand what happens at the operating threshold we actually intend to use.&lt;/p&gt;

&lt;p&gt;My practical checklist is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Inspect the class distribution. Understand how rare the positive class is before interpreting scores.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Report more than accuracy. Consider ROC-AUC, average precision, precision, recall, and the confusion matrix.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Choose thresholds based on consequences. Think about the workload created by false positives and the harm caused by missed events.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validate on representative data. A model's performance on a controlled dataset does not automatically establish its usefulness in a live environment.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most importantly, evaluate the model against the task it is intended to support.&lt;/p&gt;

&lt;p&gt;In AI-assisted decision-making, the goal is not simply to produce a high score. It is to understand what that score establishes—and what remains uncertain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References and further reading&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Saito, T., &amp;amp; Rehmsmeier, M. (2015). The Precision-Recall Plot Is More Informative than the ROC Plot When Evaluating Binary Classifiers on Imbalanced Datasets. PLOS ONE, 10(3), e0118432.&lt;/li&gt;
&lt;li&gt;Davis, J., &amp;amp; Goadrich, M. (2006). The Relationship Between Precision-Recall and ROC Curves. Proceedings of the 23rd International Conference on Machine Learning, 233–240.&lt;/li&gt;
&lt;li&gt;scikit-learn. ROC-AUC documentation: &lt;a href="https://scikit-learn.org/stable/modules/model_evaluation.html#receiver-operating-characteristic-roc" rel="noopener noreferrer"&gt;https://scikit-learn.org/stable/modules/model_evaluation.html#receiver-operating-characteristic-roc&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;scikit-learn. Average Precision documentation: &lt;a href="https://scikit-learn.org/stable/modules/model_evaluation.html#precision-recall-and-f-measures" rel="noopener noreferrer"&gt;https://scikit-learn.org/stable/modules/model_evaluation.html#precision-recall-and-f-measures&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enjoyed this breakdown? Feel free to check out my website at &lt;a href="https://www.ioannidis.dev" rel="noopener noreferrer"&gt;ioannidis.dev&lt;/a&gt; for more machine learning guides and articles.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>datascience</category>
      <category>python</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>An Anomaly Is Not Misinformation: Building AI-Assisted Fact-Checking for Crisis Social Media</title>
      <dc:creator>Dimitrios Ioannidis</dc:creator>
      <pubDate>Sat, 17 Oct 2026 11:49:11 +0000</pubDate>
      <link>https://dev.to/dmitrisgr/an-anomaly-is-not-misinformation-building-ai-assisted-fact-checking-for-crisis-social-media-3cg5</link>
      <guid>https://dev.to/dmitrisgr/an-anomaly-is-not-misinformation-building-ai-assisted-fact-checking-for-crisis-social-media-3cg5</guid>
      <description>&lt;p&gt;Imagine that a wildfire breaks out near a populated area.&lt;/p&gt;

&lt;p&gt;In a matter of minutes, social media fills with evacuation warnings, photographs, eyewitness reports, speculation, and conflicting updates. Some posts contain critical information. Others repeat outdated claims. A few may be misleading.&lt;/p&gt;

&lt;p&gt;An AI system detects a sudden change in posting activity and flags several messages as anomalies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What has the system actually discovered?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It has identified unusual patterns in the data. It has not necessarily established which messages are false, which describe a real emergency, or which deserve immediate human attention.&lt;/p&gt;

&lt;p&gt;That distinction is central to a problem I explore in my 2026 MSc thesis research, &lt;em&gt;Anomaly Detection (Fact-Checking) of Social Media Data in Crisis Management&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It also motivates a broader question: how can we build AI systems that help us investigate information without giving their outputs more authority than the evidence warrants?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Anomaly detection is not fact-checking&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anomaly detection identifies observations that deviate from an expected pattern. In social media, this might mean unusual language, a rare combination of terms, a sudden change in activity, or a post that differs substantially from its surrounding data.&lt;/p&gt;

&lt;p&gt;These observations can be useful. During an emergency, a monitoring system cannot investigate every post with equal depth. An anomaly detector can help prioritize material that warrants closer examination.&lt;/p&gt;

&lt;p&gt;However, unusual does not mean false.&lt;/p&gt;

&lt;p&gt;A more defensible process is:&lt;/p&gt;

&lt;p&gt;Anomaly detected → Prioritize for investigation → Examine evidence → Assess claim → Review when necessary&lt;/p&gt;

&lt;p&gt;The anomaly score helps determine what to inspect. Verification requires a different kind of reasoning.&lt;/p&gt;

&lt;p&gt;This separation reflects an established distinction in anomaly detection and automated fact-checking research: detecting unusual observations and assessing whether a claim is supported by evidence are different tasks (Chandola, Banerjee, &amp;amp; Kumar; Shu et al., 2017).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A modular architecture for crisis-related social media&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My thesis investigated how anomaly detection could be integrated with automated fact-checking and natural language processing (NLP) in a crisis-monitoring framework, without treating unusual activity as proof of misinformation.&lt;/p&gt;

&lt;p&gt;Rather than relying on a single model to make every decision, I designed a modular pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 1: Collect and normalize social media data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The framework uses a data-collection component and a preprocessing stage to prepare social media posts for analysis.&lt;/p&gt;

&lt;p&gt;The controlled experiment used a disaster-related tweet dataset containing 2,559 entries and 13 original fields. A second experiment used a Mastodon API prototype to explore how public posts from a federated social platform could enter the same processing pipeline.&lt;/p&gt;

&lt;p&gt;Normalization matters because different platforms expose different fields, metadata, and content formats. A reusable internal representation makes it easier to apply downstream processing consistently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 2: Identify unusual content&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The framework evaluated several approaches to anomaly detection, including:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;K-Means&lt;/strong&gt; to organize observations into clusters.&lt;br&gt;
&lt;strong&gt;DBSCAN&lt;/strong&gt; to identify density-based clusters and potential outliers.&lt;br&gt;
&lt;strong&gt;Spectral autoencoder-based detection&lt;/strong&gt; using reconstruction-based deviations&lt;br&gt;
&lt;strong&gt;A hybrid DT-SVMNB model&lt;/strong&gt; combining decision-tree, support-vector-machine, and naïve Bayes components.&lt;/p&gt;

&lt;p&gt;The experiments also examined different feature representations, including document-term matrices (DTM), TF-IDF vectors, and BERT embeddings.&lt;/p&gt;

&lt;p&gt;These representations capture different properties of the text. DTM and TF-IDF emphasize lexical patterns, whereas BERT embeddings provide contextual semantic representations.&lt;/p&gt;

&lt;p&gt;The important engineering lesson is that model performance depends not only on the algorithm, but also on how the data is represented and what task the model is expected to perform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 3: Add semantic and verification-oriented analysis&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Posts identified for further examination can then enter downstream components.&lt;/p&gt;

&lt;p&gt;The framework includes NLP components for sentiment and emotion analysis, alongside an automated fact-checking verifier that classifies claims using labels such as True, False, Partially Supported, Partially Not Supported, and Unclear.&lt;/p&gt;

&lt;p&gt;These outputs answer different questions.&lt;/p&gt;

&lt;p&gt;Sentiment analysis can provide information about the tone of a message. Emotion classification can offer additional context. A verification component attempts to assess a factual claim.&lt;/p&gt;

&lt;p&gt;Neither sentiment nor emotional intensity establishes whether a claim is true. A frightened eyewitness may be accurate, and a confidently written message may be completely unsupported.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What did the experiments show?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One useful finding was that performance varied with both the model and the feature representations.&lt;/p&gt;

&lt;p&gt;For example, in the controlled dataset experiment, K-Means using BERT embeddings achieved a ROC-AUC of 0.59 and a PR-AUC of 0.30. These results indicate a limited discriminatory ability in that experimental setting.&lt;/p&gt;

&lt;p&gt;This is important because a technically functioning model is not necessarily a sufficiently reliable operational detector.&lt;/p&gt;

&lt;p&gt;A pipeline can collect posts, transform text into features, calculate scores, and display suspicious messages while still struggling to distinguish the cases that matter most.&lt;/p&gt;

&lt;p&gt;The Mastodon experiment demonstrated a different kind of result: the framework could ingest, normalize, and process public posts through the existing pipeline.&lt;/p&gt;

&lt;p&gt;That was a deployment-oriented feasibility test, not proof that the system could reliably determine the truth of claims during a live crisis.&lt;/p&gt;

&lt;p&gt;The distinction matters. The Mastodon sample did not have manually verified labels for the relevant fact-checking and NLP evaluations, so simulated reference labels were used to test the evaluation workflow. The resulting scores should not be interpreted as definitive evidence of real-world verification accuracy.&lt;/p&gt;

&lt;p&gt;These limitations are not incidental details. They define what can responsibly be concluded from the research.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Turning the architecture into a trustworthy system&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The experiments suggest a practical design principle: &lt;strong&gt;store detection, verification, and review as separate parts of an assessment.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, a developer might represent the output of a monitoring system with a structure like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dataclass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Literal&lt;/span&gt;

&lt;span class="n"&gt;VerificationStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Literal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
 &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;not_assessed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;supported&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;partially_supported&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unclear&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;partially_not_supported&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;not_supported&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ClaimAssessment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="n"&gt;post_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
 &lt;span class="n"&gt;anomaly_score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
 &lt;span class="n"&gt;verification_status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;VerificationStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;   &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;not_assessed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
 &lt;span class="n"&gt;evidence_refs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_factory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;needs_human_review&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an illustrative design, not code copied from the thesis. &lt;/p&gt;

&lt;p&gt;Its purpose is to make an important boundary explicit: an anomaly score does not automatically change a claim's verification status. The system can flag a post for investigation while leaving its factual status unassessed. &lt;/p&gt;

&lt;p&gt;The same design also makes room for uncertainty. A claim can remain unclear when the available evidence is insufficient, rather than being forced into a binary category.&lt;/p&gt;

&lt;p&gt;For consequential decisions, I would extend this representation with timestamps, source provenance, the basis for each assessment, and a record of subsequent corrections.&lt;/p&gt;

&lt;p&gt;I would also treat human review as an explicit operational stage for ambiguous or high-impact claims. Although the thesis includes a feedback mechanism, it does not implement a complete expert-review process. That remains an important direction for future development.&lt;/p&gt;

&lt;p&gt;Finally, evaluation should reflect the task's practical requirements. When relevant positive cases are relatively rare, PR-AUC and precision-recall behaviour can be particularly informative. A high-level accuracy figure alone may conceal how many important cases are missed or how many ordinary posts are incorrectly flagged.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The larger lesson: useful signals are not final judgments&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is a broader implication for AI-assisted decision-making.&lt;/p&gt;

&lt;p&gt;A machine can detect a pattern, generate a classification, summarize several sources, or produce a plausible explanation. Each capability can be valuable. None, by itself, guarantees that the resulting conclusion is justified.&lt;/p&gt;

&lt;p&gt;In crisis management, this distinction can influence how information is prioritized and communicated. In other settings, it can affect moderation decisions, reputation assessments, public services, and the interpretation of AI-generated answers.&lt;/p&gt;

&lt;p&gt;The practical objective should not be to eliminate uncertainty by giving every message a confident label. It should be to organize uncertainty so that people can investigate the right questions with the evidence available.&lt;/p&gt;

&lt;p&gt;That means asking:&lt;/p&gt;

&lt;p&gt;What exactly did the model detect?&lt;br&gt;
What evidence supports the resulting claim assessment?&lt;br&gt;
Are the sources independent, current, and relevant?&lt;br&gt;
What remains uncertain?&lt;br&gt;
Who can review or challenge the decision?&lt;/p&gt;

&lt;p&gt;These questions turn transparency from a general aspiration into a set of engineering requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My thesis explored a modular approach in which anomaly detection prioritizes unusual social media content, while downstream fact-checking and NLP components provide additional context and claim assessment.&lt;/p&gt;

&lt;p&gt;The main lesson is not that one particular algorithm solves misinformation detection. It is that &lt;strong&gt;different models should perform clearly defined tasks, and their outputs should not be mistaken for conclusions they have not established.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The next research steps include larger-scale live validation, broader data sources, multimodal and graph-based analysis, and evaluation with crisis-management practitioners. Human oversight, evidence provenance, and responsible handling of public social media data also remain essential considerations.&lt;/p&gt;

&lt;p&gt;These technical questions eventually lead to a more fundamental one: what should we be entitled to conclude when a machine gives us an answer?&lt;/p&gt;

&lt;p&gt;That question is the subject of my book, &lt;em&gt;Beyond True or False: Artificial Intelligence, Uncertainty, and the Future of Human Judgment.&lt;/em&gt;&lt;br&gt;
It develops the broader implications of AI-assisted assessment, including evidence, uncertainty, human oversight, and the responsibilities of institutions that rely on algorithmic judgments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read more:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;My research thesis: &lt;a href="https://www.researchgate.net/publication/415288464_Anomaly_Fact-Checking_Detection_of_Social_Media_Data_in_Crisis_Management" rel="noopener noreferrer"&gt;https://www.researchgate.net/publication/415288464_Anomaly_Fact-Checking_Detection_of_Social_Media_Data_in_Crisis_Management&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;My book, &lt;em&gt;Beyond True or False:&lt;/em&gt; &lt;a href="https://www.lulu.com/shop/dimitrios-ioannidis/beyond-true-or-false/paperback/product-7k5pyp7.html?page=1&amp;amp;pageSize=4" rel="noopener noreferrer"&gt;https://www.lulu.com/shop/dimitrios-ioannidis/beyond-true-or-false/paperback/product-7k5pyp7.html?page=1&amp;amp;pageSize=4&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.amazon.com/dp/B0HN5WZ2V4" rel="noopener noreferrer"&gt;https://www.amazon.com/dp/B0HN5WZ2V4&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would be interested to hear how other developers approach this boundary between anomaly detection and verification. In your own systems, how do you prevent a model's signal from being treated as proof?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Chandola, V., Banerjee, A., &amp;amp; Kumar, V. (2009). Anomaly Detection: A Survey. ACM Computing Surveys, 41(3).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Devlin, J., Chang, M.-W., Lee, K., &amp;amp; Toutanova, K. (2019). BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. Proceedings of NAACL-HLT.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shu, K., Sliva, A., Wang, S., Tang, J., &amp;amp; Liu, H. (2017). Fake News Detection on Social Media: A Data Mining Perspective. ACM SIGKDD Explorations Newsletter, 19(1), 22–36.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>nlp</category>
      <category>datascience</category>
    </item>
  </channel>
</rss>
