Well, that it returns in 10 seconds is already pretty good, considering you:
- need to count all the up and down votes for every post across almost 2,000 tags
- scan the entire Votes table twice, leading to reading almost 25 million rows (due to 8x parallelism)
- sort five times (up to 10 million rows)
- include tags in the aggregate scan just to get the name (you should defer getting names until after aggregation)
- won't get help from indexes tailored specifically for this query
- won't get any noticeable benefit from statistics
How much faster than 10 seconds does it need to be? How fast do you expect this type of aggregate query to be?
Here is the complex plan for your existing query, with lots of thick lines and with the pain points highlighted (right-click to enlarge in a new tab):

Well, it can be a lot faster, relatively, but if the complexity of the query makes maintenance or understanding harder, it's probably not worth saving a few seconds of runtime.
I can't benefit any more from indexes or stats than you can (well, I could if I changed the database), and I can't change the fact that reading all of the votes for all of the posts across 2,000 tags is never going to be cheap.
But we can restructure the query so that Votes is only scanned once, the expensive sorts are removed, and the runtime is about 2 seconds. I don't like that we still have to scan PostTags twice, and it can probably be avoided with window functions, but I think an 80% improvement is a pretty good start.
;WITH BusyTags AS /* isolate the tag aggregate */
(
SELECT TagId
FROM PostTags
GROUP BY TagId
HAVING COUNT(*) >= 1000
), t AS /* then get the names */
(
SELECT bt.TagId, t.TagName
FROM BusyTags AS bt
INNER JOIN Tags AS t
ON bt.TagId = t.Id
), pt AS /* now get the posts */
(
SELECT pt.PostId, t.TagId, t.TagName
FROM PostTags AS pt
INNER JOIN t
ON pt.TagId = t.TagId
), v AS /* then sum the votes with a single scan */
(
SELECT pt.TagId, Tags = pt.TagName,
UpVotes = SUM(CASE WHEN v.VoteTypeId = 2 THEN 1 ELSE 0 END),
DownVotes = SUM(CASE WHEN v.VoteTypeId = 3 THEN 1 ELSE 0 END)
FROM pt
INNER JOIN Votes AS v
ON pt.PostId = v.PostId
GROUP BY pt.TagId, pt.TagName
)
SELECT Tags,
ratio = CONVERT(DECIMAL(5,2),
1.0 * Upvotes/NULLIF(DownVotes,0))
FROM v
ORDER BY ratio DESC;
Here is the simpler plan, with fewer (largely unavoidable) pain points highlighted (right-click to enlarge in a new tab):

To see real runtime instead of benefitting from cached results, make a meaningless text change to the query and/or enable Include execution plan.