Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions isic.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
0111;Growing of cereals (except rice), leguminous crops and oil seeds
0112;Growing of rice
0113;Growing of vegetables and melons, roots and tubers
0114;Growing of sugar cane
0116;Growing of fibre crops
0311;Marine fishing
0510;Mining of hard coal
1010;Processing and preserving of meat
1071;Manufacture of bakery products
1811;Printing
2011;Manufacture of basic chemicals
4610;Wholesale on a fee or contract basis
4711;Retail sale in non-specialized stores with food, beverages or tobacco predominating
5510;Short term accommodation activities
5610;Restaurants and mobile food service activities
6201;Computer programming activities
7020;Management consultancy activities
8610;Hospital activities
9311;Operation of sports facilities
9602;Hairdressing and other beauty treatment
57 changes: 57 additions & 0 deletions isic_classifier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import csv
import re
import sys
from typing import List, Tuple


def load_isic(path: str = "isic.csv") -> List[Tuple[str, str]]:
"""Load ISIC code descriptions from a semicolon separated file."""
with open(path, newline='', encoding='utf-8') as f:
reader = csv.reader(f, delimiter=';')
return [(code.strip(), desc.strip()) for code, desc in reader]


def _tokenize(text: str) -> set:
"""Return a set of word tokens from the given text."""
return set(re.findall(r"\b\w+\b", text.lower()))


def classify(activity: str, isic_data: List[Tuple[str, str]]) -> Tuple[str, float]:
"""Return the ISIC code with the highest token overlap score."""
tokens = _tokenize(activity)
best_code = None
best_score = 0.0
for code, desc in isic_data:
desc_tokens = _tokenize(desc)
if not desc_tokens:
continue
score = len(tokens & desc_tokens) / len(desc_tokens)
if score > best_score:
best_score = score
best_code = code
return best_code, best_score


def classify_file(input_csv: str, output_csv: str, column: str = "d1a1x", isic_path: str = "isic.csv") -> None:
"""Classify activities in a CSV file and write results to a new CSV."""
isic_data = load_isic(isic_path)
with open(input_csv, newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
rows = list(reader)

for row in rows:
code, ratio = classify(row[column], isic_data)
row['isic_code'] = code
row['match_score'] = f"{ratio:.2f}"

with open(output_csv, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=list(rows[0].keys()))
writer.writeheader()
writer.writerows(rows)


if __name__ == "__main__":
if len(sys.argv) == 3:
classify_file(sys.argv[1], sys.argv[2])
else:
print("Usage: python isic_classifier.py input.csv output.csv")
6 changes: 6 additions & 0 deletions sample_activities.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
d1a1x
Growing of rice
Computer software development
Restaurants
Short term accommodation services
Operation of sports stadium
26 changes: 26 additions & 0 deletions test_classifier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import csv
import os
from isic_classifier import classify_file


def test_classify_file(tmp_path):
input_csv = os.path.join(tmp_path, 'input.csv')
output_csv = os.path.join(tmp_path, 'output.csv')
# copy sample activities file
with open('sample_activities.csv', 'r', encoding='utf-8') as src:
data = src.read()
with open(input_csv, 'w', encoding='utf-8') as dst:
dst.write(data)

classify_file(input_csv, output_csv)

with open(output_csv, newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
results = list(reader)

codes = [row['isic_code'] for row in results]
assert codes[0] == '0112'
assert codes[1] == '6201'
assert codes[2] == '5610'
assert codes[3] == '5510'
assert codes[4] == '9311'