한전, 포스코, 현차, SK, GS, 삼성 등의 탄소배출 데이터 파일
*dummy 데이터입니다
[데이터베이스] DBMS → Data Warehouse → Data Mining 흐름 이해
개괄식으로 먼저 알려주자면, 다음과 같은 파이프라인 구조를 지닌다[DBMS] → [Data Warehouse] → [Data Mining] (저장) (분석용 정리) (패턴/예측) DBMS는 현재의 데이터를 실시간으로 저장하고 관리한다Da
claremont.tistory.com
위의 글에서 알 수 있듯이, 다음과 같은 데이터 처리 파이프라인을 구성해야 한다
[DBMS] → [Data Warehouse] → [Data Mining]
(저장) (분석용 정리) (패턴/예측)
1. DBMS 관점: 원본 데이터를 테이블로 만들기
테이블 생성 방법
① DDL (Oracle SQL)
CREATE TABLE carbon_emissions (
company_name VARCHAR2(100),
total_emissions NUMBER,
domestic_contribution NUMBER,
total_assets_billion NUMBER,
asset_rank NUMBER,
num_affiliates NUMBER,
num_submitters NUMBER,
top_emitter VARCHAR2(100)
);
② csv 파일을 import(자동으로 마법사가 테이블을 생성해준다)
데이터 삽입 예시 (명령문 실행이 아닌 스크립트 실행을 눌러야 모든 쿼리문이 반영된다!)
INSERT INTO carbon_emissions VALUES (
'한국전력',
181432888,
27.97,
203142,
4,
30,
12,
'한국남동발전(23.4%)'
);
INSERT INTO carbon_emissions VALUES (
'포스코',
85341708,
13.16,
82036,
7,
33,
8,
'포스코(88.6%)'
);
INSERT INTO carbon_emissions VALUES (
'현대자동차',
31897468,
4.92,
246084,
2,
53,
14,
'현대제철(89.7%)'
);
INSERT INTO carbon_emissions VALUES (
'에스케이',
28350752,
4.37,
239530,
3,
148,
28,
'SK에너지(24.4%)'
);
INSERT INTO carbon_emissions VALUES (
'지에스',
20774157,
3.2,
67677,
9,
80,
11,
'GS칼텍스(37.5%)'
);
INSERT INTO carbon_emissions VALUES (
'삼성',
19013885,
2.93,
457305,
1,
59,
12,
'삼성전자(65.9%)'
);
INSERT INTO carbon_emissions VALUES (
'엘지',
16439837,
2.53,
151322,
5,
70,
16,
'LG화학(49.7%)'
);
INSERT INTO carbon_emissions VALUES (
'한화',
12297122,
1.9,
72898,
8,
83,
7,
'한화토탈(39.0%)'
);
INSERT INTO carbon_emissions VALUES (
'현대중공업',
9320875,
1.44,
63803,
10,
33,
10,
'현대오일뱅크 (74.4%)'
);
INSERT INTO carbon_emissions VALUES (
'롯데',
8601894,
1.33,
117781,
6,
86,
18,
'롯데케미칼(64.7%)'
);
INSERT INTO carbon_emissions VALUES (
'농협',
276834,
0.04,
63552,
11,
58,
4,
'농협은행(34.0%)'
);
조건 기반 검색 예시 쿼리문들
-- 배출량이 1억 tCO2 이상인 기업 조회
SELECT * FROM carbon_emissions
WHERE total_emissions >= 100000000;
-- 자산 대비 탄소 배출 비율이 높은 상위 기업 추출
SELECT company_name, total_emissions / total_assets_billion AS emission_ratio
FROM carbon_emissions
ORDER BY emission_ratio DESC;
-- 국내 기여도가 25% 이상인 기업
SELECT company_name, domestic_contribution
FROM carbon_emissions
WHERE domestic_contribution >= 25;
-- 계열사가 20개 이상이고 명세서 제출 업체가 10개 이상인 기업
SELECT company_name, num_affiliates, num_submitters
FROM carbon_emissions
WHERE num_affiliates >= 20 AND num_submitters >= 10;
2. Data Warehouse 관점: 분석 기준 정의
데이터 웨어하우스는 분석을 위한 정형화된 저장소이므로 다음과 같은 분석 기준(차원)을 설정할 수 있다
목적
- 다양한 분석 기준에 따라 데이터를 정리·요약된 형태로 저장
- 의사결정에 필요한 분석이 효율적으로 수행되도록 구조화
- 산업군별, 시계열별, 지역별, 배출특성별 다차원 분석(OLAP) 기반 마련
DW 파생 지표 테이블 생성 예시 (분석용으로 변환된 형태)
CREATE TABLE dw_carbon_summary (
company_name VARCHAR2(100), -- 기업집단명
total_emissions NUMBER(15, 2), -- 배출량 합계 (tCO2)
total_assets_billion NUMBER(15, 2), -- 자산총액 (십억원)
domestic_contribution_percent NUMBER(5, 2), -- 국내 배출량 기여도 (%)
num_affiliates NUMBER(5), -- 계열사 수
num_submitters NUMBER(5), -- 명세서 제출 업체 수
emission_per_asset NUMBER(15, 4), -- 자산 대비 배출량 (tCO2/십억원)
normalized_asset_rank NUMBER(10, 4), -- 정규화된 자산 순위 (0~1)
top_emitter_info VARCHAR2(100) -- 최다배출 계열사 정보 (예: '포스코(88.6%)')
);
DW 데이터 삽입 예시 (명령문 실행이 아닌 스크립트 실행을 눌러야 모든 쿼리문이 반영된다!)
INSERT INTO dw_carbon_summary (
company_name,
total_emissions,
total_assets_billion,
domestic_contribution_percent,
num_affiliates,
num_submitters,
emission_per_asset,
normalized_asset_rank,
top_emitter_info
) VALUES (
'한국전력',
181432888.00,
203142.00,
27.97,
30,
12,
893.1333,
0.3636,
'한국남동발전(23.4%)'
);
INSERT INTO dw_carbon_summary (
company_name,
total_emissions,
total_assets_billion,
domestic_contribution_percent,
num_affiliates,
num_submitters,
emission_per_asset,
normalized_asset_rank,
top_emitter_info
) VALUES (
'포스코',
85341708.00,
82036.00,
13.16,
33,
8,
1040.2958,
0.6364,
'포스코(88.6%)'
);
INSERT INTO dw_carbon_summary (
company_name,
total_emissions,
total_assets_billion,
domestic_contribution_percent,
num_affiliates,
num_submitters,
emission_per_asset,
normalized_asset_rank,
top_emitter_info
) VALUES (
'현대자동차',
31897468.00,
246084.00,
4.92,
53,
14,
129.6202,
0.1818,
'현대제철(89.7%)'
);
INSERT INTO dw_carbon_summary (
company_name,
total_emissions,
total_assets_billion,
domestic_contribution_percent,
num_affiliates,
num_submitters,
emission_per_asset,
normalized_asset_rank,
top_emitter_info
) VALUES (
'에스케이',
28350752.00,
239530.00,
4.37,
148,
28,
118.3599,
0.2727,
'SK에너지(24.4%)'
);
INSERT INTO dw_carbon_summary (
company_name,
total_emissions,
total_assets_billion,
domestic_contribution_percent,
num_affiliates,
num_submitters,
emission_per_asset,
normalized_asset_rank,
top_emitter_info
) VALUES (
'지에스',
20774157.00,
67677.00,
3.20,
80,
11,
306.9604,
0.8182,
'GS칼텍스(37.5%)'
);
INSERT INTO dw_carbon_summary (
company_name,
total_emissions,
total_assets_billion,
domestic_contribution_percent,
num_affiliates,
num_submitters,
emission_per_asset,
normalized_asset_rank,
top_emitter_info
) VALUES (
'삼성',
19013885.00,
457305.00,
2.93,
59,
12,
41.5781,
0.0909,
'삼성전자(65.9%)'
);
INSERT INTO dw_carbon_summary (
company_name,
total_emissions,
total_assets_billion,
domestic_contribution_percent,
num_affiliates,
num_submitters,
emission_per_asset,
normalized_asset_rank,
top_emitter_info
) VALUES (
'엘지',
16439837.00,
151322.00,
2.53,
70,
16,
108.6414,
0.4545,
'LG화학(49.7%)'
);
INSERT INTO dw_carbon_summary (
company_name,
total_emissions,
total_assets_billion,
domestic_contribution_percent,
num_affiliates,
num_submitters,
emission_per_asset,
normalized_asset_rank,
top_emitter_info
) VALUES (
'한화',
12297122.00,
72898.00,
1.90,
83,
7,
168.6894,
0.7273,
'한화토탈(39.0%)'
);
INSERT INTO dw_carbon_summary (
company_name,
total_emissions,
total_assets_billion,
domestic_contribution_percent,
num_affiliates,
num_submitters,
emission_per_asset,
normalized_asset_rank,
top_emitter_info
) VALUES (
'현대중공업',
9320875.00,
63803.00,
1.44,
33,
10,
146.0884,
0.9091,
'현대오일뱅크 (74.4%)'
);
INSERT INTO dw_carbon_summary (
company_name,
total_emissions,
total_assets_billion,
domestic_contribution_percent,
num_affiliates,
num_submitters,
emission_per_asset,
normalized_asset_rank,
top_emitter_info
) VALUES (
'롯데',
8601894.00,
117781.00,
1.33,
86,
18,
73.0330,
0.5455,
'롯데케미칼(64.7%)'
);
INSERT INTO dw_carbon_summary (
company_name,
total_emissions,
total_assets_billion,
domestic_contribution_percent,
num_affiliates,
num_submitters,
emission_per_asset,
normalized_asset_rank,
top_emitter_info
) VALUES (
'농협',
276834.00,
63552.00,
0.04,
58,
4,
4.3560,
1.0000,
'농협은행(34.0%)'
);
DW에서 수집된 데이터를 기반으로, 정책적 분석에 필요한 파생 지표를 생성하였다.
단순 저장된 원본 데이터를 그대로 사용하는 것이 아니라, DW 관점에서 분석 목적에 따라 다음과 같은 지표 중심으로 구조화된 데이터를 만들어냈다!
이러한 변수는 단순 수치 비교를 넘어서, 기업의 배출 효율성 또는 자산 대비 부담률을 파악하는 데 활용되며 분석 대상 선정, 정책 타깃 설정에 있어 중요한 기준으로 작용할 수 있다.
3. Data Mining 관점: 패턴 도출 및 의사결정 근거 제공
"군집화(Clustering)"
DW 단계에서 구조화된 데이터를 바탕으로, 비지도 학습 기반의 KMeans 알고리즘을 적용하여 기업 간 유사 특성을 파악하였다.
분석에 사용된 주요 변수는 다음과 같다
- 총 배출량(total_emissions)
- 자산총액(total_assets_billion)
- 자산 대비 배출량(emission_per_asset) (DW에서 생성)
- 자산 순위 정규화 값(normalized_asset_rank) (DW에서 생성)
Python 코드 (pandas + scikit-learn 라이브러리를 사용한 KMeans 군집화 + 시각화)
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
# 사용자 지정 한글 폰트 설정 (Pretendard 등 원하는 폰트로 변경 가능)
font_path = "./fonts/Pretendard-Regular.otf"
font_name = fm.FontProperties(fname=font_path).get_name()
plt.rcParams["font.family"] = font_name
plt.rcParams["axes.unicode_minus"] = False # 마이너스 기호 깨짐 방지
# 데이터 불러오기
df = pd.read_csv("./data/NET_Company.csv", encoding="euc-kr")
# 필요한 컬럼만 추출하여 파생 변수 생성
df["emissions"] = df["명세서 배출량 합계(tCO2)"].str.replace(",", "").astype(float)
df["assets"] = df["자산총액 (십억원)"].str.replace(",", "").astype(float)
df["rank"] = df["자산 총액 순위"].astype(float)
# DW 파생 변수 생성
df["emission_per_asset"] = df["emissions"] / df["assets"]
df["normalized_rank"] = df["rank"] / df["rank"].max()
# 군집화에 사용할 컬럼 선택
data = df[["emissions", "assets", "emission_per_asset", "normalized_rank"]]
# 정규화 수행
scaler = StandardScaler()
scaled_data = scaler.fit_transform(data)
# KMeans 군집화 수행 (군집 수: 3개)
kmeans = KMeans(n_clusters=3, random_state=42)
df["cluster"] = kmeans.fit_predict(scaled_data)
# 영어 기업명 매핑 (시각화를 위해)
name_map = {
"한국전력": "KEPCO",
"삼성": "Samsung",
"현대자동차": "Hyundai Motor",
"에스케이": "SK Group",
"포스코": "POSCO",
"지에스": "GS Group",
"엘지": "LG Group",
"한화": "Hanwha",
"현대중공업": "Hyundai Heavy",
"롯데": "Lotte",
"농협": "NongHyup"
}
df["company_en"] = df["기업집단명"].map(name_map).fillna(df["기업집단명"])
# 시각화 (자산 vs 배출량 기준 시각화)
plt.figure(figsize=(10, 6))
colors = ["red", "green", "blue"]
for cluster_id in df["cluster"].unique():
cluster_data = df[df["cluster"] == cluster_id]
plt.scatter(
cluster_data["assets"],
cluster_data["emissions"],
label=f"Cluster {cluster_id}",
color=colors[cluster_id],
s=100,
alpha=0.7,
)
# 각 점에 영어 기업명 표시
for _, row in cluster_data.iterrows():
plt.text(row["assets"], row["emissions"], row["company_en"], fontsize=9)
# 축 및 제목 설정
plt.xlabel("Total Assets (Billion KRW)")
plt.ylabel("Total Emissions (tCO2)")
plt.title("Company Carbon Emissions Clustering (w/ DW Variables)")
plt.legend()
plt.grid(True)
plt.tight_layout()
# 이미지 파일 저장
save_path = "carbon_emissions_clustering.png"
plt.savefig(save_path, dpi=300)
plt.show()
KMeans 클러스터링을 통해 총 3개의 그룹(k=3)이 도출되었다
이러한 군집 구조는 실제 탄소 감축 정책의 우선순위 설정, 맞춤형 규제 설계, ESG 평가 기준 마련 등에 활용 가능한 분석 근거를 제공할 수 있다!
그리고 DW 파생 변수를 활용하여 각 기업이 상대적으로 얼마나 비효율적인 배출을 하고 있는지를 알 수 있는 데이터 시각화는 다음과 같다
[정규화된 자산 순위(normalized_rank)와 자산 대비 배출량(emission_per_asset)을 기준으로 기업들을 클러스터링한 결과]
X축: Normalized Asset Rank
0에 가까울수록 자산 순위가 높음 (즉, 대기업일수록 왼쪽)
Y축: Emission per Asset
자산 1십억원당 탄소 배출량 (즉, 배출 효율이 낮을수록 위로 올라감)
[기업 환경영향도 평가]
기업별 탄소 배출량과 자산 규모를 결합한 지표인 자산 대비 배출량(emission per asset) 을 활용하여 환경영향도를 정량적으로 평가할 수 있다! 또한 단순히 총 배출량이 많은 기업뿐만 아니라, 재무 규모에 비해 비효율적으로 온실가스를 배출하는 기업을 식별함으로써 실제 환경 부담이 큰 기업을 효과적으로 분류할 수가 있었다. 이러한 평가 방식은 탄소중립 정책 수립, ESG 등급 산정, 규제 우선 대상 선정 등 다양한 분야에서 실질적인 의사결정 자료로 활용 가능하다.
[탄소 배출량이 높은 기업과 낮은 기업의 차이 분석]
정규화된 자산 순위와 자산 대비 배출량을 기준으로 기업들을 시각화한 결과, 고배출 기업과 저배출 기업 간 뚜렷한 차이를 확인할 수 있었다. 예를 들어, POSCO와 KEPCO는 자산 규모는 크지 않음에도 불구하고 단위 자산당 배출량이 매우 높아, 환경적으로 비효율적인 기업군에 속하였다. 반면 Samsung, Hyundai Motor Group 등은 자산 규모가 크면서도 배출 효율이 높아, 상대적으로 우수한 ESG 성과를 보이는 것으로 분석되었다. 이러한 분석은 단순 배출량이 아닌 배출 효율성과 자산 규모를 함께 고려함으로써, 정책 타깃 기업 선정이나 감축 우선순위 결정에 실질적인 근거를 제공할 수 있다.
(참고) “탄소 배출량이 높은 기업과 낮은 기업”을 조회하는 SQL문
1. 탄소 배출량이 높은 상위 5개 기업 조회
SELECT company_name, total_emissions
FROM carbon_emissions
ORDER BY total_emissions DESC
FETCH FIRST 5 ROWS ONLY;
2. 탄소 배출량이 낮은 하위 5개 기업 조회
SELECT company_name, total_emissions
FROM carbon_emissions
ORDER BY total_emissions ASC
FETCH FIRST 5 ROWS ONLY;
3. 배출량 구간별로 분류해서 조회
-- 배출량 1억 tCO2 이상인 '고배출 기업'
SELECT company_name, total_emissions
FROM carbon_emissions
WHERE total_emissions >= 100000000;
-- 배출량 1천만 tCO2 이하인 '저배출 기업'
SELECT company_name, total_emissions
FROM carbon_emissions
WHERE total_emissions <= 10000000;
+ 시사점과 확장 가능성
해당 군집 결과는 기존 CSV 데이터에서 직접 사용한 변수가 아닌, DW 단계에서 분석 목적에 맞게 파생된 지표를 기반으로 수행되었기 때문에 정책적 의사결정에 보다 근거 있는 인사이트를 제공할 수 있었다.
향후 분석 정밀도를 높이기 위한 확장 방향은 다음과 같다..!
- 산업군 분류를 통한 업종별 탄소 배출 특성 파악
- 연도별 데이터를 통한 시계열 기반 클러스터링
- 지역, 수출입 의존도 등 외부 요인 추가
- 기업집단 내 배출 최다 계열사의 기여도 비중 반영
이러한 확장은 ESG 등 지속가능성 분석이나, AI 기반의 규제 사전 설계, 감축 로드맵 추천 시스템 등의 핵심 분석 요소로 발전할 수 있을 것 같다 :)
마무리 및 학습 성찰
이번 실습은 단순 데이터 활용을 넘어서,
DBMS → DW → Data Mining으로 이어지는 데이터 분석 파이프라인 전체를 직접 경험하는 과정이었다.
1.DBMS 단계에서는 원본 데이터를 저장 및 조회 가능한 형태로 정형화하였다.
2. Data Warehouse 단계에서는 비즈니스 목적에 맞는 분석 기준과 파생 지표를 정의하여 구조화된 데이터셋으로 재구성하는 과정을 학습하였다.
3. Data Mining 단계에서는 DW에서 구성한 지표들을 바탕으로 군집화를 수행하였고, 그 결과를 바탕으로 기업을 유형화하고 정책 판단의 기초 자료로 활용할 수 있는 분석을 실현하였다.
정리하자면, 이 실습을 통해 실제 데이터를 분석 목적에 맞게 정제하고, 모델로 연결하여 인사이트를 도출하는 전 과정을 통합적으로 이해할 수가 있었다! 쉽지 않았지만, 결국 다 해내니까 정말 뿌듯하다 ㅎㅎ
#SK, #SKALA, #SKALA1기
'DBMS > Oracle' 카테고리의 다른 글
[Oracle] 레스토랑 신규 매출 분석 (0) | 2025.04.17 |
---|---|
[Oracle] 온라인 쇼핑몰 DB: JOIN/INDEX 실습 (1) | 2025.04.16 |
[Oracle] 맥북(m3칩↑)에서 오라클 SQL Developer 사용법(w/도커) (0) | 2025.04.15 |