SlowGuess/NeurIPS_2023_OCR huggingface dataset:
We tackle both of these issues by adapting the A-ExpJ algorithm of [40], and use their naming conventions to make comparison easier. This algorithm works on a stream of items with weights  $w_{i}$ , and in  $\mathcal{O}(1)$  space can produce a valid weighted sample from the stream. It does so by computing a randomized threshold  $T_{w}$  and processing samples until the cumulative weights  $\sum_{i} w_{i} > T_{w}$ , at which the final item in the sum becomes the new sample. A new value of  $T_{w}$  is computed, and the process continues until the stream is empty. This process requires generating only  $\mathcal{O}(\log D)$  random thresholds for a stream of  $D$  items.
We exploit the fact that we have a known and fixed set of  $D$  items to develop a new version of this algorithm that can be updated in constant time, is numerically sta
Algorithm 4 Big-Step Little-Step Exponential Sampler
1: function GETNEXT()
2:  $j\gets 0$
3:  $o \gets \exp(\mathbf{v}^{(j)} - z_{\Sigma})$
4:  $\log T_w \gets \frac{\log\mathcal{U}(0,1)}{\exp\mathbf{v}^{(i)} - z_{\Sigma}}$
5:  $c\gets 0$
6: while  $c < N$  do
7:  $X_w \gets \frac{\log \mathcal{U}(0,1)}{\log T_w}$
8: while  $\exp \left(\mathbf{c}^{(c \mod \lfloor \sqrt{N} \rfloor)} - z_{\Sigma}\right) - o < X_w \mathbf{d}\mathbf{o}$
9:  $X_w \gets X_w - (\exp(\mathbf{c}^{(c \mod \lfloor \sqrt{N} \rfloor)} - z_{\Sigma}) - o)$
10:  $o\gets 0$
11:  $c\gets \lfloor \sqrt{N}\rfloor -c$  mod  $\lfloor \sqrt{N}\rfloor$
12: end while
13: while exp  $\left(\mathbf{v}^{(c)} - z_{\Sigma}\right)$ $<  X_w$  do  $\mathcal{O}(\sqrt{N}\log N)$
14:  $X_{w}\gets X_{w} - \exp \left(\mathbf{v}^{(c)} - z_{\Sigma}\right)$
15:  $o\gets o + \exp \left(\mathbf{v}^{(c)} - z_{\Sigma}\right)$
16:  $c\gets c + 1$
17: end while
18: if  $c < N$  then
19:  $j\gets c$
20:  $c\gets c + 1$
21:  $t_w \gets \exp \left(\exp \left(\mathbf{v}^{(j)} - z_{\Sigma}\right)\right) \cdot \log T_w$
22:  $\log T_w\gets \frac{\log\mathcal{U}(t_w,1)}{\exp(\mathbf{v}^{(j)} - z_\Sigma)}$
23: if  $j \mod \lfloor \sqrt{N} \rfloor \neq 0$  then
24:  $o\gets 0$
25: else
26:  $o\gets o + \exp \left(\mathbf{v}^{(j)} - z_{\Sigma}\right)$
27: end if
28: end if
29: end while
30: end function
31: function UPDATE(i, v)
32:  $v_{cur} \gets$  current priority of item  $i$
33:  $k\gets i$  mod  $\lfloor \sqrt{N}\rfloor$
34:  $\mathbf{c}^{(k)}\gets \mathbf{c}^{(k)} + \log \left(1 - e^{v_{cur} - \mathbf{c}^{(k)}} + e^{v - \mathbf{c}^{(k)}}\right)$
35:  $z_{\Sigma}\gets z_{\Sigma} + \log \left(1 - e^{v_{cur} - z_{\Sigma}} + e^{v - z_{\Sigma}}\right)$
36: end function
<sup>3</sup>We note that there can be mild disagreement on update order caused by numerical differences in brute-force recalculation of Algorithm 1 and the updates of Algorithm 2, but we observe no issues with this.
ble for a wide range of weights, and can draw a new sample in  $\mathcal{O}(\sqrt{D}\log D)$  time. The key idea is to form large groups of variables and keeping track of their collective weight. If the group's weight is smaller than  $T_{w}$ , then the entire group can be skipped to perform a "Big-Step". If the group's weight is larger than  $T_{w}$ , then the members of the group must be inspected individually to form "Little-Steps". For this reason we term our sampler the "Big-Step Little-Step" sampler, and this procedure is shown in Algorithm 4.
The scale of gradients can change by four or more orders of magnitude due to the evolution of the gradient during training and the exponentiation of the Exponential Mechanism. For this reason, all logic is implemented at log scale, and a total log-sum-weight  $z_{\Sigma}$  is tracked. Every exponentiation of a log-weight then subtracts this value, performing the log-sum-exp trick to keep the sample weights in a numerically stable range<sup>4</sup>
Similarly, each group has a group log-sum weight, and we denote the vector of the group weights as  $\mathbf{c}$ . There are  $\sqrt{D}$  groups so that each group has  $\sqrt{D}$  members. On lines 34 and 35 of Algorithm 4, a log-sum-exp update is used to update the group sum  $\mathbf{c}^{(k)}$  and total sum  $z_{\Sigma}$  (which are already log-scale since there was no exponentiation on line 30 of Algorithm 2). In both cases we always expect the group sum to be larger, and so we use  $\mathbf{c}^{(k)}$  and  $z_{\Sigma}$  as the maximal values to normalize by in each update. Lines 31 and 32 select the "Big-Step" group to update for the change in weight of the  $i$ 'th item.
Lines 8-12 and 13-17 perform the same loop at two different scales. 8-12 perform big steps over groups, and must handle that the starting position could be in the middle of a group from a previous iteration, making it a partial group. For this reason, there is a "group offset"  $o$  that subtracts the weight of items already visited in the group. Once a Big-Step is made, on line 11 the position is incremented by the group size modulo the current position, so that each step starts at the beginning of the next group regardless of starting position, handling the case of starting from a previous little step's location. Then lines 13-17 perform little steps within a group, and it is known that a new item must be found in the little group, otherwise, lines 8-12 would have repeated due to having a sum smaller than  $T_w$ .
The remainder of lines 2-5 and 18-30 work as the standard A-ExpJ algorithm, except each calculation, is done at log-scale or exponentiated if an item is needed at a non-log scale, for example on line  $21^{5}$ .
Each of the  $\log (D)$  random variates needed by Algorithm 4 corresponds to the selection of a new current sample. In the worst cases, each of these samples will belong to a different group, necessitating exploring  $\mathcal{O}(\log D)$  groups each of size  $\sqrt{D}$  by construction, giving a total sampling complexity of  $\mathcal{O}(\sqrt{D}\log D)$ . Just as with the Fibonacci Heap, the update procedure is  $\mathcal{O}(1)$  per update, and so the final DP-FW complexity becomes  $\mathcal{O}(NS_cT\sqrt{D}\log D + TS_rS_c)$ . As we will demonstrate in our results, this provides significant speedups over the standard Frank-Wolfe for sparse datasets. This is because, by design, the Algorithm 4 procedure is very cache friendly, performing linear scans over  $\sqrt{D}$  items at a time making pre-fetching very easy, and thus has only  $\mathcal{O}(\log D)$  cache-misses when performing Little-Step transitions.
Having derived a sparsity-aware framework for implementing Frank-Wolfe iterations in time proportional to the sparsity of the data, we will now demonstrate the effectiveness of our results. Since our goal is to support faster training with sparse datasets, we focus on high-dimensional
Table 2: Datasets used for evaluation. We focus on cases that are high-dimensional and sparse.
Dataset	N	D
RCV1	20,242	47,236
20 Newsgroups(Binary “News20”	19,996	1,355,191
Malicious URLs, “URL”	2,396,130	3,231,961
Webb Spam Corpus, “Web”	350,000	16,609,143
KDD2010 (Algebra), “KDDA”	8,407,752	20,216,830
problems listed in Table 2 where  $D \geq N$ . Note that to the best of our knowledge, the RCV1 dataset at
<sup>4</sup>Very small weights will still underflow, but by definition this happens when their probability to be selected is several orders of magnitude lower and thus are astronomically unlikely to be chosen anyway. Adding a small  $10^{-15}$  value guarantees a chance to be selected and maintains DP via technically adding more noise than necessary.
<sup>5</sup>We note that the double exponentiation on this line is correct and numerically stable. The first exponentiation will produce a value in the range of [0, 1] for the second exponentiation to use per the A-ExpJ algorithm
$D = 47\mathrm{k}$  is the highest-dimensional dataset any prior work has used to train a DP logistic regression model [16], and its  $D$  is  $428\times$  smaller than the largest  $D$  we consider.
Our results will first focus on the non-private Frank-Wolfe due to its deterministic behavior and clear convergence criteria via the Frank-Wolfe gap  $g_{t}^{6}$ . This will allow us to show clearly that we reduce the total number of floating point operations per second (FLOPs) required, though we note that in practice the runtime remains similar due to cache inefficiency.
After establishing that Algorithm 2 requires fewer FLOPs, we turn to testing the DP version leveraging our Big-Step Little-Step Sampler Algorithm 4, showing speedups ranging from  $10 \times$  to  $2,200 \times$  that of the standard DP Frank-Wolfe algorithm when training a model on sparse datasets.
Due to the computational requirements of running all tests, we fix the total number of iterations  $T = 4,000$  and maximum  $L_{1}$  norm for the Lasso constraint to be  $\lambda = 50$  in all tests across all datasets. This value produces highly accurate models in all non-private cases, and the goal of our work is not to perform hyper-parameter tuning but to demonstrate that we have taken an already known algorithm with established convergence rates and made each iteration more efficient. All experiments were run on a machine with 12 CPU cores (though only one core was used), and 128GB of RAM. The total runtime for all experiments took approximately 1 week and exploring larger datasets was limited purely by insufficient RAM to load larger datasets in memory. Our code was written in Java due to the need for explicit looping, and implemented using the JSAT library [36]. When comparing Algorithm 1 and our improved Algorithm 2, the latter will be prefixed with “-Fast” in the legend to denote the difference.
4.1 Non-Private Results
We first begin by looking at the convergence gap  $g_{t}$  over each iteration to confirm that we are converging to the same solution, which is shown in Figure 1. Of note, it is often impossible to distinguish between the standard and our fast Frank-Wolfe implementations because they take the exact same steps. Differences that occur are caused by nearly equal gradients between variables and are observable via inspection of  $g_{t}$ . In all cases, the solutions returned achieve identical accuracy on the test datasets.
Figure 1: Convergence gap  $g_{t}$  (y-axis, same scale for both plots) as the number of iterations increases (x-axis), showing that our Algorithm 2 (dotted lines) converges to the same solutions as Algorithm 1, with minor differences due to numerical floating point changes (i.e., both plots look nearly identical, the desired behavior). This shows our new approach maintains solution quality.
In Algorithm 2, the updating in differences can cause catastrophic cancellation due to the zig-zag behavior of Frank-Wolfe iterates (updating the same coordinate  $j$  multiple times with differing
<sup>6</sup>In the DP case  $g_{t}$  is especially noisy and hard to leverage meaningfully, often starting lower and increasing. This makes it a non-informative measure
signs on each update), resulting in similar magnitude sign changes that result in slightly different results numerically compared to re-computing the entire gradient from scratch. Choosing an adaptive stepsize  $\eta_t$  may alleviate this issue in future work.
Next, we empirically validate the  $\mathcal{O}(\| \mathbf{w}^*\|_0)$  number of times we must query the Fibonacci Heap for selecting the next iterate. The ratio of the number of times we must pop an item from the Heap against the value of  $\| \mathbf{w}^*\|_0$  is plotted over training iterations in Appendix Figure 3. We can see in all cases the ratio is  $\leq 3$ , and so few calls to the heap are necessary.
Finally, we look at the convergence rate  $g_{t}$  as a function of the number of FLOPs required to obtain it, as shown in Figure 2. It is clear that we avoid orders of magnitude more operations than a naive implementation of Frank-Wolfe would normally require, providing the foundation for our faster DP results in the next section. Unfortunately, the Fibonacci Heap has poor caching behavior, resulting in no meaningful difference in runtime for the sparse case.
4.2 Differentially Private Results
Having established that Algorithm 2 avoids many floating point operations by exploiting sparseness in the training data, we now turn to training DP versions of the normal and our faster Frank-Wolfe algorithms. The total speedup in the runtime of our Algorithm 2 over Algorithm 1
Figure 2: The y-axis (larger is better) shows how many times fewer FLOPs our Alg.  $2 + \mathrm{Alg}3$  needs compared to the original Frank-Wolf (Alg. 1). The x-axis is how many iterations into training have been performed. Note that in all cases the difference is difficult to differentiate reaching 1,000 iterations as we reduce the number of FLOPs by orders of magnitude per iteration.
is shown in Table 3. As can be seen, our results range from a  $10 \times$  speedup for the URL dataset at the low end, up to a 2,  $200 \times$  speedup for the KDDA and URL datasets at  $\epsilon = 0.1$ . In addition we ablated using Algorithm 2 with the brute force noisy-max as an ablation, which shows smaller speedups. This demonstrates that the combination of Algorithms 2 and 4 are necessary to get our results.
Table 3: How many times faster our Algorithm 2+Algorithm 4 over the standard FW implementation. In addition, just Algorithm 2 using the noisy-max sampling is included as an ablation, showing that both Alg. 4 & 2 combined are necessary to obtain maximum speed.
Dataset	ε1	ε0.1
Alg. 2+4	Alg. 2	Alg. 2+4	Alg. 2
News20	81.69	17.83	93.51	19.05
URL	9.99	1.02	2451.80	95.58
RCV1	19.44	1.36	20.37	1.82
Web	581.25	21.24	537.65	20.79
KDAA	1239.64	206.50	2245.56	368.96
We note that the speedup of our method is a function of the sparsity of informative and non-informative features. This is more noticeable on the URL dataset which jumps from a  $10 \times$  speedup to a  $2,400 \times$  speedup when moving from  $\epsilon = 1$  down to  $\epsilon = 0.1$ . This is because the URL dataset has 200 dense features that are highly informative, and the remaining features are all sparse. When a feature is dense, there is no advantage to using Alg. 2 & 4, and so no benefit is obtained. At the lower noise level of  $\epsilon = 1$ , the denser (and thus slower) informative features are selected more frequently, resulting in longer total runtime. As the noise increase with  $\epsilon = 0.1$ , the sparser non-informative features are selected more often, which reduces the average amount of work per update. This phenomena occurs in most datasets as denser features intrinsically have more opportunities to be discriminative, but is uniquely pronounced on the URL dataset.
This is ultimately a desirable property of our method, as large values of  $\epsilon > 10$  are effectively not private, and so faster methods of non-private training should be used instead. Our Algorithm 2 with the Big-Step-Little-Step Sampler of Algorithm 4 will increase its effective utility as the desired amount of privacy increases.
Table 4: Even at high privacy  $\epsilon = 0.1$  we obtain non-trivial Accuracy and AUC on most datasets by using  $T = 400,000$  iterations. Because the datasets are so high dimensional, we still obtain sparse solutions (rightmost column).
Dataset	Accuracy (%)	AUC (%)	Sparsity (%)
RCV1	90.53	97.29	5.81
News20	92.37	98.65	75.19
URL	73.23	82.60	89.44
Web	75.42	92.51	99.90
KDDA	85.25	53.31	85.30
As our final test to highlight the utility and importance of our approach, we re-run each dataset using  $\lambda = 5000$  with  $T = 400$ , 000 iterations at a real-world useful  $\epsilon = 0.1$ . As shown in Table 4 this results in non-trivial accuracy and AUC for all datasets but KDDA, and is only possible by performing hundreds of thousands of training iterations. Iyengar et al. [16] show the best prior results at  $\epsilon = 0.1$  for RCV1  $64.2\%$  accuracy, and in fact, we trail the non-private accuracy of  $93.5\%$  by only  $3\%$  points (note as well that their solution has  $0\%$  sparsity). This is made possible by simply performing far more iterations, which is computationally intractable with prior methods. We also note that we obtain significant sparsity on the higher dimensional datasets News20, URL, Web, and KDDA due to the fact that  $T < D$  for each of them, and the Frank-Wolfe will by construction have a number of non-zero coefficients  $\leq T$ .
We have developed the first DP training procedure that, for a sparse input dataset, obtains a training complexity that is sub-linear in the total number of features  $D$  at  $\mathcal{O}(NS_c + T\sqrt{D}\log D + TS_rS_c)$ . Testing on multiple high-dimensional datasets, we obtain up to 2,  $200\times$  speedup, with increasing efficiency as the value of  $\epsilon$  decreases. Using this speed efficiency, we show non-trivial accuracy and privacy at  $\epsilon = 0.1$  for  $352\times$  more features than ever previously attempted and improve accuracy compared to prior work by an absolute  $26.3\%$ .
[1] Cynthia Dwork. Differential privacy. In 33rd International Colloquium on Automata, Languages and Programming, part II (ICALP 2006), volume 4052 of Lecture Notes in Computer Science, pages 1-12, July 2006.
[2] Ashwin Machanavajjhala, Daniel Kifer, John Abowd, Johannes Gehrke, and Lars Vilhuber. Privacy: Theory meets Practice on the Map. In 2008 IEEE 24th International Conference on Data Engineering, pages 277-286, April 2008. doi: 10.1109/ICDE.2008.4497436. ISSN: 2375-026X.
[3] Ryan Rogers, Subbu Subramaniam, Sean Peng, David Durfee, Seunghyun Lee, Santosh Kumar Kancha, Shraddha Sahay, and Parvez Ahammad. LinkedIn's Audience Engagements API: A Privacy Preserving Data Analytics System at Scale, November 2020. URL http://arxiv.org/abs/2002.05839. arXiv:2002.05839 [cs].
[4] Ülfar Erlingsson, Vasyl Pihur, and Aleksandra Korolova. RAPPOR: Randomized Aggregatable Privacy-Preserving Ordinal Response. In Proceedings of the 2014 ACM SIGSAC Conference on Computer and Communications Security, CCS '14, pages 1054-1067, New York, NY, USA, November 2014. Association for Computing Machinery. ISBN 978-1-4503-2957-6. doi: 10.1145/2660267.2660348. URL https://doi.org/10.1145/2660267.2660348.
[32] Naoise Holohan, Stefano Braghin, Pol Mac Aonghusa, and Killian Levacher. Diffprivlib: The IBM Differential Privacy Library, July 2019. URL http://arxiv.org/abs/1907.02444.arXiv:1907.02444 [cs].
[33] Douglas W. Jones. An empirical comparison of priority-queue and event-set implementations. Communications of the ACM, 29(4):300–311, April 1986. ISSN 0001-0782. doi: 10.1145/5684.5686. URL https://doi.org/10.1145/5684.5686.
[34] Daniel H. Larkin, Siddhartha Sen, and Robert E. Tarjan. A Back-to-Basics Empirical Study of Priority Queues. In 2014 Proceedings of the Meeting on Algorithm Engineering and Experiments (ALENEX), Proceedings, pages 61-72. Society for Industrial and Applied Mathematics, December 2013. doi: 10.1137/1.9781611973198.7. URL https://epubs.siam.org/doi/abs/10.1137/1.9781611973198.7.
[35] Rong-En Fan, Kai-Wei Chang, Cho-Jui Hsieh, Xiang-Rui Wang, and Chih-Jen Lin. LIBLINEAR: A Library for Large Linear Classification. The Journal of Machine Learning Research, 9: 1871–1874, 2008.
[36] Edward Raff. JSAT: Java Statistical Analysis Tool, a Library for Machine Learning. Journal of Machine Learning Research, 18(23):1-5, 2017. URL http://jmlr.org/papers/v18/16-131.html.
[37] Guo-Xun Yuan, Kai-Wei Chang, Cho-Jui Hsieh, and Chih-Jen Lin. A Comparison of Optimization Methods and Software for Large-scale L1-regularized Linear Classification. The Journal of Machine Learning Research, 11:3183-3234, 2010.
[38] Kunal Talwar, Abhradeep Guha Thakurta, and Li Zhang. Nearly Optimal Private LASSO. In Advances in Neural Information Processing Systems, volume 28. Curran Associates, Inc., 2015. URL https://proceedings.neurips.cc/paper/2015/bitstream/52d080a3e172c33fd6886a37e7288491-Abstract.html.
[39] Cynthia Dwork, Frank McSherry, Kobbi Nissim, and Adam Smith. Calibrating Noise to Sensitivity in Private Data Analysis. In Shai Halevi and Tal Rabin, editors, Theory of Cryptography, Lecture Notes in Computer Science, pages 265-284, Berlin, Heidelberg, 2006. Springer. ISBN 978-3-540-32732-5. doi: 10.1007/11681878_14.
[40] Pavlos S. Efraimidis and Paul G. Spirakis. Weighted random sampling with a reservoir. Information Processing Letters, 97(5):181-185, March 2006. ISSN 00200190. doi: 10.1016/j.ipl.2005.11.003. URL https://linkinghub.elsevier.com/retrieve/pii/S002001900500298X.
[41] Martin Jaggi. Revisiting frank-wolfe: Projection-free sparse convex optimization. In International Conference on Machine Learning, pages 427-435, 2013.
[42] Shai Shalev-Shwartz. Online learning and online convex optimization. Foundations and Trends in Machine Learning, 4(2):107-194, 2012.
[43] Raghav Bhaskar, Srivatsan Laxman, Adam Smith, and Abhradeep Thakurta. Discovering frequent patterns in sensitive data. In Proceedings of the 16th ACM SIGKDD International Conference on Knowledge Discovery and Data Mining, KDD '10, page 503-512, New York, NY, USA, 2010. Association for Computing Machinery. ISBN 9781450300551. doi: 10.1145/1835804.1835869.
Figure 3: The ratio of items popped from a Fibonacci Heap over the non-zeros in the final solution (y-axis) over the number of iterations (x-axis) empirically demonstrates that Algorithm 3 does not need to consider all  $D$  possible features to select the correct iterate.
Figure 4: The number of floating point operations (x-axis) against the convergence gap  $g_{t}$  (y-axis), showing that Algorithm 2 (solid lines) reduces the required numerical steps by multiple orders of magnitude over the original Frank-Wolfe Algorithm 1 (dashed lines).
B Proofs of Correctness
Because our method is a direct translation of Frank-Wolfe to equivalent mathematical steps, all prior proofs apply to our version of the algorithm. We repeat/sketch the proofs here for further confidence in the correctness of the method.
B.1 Utility/Error Bounds
We provide a proof sketch that our algorithm's utility is near-optimal below which follows that of [38].
Let  $L$  be defined as in the paper: the Lipschitz constant of the loss function with respect to the  $L_{1}$  norm. Let  $S$  be the number of vertices of the constraint region, which we denote  $\mathcal{C}$ . Let  $\lambda$  be the scaling factor of the  $L_{1}$  ball to achieve the constraint region  $\mathcal{C}$ . Then for a loss with upper bound  $\Gamma_{\mathcal{L}}$  on the curvature constant as defined in [41], running Algorithm 2 for  $T = \frac{\Gamma_{\mathcal{L}}^{2/3}(n\epsilon)^{2/3}}{(L\lambda)^{2/3}}$  iterations, we have
$$
\mathbb {E} [ \mathcal {L} (\mathbf {w} ^ {p r i v}; D) ] - \min _ {\mathbf {w} \in \mathcal {C}} \mathcal {L} (\mathbf {w}; D) = \mathcal {O} \left(\frac {\Gamma_ {\mathcal {L}} ^ {1 / 3} (L \lambda) ^ {2 / 3} \log (n | S |) \sqrt {\log (1 / \delta)}}{(n \epsilon) ^ {2 / 3}}\right).
$$
To prove this statement, we use Lemma 5 and Theorem 1 from [41]. Lemma 5 states that at each step of the Frank-Wolfe algorithm, an inexact gradient can be used so long as its score is within  $\kappa$  to that of the true minimum vertex. [38] computed the value of  $\kappa$  and showed that with probability  $1 - \xi$ , this occurs over all steps. Then Theorem 1 in [41] stated that if Lemma 5 holds, an exact bound on the overall loss holds. Thus it follows that with probability  $1 - \xi$ , this statement holds. Finally, [38] used standard learning theory arguments to convert the bound in probability to one in expectation. Plugging in the desired value of  $T$  finishes the proof. Note that this proof is not affected by our sparse-aware framework. Indeed, the algorithm presented in [38] is simply algorithm [41] in our paper with dense calculations. (Lines 7-13 of our Algorithm 2 calculate scores for the exponential mechanism, like line 3 in Algorithm 2 of [38]. Line 15 in our algorithm corresponds to line 4 of Algorithm 2 in [38]. Lines 16-21 of our algorithm correspond to line 5 of Algorithm 2 in [38].) For that reason, at every iteration, as our updates are equivalent to that of [38].
Note that  $\Gamma_{\mathcal{L}}$  can be upper bounded for logistic regression. See [17] for details.
Finally, using a fingerprinting codes argument, Theorem 3.1 of [38] showed that under weak conditions, an optimal DP-learning algorithm  $\mathcal{A}$  has