데이터 구축 · 그림책

1960~2023년, 64개 연도의 부가가치를 어떻게 한 줄로 이었나

62개 KEIT 산업과 7개 신규산업의 비중을 정확히 나누려면, 산업연관표에서 나온 연도별 명목 부가가치가 필요합니다. 그런데 정부가 공식으로 내는 표는 5년마다 한 번(2010·2015·2020...)뿐입니다. 그 사이 해를 메우고, 도중에 산업분류 체계 자체가 통째로 바뀐 지점을 넘어, 1960년까지 이어 붙인 과정을 정리합니다.

1. 왜 5년 벤치마크만으로는 안 되는가

한국은행이 5년마다 발표하는 "실측" 산업연관표 사이 연도는 연장표(매년 발표되는 간이·확장판)로 메울 수 있습니다. 이 연장표를 최대한 과거로 거슬러 모으면 — 1960, 1963, 1966, 1968, 1970, 1973, 1975, 1978... — 총 36개 연도의 파일을 확보할 수 있었습니다 (1980~2023은 거의 매년, 그 이전은 3년 내외 간격).

문제 1

2010년을 기점으로 산업분류 자체가 통째로 바뀐다

1960~2009년 파일은 "농산물·축산물·선철및조강..." 식의 옛 분류(연도별로 52~95개 항목)를 쓰고, 2010년부터는 "작물·반도체·전자표시장치..." 식의 신 분류(KSIC 정합, 83개 항목)를 씁니다. 한국은행 자신이 만든 "연결표"(분류 개편 전후를 이어주는 공식 변환표)도 1975→1980→1985, ...→2000→1995→1990 처럼 옛 세대 안에서만 이어줄 뿐, 2005년에서 2010년으로 넘어가는 연결표는 없습니다 — 즉 이 경계는 공식적으로 아무도 안 이어줍니다.

주의할 점: 2011년 파일은 연도만 새것이지 내용은 옛 분류 그대로입니다 (파일명 자체가 "2011(2005기준)"). 그래서 연도 숫자로 신구세대를 나누면 안 되고, 신세대에만 있는 산업명("반도체")이 실제로 존재하는지로 판별해야 합니다.

해법 1

78개 항목 수작업 크로스워크

옛 세대(1995~2005년 연결표 기준, 78개 항목)를 공통 기준으로 놓고, 신세대 83개 항목을 이 78개 항목 해상도로 묶어 내리는 대응표를 항목 하나하나 대조해 만들었습니다. 예: 신세대의 "금속 주물"+"금속가공제품" → 옛 세대의 "금속제품" 하나로 합산. 반도체·전자표시장치·정보서비스·소프트웨어처럼 옛 세대에 아예 없던 신산업은 별도로 "[신산업]"이라 표시해 옛 세대와 억지로 합치지 않았습니다.

문제 2

집계행 이름 표기가 연도마다 다 다르다

산업이 아니라 "총수요·총공급·최종소비·고정자본형성" 같은 수요측 집계행도 같은 파일 안에 함께 들어 있는데, 이 이름이 연도마다 미묘하게 다릅니다 — "총수요"(1973년) vs "총수요계"(1975년), 반각 괄호 "(공제)관세" vs 전각 괄호 "(공제)관세"(1960년대), "(공제)수입계"(대부분) vs 그냥 "수입계"(2005~2011년). 이 표기 차이를 놓치면 집계행을 산업으로 착각해 총량이 실제보다 부풀어 오릅니다.

실제로 1975년 파일에서 "총수요계"·"총공급계"를 제외 목록에서 놓쳤더니, 1975년 합계가 실제보다 3배 가까이(29.2조원, 정답은 9.72조원) 부풀려졌습니다.

해법 2 · 검증

모든 연도에 공통으로 있는 자체 검산행을 쓴다

다행히 모든 연도의 파일에 "중간수요계"라는 행이 공통으로 있고, 이 값은 정의상 그 해 모든 산업의 부가가치를 더한 값과 정확히 같습니다. 그래서 "이 연도가 맞게 걸러졌는지"를 매번 사람 눈으로 훑어보는 대신, 우리가 필터링해 계산한 산업 합을 이 "중간수요계" 행과 자동으로 대조하는 코드를 만들었습니다 — 어긋나면 조용히 넘어가지 않고 바로 표시됩니다.

필터링한 산업 합(그 해) = 원본 파일의 "중간수요계" 행 값  →  아니면 경고

이 검증을 1960~2023년 36개 연도 전부에 돌린 결과, 처음엔 7개 연도가 어긋났습니다(집계행 표기 차이 때문). 정규식을 표기 차이에 안 흔들리게 다듬은 뒤 —

연도검산값(백만원)계산값(백만원)차이
19759,722,045.99,722,045.90.0000%
197823,263,633.723,263,633.70.0000%
198578,847,98378,847,9830.0000%
1993272,579,295272,579,2950.0000%
2000599,645,133599,645,1330.0000%
36개 연도 전체전부 통과
문제 3 · 사례

2010년만 유독 튀는 이유

신세대의 첫 해인 2010년 파일은 코드 번호가 진짜 산업코드가 아니라 그냥 "1, 2, 3...104" 순번이었습니다. 그래서 "코드 1~90은 산업"이라는 규칙을 그대로 적용하면 "중간수요계·수출· 민간소비지출" 같은 최종수요행까지 산업으로 잘못 포함됩니다. 게다가 2010년 산업명 표기가 2015~2023년과도 달라서("일반목적용기계" vs "일반목적용 기계", "인쇄 및 복제" vs "인쇄 및 기록매체 복제") 78개 항목으로 묶는 대응표가 매칭에 실패해, 상당수 산업이 조용히 누락되고 있었습니다.

고친 뒤 결과 — 2009년 1,047.9조원 → 2010년 1,177.6조원(신산업 67.0조원은 옛 세대와 비교 가능하도록 제외한 값) → 2011년 1,213.6조원으로, 이제 매끄럽게 증가합니다.

2. 완성된 연도별 합계(78개 항목 해상도, 조원)

연도합계연도합계연도합계
19600.2198578.82007960.1
19702.71990178.320091,047.9
19759.71995375.820101,177.6
197823.31998471.620151,537.2
198037.12000599.620201,903.4
198360.92005852.020232,251.3

3. 코드

code/industry_models_36q/extract_annual_v2.py — 원본 엑셀(.xls/.xlsx)에서 "부문명칭" 행을 찾아 연도별 산업명·부가가치 추출 · code/industry_models_36q/crosswalk_old_new.py — 78↔83개 항목 대응표· 2010년 표기 별칭표 · code/industry_models_36q/apply_crosswalk.py — 정규식 기반 집계행 제외, 신세대→78개 항목 재편성, 연도별 자체 검증

# 집계행(산업 아님) 판별 — 표기 차이에 안 흔들리게 정규식으로
NON_INDUSTRY_PATTERN = re.compile("|".join([
    r"^중간수요계?$", r"^최종수요계?$", r"^총수요계?", r"^총공급계?", r"^총산출",
    r"소비지출", r"고정자본형성", r"재고증", r"^수출$",
    r"[((]공제[))]", r"^관세$", r"^수입계$", r"^수입및관세",
    r"^가격전환계", r"^사무용품$", r"^가계외소비지출$",
]))

# 매 연도, 원본 자체의 "중간수요계" 행과 직접 대조
checksum = df[df.name == "중간수요계"].va.iloc[0]
computed = df[~df.name.apply(is_non_industry)].va.sum()
assert abs(computed - checksum) / checksum < 0.0001

4. 다음 단계

지금 만든 건 78개 옛 세대 항목 해상도의 1960~2023년 연도별 명목 부가가치입니다. 이걸로 아직 부족합니다 — 실제로 필요한 건 KEIT의 62개 산업과 거기서 갈라져 나온 7개 신규산업을 식별할 수 있는 해상도입니다. 다음 단계는 이 78개(또는 더 세분화된 기본부문 380개) 항목을 KEIT 62+7 분류에 다시 매핑하는 작업이며, 이게 끝나야 비로소 69개 산업 월별 자료에서 지금 임의로 나눠져 있는 7개 신규산업의 비중을 근거 있는 숫자로 바로잡을 수 있습니다.

정리: 5년 벤치마크 대신 연장표로 최대한 촘촘히, 2010년 분류대개편은 수작업 대응표로 넘고, 표기가 제각각인 집계행은 정규식으로 걸러내되 — 무엇보다 모든 연도에 공통으로 있는 검산행과 기계적으로 대조해서, 사람이 놓친 표기 변형이 있으면 바로 드러나게 만들었습니다.