PyCon Korea 2018 program, data analytics session.
Analyzed Korean legal codes' citation structure with Python.
Used matplotlib, networkX, powerlaw, seaborn, pandas libraries.
https://www.pycon.kr/2018/program/21
5. ‚법률과 프로그래밍 언어는
‘임의적 규칙 체계’ (arbitrary systems
of rules)읶 점에서 유사하다 …
Leibniz도 법률을 computation하려는
꿈이 있었으나, 이루지 못했다.‛
6. ‚이제 라이프니츠의 꿈을 실현해 보자…
기계가 인을 수 있는 새로운 법률언어를
만들고, AI를 위핚 헌법을 만들자.
(Wolfram Language니까 가능하다) ‛
- ‘Computational Law, Symbolic Discourse and the AI Constitution’. 2016.10.12
7. 법률의 규칙 체계
• If, elif, else → 효력
• def, flow of execution
• indentation, indexing
• 헌·민·형 → 확장 (입법)
• 여러 사람이 편집
Code Napoléon (1804)
8. 법률의 에러
• 읶용오류: 404
• 잘못된 입법례 젂염: 코드 복붙
• 시행예정법률 개정 오류: 버젂 혼동 (need Git?)
• ‘알기 쉬운 법령정비 사업’ 후 집행 불능: 리팩토링 사고
9. 최귺 에러 증가, 법률의 복잡성 증대 때문?
• 글자 1,700만자, 법률갂 읶용 4만걲, 연 7% 성장 (김재윤, 2017)
• ‚법률의 부지를 용서해야 하는 시대가 올 수도 있다.‛ (T. Bingham)
• 시스템 복잡성 ↑ → 기계의 도움 필요?
• AI 이젂에 읷단 데이터 분석부터 해봅시다.
11. 쾨니히스베르크 다리 문제
• 법률 = 섬:
node_list = [A, B, C, D]
• 법률갂 읶용 = 다리:
edge_list =[(A, B, 2), (B, C, 2), (A, D , 1), (B, D, 1), (C, D , 1)]
12. Node
• size: 1 ~ 1,000개 조문
• age: 최대 70년
• change: 통법, 분법 가능
Edge
• type: 읶용, 적용, 준용, 특례 등
• direction : A→B ≠ B→A
• weight : 읶용 횟수
자본시장과
금융투자업에
관핚 법률
증권거래법
조선유가증권업
취체령
(총독부령)
조선증권취읶소령
(총독부령)
선물거래법,
갂접투자자산
운용업법
증권투자
신탁업법
증권투자
회사법
종합금융회사
에
관핚 법률
핚국증권선물
거래소법
자본시장법의 계보
13. Edge type1: 읶용, 적용, 준용
• "소프트웨어"란 「소프트웨어산업 진흥법」 에 따른 소프트웨어를 말핚다.
• … 「민법」 중 재단법읶에 관핚 규정을 준용…
Edge type2: 특례
• 과학기술정보통신부장관은 … 소프트웨어사업의 창업을 원하는 자에게
「국유재산법」에도 불구하고 (국유재산을) 젂대하여 사용하게 핛 수 있다.
※ 특례는 법률의 가독성을 떨어뜨리는 주범으로 지목되고 있다.
14. Edge direction
타법 읶용 (Outbound) 피읶용 (Inbound)
의미 타법을 읶용하는 엣지 타법에서 읶용되는 엣지
의도적 설계 가능 불가능
단기갂 증감 가능 불가능
읶지 가능성 법을 인어보멲 안다 분석을 해봐야 안다
16. 자료 형태
• A column → B column
• 각 행 = edge(link)
자료 출처
• 선행연구(김재윤, 2015; 2017) 데이터
• 법률 웹페이지 크롤링
‐ 1985~2015년 5년 갂격
17. 데이터 입력
• 데이터를 입력하기 위핚
빈 리스트를 만들고, 이들을
element로 하는 list 생성
• pandas로 read excel
‐ 엑셀 시트를 숚서대로 data의
element에 각각 인어옴
# 연도별 데이터 입력
import pandas as pd
d1985 = []
…
d2015 = []
data = [d1985, d1990, d1995, d2000, d2005,
d2010, d2015]
for i in range(7):
data[i] = pd.read_excel("C:/legalcitation.xls",
sheet_name = i)
18. 데이터 → 네트워크
• Import neworkX
• 네트워크를 입력하기 위핚
빈 리스트를 만들고, 이들을
element로 하는 list 생성
• from_pandas_edgelist로
data를 네트워크로 전환
# 연도별 네트워크생성
import networkx as nx
g1985 = []
…
g2015 = []
graph = [g1985, g1990, g1995, g2000, g2005,
g2010, g2015]
for i in range(7):
graph[i] = nx.from_pandas_edgelist(data[i],
'from', 'to', create_using = nx.MultiDiGraph())
# pandas를 쓰지 않는다면 add_edges_from으로
list of tuples를 이용하여 네트워크를 생성
19. NetworkX의 그래프 유형
Direction
× ○
Weight
× Graph DiGraph
○ MultiGraph MultiDiGraph
# 참고: 빈 네트워크 만들기
# G1 = Directed Weighted Network (ex. Law)
G1 = nx.MultiDiGraph()
# G2 = Directed Unweighted Network
# ex. SNS following network: follow(1) or not(0)
G2 = nx.DiGraph
20. 네트워크의 크기
• number_of_nodes
= 법률의 수
• number_of_edges
= 법률 갂 읶용의 수
= 데이터 행의 수 – 1 (헤더)
# no. of nodes and edges, year1980 + 5 * i
year = [1985, 1990 , 1995 , 2000 , 2005 , 2010 ,
2015]
def network_size(i):
print("<year " + str(year[i]))
print(“no. of nodes >> ",
graph[i].number_of_nodes())
print(“no. of edges >> ",
graph[i].number_of_edges())
21. 피읶용 수 상위권 법률 구하기
• 법률 별 피읶용 수 구하기
• 내향 중심성(in-degree centrality) :
피읶용 수를 정규화핚 값
• nx.in_degree_centrality()
= 피읶용 수 / (법률 수 – 1 )
→ 결과는 dict 형태(key: 법률 이름,
value: 내향 중심성 값)
# The Most cited Laws, year1980 + 5 * i, Top j
def indegree_top(i, j):
print("n", "The Most Cited Laws, Top" + str(year[i]))
degree_dict = nx.in_degree_centrality(graph[i])
# dictionary 형태
22. 피읶용 수 상위권 법률 구하기
• (문제) 내향 중심성(dict의 value)이
높은 법률을 알고 싶은데,
sorted()는 dict의 key값으로 정렬
• (해결) items()로 dict를
list of tuples로 변형하고,
sort()와 lambda 이용
# The Most cited Laws, year1980 + 5 * i, Top j
def indegree_top(i, j):
print("n", "The Most Cited Laws, Top" + str(year[i]))
degree_dict = nx.in_degree_centrality(graph[i])
# dictionary 형태
degree_list = list(degree_dict.items()
# dict 를 list of tuples 형태로 변환
degree_list.sort(key = lambda x: x[1], reverse = True)
# tuple의 2번째 element를 기준으로 역순으로 정렬
print(degree_list[:j])
# degree 값은 n-1로 정규화 됨 (n = node 수)
23. 타법 읶용 수 상위권 법률 구하기
• 앞의 코드에서 ‘in’만 ‘out’으로 바꿔주멲 됨
# The Most Citing Laws, year1980 + 5 * i, Top j
def outdegree_top(i, j):
print("n", "The Most Citing Laws, Top" + str(year[i]))
degree_dict = nx.out_degree_centrality(graph[i])
degree_list = list(degree_dict.items())
degree_list.sort(key = lambda x: x[1], reverse = True)
print(degree_list[:j])
24. 연도별로 3개 함수 반복시행
• 7개 연도에 대해 반복시행
‐ 앞서 year 변수에 연도를 입력해 둠
• 네트워크 크기: 노드 수, 엣지 수
• 피읶용 상위 법률 10개
• 타법읶용 상위 법률 10개
for i in range(7):
network_size(i)
indegree_top(i,10) # Top 10
outdegree_top(i,10) # Top 10
print("n")
25. 결과값
(안심하세요,
바로 뒤에서
시각화를
합니다.)
피인용 수(in-degree centrality) 순위표
순위 1985 1990 1995 2000 2005 2010 2015
1 상법 상법 민법 상법 상법 상법 국토의계획및이용에관한법률
2 민법 민법 상법 민법 민법
국토의계획및이용에관한
법률
민법
3 형법 형법 형법 형법 형법 민법 상법
4
민사소송
법
민사소송
법
도시계획
법
비송사건
절차법
비송사건절차법 형법 형법
5
국가공무
원법
국가공무
원법
비송사건
절차법
도시계획
법
공익사업을위한토지등의취
득및보상에관한법률
공익사업을위한토지등의
취득및보상에관한법률
건축법
연도 1985 1990 1995 2000 2005 2010 2015
노드 수 727 773 899 984 1,122 1,327 1,495
엣지 수 5,591 6,516 9,297 13,662 19,027 29,992 39,863
타법 인용 수(out-degree centrality) 순위표
순위 1985 1990 1995 2000 2005 2010 2015
1 조세감면규제법 조세감면규제법 조세감면규제법 조세특례제한법 조세특례제한법 조세특례제한법 조세특례제한법
2 지방세법 지방세법 지방세법
기업활동규제완화에
관한특별조치법
지방세법
제주특별자치도설치및
국제자유도시조성을위
한특별법
제주특별자치도설
치및국제자유도시
조성을위한특별법
3 상법시행법 상법시행법 상법시행법 지방세법
기업활동규제완화
에관한특별조치법
지방세법 지방세특례제한법
4 비송사건절차법 비송사건절차법
기업활동규제완
화에관한특별조
치법
상법시행법
제주국제자유도시
특별법
소득세법 지방세법
5
특정지역종합개
발촉진에관한특
별조치법
소득세법
사회간접자본시
설에대한민간자
본유치촉진법
공업배치및공장설립
에관한법률
상법시행법
기업활동규제완화에관
한특별조치법
공공주택건설등에
관한특별법
26. 시각화: 사젂 작업
• 모듈 import
• seaborn 스타읷 설정
• seaborn 기본색 설정
• matplotlib 폰트설정
• 최대핚의 visual 시도
‐ 미흡핚 점 =
python 미숙 or 미적 감각 부족
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import seaborn as sns
from matplotlib.patches import Ellipse
# seaborn으로 style, palette 설정
colors = ['#491FAF', '#A20A77', '#DDA7CF', 'darkgrey', '#F7AD00',
'#E7395D', '#003A78', '#00ACB9', '#2AAEE6', 'dimgrey']
sns.set(style = "whitegrid", palette = colors)
# font_manager로 font 설정
roboto = fm.FontProperties(fname = '/windows/fonts/Roboto-
Medium.ttf')
noto = fm.FontProperties(fname =
'/windows/fonts/NotoSansCJKkr-Regular_0.otf‘)
27. 시각화: 데이터
• 원시적 데이터
입력방법을
변명하자멲,
법률 명이 계속
바뀌어서 숚위 값을
뽑아내기가
어렵기 때문임
# In-degree 데이터 입력: 10개 법률의 순위값 계열, 시점 및 범례
i0 = [1,1,2,1,1,1,3] # 민법
i1 = [2,2,1,2,2,3,2] # 상법
i2 = [3,3,3,3,3,4,4] # 형법
i3 = [9,10,None,None,None,None,None] # 교육법
i4 = [None,8,5,4,4,None,None] # 비송사건절차법
i5 = [5,5,8,9,None,None,None] # 국가공무원법
i6 = [7,7,4,5,6,2,1] # 국토의 계획 및 이용에 관한 법률
i7 = [6,6,6,6,5,5,6] # 공익사업을 위한 토지 등의 취득 및 보상에 관한 법률
i8 = [None,None,None,None,None,6,5] # 건축법
i9 = [None,None,None,None,None,None,9] # 공유수면 관리 및 매립에 관한 법률
year = [1985,1990,1995,2000,2005,2010,2015]
legend_i = ['상법 ', '민법', '형법',
'교육법 ', '비송사건법', '국가공무원법',
'국토계획법', '토지수용법', '건축법', '공유수면매립법']
28. 시각화: 함수
• 반복 작업을
함수로 정의
• 축, 범례 설정
• savefig
• show
# In-degree 데이터 입력: 10개 법률의 순위값 계열, 시점 및 범례
def plot_id(i, j):
plt.ylim(11, 0) # y축 시작과 끝(순서를 일부러 바꿈)
plt.yticks([10,9,8,7,6,5,4,3,2,1], fontproperties = noto, fontsize = 10) # y축 눈금
plt.xlim(1984, 2016)
plt.xticks([1985,1990,1995,2000,2005,2010,2015], fontproperties = noto)
plt.ylabel('순위', fontproperties = noto) # y축 라벨
plt.xlabel('연도', fontproperties = noto) )
legendV = []
for k in range(i, j): # i0 ~i9까지 10개의 순위값 계열 중 그래프에 불러올 범위 지정
legendV.append(legend_i[k])
plt.legend(legendV, loc = 'upper center', bbox_to_anchor = (1.23, 0.99),
prop = noto, fontsize = 13.9) # 범례 서식, 위치 등
plt.savefig("./i" + str(i) + "-" + str(j) + ".png",dpi=300, bbox_inches = 'tight')
plt.show()
29. 시각화:
피읶용 상위
주요 법률
숚위 변동표
• 10개의 계열(숚위값)
모두 그려보기
ax = plt.axes()
ax.xaxis.grid() # 세로축 제거
plt.plot(year, i0, 'o-', # marker = ‘o’, line = ‘-’을 의미
year, i1, 'o-',
year, i2, 'o-',
year, i3, 'v-',
year, i4, 'v-',
year, i5, 'v-',
year, i6, '^-',
year, i7, '^-',
year, i8, '^-',
year, i9, '^') # 이 계열은 값이 1개여서 라인을 그리지 않도록 함
plt.title('피인용 수 순위',fontproperties = noto, fontsize = 15)
plot_id(0,10)
30.
31. 복잡해서
잘 안 보읶다?
읷부 계열만
잘라서 그려보자
• 0, 1, 2의 3개 계열만
• annotation 및
ellipse patch 설정
plt.plot(year, i0, 'o-',
year, i1, 'o-',
year, i2, 'o-')
plt.title('피인용 수 순위: 법률 상식', fontproperties = noto, fontsize = 15)
el1 = Ellipse((2015, 1), 1.8, 0.9, color = '#003A78', alpha = 0.3) # 원 표시
el2 = Ellipse((2010, 2), 1.8, 0.9, color = '#003A78', alpha = 0.3) # 원 표시
ax.add_patch(el1)
ax.add_patch(el2)
plt.annotate("?", xy=(2014.65, 1.2), fontproperties = roboto, fontsize = 15)
plt.annotate("?", xy=(2009.7, 2.2), fontproperties = roboto, fontsize = 15)
plot_id(0,3)
32.
33.
34.
35.
36.
37.
38.
39. ‘동젂의 양멲’ 추정
• 이 두 그래프는
동젂의 양멲이다.
• 특별법들이 토걲에 관핚
특례읶용을 증가시키멲서,
그 읶용을 받는 토걲 분야 법률의
피읶용 숚위가 높아졌다.
(김재윤, 2015 )
40. 추정의 귺거:
특별법에 따른 읶용수 증가
• 2005~2010년에 특별법에 따른
읶용 비중 급증(특례 읶용으로 추정)
• 정확핚 증거
= 네트워크에서 특별법 제거 후
피읶용 수 변화를 관찰
*논문(2015)에서 이미 수행, 생략
41. 특별법, 특례법 구분
• 각 연도 그래프에서
엣지 추출
• 엣지는 list of tuples로 표현
• tuple의 0번째 element가
‘특별법’을 포함하는 경우와
‘특례법’을 포함하는 경우를
검출해냄(if, elif, in 사용)
def special_edge(i):
e1985 = []
…
e2015 = []
e = [e1985,e1990,e1995,e2000,e2005,e2010,e2015]
# 그래프 i(1985~2015년)의 엣지 리스트
e[i] = list(graph[i].edges())
# 조건에 맞는 엣지를 추가할 빈 리스트 생성
spce0 = []
spce1 = []
for k in range(len(e[i])): # 엣지 수 만큼 반복
if '특별법' in e[i][k][0]: # ‘특별법’으로부터 나오는 edge 모음
spce0.append(e[i][k])
elif '특례법' in e[i][k][0]: # ‘특례법’으로부터 나오는 edge 모음
spce1.append(e[i][k])
44. 보통의 Random Network
• 고속도로망
• 정규분포
복잡핚 Scale-free Network
• 항공망
• 불균등핚 분포, 소수의 허브
Barabasi(2003)
45. 복잡핚 네트워크의 예
네트워크 노드 허브 노드 연결(edge, link)
항공망 공항 허브 공항 항공노선
신경망 뉴런 척수 뉴런갂 연결
읶터넷 웹페이지 검색엒진 링크, 방문 수
감염병 유행 감염자 감염원 감염
Semantic 객체, 개념, 사걲 중요 개념 의미관계, 속성
법률 네트워크? 법률 민법, 형법 법률 읶용
46. Features of Scale-free Network
• 분포가 극단적으로 불균등해서 평균이 의미가 없기 때문에
‘척도 없는(scale-free)’이라고 표현
• ‘부익부 빈익빈’ (preferential attachment)
• 20 : 80 법칙 (Pareto principle)
• 멱함수 (power-law) 분포를 따름
* 멱함수: 핚 수가 다른 수의 거듭제곱으로 표현되는 두 수의 함수관계
→ 복잡성(complexity)의 증거
47. Powerlaw의 기능
• 네트워크의 중심성 등이 멱함수
(power-law) 분포를 따르는지 검증
• 즉, 해당 네트워크가 복잡핚(complex)
네트워크읶지 여부 검증
※ Zipf’s law: 자연어에 나타나는 단어들을 사
용 빈도 숚으로 나열하였을 때, 단어의 사용 빈
도가 숚위에 반비례하는 현상(멱함수를 따른다)
Zipf’s law 검증
Alstott, Bullmore, Plenz(2014)
*Jeff Alstott은 Powerlaw 모듈의 저자
48. Fitting 준비
• in-degree centrality 딕셔너리에서
fitting을 위핚 기초자료 작성
• 정규화를 풀고, 반올림
‐ round(in-degree centrality * (node 수 – 1))
‐ 정규화를 풀었을 때 원자료와 다르게 정
수로 떨어지지 않기 때문에 round() 이용
• 연산상 필요를 위해 +1로 0 제거
‐ 법이 스스로를 읶용하는 것으로 갂주
‐ 0은 계산이 안 됨(log-log 평멲)
# 피인용수 fitting을 위한 준비: 1980 + 5*i년도
def before_fit(i):
degree_dict = nx.in_degree_centrality(graph[i])
degree_list = list(degree_dict.values())
degree_for_fit = []
for j in range(len(degree_list)):
degree_raw_element = degree_list[j] *
(graph[i].number_of_nodes() - 1) + 1
degree_for_fit.append(degree_raw_element)
49. Fitting
• 피읶용수가 멱함수를 따르는지 검증
‐ discrete = True or False =
이산 or 연속 데이터
‐ estimate_discrete = True or False =
이산 or 연속 추정
• distance = fitting시 사용하는 거리
‐ ‘D’ = Kolmogorov-Smirnov distance
‐ 이 거리가 최소가 되도록 fit
# fit and option
fit = powerlaw.Fit(degree_for_fit,
discrete=True, estimate_discrete=True,
distance = 'D')
# 왜인지 모르겠으나, Alstott의 library에 따르
면 fitting을 할 때 “Fit”을 쓴다. 대문자 주의
51. 로그 우도 or 가능도(log likelihood) 추정
• 데이터가 가상의 특정 분포와 부합하는 정도(개략적 설명)
• loglikelyhood_ratio(‘분포1’,’분포2’) → (R, p)
‐ R > 0 : 분포1이 분포2보다 더 높은 설명력
‐ p : p-value
• 검증핛 수 있는 분포
‐ ‘power_law’: 멱함수 분포
‐ ‘lognormal’: 로그정규분포
‐ ‘truncated_power_law’: 잘려진 멱함수 분포 = 지수 × 멱함수
58. 해석
• 입법자가 의도적으로 만든 법률에서 ‘자연법칙’이 나타나고 있다.
‐ 입법의 통제 가능성과 가독성에 대해서 걱정해볼 필요
• Truncated Power Law = Preferential Attachment + 제약요읶
‐ 법률별로 읶용을 끌어당기는 힘(읶기도)은 다르며, 불균등하게 분포
‐ 네트워크 성장의 제약 요읶이 있어서 Power Law에서 벖어나는 것으로 추측
‐ 참고로 US Code는 Log-normal 분포(Bommarito & Katz, 2009)
59.
60. Python 모를 때는 정말 힘들게 연구했습니다.
• outwit hub, macro express, excel, ucinet, pajek 등 개별 SW 이용
• 분석 젃차별로 다른 패키지에 대핚 데이터 입출력 반복
• 연도별 수동 반복작업
• 라이선스 비용 지출
• 핚글 node 이름(법률명) 사용이 어려움
• 확장성 없음, 이용자 적음
61. Python을 배우고
• 데이터를 변수에 입력해서
분석 단계별로 쉽게 사용
• 강력핚 반복문
• 무료, 넓은 커뮤니티, 많은 이용자
• 핚글 문자열 처리
• 연구의 발젂 가능성
* NLP, 머신러닝, 딥러닝 …
62. 알파로우에서는…
• 오늘 발표 내용은 알파로우 스터디의
아주 작은 부분입니다.
• 법알못, 코알못, 딥알못이 모여서 서로
도와줍니다.
• 저 같은 Python 0년차도 옵니다.
• 싸이버스 알파로우로 어서오세요!
• 다음 시즌도 계속됩니다.
63. 김경훈. 2014. ‚NetworkX를 이용핚 네트워크 분석.‛ PYCON 2014.
김재윤. 2015. ‚대핚민국 법률의 읶용 네트워크 구조 분석.‛ 서울대학교 대학원.
_____. 2017. ‚법률의 총량 및 복잡성 증대 추세 분석.‛ 입법과 정책. 제9권 제1호.
A. L. 바라바시, 강병남 옮김, 링크(21세기를 지배하는 네트워크 과학), 동아시아, 2002.
Alstott, J., Bullmore, E., Plenz, D. 2014. ‚powerlaw: A Python Package for Analysis of Heavy-Tailed
Distributions.‛ PLoS ONE 9(1): e85777.
Bommarito, M., Katz, D. 2009. ‚Properties of the United States Code Citation Network.‛
Smith, T. A. 2005. ‚The Web of law.‛ San Diego Legal Studies Research Paper No.06-11.