현시점 한국에서 가장 '프로덕트'를 잘 만드는 팀은 어디가 있을까? 에 가장 먼저 생각난 게 '토스'였다.
가장 프로덕트를 잘 만드는 팀은 프로덕트를 어떻게 만드는지, 어떤 방식으로 일하는지 궁금해졌다. 그래서 이승건 대표의 PO SESSION을 듣기 시작했고, 더 자세한 내용을 알고 싶어서 토스팀에서 발간한 <유난한 도전>을 구입해 보게 됐다.
책의 내용은 대단히 토스의 영웅서사를 담은 듯하다. 전쟁에서 승리한 국가가 남긴 역사서 한쪽 같은 느낌이랄까.
토스의 시작과 고난, 극복의 이야기를 통해 내가 지난 몇 년간 일했던 팀에서, 왜 그렇게 어려움들이 있었는지, 왜 그때 그 문제를 해결하지 못했는지를 깨닫게 되었다. 그냥 토스가 알고 싶어서 산 책이, 내 과거에 대한 회고를 하게 해 준 좋은 책이었다.
그 이야기를 부분 부분 여러 레슨런으로 나눠서, 내용을 발췌해서 조금씩 적어두려고 한다.
"사람들이 오프라인 만남을 앱에 기록하고 싶을 것이라는 첫 번째 가설이 틀렸다는 사실을 인정하지 못했다"
PO로 일하면, 스스로는 계속 확신을 가져야만 한다. 내가 가설을 가지고 타인을 설득하고, 실험하고 깨지고를 반복해야 하기 때문이다. 그렇기에 스스로 갖게 되는 '확신'이 굉장히 위험한 것인데, 이승건대표도 같은 단계를 거친듯하다. 내가 생각하는, 상상하는 세상은 정확하게 내 머릿속에만 있을 가능성이 높다. PO는 내가 생각한 가설을 감히 확신하지 않아야 한다. 그럴 수도 있겠다, 하지만 틀릴가능성이 더 높다.라고 전재해야 위험한 판단을 지양할 수 있다.
EO의 클래스 101 대표 인터뷰 영상을 보면, 처음 PMF를 찾은 순간 "드디어 우리가 시장에 왔어"라는 말이 나온다. 팀이 가지고 있었던 여러 가설 중에 한 가지가 실제 마켓에, 고객에게 워킹한 그 순간의 짜릿함 환희를 표현한 것이다. 여기서 '드디어'라는 말을 통해서 우리는 그 어려움을 예상할 수 있다.
나의 생각이 고객에게도 동일하게 있을 가능성은 0에 가깝다. 그렇기에, 항상 의심해야 하고, '무조건'이라는 과한 확신을 지양해야 한다. PMF를 찾는 팀이라면, 우리는 언젠가 '드디어' 그곳에 도착하게 될 것이기 때문이다. 오히려 너무 쉽게 도착하게 되면 옳게 도착한 것이 맞는지 의심해 보는 게 건강할 것 같다.
책링크는 쿠팡 파트너스 링크입니다. 쿠팡 파트너스 링크를 통해 제품을 구입할 경우, 소정의 수수료를 부여받습니다.
블로그를 운영하는 원동력으로 사용되며, 쿠팡 파트너스 링크와 글의 내용은 이해관계가 없습니다.
from wordcloud import WordCloud
text = ''
with open("kakaotalk.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
for line in lines:
text += line
wc = WordCloud(font_path='/System/Library/Fonts/AppleSDGothicNeo.ttc', background_color="white", width=600, height=400)
wc.generate(text)
wc.to_file("result.png")
코드 설명
from wordcloud import WordCloud
워드클라우드 라이브러리를 사용한다.
text = '' with open("kakaotalk.txt", "r", encoding="utf-8") as f: lines = f.readlines() for line in lines: text += line
text를 공란으로 만들어주고, kakaotalk.txt라는 파일을 오픈한다. (txt파일이라면 어떤 파일도 무방하다. 카카오톡 톡 내보내기를 통해 사용하는 것을 강의에서 권하고 있으나, 그럴 경우 csv파일로 export되어 적용이 안된다.)
아래의 코드를 통해 폰트들의 링크를 가져올 수 있다. 왜인지 모르게 ttf type의 폰트는 적용이 안돼서, ttc파일을 적용시켰다.
폰트 경로 가져오기
import matplotlib.font_manager as fm
for font in fm.fontManager.ttflist:
if 'Gothic' in font.name:
print(font.name, font.fname)
폰트 경로 출력 결과
Apple SD Gothic Neo /System/Library/Fonts/AppleSDGothicNeo.ttc
Hiragino Maru Gothic Pro /System/Library/Fonts/ヒラギノ丸ゴ ProN W4.ttc
Noto Sans Gothic /System/Library/Fonts/Supplemental/NotoSansGothic-Regular.ttf
AppleGothic /System/Library/Fonts/Supplemental/AppleGothic.ttf
위의 링크에서 /로 시작하는 폰트 링크를 복사해 위의 내용을 font_path에 넣으면 된다.
if, 혹시 폰트 경로만 출력하고싶다면 아래의 코드를 입력하면 된다.
import matplotlib.font_manager as fm
for font in fm.fontManager.ttflist:
if 'Gothic' in font.name:
print(font.fname)
출력 결과
결과를 보면 무의미한 내용이 엄청 많이 들어있다. ㅋㅋㅋ, hk 이런내용들이다.
여기서 무의미한 데이터들을 필터링해주는 데이터클리닝 과정을 진행한다.
데이터 클리닝
text = ''
with open("kakaotalk.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
for line in lines[5:]:
if '] [' in line:
text += line.split('] ')[2].replace('ㅋ','').replace('ㅜ','').replace('이모티콘\n','').replace('삭제된 메시지입니다','')
for line in lines[5:]:
5번째 줄부터 출력 (초반에 불필요한 메시지들 제외)
if '] [' in line:
사람들이 말한 경우만 포함하기 = 시스템 명령어 제거하기
파일 구조에 시스템 명령어들은 ] [를 포함하고 있지 않고, 사람이 말한 경우 "[말한사람이름] [시간] 말한 내용 "이렇게 돼서 위의 트릭으로 사람이 말한 경우만 포함 할 수 있다.
line.split('] ')[2]
파일 구조가 "ex. [정훈hk] [오후 5:10] 왜 우울한지 고르시오"이런식으로 생겨서 '] '를 기준으로 짜르면 text부분이 2순서에 위치함. 일종의 트릭
from wordcloud import WordCloud
text = ''
with open("kakaotalk.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
for line in lines[5:]:
if '] [' in line:
text += line.split('] ')[2].replace('ㅋ','').replace('ㅜ','').replace('이모티콘\n','').replace('삭제된 메시지입니다','').replace('저두','').replace('저도','').replace('근데','').replace('나','').replace('아','')
wc = WordCloud(font_path='/System/Library/Fonts/AppleSDGothicNeo.ttc', background_color="white", width=600, height=400)
wc.generate(text)
wc.to_file("result4.png")
출력 결과
전보다는 훨씬 유의미한 내용들만 남은것을 볼 수 있다.
원하는 모양으로 워드클라우드
원하는 형태의 이미지를 import 해서 워드클라우드를 만들자
from wordcloud import WordCloud
from PIL import Image
import numpy as np
text = ''
with open("kakaotalk.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
for line in lines[5:]:
if '] [' in line:
text += line.split('] ')[2].replace('ㅋ','').replace('ㅜ','').replace('이모티콘\n','').replace('삭제된 메시지입니','').replace('저두','').replace('저도','').replace('근데','').replace('나','').replace('아','')
mask = np.array(Image.open('cloud.png'))
wc = WordCloud(font_path='/System/Library/Fonts/AppleSDGothicNeo.ttc', background_color="white", mask=mask)
wc.generate(text)
wc.to_file("result_masked.png")
적용시킨 이미지 (cloud.png)
출력 결과
wordcloud 함수는 이미지상의 '검은색영역'에 워드클라우드를 만드는 것을 볼 수 있다.