Picard lookups for single tracks are wildly off?

I had a hiatus from Picard and MusicBrainz until a few of months ago, and I figured there would be changes to adjust to. The main thing I’ve noticed, to my surprise, is that Picard’s ability to look up single tracks seems to have gone haywire (currently on 2.11). Clusters are good, and scans are as good as they’ve ever been, but for single files I get some of the weirdest results.

I mean, it was always a little finicky based on settings for release type and so on, but I don’t remember it having any trouble with a well-tagged file. I tried resetting the release type filters to see if that helped, but I can’t tell that it has.

In the example below, the track was already tagged with almost all the details (99% match) and the correct release was loaded in Picard, and yet it matched to this other release with a 66% match (I’m not sure how it’s even that high).

How is Picard prioritizing results? I can make a ticket if I need to, I just feel like I’m losing my mind. I haven’t seen any sign of other people having the problem. (I know I can tweak the match thresholds but in something like 15 years of using Picard I’ve never had to.)

1 Like

@outsidecontext Philipp?

The problem comes in part from the popular recording title, there are a lot of songs called “You’re the One”, and in parts on how Picard’ search is fuzzy.

Picard essentially performs this search on MB: track:(You’re the One) artist:(Tracy Chapman) release:(Let It Rain) tnum:(3) tracks:(12) qdur:(93) isrc:(USEE10240646)

In most cases this works, because some well matching result is in the returned data (Picard takes the first 50 results by default, but you can increase it to 100 in the advanced options). As Picard then filters the results for similarity it often gets a match.

But note that Tracy Chapman does not appear in the top 100 of results. The reason is, that the query actually is an OR query for the different fields. And because the recording title gets a high match priority you get a lot of different “You’re the One” results first.

If Picard would use an AND you actually would get an exact result. The following returns exactly one result (the one you were looking for): track:(You’re the One) AND artist:(Tracy Chapman) AND release:(Let It Rain) AND tnum:(3) AND tracks:(12) AND qdur:(93) AND isrc:(USEE10240646)

The problem with this is that it only works well with really well tagged data and is not very tolerable to wrong tags. Which makes the search perform very badly on not well tagged files.

That doesn’t mean the search couldn’t be improved, though. There is a partially related ticket PICARD-2788: Lookup provides unexpected results (wrapping with parentheses vs quotation marks). It’s about the use of using e.g. title:(You’re the One) (title matching any of the words, with better score if it matches more) vs. title:"You’re the One" (title matches exactly what’s given) or maybe a fuzzy variation title:"You’re the One"~. I experimented with this, and again the problem comes up that it works well with well tagged files. But it quickly gives no results at all for not so well tagged files, without providing Picard the ability to filter and match the results client side.

@Sophist No need to ping me on Picard topics. I am subscribed to the Picard category and get an e-mail notification for every topic here.

6 Likes

Just off the top of my head, I wonder if there would be any value in doing a second search with some of the fields (such as title and artist) ANDed if the first search returned the maximum number of results. I know this would slow down processing a bit because of the second call to the api, but it might be worth it in the long run.

2 Likes

I rather thought about the opposite: more exact match first (still with some fuzziness to allow for simple typos), and if that gives no results then the OR matches afterwards

3 Likes

That definitely makes more sense. Potentially fewer api calls.

1 Like

In a former life (in about 2001 - I was in this role on 9/11 and so the timescales are quite memorable) I was actually a complex fuzzy search engine expert.

IMO (and remember it is more than two decades since I was an expert) the use of the OR for selecting records is the correct one, and the magic is about how you then score each of the search results and sort them in decreasing score before you select the top 50 or 100 to send to Picard.

It is complex enough doing the scoring if you search for exact matches on each of the fields (with “OR”) but it gets even more complicated if each of the search values is fuzzy matched itself.

So if the track name you are searching on is “You’re the one” you might have synonyms of “Your” and “You are” for the word “You’re”, so that the search becomes track = 'you're the one' OR track = 'your the one' or track = 'you are the one' or possibly (track = '%you're %' OR track = '%your %' OR track = '%you are %') AND track = '% the %' AND track = '% one%'. And of course you will need to simplify any punctuational synonyms or remove all punctuation from both search and data values.

The way we did it was using SQL Stored Procedures - from memory, we would select each of the search terms separately, inserting the index-id and a weighted score for that term into a temporary table, and then we would then group by index-id and sum the scores, sort descending by score and output the top 50 results.

So in this example the SQL might be something along the lines of:

SELECT track_id, 10000 AS score FROM tracks
    WHERE track = "you're the one" AND artist = "Tracy Chapman" AND release = "Let It Rain"  AND tnum = 3 AND tracks = 12 AND qdur BETWEEN 90 AND 96
    INSERT INTO temp;
SELECT track_id, 1000 AS score FROM tracks
    WHERE isrc ="USEE10240646"
    INSERT INTO temp;
SELECT track_id, 50 AS score FROM tracks
    WHERE track = "you're the one" 
    INSERT INTO temp;
SELECT track_id, 30 AS score FROM tracks
    WHERE track = "your the one" or track = "you are the one"
    INSERT INTO temp;
SELECT track_id, 50 AS score FROM tracks
    WHERE artist = "Tracy Chapman"
    INSERT INTO temp;
SELECT track_id, 30 AS score FROM tracks
    WHERE artist = "Tracey Chapman" OR artist = "Tracy Chappman" OR artist = "Tracey Chappman"
    INSERT INTO temp;
SELECT track_id, 40 AS score FROM tracks
    WHERE release = "Let It Rain" AND tnum = 3 AND tracks = 12 AND qdur BETWEEN 90 AND 96
    INSERT INTO temp;

SELECT FIRST 50 ROWS ONLY track_id, SUM(score) FROM temp
    GROUP BY track_id
    ORDER BY SUM(score) DESC;

IIRC, the temp table was an in-memory table, and each transaction had its own temp table. And because this is all done in one go on the SQL server using Stored Procedures and is not transmitting the full interim results back to the app server but rather only the top 50 scores, the performance was excellent.

(For the specific application domain I designed this for in 2001, there were several additional rules that were applied to the interim table to remove specific combinations of results that we deemed false positives before the scores were summarised and results returned. So you can see that using this style of approach there is a lot of flexibility on weightings and business rules etc. And the users were absolutely amazed by the accuracy of the search results - which were way better than the much simpler search engine they previously had. Unfortunately, when I went back several years later to visit my friends there, the system had been replaced again by something much simpler and the improvements had been lost. Ah well.)

3 Likes

Thanks @outsidecontext, that clarifies the difficulties. I hope some improvements can be made but it’s certainly not simple.

The more I think about it, the more baffled I am that this other release/track got even a 66% match. The matching values are title (significant), genre (by coincidence, seems iffy for considering in a match), disc # (minimal significance), total tracks/discs (minimal significance), and release status (minimal significance). That’s not even half the fields involved.

A match on title, artist and album should take priority over a match on title, disc #, and release status. Could anything be done similar to what @Sophist says about weighting the queries?

How do tags that are in the “preserve tags” list affect the %? It seems like they should not be included at all.

Added: another thought, which I’m not quite sure how to put into words, has to do with taking into account which values are most likely to have false positives. Artists are much less likely than titles or albums to match wrong items. If I were searching for this in my own library, I’d find Tracy Chapman first and narrow it down from there.

1 Like

To be fair with default settings the lookup for this track does not give any results. The default threshold for file lookups is 70%. If the preferred release settings are on default the best match I got was Recording “You're the One For Me” by Marshall Chapman - MusicBrainz with 58%. And it is not surprising, as title and artist have some similarity, and track length and position match also.

If I fiddle with the peferred release types and increase the preference for type album to highest the best match increases to 69%, still just below the default threshold.

Title has a high significance for the “Lookup” action. Genre is not considered at all, as is disc number. Track length does have a significant impact. But for your result it is not applied at all as the length is not defined.

It usually would, but as Picard did not receive a match with matching title, artist and album this didn’t apply.

I don’t think that applies here. Server side MusicBrainz uses Lucene to do the searching, see also MusicBrainz API / Search - MusicBrainz. So any optimizations are specific to this. There are two general ways to change the results:

  1. Client side (i.e. Picard): Change the way the search query is constructed. This means using the Lucene search syntax to construct a query to get results. As described above Picard currently is intentionally broad currently so it can perform its own weighting on the results afterwards. But it might be possible to improved this.

  2. Server side, e.g. by changing the way individual fields are indexed and by changing the default weights applied. Maybe @yvanzo can say more about that.

How do tags that are in the “preserve tags” list affect the %? It seems like they should not be included at all.

The “preserved tags” setting does not affect the matching, and I don’t think it should. There is a dedicated setting for that in Options > Advanced to exclude tags from comparison.

I disagree with that. On not well tagged collections artist information is often not that great actually.

4 Likes

Do you have specific fields with search issues in mind (independently of weights and AND/OR combinations)?

Server-side default weights don’t apply to advanced search queries that Picard is using. Actually weights can be specified in those queries using the caret ^ to boost a term.

4 Likes

Odd, mine are at 50. Could that be a holdover from a previous default? I have had this settings file for literally a decade or more. Anyway, I’ll change them to 70 and hopefully that will help.

Sure, in terms of source data I expect that’s true. What I mean is that on MusicBrainz’ end, there are fewer artist values and any given match is less likely to have a duplicate, therefore there’s a higher probability of a good match on artist. How that helps in constructing a search, I don’t know.

That makes sense, and leaves me even more confused as to why the other got 66%. I’ve already re-saved it, so it may remain a mystery.

2 Likes