Python

파이썬을 활용한 네트워크 분석 (고양국제고 진로특강)

카루-R 2022. 4. 10. 00:03
반응형
 

환영합니다, Rolling Ress의 카루입니다.

목요일 8/9교시에 "네트워크 분석" 진로특강 수업을 들을 수 있더라고요. 파이썬을 활용할 수 있는 친구들을 찾고 있던 듯 한데, 덜컥 겁이 났습니다. 제가 저 수업을 못 따라가면 어쩌지. 근데...ㅋㅋㅋㅋㅋㅋㅋㅋㅋ 사실 좀 자뻑을 해도 됩니다. 내가 못 알아들을 정도면 아무도 못 따라감.

저는 막 네트워크 패킷 분석하고 뭐 그런 수업인 줄 알았느데 그냥 그림 그리는(?) 거였습니다. 노드와 엣지 가지고 네트워크형 모델을 만든다고 해야 하나, 창문해 선생님께서 저희를 위해 자료들을 다 준비해주셨더라고요.

 

Software for Complex Networks — NetworkX 2.7.1 documentation

NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. It provides: With NetworkX you can load and store networks in standard and nonstandard data formats, generate many types o

networkx.org

파이썬을 활용합니다. NetworkX라는 라이브러리를 사용하는데, Conda에는 기본적으로 들어있는 것 같아요. 없으면 그냥 pip으로 설치하면 됩니다.

import networkx as nx

그리고 이 한 줄이면 준비가 된 겁니다.

import networkx as nx

G = nx.Graph()

G.add_node(1)
G.add_node(2)
G.add_edge(1,2)

nx.draw(G,with_labels=True)

원리는 간단합니다. 네트워크에는 지점 내지는 데이터를 표시해주는 "노드"와 노드를 이어주는 "엣지"로 구성되어 있습니다. networkx에서는 nx.Graph.add_node 및 add_edge를 통해 노드와 엣지를 추가해줄 수 있어요. 파이썬 라이브러리의 특징인데, 저걸 참 저렇게 전역메서드로 사용하는 방식이 딱히 내키지는 않습니다. 그냥 G.draw하면 편할텐데 굳이 저걸 nx에서 끌고 와야 하나...C# 그립습니다...

참고로 네트워크에선 노드보다 엣지가 더 중요합니다. 그래서 노드를 추가하지 않고 엣지만 추가해도 똑같은 결과가 나옵니다. 그리고, 노드와 엣지는 리스트로 여러 개를 추가할 수 있습니다. 엣지의 경우 반드시 튜플의 리스트로 값을 전달해야 합니다.

G.add_nodes_from([3,4,5])
G.add_edges_from([ (3,4) , (4,5)])

참고로 저렇게 값을 할당하면, 순회할 수 있습니다. G에 nodes와 edges라는 프로퍼티가 있어요.

저건 간단한 그래프고, Graph 대신 DiGraph를 사용하면 방향성을 나타낼 수 있습니다. 자세한 설명은 생략하도록 할게요. 오늘은 그냥 제 과제 보여드리려고 쓴 거니까. 사실 수업자료는 여기에 올릴 수가 없어서, 제가 작성한 것들만 공개하려고 합니다.

import networkx as nx
import matplotlib.pyplot as plt

def append_tuples(source: str, dest: list[(str, str)], words: list[str]):
    for word in words:
        dest.append((source, word))
        
# 전역 인스턴스 생성
G = nx.Graph()
tupleList: list[(str, str)] = []

자, networkx를 불러옵니다. 그리고 함수를 하나 정의했는데, 이거...그냥 귀찮아서 엣지 추가하는 함수를 아예 만들어버렸습니다. 참고로 저는 유의 관계에 있는 단어들을 주제로 네트워크 분석을 진행할 예정입니다. 언어학과 데이터과학의 융합... 적절한 것 같기도?

# 예쁘다 > 유의어 설정
append_tuples('예쁘다', tupleList, ['반반하다', '귀엽다', '기특하다', '곱다', '사랑스럽다', 
             '아기자기하다', '아름답다', '예쁘장하다', '착하다'])
    
# 귀엽다 > 유의어 설정
append_tuples('귀엽다', tupleList, ['사랑스럽다', '깜찍스럽다', '깜찍하다', '기특하다',
             '사랑옵다', '애교스럽다', '예쁘다'])    
    
# 착하다 > 유의어 설정
append_tuples('착하다', tupleList, ['상냥하다', '순진하다', '곱다', '기특하다', '순하다', '갸륵하다',
             '아름답다', '예쁘다', '장하다', '좋다'])

# ... (이하 생략)

네이버 국어사전 뒤져가며 열심히 찾았습니다. 대강 아시겠나요? 첫 번째 인자는 기준 단어이고, 뒤에 나오는 리스트가 그 단어의 유의어들입니다. 그래서 tupleList에 튜플 형태로 저장되는 거예요.

G.add_edges_from(tupleList)

plt.figure(figsize=(12, 8))
nx.draw(G, with_labels=True, font_family='Malgun Gothic', alpha=0.6, node_size=1400,
        font_size=14,
        node_color = list(nx.pagerank(G).values()), width=3)

matplotlib.pyplot을 통해 캔버스 크기를 쭉 늘립니다. 그리고 적당히 추가해준 다음에, 살짝 꾸며서 완성하면 됩니다.

그럼 이렇게 네트워크 모양으로 분석이 됩니다.

참고로 실행할 때마다 모양이 조금씩 바뀝니다. 뭐가 뭐에 연결되었는지가 중요하지, 어디에 있는지는 중요하지 않아요.

# 끊어져 있는 단어는 없는가?
print('Connected: ', nx.is_connected(G))

# 연결 상태 확인
nx.closeness_centrality(G)

# 몇 개의 가지가 뻗어나가나?
nx.core_number(G)

그리고 자세한 항목들은 nx 내장 함수를 이용해서 정보를 확인할 수 있습니다.

출력 결과는 뭐 이런 식으로 나오게 됩니다.


여기서 끊겠습니다. 사실 가중치라든가, 완전 연결이라든가,

....이런 정신나간 네트워크를 그릴 수도 있어요. (이쯤되니 물감 쏟은 것 같기도...?) 참고로 저런 건 연산량이 많아서 그리는 데에도 한세월 걸립니다. 근데 분명 네트워크 분석도 재미있는 분야라, 알아두면 언젠가 유용하게 쓸 데가 있을 것 같긴 해요.

반응형

'Python' 카테고리의 다른 글

파이썬 코딩 효율을 크게 높여주는 7가지 팁들  (0) 2022.02.16