> Contrast that to a weighted random shuffle where each subscription's weight is its affinity score and we sample them based on weight without regard to their order in the original list. That approach is much more influenced by the size of the total list, and my experience is the handful of subscriptions that I really liked were always drowned out by all the other "speculative" subscriptions I had accumulated in my account.
I personally see that as an argument for having the original position affect the weight.
I experimented with modifying Fisher-Yates to generate a slightly less left-skewed distribution, and decided upon inverse transform sampling as a fairly cheap solution -- basically, with some function f(X): [0,1) -> [0,1), you can transform a uniformly-distributed random variable X ~ Unif[0,1), which then allows you to bias the shuffle without affecting its asymptotic performance.
> There probably is some more efficient way to implement this though.
One potential optimization is to use rejection sampling: keep track of the elements you've seen, then reject any duplicates when pulling out a sample (instead of manually constructing a new list every time). Now, this interacts poorly with your biasing -- in the extreme case where p=1, you'd keep trying to select the first element, then rejecting it. I might then suggest tracking the first element you haven't selected yet, but at some point this ends up being a lot of complexity for asymptotic behavior when what you have is more than good enough for the scale that you're considering.
This also only addresses the "copy the list every iteration of the sampling" aspect of your algorithm's performance, not the fact that with p=0 (or arbitrarily low) you may end up walking the entire list.
(Rejection sampling is more generally using some criterion to reject samples, e.g. if you were trying to select points within a circle by checking x^2 + y^2 < r^2.)