파이썬의 matplotlib 노트

파이썬의 matplotlib는 수치 데이터를 그래프로 효과적으로 표시해주는 API입니다. 이에 대해 간단한 활용 예시에 대한 코드를 기록해 둡니다.

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y = [1, 2, 3, 4, 5]

plt.scatter(x, y)

plt.show()

X축과 Y축에 대한 포인트 데이터를 표시하는 코드입니다. 결과는 다음과 같습니다.

그래프에서 포인트의 크기와 색상, 투명도를 지정하는 예제는 다음과 같습니다.

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y = [1, 2, 3, 4, 5]
s = [10, 20, 30, 40, 50]

plt.scatter(x = x, y = y, s = s, c = 'red', alpha=0.5)

plt.show()

결과는 다음과 같습니다.

다음은 꺽은선 그래프입니다.

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 10, 0.5)
y = np.sin(x)

plt.plot(x, y)
plt.show()

x축과 y축의 데이터는 4번과 5번 코드에서 정의합니다. 결과는 다음과 같습니다.

하나의 차트에 여러개의 그래프를 동시에 표시하고, 추가적으로 제목, 축이름 등을 표시하는 코드입니다.

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 10, 0.5)
y1 = np.sin(x)
y2 = np.cos(x)

plt.plot(x, y1, label="sin(x)")
plt.plot(x, y2, label="cos(x)", linestyle="--")

plt.xlabel("x")
plt.xlabel("y")

plt.title("sin & cos")
plt.legend()

plt.show()

3차원 차트의 경우 먼저 X, Y축에 대한 데이터와 이 X, Y를 변수로 하여 계산된 Z 값의 함수가 정의해야 합니다. 이렇게 정의된 X, Y, Z에 대한 3차원 그래프는 아래의 예제 코드를 통해 3차원 차트로 시각화할 수 있습니다.

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
Z = X**2 + Y**2

fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_wireframe(X, Y, Z, color='black')

plt.show()

여러개의 차트를 동시에 표시하는 경우입니다.

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, np.pi * 3, 100)
fig, axes = plt.subplots(2,2)

axes[0][0].plot(x, np.sin(x))
axes[0][1].plot(x, np.arccos(x))
axes[1][0].plot(x, np.cos(x))
axes[1][1].plot(x, np.arcsin(x))

plt.show()

아래는 차트를 그리는 스타일을 지정하고 범례를 표현하는 코드입니다.

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(-10,10)
y = x**2

plt.plot(x, y, 
    linewidth=2, color='green', linestyle=':', 
    marker='*', markersize=10, markerfacecolor='yellow', markeredgecolor='red', 
    label='y=x^2')
   
plt.legend()

plt.show()

결과는 다음과 같습니다.

파이썬의 NLTK 라이브러리를 이용한 WordNet 활용

WordNet은 프린스턴 대학교에서 구축한 유의어 DB인데, 유의어 사이의 관계를 그래프로 정의하고 있는 방대한 데이터입니다. 이 WordNet을 이용하여 유사한 단어를 파악할 수 있고, 각 단어의 유사도를 계산할 수 있습니다. 이를 파이썬의 NLTK를 이용해 활용할 수 있는데, 이에 대한 코드를 정리해 봅니다.

먼저 NLTK 패키지의 설치가 필요합니다. 제 환경에서는 conda install nltk와 같은 식으로 설치하였습니다.

NLTK 패키지의 설치가 끝나면 다음과 같은 코드를 통해 WordNet 데이터를 PC에 다운로드 받을 수 있습니다.

import nltk

nltk.download('wordnet')

가장먼저 ‘man’이라는 단어의 유의어를 검색하기 위해 다음 코드가 사용됩니다.

from nltk.corpus import wordnet

print(wordnet.synsets('man'))
''' Output:
[
    Synset('man.n.01'), 
    Synset('man.n.03'), 
    Synset('man.n.05'), 
    Synset('man.n.06'),     
    Synset('man.n.08'), 
    Synset('man.n.09'), 
    Synset('man.n.10'), 
    Synset('man.v.01'), 
    Synset('man.v.02')],
    Synset('serviceman.n.01'), 
    Synset('homo.n.02'), 
    Synset('valet.n.01'),     
    Synset('world.n.08')
]     
'''

위의 검색에서 man.n.01의 경우 n은 명사를 의미합니다. 참고로 v는 동사이구요. 01은 man에 대한 인덱스값입니다. 이 man.n.01에 대한 사전적 의미를 얻기 위한 코드는 다음과 같습니다.

man = wordnet.synset('man.n.01')
print(man.definition()) # an adult person who is male (as opposed to a woman)

버그인지는 모르겠으나, man.n.02는 검색되지 않았음에도 아래의 코드는 유효합니다.

man2 = wordnet.synset('man.n.02')
print(man2.definition()) # someone who serves in the armed forces; a member of a military force

man.n.01에 대한 단어의 관계 그래프는 다음 코드를 통해 얻을 수 있습니다.

print(man.hypernym_paths())
''' Output:
[
    [Synset('entity.n.01'), Synset('physical_entity.n.01'), Synset('causal_agent.n.01'), Synset('person.n.01'), Synset('adult.n.01'), Synset('man.n.01')], 
    [Synset('entity.n.01'), Synset('physical_entity.n.01'), Synset('object.n.01'), Synset('whole.n.02'), Synset('living_thing.n.01'), Synset('organism.n.01'), Synset('person.n.01'), Synset('adult.n.01'), Synset('man.n.01')], 
    [Synset('entity.n.01'), Synset('physical_entity.n.01'), Synset('causal_agent.n.01'), Synset('person.n.01'), Synset('male.n.02'), Synset('man.n.01')], 
    [Synset('entity.n.01'), Synset('physical_entity.n.01'), Synset('object.n.01'), Synset('whole.n.02'), Synset('living_thing.n.01'), Synset('organism.n.01'), Synset('person.n.01'), Synset('male.n.02'), Synset('man.n.01')]
]
'''

위의 관계 그래프 정보는 총 4개의 list로 구성된 list인데, 이를 시각화하면 다음과 같습니다.

관계 그래프의 경로 역시 4개라는 것을 알 수 있고, 경로의 흐름에 따라 단어의 의미가 점점 구체화됩니다. 이 관계 그래프를 통해 서로 다른 단어에 대한 유사도를 계산할 수 있는데, 아래의 코드가 그 예입니다.

boy = wordnet.synset('boy.n.01')
guy = wordnet.synset('guy.n.01')
girl = wordnet.synset('girl.n.01')
woman = wordnet.synset('woman.n.01')

print(man.path_similarity(man))     # 1.0
print(man.path_similarity(boy))     # 0.3333333333333333
print(man.path_similarity(guy))     # 0.5
print(man.path_similarity(girl))    # 0.25
print(man.path_similarity(woman))   # 0.3333333333333333

단어 간의 유사도는 0부터 1까지의 값으로, 1에 가까울수록 두 단어의 의미가 더욱더 유사하다는 의미이고, 0에 가까울수록 그 의미의 관계가 거의 없다는 것을 의미합니다.