Matching The Data

The two datasets describe companies differently, and one had been rescaled before publication. Getting them onto common ground is where the interesting problem was.

Two files describing the same thing — the financial health of a company — in two incompatible vocabularies. Nothing can be borrowed until they line up.

Input A

Taiwan

6,819 companies. 95 ratios, each with a proper name. Numbers already squashed into a 0-to-1 range.

Input B

Poland

Up to 10,503 companies. 64 ratios with the names stripped out. Original numbers, untouched.

Output

Common Ground

17 ratios that exist in both, with every company measured against others in its own country.

Pairing up the columns

Poland’s columns are anonymous. Attr6 tells you nothing until you look it up in the dataset’s documentation and find it means retained earnings divided by total assets — profit the company kept rather than paid out.

Every pair has to be matched by hand against that documentation. That makes this the easiest place in the whole project to introduce a silent mistake: mistype one column name and the model still trains, still scores, and still produces a believable-looking number. Nothing crashes. You simply get a wrong answer that looks right.

So the matching lives in a file of its own, written out as data rather than buried in analysis code — one entry per pair, each recording where the definition came from and how exact the match is. A check runs automatically and fails if any column gets claimed twice.

Pairs are matched on what a ratio actually measures, not on how similar the two names look. The anchor is a shortlist an accountant named Edward Altman published in 1968: five ratios he identified as the ones that matter for predicting bankruptcy. All five exist in both datasets, which gives the shared set a known backbone rather than an arbitrary one.

Name used here What it measures Match quality One of Altman’s five
gross margin gross profit / sales exact
quick ratio (current assets - inventory) / short-term liabilities exact
net profit to assets net profit / total assets exact
ebit to assets EBIT / total assets approximate yes
equity to assets equity / total assets exact
current ratio current assets / short-term liabilities exact
equity to liabilities book value of equity / total liabilities exact yes
liabilities to assets total liabilities / total assets exact
working capital to assets working capital / total assets exact yes
short term liabilities to assets short-term liabilities / total assets exact
retained earnings to assets retained earnings / total assets exact yes
operating margin profit on operating activities / sales approximate
sales to assets sales / total assets exact yes
receivable turnover sales / receivables exact
inventory turnover sales / inventory exact
collection days (receivables * 365) / sales exact
fixed asset turnover sales / fixed assets exact

Two matches are marked approximate. In one, Poland measures profit before tax while Taiwan’s nearest equivalent is after tax. In the other, Taiwan’s documentation doesn’t say what the figure is divided by. Both are kept, but flagged, so anyone reading the results can see how much rests on a loose match.

Two things were deliberately left out. Company size — Poland records it, Taiwan has no honest equivalent. And upside-down pairs, where one file reports A divided by B and the other reports B divided by A. You can flip one to match the other in principle, but the result explodes whenever the bottom number is near zero.

The problem nobody warns you about

With the columns paired, the obvious next step is to train on Taiwan and predict Poland. It produces a coin flip. Here is why.

Chart comparing the range each ratio spans in the two datasets. Taiwan's ranges all sit inside a narrow zero-to-one band. Poland's stretch far into negative numbers and up into the hundreds. Chart comparing the range each ratio spans in the two datasets. Taiwan's ranges all sit inside a narrow zero-to-one band. Poland's stretch far into negative numbers and up into the hundreds.
The same named ratio, as each source published it. Taiwan’s have been compressed into a 0-to-1 range; Poland’s are the original figures, and go negative wherever a company’s debts exceed everything it owns.

Whoever prepared the Taiwanese file rescaled every column so the smallest value became 0 and the largest became 1. The Polish file was published untouched. The same named ratio therefore lives on two completely different scales.

The consequence is concrete. A model trained on Taiwan learns rules like “flag it when the debt figure goes above 0.11”. Polish debt figures run past 400. Nearly every Polish company lands on the same side of that rule, so the model stops telling them apart at all. It still produces a number between 0 and 1 — it just no longer has anything to do with risk.

This looks like a modelling failure and isn’t. It’s a data problem, and no amount of tuning would have fixed it. You only catch it by looking at the numbers before you start.

The fix: compare each company to its neighbours

Stop comparing raw figures. Instead, replace each one with the company’s position among other companies in its own country: “this firm carries more debt than 80% of the firms around it.”

That sentence means the same thing in Taipei and in Warsaw, whatever units the original file happened to use. Rescaling a column can’t change anyone’s position in the queue — which is exactly the difference between the two files. So the comparison survives it.

This step never looks at which companies actually failed, so applying it to Poland gives the model no head start.

What it costs. Ranking throws away the absolute figure. “This company owes more than it owns” is a genuinely meaningful line to cross, and it becomes just a high position in a queue. And two companies at the same position are only equally healthy if the two countries are comparable to begin with — which, for listed Taiwanese firms against private Polish ones, they aren’t entirely. Comparability was bought with real information.

Next: does it actually work?