Mail.app is often lauded (and rightfully so) for its exceptional spam filtering, but what to do when the filters start breaking down? It seems that after the file that contains your filtering rulebase (~/Library/Mail/LSMMap2) becomes too large, Mail.app effectively stops catching spam. I've experienced this more than once and each time it has come on rather suddenly, leading me to believe that there is a specific filesize threshold that, when crossed, breaks the filters (the last time I noticed this the size of the LSSMap2 file was ~8.5MB).
The only way to "fix" this is to remove the LSSMap2 file (Mail.app recreates a new, blank file when you restart the application). Yes, this means that you have to start training the application again, which, for at least a little while, puts you in the same position you were in before you removed the file.
JunkMatcher filters spam using flexible regular expressions, IP query against multiple blacklists (such as SpamCop.net) and varoius other techniques such as email property matching, HTML final rendering matching etc. You can match against almost every bit of a message (including attachment filenames and charsets), and the raw material for matching is cleaned out for you to defeat some of the tricks spammers use to obfuscate their messages.
To get my rules back on track again, I simply let JunkMatcher "define" the native filters by using it for a few days. This means that you have to actively look for false-positives (I always get quite a few with JunkMatcher's default rules), but I've found that after just two or three days (given the extremely high volume of spam I get; >2000/day) the filters have been "trained" well enough that I can turn JunkMatcher off (until LSSMap2 decides to shit on itself again).
It isn't the best solution, but for now it does the trick and has stopped me from implementing Knowspam or something similar.