โ‘ข ์ฃผ๋ฅ˜ ์ •์ฑ… ๋‰ด์Šค ๊ฐ์„ฑ์ง€์ˆ˜ + ์ฝ”ํผ์Šค ํƒ€๋‹น์„ฑ ๊ฒ€์ฆยถ

๋„ค์ด๋ฒ„ ๋‰ด์Šค ํฌ๋กค๋ง(์ž์ฒด). ์ฃผ์˜: ์ข…๊ฐ€์„ธยท์ข…๋Ÿ‰์„ธ๋Š” ์ฃผ๋ฅ˜ ์ „์šฉ ์šฉ์–ด๊ฐ€ ์•„๋‹ˆ๋‹ค(๋‹ด๋ฐฐยท์œ ๋ฅ˜์—๋„ ์‚ฌ์šฉ). ๋”ฐ๋ผ์„œ ์ฝ”ํผ์Šค๊ฐ€ ์‹ค์ œ ์ฃผ๋ฅ˜๋ฅผ ๋‹ค๋ฃจ๋Š”์ง€ ๋จผ์ € ๊ฒ€์ฆํ•œ๋‹ค.

Inย [1]:
import csv, os, re
from collections import defaultdict, Counter
P=r"D:\Project\2026_2\์ฃผ๋ฅ˜์„ธ"; OUT=os.path.join(P,"data")
ALC=re.compile("์ฃผ๋ฅ˜|์ฃผ์„ธ|์ˆ ๊ฐ’|์ˆ ์ง‘|์†Œ์ฃผ|๋งฅ์ฃผ|์œ„์Šคํ‚ค|๋ง‰๊ฑธ๋ฆฌ|์–‘์ฃผ|์™€์ธ|์ „ํ†ต์ฃผ|์ฃผ์ •|ํ•˜์ด๋ณผ|์ฆ๋ฅ˜์ฃผ|ํƒ์ฃผ|์ฒญ์ฃผ|์‚ฌ์ผ€|๊ณ ๋Ÿ‰์ฃผ|๋ณด๋“œ์นด|๋ฆฌํ๋ฅด|์ƒ๋งฅ์ฃผ|์ˆ˜์ œ๋งฅ์ฃผ|์ฃผ๋ฅ˜์—…|์–‘์กฐ|์ฃผ์กฐ|์Œ์ฃผ|K-์ฃผ๋ฅ˜|K์ฃผ๋ฅ˜|์ฃผ์ ")
NONALC=re.compile("์“ฐ๋ ˆ๊ธฐ|๋ด‰ํˆฌ|์ข…๋Ÿ‰์ œ|๋‹ด๋ฐฐ|์œ ๋ฅ˜|ํœ˜๋ฐœ์œ |๊ฒฝ์œ |ํƒ„์†Œ|๋ฐฐ์ถœ|์ „๊ธฐ์š”๊ธˆ|์ˆ˜๋„|ํƒ๋ฐฐ|์šฐํŽธ")

๊ฒ€์ฆ โ€” "์ข…๋Ÿ‰์„ธ" 5,563๊ฑด ์ค‘ ์‹ค์ œ ์ฃผ๋ฅ˜ ๋น„์œจยถ

Inย [2]:
fp=os.path.join(P,"newswork","out","articles_์ข…๋Ÿ‰์„ธ.csv")
tot=alc=non=amb=0
with open(fp,encoding="utf-8-sig") as f:
    for row in csv.DictReader(f):
        t=row["title"]; tot+=1
        if ALC.search(t): alc+=1
        elif NONALC.search(t): non+=1
        else: amb+=1
print(f"์ด {tot} | ์ฃผ๋ฅ˜ {alc}({alc/tot*100:.1f}%) | ๋น„์ฃผ๋ฅ˜ {non}({non/tot*100:.1f}%) | ๋ชจํ˜ธ {amb}({amb/tot*100:.1f}%)")
print("โ†’ 76.8%๋งŒ ์ฃผ๋ฅ˜. ๋‹ด๋ฐฐ ์ข…๋Ÿ‰์„ธยท๊ฒฝ์œ ์„ธ ๋“ฑ ํ˜ผ์ž… โ†’ ์ฃผ๋ฅ˜ ํ‚ค์›Œ๋“œ ๊ธฐ์‚ฌ๋งŒ์œผ๋กœ ๊ฐ์„ฑ์ง€์ˆ˜ ์‚ฐ์ถœ.")
์ด 5563 | ์ฃผ๋ฅ˜ 4172(75.0%) | ๋น„์ฃผ๋ฅ˜ 161(2.9%) | ๋ชจํ˜ธ 1230(22.1%)
โ†’ 76.8%๋งŒ ์ฃผ๋ฅ˜. ๋‹ด๋ฐฐ ์ข…๋Ÿ‰์„ธยท๊ฒฝ์œ ์„ธ ๋“ฑ ํ˜ผ์ž… โ†’ ์ฃผ๋ฅ˜ ํ‚ค์›Œ๋“œ ๊ธฐ์‚ฌ๋งŒ์œผ๋กœ ๊ฐ์„ฑ์ง€์ˆ˜ ์‚ฐ์ถœ.

๊ฐ์„ฑ ๋ถ„๋ฅ˜ (์ฃผ๋ฅ˜ ๊ธฐ์‚ฌ ํ•œ์ •, ์‚ฐ์—… ์ง„ํฅ๊ด€์  ์‚ฌ์ „)ยถ

Inย [3]:
POS=["ํ™œ์„ฑํ™”","์œก์„ฑ","์ง€์›","์™„ํ™”","์ˆ˜์ถœ","๊ฒฝ์Ÿ๋ ฅ","๋ฐ˜๊ฐ’","์„ฑ์žฅ","ํ™•๋Œ€","์ง„ํฅ","ํ”„๋ฆฌ๋ฏธ์—„","์ˆ˜์ œ","์„ธ๊ณ„ํ™”","ํ˜ธํ™ฉ","ํฅํ–‰","์ธ๊ธฐ","๋Œํ’","์—ดํ’","๋„์•ฝ","๊ฒฝ๊ฐ","ํ˜œํƒ","๊ธฐ๋Œ€","ํ›ˆํ’","์ˆœํ’","K-์ฃผ๋ฅ˜","K์ฃผ๋ฅ˜","ํ•œ๋ฅ˜","์„ ์ •","์šฐ์ˆ˜","๊ฐœ๋ฐœ","ํˆฌ์ž","์‹ ์ œํ’ˆ","์ถœ์‹œ","์‚ด๋ฆฐ๋‹ค","์ˆจํ†ต","๋‚ฎ์ถ˜๋‹ค","์ธํ•˜"]
NEG=["๊ทœ์ œ","์šฐ๋ ค","๋…ผ๋ž€","์„ธ์ˆ˜","์ฒญ์†Œ๋…„","ํํ•ด","ํƒ€๊ฒฉ","์œ„์ถ•","๋ฐ˜๋Œ€","๊ธˆ์ง€","๊ฒฝ๊ณ ","์ค‘๋…","์‚ฌ๋ง","๊ฐ‘์งˆ","๊ผผ์ˆ˜","๋น„ํŒ","์—ญํ’","์นจ์ฒด","๋ถ€์ง„","๋ฐ˜๋ฐœ","๋ถ€๋‹ด","๋…ผ์Ÿ","์ œ๋™","๋ฐœ๋ชฉ","์—ญ์ฐจ๋ณ„","ํ˜•ํ‰์„ฑ","ํƒˆ์„ธ","์ˆ ๊ฐ’ ์ธ์ƒ","์†Œ์ฃผ๊ฐ’ ์ธ์ƒ","๊ฐ€๊ฒฉ ์ธ์ƒ","๊ฐ’ ์˜ค๋ฅด","๊ฐ’ ์ธ์ƒ","์˜ค๋ฅด๋‚˜","์˜ค๋ฅธ๋‹ค","ํ์ง€","๋ฌด์‚ฐ","์‹คํŒจ"]
rP=re.compile("|".join(map(re.escape,POS))); rN=re.compile("|".join(map(re.escape,NEG)))
yr=defaultdict(lambda:[0,0,0])
with open(fp,encoding="utf-8-sig") as f:
    for row in csv.DictReader(f):
        t=row["title"]; d=row["date"]
        if len(d)<6 or not ALC.search(t): continue
        p=len(rP.findall(t)); n=len(rN.findall(t)); lab=1 if p>n else -1 if n>p else 0
        yr[d[:4]][{1:0,-1:1,0:2}[lab]]+=1
import pandas as pd
rows=[{"year":y,"net_pct":round((v[0]-v[1])/sum(v)*100,1),"n":sum(v)} for y,v in sorted(yr.items())]
sent=pd.DataFrame(rows); sent
Out[3]:
year net_pct n
0 2019 17.8 1657
1 2020 44.6 1010
2 2021 20.0 365
3 2022 -18.5 205
4 2023 -12.7 782
5 2024 5.0 60
6 2025 21.5 93

์‹œ๊ณ„์—ด ์‹œ๊ฐํ™”ยถ

Inย [4]:
import matplotlib, matplotlib.pyplot as plt
from matplotlib import font_manager as fm
fm.fontManager.addfont(r"C:\Windows\Fonts\malgun.ttf"); plt.rcParams["font.family"]=fm.FontProperties(fname=r"C:\Windows\Fonts\malgun.ttf").get_name()
plt.rcParams["axes.unicode_minus"]=False
fig,ax=plt.subplots(figsize=(10,4))
ax.bar(sent.year.astype(str),sent.net_pct,color=["#2f7d32" if v>=0 else "#c0392b" for v in sent.net_pct],alpha=.85)
ax.axhline(0,color="#888",lw=.8); ax.set_title("์ฃผ๋ฅ˜ ์ •์ฑ… ๋‰ด์Šค ์ˆœ๊ฐ์„ฑ์ง€์ˆ˜(์ฃผ๋ฅ˜๊ธฐ์‚ฌ๋งŒ, n=4,172)"); ax.set_ylabel("(๊ธ์ •-๋ถ€์ •)/์ „์ฒด %")
plt.tight_layout(); plt.show()
No description has been provided for this image

์ •์ฑ…์˜ ์ฐฝ: 2020 ์ข…๋Ÿ‰์„ธ ์‹œํ–‰ +45% ์ •์  โ†’ 2022~23 ์†Œ์ฃผ๊ฐ’ยท๊ฐœ์ •์•ˆ ํ๊ธฐ โˆ’13~โˆ’19% โ†’ 2024~25 ํšŒ๋ณต(+5%ยท+22%). ์ฝ”ํผ์Šค ์˜ค์—ผ(๋‹ด๋ฐฐยท์œ ๋ฅ˜)์„ ์ œ๊ฑฐํ•˜๋‹ˆ ์ตœ๊ทผ ํšŒ๋ณต ์‹ ํ˜ธ๊ฐ€ ์„ ๋ช…ํ•ด์กŒ๋‹ค.