스토리 홈

인터뷰

피드

뉴스

조회수 1191

[Buzzvil Career] 좋은 글로벌 사업 개발 매니저는 어떤 사람일까?

 모바일 잠금화면 미디어 플랫폼 사업자 버즈빌은 어떠한 인재를 찾는지 지원자에게 잘 알리려고 노력합니다. 그럼 지원자도 버즈빌이 자신에게 맞는 기업인지 알 수 있을 테니까요. Buzzvil Career에서는 각 직무에 대해 더욱 심도 있는 정보를 제공합니다. 현재 채용 중인 글로벌 사업 개발 매니저 포지션에 대한 자세한 내용은 여기에서도 확인 가능합니다. 이번 글은 2013년에 버즈빌에 합류하여, 글로벌 사업 개발, 서비스 운영 및 마케팅을 포함한 전반적인 사업 전략을 책임지는 Joshua에 대한 직무 인터뷰입니다. 그가 생각하는 ‘좋은 글로벌 사업 개발 매니저’란 누구인지 함께 이야기해 보았는데요. 한 사업을 시작하여 끝맺음까지 몸소 경험하고 싶은 분이라면 이 글에 주목해 주세요.  글로벌 사업 개발 매니저의 업무에 대해 설명해주세요. 우선 버즈빌의 글로벌 사업 개발 매니저(이하 매니저) 포지션은 상대하는 파트너에 따라 크게 두 가지로 분류할 수 있어요. 먼저 광고주 및 애드네트워크 등을 비롯한 파트너로 부터 광고 Demand를 확보하고, 광고 수익 최적화 로직을 관리 및 운영하는 Demand 방면에 집중하는 글로벌 사업 개발 매니저와 본 글에서 소개드릴, Supply 방면의 글로벌 사업 개발 매니저로 구분하여 운영하고 있어요. 편의상 본 소개 글에서의 ‘글로벌 사업 개발 매니저’는 Supply 방면의 글로벌 사업 개발 담당자로 한정해서 사용할게요. (Supply 방면의) 글로벌 사업 개발 매니저는 모바일 앱을 보유한 고객사 – 모바일 광고 업계에서는 흔히 ‘퍼블리셔’라고 부르는 – 에 버즈빌의 모바일 잠금화면 미디어 플랫폼인 버즈스크린을 제공하는 일을 해요. 퍼블리셔는 버즈스크린 SDK를 기반으로 손쉽게 자사 브랜드의 잠금화면 광고 서비스를 직접 개발할 수도 있고, 경우에 따라서는 버즈빌이 Whitelabel 방식으로 전체 서비스를 개발하여 제공하기도 하지요. 퍼블리셔는 잠금화면 광고 서비스 도입을 통해 추가 광고 수익화가 가능하고, 기존 모바일 앱 사용자들의 충성도를 제고할 수 있어요. 사용자는 퍼블리셔 브랜드의 잠금화면 광고 서비스의 사용을 통해 퍼블리셔 앱에서 제공하는 각종 재화를 리워드로 제공받을 수 있고요. 퍼블리셔의 기존 서비스가 온라인 쇼핑앱이라면 온라인 쇼핑 시 할인을 받을 수 있는 포인트나 쿠폰을 제공받을 수 있고, 로열티 프로그램이라면 해당 로열티 프로그램의 포인트를 제공받아요. 뿐만 아니라 콘텐츠 서비스라면 유료 콘텐츠의 이용에 필요한 크레딧이나, 유료 서브스크립션을 할인받을 수도 있어 활용할 수 있는 방법은 무궁무진하다고 볼 수 있어요. 잠금화면 광고 서비스에서 발생한 광고 수익을 기반으로 사용자에게 각 퍼블리셔 서비스에 특화된 혜택을 제공하고, 궁극적으로 사용자 충성도를 극대화할 수 있는 것이지요. 이렇게 퍼블리셔와의 제휴를 통해 확보된 잠금화면 광고 지면들은 하나의 애드 네트워크로서 광고주에게 판매됩니다. 더 많은 지면/매체가 확보할 수록 도달 가능한 사용자 수가 늘어나며 궁극적으로 광고 플랫폼으로서의 가치가 커지므로 사업 개발 매니저의 업무는 플랫폼으로서의 입지를 단단하게 만들기 위해 가장 먼저 충족되어야 하는 업무입니다.  실제 제휴 업무는 단순 영업이라기 보다는 각 퍼블리셔의 카테고리와 상황에 적합한 제안을 하는 것이 중요하고, 어떤 면에서는 컨설팅에 가깝다고 생각해요. 크게 보았을 때에는 위에서 설명드렸던 것처럼 카테고리 별로 잠금화면 서비스의 활용 목적과 제품 전략이 달라질 수 있으며, 조금 더 작게 보면 동일한 카테고리 내에서도 각 파트너사의 상황을 반영한 맞춤형 제안을 진행하는 것이 중요하고요. 이렇게 맞춤형 제안을 하기 위해서는 목표로 하는 파트너사의 사업 현황을 이해하고, 또 해당 서비스를 직접 사용을 해보면서 이해도를 높여야해요.  글로벌 사업 개발의 경우, 한국에서 이미 증명된 로열티 프로그램이나, 통신사와 같은 카테고리를 중심으로 제휴 영업을 진행하고 있어요. 상대적으로 제시할만한 레퍼런스가 많이 존재하며 제품 전략도 상당히 틀이 갖추어진 상태이기 때문에 효율적으로 접근이 가능하기 때문이에요. 하지만 글로벌 시장의 환경이 한국과 다른 점도 분명있기 때문에 반드시 한국에서의 카테고리 전략만을 따라가지는 않아요. 예를 들면 스마트폰 기기 제조사와의 제휴는 한국이 아닌 글로벌 시장에서 먼저 사례가 만들어졌으며, 컨텐트 서비스와의 제휴도 글로벌 시장에서 좀 더 다양한 사례들이 나오고 있어요. 일례로 클라우드 저장소 사업을 영위하는 한 파트너가 잠금화면 서비스 사용을 대가로 무료로 추가 저장 공간을 제공하는 제휴 모델 또한 한국에서는 시도되지 않았으나, 글로벌 시장에서 처음 시작되어 좋은 호응을 얻고 있어요. 왜 버즈빌을 선택 했나요? 모두 그렇지는 않지만, 상당수의 국내 스타트업의 사업 모델을 보면 해외 시장에 이미 시장을 장악한 유사 서비스가 존재하는 경우가 많아요. 애초에 사업을 시작할 때 부터 해외 모델을 벤치마킹해서 진행하는 경우도 있고, 우연히 비슷한 시기에 사업을 시작하여 각 시장을 공략하는 경우도 있겠지만 누가 먼저 진행했는지가 중요하다기 보다는 해외에 이미 강력한 경쟁자가 존재한다는 사실을 눈여겨 봐야 한다고 생각해요. 이런 경우에는 해외 시장에 진출하기가 녹록치 않기 때문이지요.  이에 비해 버즈빌은 글로벌 사업을 본격적으로 해볼 수 있는 제품을 가지고 있다고 생각해요. 잠금화면 사업 모델은 해외의 것을 한국에 들여온 것이 아니라, 버즈빌을 비롯한 한국의 스타트업들이 처음 시작하여 탄탄하게 발전시킨 모델이에요. 그리고 그 이후 해외 각지에서 비슷한 서비스를 제공하는 스타트업들이 생겨나기도 했지만 아직 까지는 한국의 사업자들 수준으로 성장한 케이스는 드물어요. 광고 매출을 일으키고 이를 기반으로 사용자에게 리워드를 제공하는 모델이다 보니 이 매출과 지급되는 리워드 비용 등을 제대로 관리해내지 못하면 금세 재무적으로 위기에 빠질 수 있기 때문이라고 생각해요.  게다가 버즈빌은 잠금화면 사업 모델은 다른 잠금화면 서비스 제공사와는 다르게 버즈스크린이라는 B2B 모델을 중심으로 하고 있어요. 많은 스타트업들이 해외 진출시 마케팅에 큰 돈을 투자했다가 손해를 보곤 하는데, 저희는 퍼블리셔와의 협업을 기반으로 진출하기 때문에 큰 마케팅 비용이 들지 않아요. 흔히 이야기하는 ‘Scalable’한 모델인 것이지요. 지금의 버즈빌이 왜 좋은지에 대해 이야기하자면 정말 많은 이유들이 있겠습니다만 제가 처음 함께한 시점인 만 5년 전을 생각해보면 글로벌 사업을 해볼만 한 모델이라고 생각했기 때문에 합류를 한 것이 가장 컸어요. 여전히 갈 길이 멀지만 그 동안 회사도, 그리고 개인적으로도 글로벌 사업에 관해서는 크게 성장했다고 생각해요. 이제는 저보다도 훨씬 뛰어난 팀원들도 함께 하고 있어 크게 외롭고 힘들다는 생각도 별로 들지 않고 더 잘 해낼 수 있다는 믿음이 있어요. 버즈빌은 어떤 곳인가요? 버즈빌은 버즈빌리언 개개인을 신뢰하고 자율성을 부여하는 곳이에요. 추후에 사업을 하고 싶다거나, 꼭 그렇지 않더라도 어떤 업무를 처음부터 끝까지 책임지고 진행시키며 자기 자신을 발전시키고 싶은 분에게 특히 더 맞는 곳이라고 생각해요.  자율성이 있다는 것을 어떤 면에서 보면, 모든 것을 통제하지는 않는 다소 느슨한 규율을 가진 것이라고 생각할 수 있고 또 이게 가끔은 ‘프로세스가 없다’라고 이해가 될 수도 있어요. 실제로 버즈빌은 스타트업이라고 보기에는 상당히 짜임새있는 프로세스나 시스템을 갖추고 있지만 여전히 프로세스 상으로는 부족한 점이 많아요. 회사가 성장하는 속도를 프로세스가 충분히 쫓아가지 못해서 그런 점도 있지만, 자율성을 부여하려고 하다보니 의도적으로 그렇게 두는 부분도 있어요. 이럴 때 프로세스의 부재를 불편해하기 보다는, 본인에게 주어진 자율성을 즐길 수 있는, 혹은 효율적인 프로세스를 직접 만들어 볼 수 있는 것에서 보람을 느낄 수 있는 분이라면 정말 잘 맞는 곳이라고 생각해요. 아울러 글로벌 사업에 대한 일종의 사명감을 갖고 있어요. 글로벌 사업은 항상 계획했던 것보다 더 긴 시간과 노력이 들어가는 일이기 때문에 지치고 힘들 수도 있지만 사명감을 갖고 임하기 때문에 조금 더 인내할 수 있다고 생각해요. 팀 분위기는 어떤가요? 버즈빌이 추구하는 문화와 마찬가지로 자율적인 문화를 만들고자 노력하고 있어요. 특히 글로벌 사업 개발 매니저의 경우 업무 범위도 넓기도 하고, 때로는 출장 등으로 인해 서로 떨어져 일하는 경우도 종종 있다보니 자율성이 보다 중요한 직군이라고 생각해요. 글로벌 사업 초창기부터 함께 고생을 해왔다보니 동료의식도 있고, ‘우리 팀이 더 잘해야 한다’는 욕심도 있어요. 그렇다보니 팀에서는 ‘이건 제 일이 아닙니다’라고 말하는 사람은 단 한 명도 없어요. 모두 각자 책임감을 가지고 오히려 할 일을 찾아서 하고 있어요. 조직에서 한 두 명쯤 있을 법한 일명 ‘프리라이더’ 없이 모두가 열심히 하니까 더 잘 지낼 수 있는 것 같아요. 감사한 일이죠.  작년에는 팀원들이 다같이 몽골 여행을 가는데, 팀장인 저까지 같이 가자고 하더군요. 정말 가도 괜찮은지 거듭 물어봐도 괜찮다는 겁니다. (하하) 그래서 눈치 없이(..원래 눈치가 좀 없긴 합니다만) 같이 다녀왔고 함께 재미있는 시간을 보냈습니다. 그 정도로 편하게 지내고 있습니다. 이 자리를 빌어 다시 한 번 초대해주어 고맙다는 말을 전하고 싶네요. 좋은 글로벌 사업 개발 매니저는 어떤 사람일까요?  #자율성과 적극성 위에서 버즈빌의 핵심 가치로서 자율성과 적극성에 대해 충분히 이야기한 것 같아 짧게 덧붙이자면, 글로벌 사업 개발 매니저라면 스스로에게 주어진 성과를 달성하기 위해 자율적으로, 또 적극적으로 프로젝트를 이끌 수 있어야 해요. #끈기 있는 사람 글로벌 사업 개발은 쉬운 일이 아니에요. 목표 회사를 선정하고 또 그 회사를 위한 맞춤 제안을 도출하는 것도 어려운 일이거니와, 그 회사 내에서 같은 뜻을 이룰 수 있는 사람을 찾는 것은 더 힘든일이에요. 같은 제안일지라도 그 회사 안에서 누구와 이야기하는지에 따라 제휴가 성공할 수도 있고 실패할 수도 있어요. 각자의 상황에 따라 누군가는 공감해줄 것이고, 누군가는 관심이 없을 수 있어요. 그래서 한 번 실패하더라도 포기하지 않고 회사 내에서 관심 있는 사람을 찾을 때까지 여러 방법을 모색해 봐야죠. 링크드인에서 검색을 해서 알아볼 수도 있고, 소개를 받아 연락을 해봐야 할 수도 있어요. 꾸준히 노력해야 하고 공격적으로 제안서를 들이대는 걸 부끄러워하지 않아야 한다고 생각해요. 그렇지만 분명히 지금 뿌린 씨앗은 나중에 저에게 열매가 돼 돌아온다고 생각해요. 하나의 제휴가 마무리될 때까지 짧으면 3개월 길면 몇 년씩 걸리거든요. 실제로 최근에 정말 큰 제휴를 하게 되었는데, 지나고 보니 이 제휴 건은 약 2년이 넘게 걸렸어요. 지금 당장 거절을 하더라도 시간이 흐른 뒤 회사 상황과 전략이 바뀌면서 다시 버즈빌을 찾는 경우도 있으니까요. 성과가 바로바로 보이지 않아서 막막하고 조급할 수도 있지만 계속 밀고 나가야 합니다.  #커뮤니케이션  글로벌 사업 개발 매니저는 퍼블리셔에게는 버즈빌을 대표하는 인물이자, 내부적으로는 Product Manager, Technical Account Manager 등의 프로젝트의 이해관계자를 설득하고 또 의견을 조율해야 하는 중요한 포지션이에요. 퍼블리셔에게 약속한 것을 일정에 맞추어 제공할 수 있어야 하고 또 거꾸로 불가능한 것을 약속하지 않으려면 프로젝트 관리 능력과 커뮤니케이션 능력이 필수적이에요. 게다가 글로벌 퍼블리셔들의 경우 대부분 영어, 혹은 그 외 외국어로 소통을 해야하니 외국어 능력도 반드시 갖추어야 하지요.. 때로는 기술적인 부분에 대한 논의도 많이 이루어지지만 반드시 기술적인 배경 지식이나 경험을 가지고 있지 않아도 됩니다. 기술적인 부분에 대한 관심을 갖고, 이해하려는 의지만 있다면 충분한 것 같아요. 기술적인 부분은 Product Manager와 Technical Account Manager가 도와줄 수 있으니 충분히 하나의 팀으로 움직일 수 있거든요. 현재 어떤 포지션을 뽑고 있나요? (2018년 11월 기준) 현재 글로벌 사업 개발 매니저를 뽑고 있는데요. 서울에 베이스를 두고 일하실 분과 버즈빌의 도쿄 오피스에서 일하실 분을 찾고 있습니다. 일본 시장은 로컬색이 짙은 시장이기 때문에 일본 오피스는 일본의 파트너사를 발굴하는 데에만 집중합니다. 일본 현지 분을 가장 선호하지만, 일본에 오래 거주하신 한국 분에게도 기회는 열려있습니다. 서울에 기반을 두고 함께하실 분은 전 세계 파트너사를 발굴하는 일을 하게 됩니다. 한 사업을 시작해서 매듭짓는 과정까지 모두 체험해보고 싶은 분, 글로벌 사업이라는 담대한 목표를 함께 성취해보고 싶은 분이라면 꼭 지원해 주세요!   *버즈빌은 현재 채용 중입니다. (전문연구 요원 포함) 자세한 내용은 아래 버튼을 눌러주세요!
조회수 4792

플랫폼 산업의 발전과 온라인 광고시장의 변화

핀테크 시장에는 P2P, 송금, 결제, 보안 등 다양한 카테고리가 있다. 해당 카테고리마다 성격은 다르지만, 대부분 '플랫폼 비즈니스'라는 공통된 특징을 가지는데, 그 중 플랫폼 비즈니스와 함께 성장한 온라인 광고 시장에 대해 더 살펴보자.  플랫폼 비즈니스와 광고 시장의 연관성  플랫폼 서비스는 인터넷 발전과 함께 다양하고, 빠르게 성장했다. 플랫폼 서비스는 양면 시장 구조로, '플랫폼'이라는 네트워크를 통해 서로 다른 집단을 연결시켜주는 시장을 뜻한다. 대표적인 예로 개인과 개인을 연결하는 '페이스북', 유휴차량과 승객을 연결하는 '우버', 숙박공간과 여행자를 연결하는 '에어비앤비' 등이 있다. 인터넷 플랫폼은 양면 시장 구조(출처=미래에셋대우 리서치센터)플랫폼, 수수료 외에 광고 수익모델이 필요  플랫폼 비즈니스의 주요 수익모델은 바로 중개 수수료다. 하지만 중개 수수료 모델은 시장에서 한 기업이 독점하지 않는 이상 수수료율을 높게 책정할 수 없다. 이에 많은 플랫폼은 중개 수수료 외에 다른 수익 모델을 찾는다. 문제는 많은 플랫폼 서비스가 높은 트래픽을 보유하고 있지만, 뚜렷한 수익모델을 찾지 못한다. 이 때 플랫폼 기업들은 일반적으로 자사 플랫폼에 광고를 붙이는 방식을 선택한다. 사실 이 수익모델도 이용자와 광고주를 연결한다는 부분에서 플랫폼 서비스 본질과 같다.  때문에 이제는 광고가 플랫폼 산업의 주요한 수익 모델로 자리잡는 중이다. 대부분의 플랫폼 서비스가 '일단 사용자를 많이 모은 후, 광고로 수익을 내자'는 계획으로 시장에 진입, 그 결과 온라인 광고시장은 폭발적으로 성장 중이다. 게다가 기존 온라인(모바일+PC인터넷) 광고 시장은 PC를 중심으로 운영되었지만, 스마트폰 등장 이후 모바일 광고 시장은 빠르게 성장했다. 다만, 온라인 광고 시장은 다른 광고 매체와 비교해 상대적으로 짧은 시간동안 급성장해, 생태계는 이제 막 형성되는 단계다. 그럼에도 확실한 것은 온라인 광고 매체 파급력은 그 어느 매체보다 강력하다는 점이다.  온라인 광고 시장 초기에는 퍼블리셔(홈페이지 운영 기업)와 광고주(광고를 요청한 기업)가 직접 연락해 자료나 게재 위치, 광고 단가 등을 합의하고 진행했다. 하지만, 온라인 광고 시장 규모가 커질수록 퍼블리셔들은 사용자를 유입시키는 주요 사업 모델이 아닌 광고를 관리하는 요소가 늘어나며 부담이 커졌다. 광고주가 바뀔 때마다 필요한 수정 작업과 코드 변경 작업 등이 점점 업무 강도를 높이고 있는 것. 이에 업무 비효율성이 증가했으며, 사이트 내 게재 광고가 많아지면서 퍼블리셔가 일일이 개별 광고 데이터를 분석하기도 어려워졌다.  방송통신 광고비 조사 결과(출처=한국방송광고진흥공사)광고를 쉽고 효율적으로 관리하는 애드서버 등장  이를 해결하기 위해 애드서버(AD server)가 등장했다. 퍼블리셔는 애드서버를 통해 많은 광고를 쉽고 효율적으로 관리할 수 있고, 애드서버는 퍼블리셔에게 일정 수수료를 받는다. 애드서버는 광고주 문제도 해결했다. 이제는 광고주도 다양한 퍼블리셔에 광고를 내고 싶기에 애드서버를 활용한다. 결국, 퍼블리셔와 광고주 모두를 위한 각각의 애드서버가 등장한다.  인터넷이 발전하면서 퍼블리셔와 광고주는 각각의 애드서버를 통해 편리하게 광고를 집행고, 보다 효율적으로 관리할 수 있도록 변화했다. 쉽게 말하자면, 애드서버는 광고주와 퍼블리셔가 광고를 진행하기 위한 하나의 툴이다. 퍼블리셔는 애드서버에 특정 조건을 설정한 광고 인벤토리(광고가 노출되는 영역)를 등록해 광고를 송출하고, 광고주는 애드서버에 광고를 등록해 매체에서 진행되는 광고 노출횟수나 결과값 등을 통합 관리하는 것.  하지만, 애드서버도 결국 퍼블리셔와 광고주의 업무를 덜어줄 뿐, 광고 효율을 위해 퍼블리셔와 광고주를 연결하는 데는 한계가 존재한다. 애드서버의 한계, 애드네트워크가 해결  당연히 광고주는 여러 퍼블리셔에 자사의 애드서버를 연결, 광고 노출 효과를 높이고 싶어한다. 하지만, 광고주가 수많은 퍼블리셔 중에서 직접 자사 광고에 적합한 퍼블리셔를 찾기 어렵고, 퍼블리셔와 각기 다른 애드서버를 통해서 광고를 집행할 경우 서버연동 문제 등이 발생했다. 퍼블리셔 또한, 한 광고주의 광고만 노출시키는 것보다 여러 광고주의 광고를 집행해 자사 매체에 가장 적합한 광고로 광고수익을 높이길 원한다. 때문에 광고주가 증가하면서 퍼블리셔도 서버연동에 문제가 발생했다. 여러 사용자들이 각각 사용하는 애드서버 툴마다 독립적으로 운영되면서, 연동하는 과정에 문제가 발생한 것. 이 문제를 해결해기 위해 등장한 것이 애드네트워크다. 애드네트워크란, 여러 퍼블리셔와 여러 광고주를 적합하게 매칭할 수 있는 환경을 조성하는 서비스다. 수많은 퍼블리셔들이 보유한 광고 인벤토리를 확보, 이를 상품화해 광고주에게 제공한다. 이를 통해 광고주는 자사가 원하는 형식의 광고를 직접 선택할 필요 없이 설정을 통해 다양한 매체에 광고를 집행할 수 있다. 퍼블리셔도 자사와 같은 애드네트워크를 이용하는 광고주가 증가할수록 다수의 광고를 확보할 수 있다. 애드네트워크 종류로는 구글의 'GDN', 다음카카오의 'DDN', 네이버의 'ACE Trader', 페이스북의 'Audience Network' 등이 있다. IT 대기업들이 자사의 애드네트워크를 구축하기 위해 경쟁을 펼치고 있는 것. 특히, 퍼블리셔와 광고주에게 ROI를 쉽게 분석할 수 있는 'Data analytics'를 제공하거나 여러 솔루션을 같이 제공하면서 자사 애드네트워크로 제휴사들을 모으고 있다.  애드네트워크와 금융  앞서 언급한 것처럼 인터넷의 발전과 스마트폰의 등장 등으로 온라인 광고 시장은 빠르게 성장했다. 이와 함께 광고를 효율적으로 집행하기 위한 시스템도 끊임없이 발전 중이다. 이에 맞춰 새롭게 등장하고 있는 플랫폼도 변화하는 흐름에 대응해야만 한다.  플랫폼 서비스가 잊지 말아야 할 것은 광고로 수익을 내기 위해서 많은 소비자들이 해당 플랫폼을 방문해야 한다는 점이다. 즉 트래픽이 높아야 한다.  핀다는 사람들에게 좋은 금융 상품을 추천하고 노출하기 위해 효과적인 광고모델을 구축하려고 노력했다. 차별점은 애드네트워크다. 여러 금융상품 중 많은 사람이 사용하는 상품이나 서비스를 핀다 파트너 매체로 제휴, 이를 통해 금융상품 부문에서 독자적인 애드네트워크를 구축했다. 소셜 커머스 티켓몬스터와, 송금 서비스를 제공하는 토스, 개인의 금융이나 신용 정보를 제공할 수 있는 플랫폼 등과 제휴해 소비자에게 금융 상품을 알린다.  즉, 핀다의 금융상품 DB와 추천 알고리즘을 많은 소비자에게 효과적으로 노출하기 위해 서로 다른 성격의 매체에 모듈을 붙인 것. 이처럼 애드서버, 애드네트워크를 구축하기 위해 플랫폼 서비스는 많은 소비자를 확보하고, 각 서비스에서 확보한 정보를 바탕으로 추천 알고리즘을 발전시켜야 한다.  온라인 광고 생태계는 변화의 물결이 부는 곳이다. 가변성과 불확실성이 높은 만큼 새로운 광고 형태가 등장할 확률도 높다. 변화하는 흐름 속에서 뒤처지지 않기 위해서는 자사가 보유하고 있는 플랫폼 서비스의 특징과 장점을 파악해 유연하게 대응해야 하는 것을 잊지 말자.  #핀다 #스타트업 #시장분석 #광고생태계 #노하우 #인사이트
조회수 791

컴공생의 AI 스쿨 필기 노트 ④ 교차 검증과 정규화

지금까지 Linear Regression, Logistic Regression 모델을 만들어보았는데요. 우리가 만든 모델이 과연 잘 만들어진 모델이라고 볼 수 있을까요? 이를 알기 위해서 이번 4주차 수업에서는 우리가 만든 모델의 적합성을 보다 객관적으로 평가하기 위한 방법으로 교차 검증(Cross Validation)과 정규화(Regularization)를 배웠어요. 차례대로 하나씩 알아볼까요?1. Cross Validation교차 검증은 새로운 데이터셋에 대해 반응하는 모델의 성능을 추정하는 방법이에요. 학습된 모델이 새로운 데이터를 받아들였을 때 얼마나 예측이나 분류를 잘 수행하는지 그 성능을 알기 위해서는 이에 대한 추정 방식이 필요해요. 먼저 Whole population(모집단)에서 Y와 f를 구하기 위해 Training Set(모집단에서 나온 데이터셋)에서 f와 똑같지 않지만 비슷한 모델 f^를 만들어요. 그리고 이 모델을 모집단에서 나온 또 다른 데이터 셋인 Test Set을 이용하여 확인해요. 하지만 일반적으로 Test Set이 별도로 존재하는 경우가 많지 않기 때문에 Training Set을 2개의 데이터셋으로 나눠요. 이 Training Set에서 Training Set과 Test Set을 어떻게 나누느냐에 따라 모델의 성능이 달라질 수 있어요. 이런 테스트 방법을 교차 검증(Cross validation)이라고 해요.이번 시간에는 교차 검증 방법으로 LOOCV(Leave-One-Out Cross Validation)와 K-Fold Cross Validation을 알아봤어요. LOOCV(Leave-One-Out Cross Validation)LOOCV는 n 개의 데이터 샘플에서 한 개의 데이터 샘플을 test set으로 하고, 1개를 뺀 나머지 n-1 개를 training set으로 두고 모델을 검증하는 방식이에요.K-Fold Cross ValidationK-Fold CV는 n 개의 데이터를 랜덤하게 섞어 균등하게  k개의 그룹으로 나눠요. 한 개의 그룹이 test set이고 나머지 k-1개의 그룹들이 training set이 되어 k번을 반복하게 돼요. LOOCV도 n-fold CV로 볼 수 있어요!코드로 나타내기Step1. 데이터 생성 & train set과 test set  단순 분리# model selection modulefrom sklearn.model_selection import train_test_splitfrom sklearn.discriminant_analysis import LinearDiscriminantAnalysis# read datadf = pd.read_csv('data/data01_iris.csv')data = df.iloc[:,:-1].as_matrix()target = df['Species'].factorize()[0]LOOCV와 K-Fold CV에 사용할 데이터를 구하는 코드에요. data 파일 안의 data01.csv 파일을 읽어서 데이터 프레임 형태로 가져와요.df(데이터 프레임) 안에는 이와 같은 105개의 데이터 셋이 저장되어 있어요.df(데이터 프레임)의 Sepal.Length부터 Petal.Width의 값들을 매트릭스 형태로 data에 할당해요.Species에는 ‘setosa’, ‘versicolor’, ‘virginica’ 값들이 있는데요. factorize() 을 이용하여 setosa는 0, versicolor는 1, virginica는 2로 바꿔줘요.# random splitX_train, X_test, y_train, y_test = train_test_split(            data, target, test_size=0.4, random_state=0)X_train.shape, y_train.shapeX_test.shape, y_test.shape그다음에는 data와 target 데이터를 가지고 training set과 test set으로 6:4로 나눠요.X_train.shape = (90,4),  X_test.shape = (60, 4)가 돼요.# LDA f = LinearDiscriminantAnalysis() f.fit(X_train,y_train) y_train_hat = f.predict(X_train) table_count(y_train,y_train_hat) f.score(X_train,y_train)LDA(Linear discriminant analysis)는 대표적인 확률론적 생성 모형이에요. 즉 y의 클래스 값에 따른 x의 분포에 대한 정보를 먼저 알아낸 후, 베이즈 정리를 사용하여 주어진 x에 대한 y의 확률 분포를 찾아낸다고 해요.Step2. test set 준비(1) LOOCV으로 test set 준비# leave-one-out  from sklearn.model_selection import LeaveOneOutloo = LeaveOneOut()loo.get_n_splits(X_train)scv = []for train_idx, test_idx in loo.split(X_train):    print('Train: ',train_idx,'Test: ',test_idx)    f.fit(X_train[train_idx,:],y_train[train_idx])    s = f.score(X_train[test_idx,:],y_train[test_idx])    scv.append(s) get_n_splits() 함수를 사용하여 (90,4)의 shape을 가지는 X_train을 90개로 나눠요.test set에 0부터 89까지 하나씩 할당되고 할당된 숫자 외의 나머지 숫자들은 training set으로 모델을 검증해요. 위의 결과에서도 볼 수 있듯이 test set에 0이 할당되면 train set에는 1 ~ 89가 할당되어 모델을 검증하게 돼요!(2) K-fold CV로 test set 준비# K-fold CVfrom sklearn.model_selection import KFoldkf = KFold(5)kf.get_n_splits()scv = []for train_idx, test_idx in kf.split(X_train):    print('Train: ',train_idx,'Test: ',test_idx)    f.fit(X_train[train_idx,:],y_train[train_idx])    s = f.score(X_train[test_idx,:],y_train[test_idx])    scv.append(s) KFold(5) : 위에서 배운 k-fold 교차 검증에서 k를 5로 설정하여 우리가 가지고 있는 데이터 셋을 5개의 그룹으로 나눠서 교차 검증을 할 거예요.kf.get_n_splits()를 사용하여 5번 교차 검증할 것을 정해요.위에서 90개의 데이터셋을 5개의 그룹으로 나눴어요. 그리고 각 그룹 한 개씩 test set으로 정하고 나머지 그룹들은 training set으로 할당하고 모델을 검증해요. 예를 들어 그룹 1이 0~17, 그룹 2가 18 ~ 35, 그룹 3이 36~53, 그룹 4가 54~71, 그룹 5가 72~89라고 할 때, test set에 그룹 1을 할당하면 train set에는 그룹 2, 3, 4, 5가 할당되어 모델을 검증하게 돼요.Step3. 교차 검증 시행CV는 단순히 데이터 셋을 나누는 역할을 수행할 뿐이에요. 실제로 모형의 성능(편향 오차 및 분산)을 구하려면 이렇게 나누어진 데이터셋을 사용하여 평가를 반복해야 해요. 이 과정을 자동화하는 명령이 cross_val_score()이에요.# K-fold CVfrom sklearn.model_selection import cross_val_scoref = LinearDiscriminantAnalysis()s = cross_val_score(f,X_train,y_train,cv=3)cross_val_score(f, X_train, y_train, cv=3) : cross validation iterator cv를 이용하여 X_train, y_train을 분할하고 f에 넣어서 scoring metric을 구하는 과정을 반복해요.2. Regularization앞서 말한 우리의 목적은 우리의 데이터셋에 맞는 Y와 f를 구하는 것이었어요. f를 결정하기 위해서는 먼저 결정해야 하는 요소가 있어요. 아래 다섯 가지가 f를 결정하는 요소들이에요.- Model family : linear, neural 등 방법론 결정- Tuning parameter : 모델에 맞는 파라미터 조절 - Feature selection(특징 선택) : 많은 데이터 중 어떤 데이터를 쓸지 고르는 것 - Regularization(정규화)  - Dimension reduction(차원 축소)f를 결정하는 요소 중 Regularization(정규화)에 대해 알아볼게요!정규화 선형회귀 방법은 선형회귀 계수(weight)에 대한 제약 조건을 추가함으로써 모형이 과도하게 최적화되는 현상(과최적화, overfitting)을 막는 방법이에요. 모형이 과도하게 최적화되면 모형 계수의 크기도 과도하게 증가하는 경향이 나타나요. 따라서 정규화 방법에서 추가하는 제약 조건은 일반적으로 계수의 크기를 제한하는 방법이에요. 일반적으로 Ridge Regression, Lasso, Elastic Net 이 세 가지 방법이 사용돼요.Ridge Regression머신 러닝에서는 모델의 오차를 찾기 위해 보통 최소제곱법(Least squares fitting)을 이용하여 β를 최소화시켜요. 위의 RSS는 잔차제곱식으로 예측값과 실제 값 사이의 차이를 구하는 식이에요. 회귀분석의 계수 값을 RSS을 최소화하는 β값을 찾음으로써 구할 수 있어요.Ridge Regression은 최소제곱법에 가중치들의 제곱합을 최소화하는 것을 추가적인 제약 조건으로 갖는 방법이에요. λ는 기존의 제곱합과 추가적 제약 조건의 비중을 조절하기 위한 하이퍼 파라미터에요. λ가 크면 정규화 정도가 커지고 가중치의 값들이 작아져요. λ가 작아지면 정규화 정도가 작아지며 λ가 0이 되면 일반적인 선형 회귀 모형이 돼요.코드로는 아래와 같이 나타낼 수 있어요.from sklearn.linear_model import Ridgef = Ridge(alpha=0.5)f.fit(xtrain,ytrain)f.intercept_,f.coef_f.score(xtrain,ytrain)f.score(xtest,ytest)LassoLasso는 가중치의 절댓값의 합을 최소화하는 것을 추가적인 제약 조건으로 가져요. 아래와 같이 코드로 나타낼 수 있어요.from sklearn.linear_model import Lassof = Lasso(alpha=1.0)f.fit(xtrain,ytrain)f.intercept_,f.coef_f.score(xtrain,ytrain)f.score(xtest,ytest)Elastic NetElastic Net은 가중치의 절댓값의 합과 제곱합을 동시에 제약 조건으로 가지는 모형이에요. 코드로는 아래와 같아요.from sklearn.linear_model import ElasticNetf = ElasticNet(alpha=0.1,l1_ratio=0.5)f.fit(xtrain,ytrain) f.intercept_,f.coef_f.score(xtrain,ytrain)f.score(xtest,ytest)Lasso와 Ridge Regression의 차이점왼쪽 : Lasso, 오른쪽 Ridge Regression위의 두 그림은 Lasso와 Ridge Regression의  차이점을 잘 나타내는 그림이에요. 초록색 부분은 회귀계수(회귀분석에서 독립변수가 한 단위 변화함에 따라 종속변수에 미치는 영향력 크기)가 가질 수 있는 영역이고 빨간색 원은 RSS가 같은 지점을 연결한 것을 보여주는 것으로 가운데로 갈수록 오차가 작아져요.Lasso와 Ridge Regression 모두 RSS를 희생하여 계수를 축소하는 방법이라는 공통점이 있어요.하지만 Ridge Regression과 Lasso의 가장 큰 차이점은 Ridge 회귀는 계수를 축소하되 0에 가까운 수로 축소하는 반면, Lasso는 계수를 완전히 0으로 축소화한다는 점이에요.Cross validation(교차 검증)과 Regularization(정규화)에 대해 알아보았는데요. 간단히 요약해 볼게요.Cross validation(교차 검증)은 머신러닝 모델의 타당성을 검증하는 방법 중의 하나로, 특정 데이터를 training set과 test set으로 분할한 뒤 training set을 활용해 학습하고 test set으로 테스트하여 학습의 타당성을 검증하는 방법이에요. 교차 검증에는 여러 가지 방법이 있는데 그중에서도 우리는 LOOCV와 K-Fold CV를 배웠어요.Regularization(정규화)는 모델의 일반화 오류를 줄여 과적합을 방지하는 방법을 말해요. 일반적으로 Ridge Regression, Lasso, Elastic Net 이 세 가지 방법을 사용해요.이상적인 머신러닝 모델을 만들기 위해 고려해야 할 점들은 정말 많은 것 같아요. 우리가 만든 모델이 적합한 모델인지 이번 수업시간에 배운 교차 검증과 정규화를 통해 잘 살펴봐요!* 이 글은 AI스쿨 - 인공지능 R&D 실무자 양성과정 4주차 수업에 대하여 수강생 최유진님이 작성하신 수업 후기입니다.
조회수 1048

컴공생의 AI 스쿨 필기 노트 ⑥인공신경망

인공지능, 머신러닝, 딥러닝이번 6주차 AI 스쿨에서는 딥러닝의 가장 기초적인 부분을 배웠어요. 인공지능과 머신러닝, 그리고 딥러닝을 많이 들어보긴 했는데 이 셋의 차이는 무엇일까요?인공지능이라는 개념은 1956년 미국 다트머스 대학에 있던 존 매카시 교수가 개최한 다트머스 회의에서 처음 등장했고 최근 몇 년 사이 폭발적으로 성장하고 있는 중이에요. 1956년 당시 인공지능의 선구자들이 꿈꾼 것은 최종적으로 '인간의 지능과 유사한 특성을 가진 복잡한 컴퓨터'를 제작하는 것이었죠. 이렇듯 인간의 감각, 사고력을 지닌 채 인간처럼 생각하는 것을 인공지능이라고 해요.인공지능은 위 세 개념 중 가장 큰 개념이에요. 머신러닝은 일반적으로 사람들이 이야기하는 인공지능, 즉 머신러닝에 기반한 인공지능을 말하는데요. 인공지능을 구현하는 구체적인 접근 방식이라고 할 수 있어요.머신러닝에는 linear regression, logistic regression 등의 여러 알고리즘이 있는데요.  그중 학습에 사용되는 모델을 딥러닝이라고 해요. 즉 딥러닝은 완전한 머신러닝을 실현하는 기능이라고 볼 수 있어요. 이러한 딥러닝의 등장으로 인해 머신러닝의 실용성은 강화됐고 인공지능의 영역은 확장됐다고 해요.인공 신경망(Neural Network)오늘 수업의 핵심인 인공 신경망(Neural Network)은 어떻게 만들어졌을까요?뉴런의 구조이것은 우리 몸에 존재하는 신경세포인 뉴런이에요. 뉴런은 전기적인 신호를 전달하는 특이한 세포인데 뇌는 뉴런의 집합체라고 할 수 있어요. 뉴런은 수상 돌기(dendrites, input)에서 신호를 받아들이고 축색 돌기(axon terminals, output)에서 신호를 전송해요. 신호가 전달되기 위해서는 일정 기준(임곗값 : threshold) 이상의 전기 신호가 존재해야 해요. 이 신호들의 전달을 통해서 정보를 전송하고 저장해요.이런 신경세포로 이뤄진 신경망 시스템을 위의 그림처럼 표현할 수 있어요. 이처럼 인공신경망은 사람 몸속의 신경들을 모방해서 만든 시스템이에요.위의 식처럼 뉴런을 수학적으로 표현할 수 있는데요. 입력 값들(X)에 가중치를 두어(W) 값 (f(x))을 구하고 그 값과 임계치와의 관계를 활성함수(active function)*로 판단하여 결괏값을 출력하게 돼요.( * 활성함수는 인공신경망의 개별 뉴런에 들어오는 입력신호의 총합을 출력 신호로 변환하는 함수로 비선형 함수(non-linear function)를 씁니다.**)이때 활성함수는 뉴런에서 임곗값을 넘었을 때만 출력하는 부분을 표현한 것으로 sigmoid 함수, Relu 함수 등 여러 방식이 있어요.인공 신경망의 구조인공 신경망 구조는 위의 그림처럼 나타낼 수 있어요. 인공 신경망 구조는 입력층(input layer), 은닉층(hidden layer), 출력층(output layer)으로 이루어져 있어요. 위의 그림은 그 구조에 의해 3-layer Neural Network 또는 2-hidden-layer Neural Network라 부를 수 있는데요. 3-layer Neural Network는 3개의 층을 가지는 인공신경망이라는 뜻이고, 위 그림에서는 은닉층1, 은닉층2, 출력층이 해당되겠죠. 인공 신경망에 입력층과 출력층은 항상 존재하기 때문에 은닉층의 개수만을 고려하여 부르기도 해요. 위 그림에서는 은닉층이 2개 있기 때문에 2-hidden-layer Neural Network라고 부를 수 있어요. 전파(Propagation)이번에는 실제로 학습하는 과정인 인공신경망의 알고리즘에 대해 알아볼게요. 순전파(Forward Propagation)와 역전파(Backward Propagation)가 있어요.순전파는 입력값에서 출력값으로 가중치를 업데이트를 하고 활성화 함수를 통해서 결괏값을 가져오는 것을 말해요. 인공신경망이 설계된 정방향(input → hidden → output)으로 데이터가 흘러가기 때문에 순전파라고 해요. 말 그대로 입력값을 앞쪽으로 보낸다고 생각하면 돼요.역전파는 출력값을 통해서 역으로 입력값 방향으로 오차를 다시 보내며 가중치를 재 업데이트하는 것이에요. 출력값에서 계산된 오차에 가중치를 사용해 바로 이전 층의 뉴런들이 얼마나 오차에 영향을 미쳤는지 계산해요. 결과에 영향을 많이 미친 뉴런일수록 더 많은 오차를 돌려줘요.개념을 코드에 적용하기NumPy로 구현된 Neural Network(이하 NN)의 작동 방법을 살펴볼게요. NN은 총 2개의 레이어로 이루어져 있어요. 이번 과제에서는 입력 x가 들어왔을 때, 레이블에 따라 예측치가 1로 수렴하는지 알 수 있는 인공신경망을 구현하는 것이 목적이에요.Neural Network다음 코드는 simpleNueralNet() 클래스를 나타내는 코드예요. simpleNueralNet()은 두 개의 레이어로 구성된 NN이에요.N, D_in, H, D_out = 64, 1000, 100, 10- N은 batch size, 즉 한 번에 처리할 수 있는 데이터 사이즈를 말해요. - D_in은 입력값 차원에 쓰이는 값으로 1000을 할당해요.- H는 은닉층 차원에 쓰이는 값으로 100을 할당해요.- D_out은 출력값 차원에 쓰이는 값으로 10을 할당해요.아래 코드를 통해서 랜덤 입력과 출력 데이터를 만들어요.x = np.zeros((N, D_in))     #1  x.fill(0.025)                         #2y = np.ones((N, D_out))   #31. np.zeros() 함수를 사용하여 (64, 1000)의 차원을 갖는 0인 행렬을 만들어요.2. fill() 함수를 통해 x 안의 모든 0을 0.025로 바꿔요.3. np.zeros() 함수를 사용해 (64, 10)의 차원을 갖는 0인 행렬을 만들어요.아래는 랜덤 값을 갖는 가중치(weight)들을 초기화하는 코드예요. w1은 1000, 100 차원의 랜덤 값을 갖는 행렬로, w2는 100, 10차원의 랜덤 값을 갖는 행렬로 만들어요.w1 = np.random.randn(D_in, H)   w2 = np.random.randn(H, D_out)learning_rate는 학습 속도를 의미해요. 아래는 단계별로 움직이는 학습 속도를 1e-6으로 정의하는 코드예요.learning_rate = 1e-6이제 5000번의 순전파를 할 거예요.h = x.dot(w1)     h_relu = relu(h)  y_pred = h_relu.dot(w2)h는 은닉층에 전달할 값이에요. x와 w1을 행렬곱한 값을 가져요.활성 함수 relu에 h를 넣어서 계산해요.y_pred는 예상되는 출력값이에요. relu로 계산된 h_relu와 가중치 w2를 행렬곱한 값이에요.아래는 순전파로 얻은 y_pred에서 진짜 y를 뺀 값을 제곱한 것의 합을 구해 손실 값(loss)을 구하는 코드예요. print(loss) 코드로 손실을 확인할 수 있어요.loss = np.square(y_pred - y).sum()순전파 후 역전파를 이용해 손실에 대한 가중치 w1과 w2의 gradients를 계산하여 update 할 거예요.grad_y_pred = 2.0 * (y_pred - y)              #1grad_w2 = h_relu.T.dot(grad_y_pred)    #2grad_h_relu = grad_y_pred.dot(w2.T)    #3grad_h = grad_h_relu.copy()                    #4grad_h[h < 0>grad_w1 = x.T.dot(grad_h)                         #61. 순전파로 얻은 y_pred에서 진짜 y값을 뺀 값에 2.0을 곱하여 grad_y_pred를 구해요.2. grad_w2는 순전파에서 y_pred = h_relu.dot(w2) 식을 사용했으므로  h_relu.T.dot(grad_y_pred) 로 구해요. h_relu가 반대로 곱해지기 때문에 T를 이용하여 shape을 바꿔줘야 해요.3. grad_h_relu는 방금 위에서 사용한 y_pred = h_relu.dot(w2)을 이용하여 grad_y_pred.dot(w2.T) 로 구해요. 이번에는 w2 shape의 반대를 grad_y_pred에 곱해줘야 해요.4. 순전파에서 h_relu = relu(h)였는데요. 역전파에선 grad_h와 grad_h_relu가 같기 때문에 copy() 함수로 그대로 복사해요!5. 0보다 작은 h는 0으로 만들어요.6. 가중치 w1의 값인 grad_w1은 순전파의 h = x.dot(w1)와 반대로 x.T.doT(grad_h) 곱해요. 역전파는 순전파의 식에서 이항한다고 생각하면 조금 더 쉽게 이해할 수 있을 것 같아요. 이항한 값은 .T를 붙여서 표현한다고 생각하면 될 것 같아요.아래는 가중치를 재업데이트하는 코드예요.w1 -= learning_rate * grad_w1 w2 -= learning_rate * grad_w2 과제1을 통하여 NN을 알아보았는데요. 복잡하지만 순전파와 역전파를 알고 있다면 많이 어렵지는 않은 것 같아요. 과제 2는 정확도를 95% 이상으로 만들어보는 과제인데 여러 가지 방법을 동원해서 풀어보는데 생각보다 쉽지가 않아요. ^^;이번 수업시간에 배운 딥러닝의 기초인 신경망은 굉장히 중요한 개념이라고 해요. 신경망을 기반으로 한 딥러닝을 강화하여 안면인식을 가능하게 하거나 저장된 데이터를 정확하게 인식하고 분류할 수 있는 기기들도 만들어지고 있어요. 이처럼 AI는 점진적으로 활용 범위가 넓어지고 있기 때문에 이 수업을 통해 쌓은 AI 지식을 마음껏 뽐낼 수 있는 날이 왔으면 좋겠어요!** 왜 활성함수로 비선형 함수를 쓸까요?선형함수인 h(x)=cx를 활성함수로 사용한 3-layer 네트워크를 생각해봐요. 이를 식으로 나타내면 y(x) = h(h(h(x)))가 되는데요.  이는 y(x) = c3x와 같습니다.  이렇게 활성함수로 선형함수를 사용하면 은닉층을 사용하는 이점이 없어요.* 이 글은 AI스쿨 - 인공지능 R&D 실무자 양성과정 6주차 수업에 대해 수강생 최유진님이 작성하신 수업 후기입니다.
조회수 1103

블랭크 소식을 볼 수 있는 곳을 모았습니다.

올해 여름에 나간 블랭크 뉴스 인터뷰 이후에 블랭크 소식이 궁금하다 라는 지인의 연락이 있었는데요. 예전보다 다양한 곳에서 블랭크 이야기를 들을 수 있어서 편하게 보실 수 있게 한방에 정리해보았습니다. 그리고 자주 업데이트 예정입니다. (최근 업데이트: 2018.9.1) 첫번째, 블랭크코퍼레이션 웹사이트 http://blankcorp.kr/블랭크 공식사이트인 만큼 블랭크에서 어떤 브랜드를 만드는지, 어떤 문화를 가지고 있는지, 어디에 위치했는지 보실 수 있습니다. 두번째, 블랭크코퍼레이션 웹사이트 내 Career 파트 http://blankcorp.kr/sp.php?p=51함께 하고 싶거나 블랭크스러운 주변 지인을 추천할 때 어떤 오픈포지션이 있는지 궁금하다면 이 곳을 확인해주세요. 각 유닛별 실시간 오픈포지션과 상세 잡디스크립션이 있습니다. 세번째, 비즈한국 인터뷰 기사 http://www.bizhankook.com/bk/article/15787남대광 대표 최초 인터뷰 "블랭크는 디지털 방문판매 회사"연매출 1500억 노리는 3년 차 스타트업…"파격적 직원 복지는 생존 위한 것"www.bizhankook.com 최근에 나온 기사로 (2018.7) 올해의 블랭크가 어떤 비전을 보고 있고, 어떤 문화를 가지고 있는지 자세하게 다뤄주셨습니다. 네번째, 블랭크오피스(아남타워)에 대한 글  https://brunch.co.kr/@mupasa324/16어떤 공간에서 일하는가 (1)시너지를 내는 오피스, 끊임없는 실험과 투자 | 어떤 공간에서 휴식을 취하고, 어떤 공간에서 회의를 하는가 공간이 주는 에너지가 있다. 분명 이 에너지는 업무의 효율을 높이고 시너지를 창출한다.사람을 연구한다. 삶의 빈 곳을 찾아보고 그곳을 메울 수 있을지 고민한다. 치열하고 빠르게 변해가는 세상, 사람은 반드시 무언가(빈, blank)를 놓칠 수 있다. “우리는 그것을 해결하는 조직이다”Lifestylbrunch.co.kr/@mupasa324/16 공간에는 그 공간을 사용하는 사람의 생각이 담긴다고 하죠. 블랭커(블랭크 피플)이 어떤 공간에서 일을 하는지, 어떤 가치관이 공간에 깃들었는지 궁금하시다면 이 글을 읽어주세요. 다섯번째, 블랭커(블랭크 멤버)의 이야기들 https://www.facebook.com/b.ple.say/비플세이비플세이. 좋아하는 사람 145명. 사람들 일상의 빈 곳(블랭크)을 찾고, 효과적인 상품 솔루션을 제안하는! 우리는 블랭크코퍼레이션 입니다! 우리의 인사이트를 나눕니다www.facebook.com 다양성을 중시하는 블랭크에는 재밌는 경험, 취미 등을 가진 분들이 많습니다. 산티아고 순례길을 다녀오신 분, 블랭크에서 배운 것을 연재하는 분, 대만을 일러스트와 함께 소개해주시는 분 등 다양한 블랭커의 이야기를 보고 들을 수 있는 공간입니다. 블랭크에 어떤 분이 있는지, 어떤 생각을 하고 사는지는 이 페이지를 팔로팔로!여섯번째, 블랭크의 소소한 이야기 연재하는 브런치  https://brunch.co.kr/magazine/startupblank블랭크의 소소한 이야기 매거진#스타트업 #성장 #블랭크brunch.co.kr/magazine/startupblank 블랭크에서 겪는 일상과 배움에 대한 소소한 글이 있습니다. 블랭크의 문화를 잘 :)   일곱번째, 블랭크와 파트너사 간의 상생이야기를 연재하는 블로그http://blankcorp.blog.me/221282132268[블랭크코퍼레이션 상생 스토리.01] 더 나은 샤워기를 위하여 - 성일화학 | 바디럽 퓨어썸 샤워기제조사와 같이 블랭크는 좋은 기술과 제품을 보유한 제조사를 발굴하고, 그들과 함께 생활의 문제에 대해 ...blog.naver.com http://blankcorp.blog.me/221291960780[블랭크코퍼레이션 상생 스토리.02] 세탁조 클리너에 담은 하나된 마음! -그린코스/서울에프엔씨 | 공백세탁조크리너제조사와 같이 블랭크는 좋은 기술과 제품을 보유한 제조사를 발굴하고, 그들과 함께 생활의 문제에 대해 ...blog.naver.com 블랭크의 샤워기, 세탁조클리너, 핌스프레이 등 히트 제품을 어떻게 만들고, 파트너사와 커뮤니케이션 하면서 성장했는지에 대한 연재글입니다. 감사합니다. 장아라blankcorp
조회수 1190

레진 기술 블로그 - 자바 기반의 백엔드와의 세션 공유를 위한 레일즈 세션 처리 분석

레일즈 기반의 프론트엔드(브라우저에서 서버 사이드 렌더링 계층까지)와 자바 기반의 백엔드(내부 API와 그 이후 계층)이 세션을 공유하기 위해 먼저 레일즈의 세션 처리 과정을 분석하고, 레일즈 세션 쿠키를 다루기 위한 자바 소스 코드를 공유합니다.여기저기 자랑하고 다녔으니 아시는 분은 아시다시피 레진은 구글앱엔진을 사용하고 있습니다. 지금이야 Java, Python, Node.js, Go 언어와 Flexible Environment 같은 다양한 선택지가 있지만, 레진이 입주할 당시만 해도 Java 7(subset), Python(subset)을 지원하는 Standard Environment라는 선택지 밖에 없었죠.최근 Saemaeul Undong 기술 부채 탕감의 일환으로 자바7, 스프링3.x, JSP(!) 기반의 백엔드에 포함되어 있던 프론트엔드를 레일즈 기반의 프론트엔드 서버(서버 사이드 렌더링을 담당하는 서버는 프론트일까요? 백엔드일까요?)로 분리하고 있습니다.서로 다른 세계의 존재들 - 자바와 레일즈의 세션을 공유해야하는 상황이 문제의 발단입니다.자바와 레일즈의 세션을 공유하는 여러가지 방법이 있겠지만, 가장 단순하고 효과적인 방법은 쿠키(cookie)라고 판단하고, 세션 encrypt/decrypt와 marshal/unmarshal을 동일한 방식으로 맞추기로 했습니다. (백엔드 API를 완전히 stateless하게 새로 만들면 좋겠지만, 코인은 벌어야 소는 키워야죠)이를 위해 레일즈의 세션 처리 과정을 분석하고 정리했습니다.레일즈의 actionpack의 action_dispatch/middleware/cookie.rb를 보면 EncryptedCookieJar 클래스의 초기화 과정은 다음과 같습니다(digest의 경우 따로 지정안하면 SHA1이 사용되는 듯):class EncryptedCookieJar < AbstractCookieJar # :nodoc: include SerializedCookieJars def initialize(parent_jar) super if ActiveSupport::LegacyKeyGenerator === key_generator raise "You didn't set secrets.secret_key_base, which is required for this cookie jar. " + "Read the upgrade documentation to learn more about this new config option." end secret = key_generator.generate_key(request.encrypted_cookie_salt || '') sign_secret = key_generator.generate_key(request.encrypted_signed_cookie_salt || '') @encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, digest: digest, serializer: ActiveSupport::MessageEncryptor::NullSerializer) end private def parse(name, encrypted_message) debugger deserialize name, @encryptor.decrypt_and_verify(encrypted_message) rescue ActiveSupport::MessageVerifier::InvalidSignature, ActiveSupport::MessageEncryptor::InvalidMessage nil end def commit(options) debugger options[:value] = @encryptor.encrypt_and_sign(serialize(options[:value])) raise CookieOverflow if options[:value].bytesize > MAX_COOKIE_SIZE end end key_generator는 EncryptedCookieJar에 포함된 SerializedCookieJars 모듈에 정의되어 있습니다:module SerializedCookieJars # ... def key_generator request.key_generator end end 흠… 좀 더 파보죠. request.key_genrator는 다음과 같습니다:class Request # ... def key_generator get_header Cookies::GENERATOR_KEY end #... end 흠… 좀 더 파야할 듯 ㅠㅠ.Cookies::GENERATOR_KEY는 다음과 같습니다:class Cookies #... GENERATOR_KEY = "action_dispatch.key_generator".freeze end action_dispatch.key_generator는 레일즈의 엔진 모듈에 해당하는 railties의 application.rb에 정의되어 있습니다:def key_generator # number of iterations selected based on consultation with the google security # team. Details at https://github.com/rails/rails/pull/6952#issuecomment-7661220 @caching_key_generator ||= if secrets.secret_key_base unless secrets.secret_key_base.kind_of?(String) raise ArgumentError, "`secret_key_base` for #{Rails.env} environment must be a type of String, change this value in `config/secrets.yml`" end key_generator = ActiveSupport::KeyGenerator.new(secrets.secret_key_base, iterations: 1000) ActiveSupport::CachingKeyGenerator.new(key_generator) else ActiveSupport::LegacyKeyGenerator.new(secrets.secret_token) end end # ... def env_config @app_env_config ||= begin validate_secret_key_config! super.merge( # ... "action_dispatch.key_generator" => key_generator, "action_dispatch.signed_cookie_salt" => config.action_dispatch.signed_cookie_salt, "action_dispatch.encrypted_cookie_salt" => config.action_dispatch.encrypted_cookie_salt, "action_dispatch.encrypted_signed_cookie_salt" => config.action_dispatch.encrypted_signed_cookie_salt, "action_dispatch.cookies_serializer" => config.action_dispatch.cookies_serializer, "action_dispatch.cookies_digest" => config.action_dispatch.cookies_digest ) end end 너무 깊이 판 느낌적느낌(?)이 있지만, 여기까지 왔으니 좀 더 파보겠습니다.핵심 알고리즘은 activesupport의 key_generator.rb, message_encryptor.rb, message_verifier.rb에 정의되어 있습니다.먼저, key_generator.rb의 핵심은 다음과 같습니다:class KeyGenerator def initialize(secret, options = {}) @secret = secret # The default iterations are higher than required for our key derivation uses # on the off chance someone uses this for password storage @iterations = options[:iterations] || 2**16 end # Returns a derived key suitable for use. The default key_size is chosen # to be compatible with the default settings of ActiveSupport::MessageVerifier. # i.e. OpenSSL::Digest::SHA1#block_length def generate_key(salt, key_size=64) OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size) end end 계속해서, message_encryptor.rb의 핵심은 다음과 같습니다:def initialize(secret, *signature_key_or_options) options = signature_key_or_options.extract_options! sign_secret = signature_key_or_options.first @secret = secret @sign_secret = sign_secret @cipher = options[:cipher] || 'aes-256-cbc' @verifier = MessageVerifier.new(@sign_secret || @secret, digest: options[:digest] || 'SHA1', serializer: NullSerializer) @serializer = options[:serializer] || Marshal end def _encrypt(value) cipher = new_cipher cipher.encrypt cipher.key = @secret # Rely on OpenSSL for the initialization vector iv = cipher.random_iv encrypted_data = cipher.update(@serializer.dump(value)) encrypted_data << cipher.final "#{::Base64.strict_encode64 encrypted_data}--#{::Base64.strict_encode64 iv}" end def _decrypt(encrypted_message) cipher = new_cipher encrypted_data, iv = encrypted_message.split("--".freeze).map {|v| ::Base64.strict_decode64(v)} cipher.decrypt cipher.key = @secret cipher.iv = iv decrypted_data = cipher.update(encrypted_data) decrypted_data << cipher.final @serializer.load(decrypted_data) rescue OpenSSLCipherError, TypeError, ArgumentError raise InvalidMessage end def encrypt_and_sign(value) verifier.generate(_encrypt(value)) end def decrypt_and_verify(value) _decrypt(verifier.verify(value)) end (Hopefully)마지막으로, message_verifier.rb의 핵심은 다음과 같습니다:def initialize(secret, options = {}) raise ArgumentError, 'Secret should not be nil.' unless secret @secret = secret @digest = options[:digest] || 'SHA1' @serializer = options[:serializer] || Marshal end def valid_message?(signed_message) return if signed_message.nil? || !signed_message.valid_encoding? || signed_message.blank? data, digest = signed_message.split("--".freeze) data.present? && digest.present? && ActiveSupport::SecurityUtils.secure_compare(digest, generate_digest(data)) end def verified(signed_message) if valid_message?(signed_message) begin data = signed_message.split("--".freeze)[0] @serializer.load(decode(data)) rescue ArgumentError => argument_error return if argument_error.message =~ %r{invalid base64} raise end end end def generate(value) data = encode(@serializer.dump(value)) "#{data}--#{generate_digest(data)}" end private def encode(data) ::Base64.strict_encode64(data) end def decode(data) ::Base64.strict_decode64(data) end def generate_digest(data) require 'openssl' unless defined?(OpenSSL) OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@digest).new, @secret, data) end # ... # encode, decode는 base64사용 이제 레일즈가 쿠키 기반의 세션을 어떻게 처리하는지 조금 눈에 들어옵니다. 그러나 우리의 최종 목표는 레일즈의 내부를 공부하는 것이 아니라, 자바에서 동일한 처리를 하는 것입니다. 모듈 의존성 따위는 가볍게 무시하고 무한복붙(?)을 시전해서, 레일즈의 세션 처리 과정을 눈으로 확인할 수 있도록 재구성했습니다:require 'openssl' require 'base64' require 'concurrent/map' class Object def blank? respond_to?(:empty?) ? !!empty? : !self end def present? !blank? end end class Hash # By default, only instances of Hash itself are extractable. # Subclasses of Hash may implement this method and return # true to declare themselves as extractable. If a Hash # is extractable, Array#extract_options! pops it from # the Array when it is the last element of the Array. def extractable_options? instance_of?(Hash) end end class Array def extract_options! if last.is_a?(Hash) && last.extractable_options? pop else {} end end end module SecurityUtils def secure_compare(a, b) return false unless a.bytesize == b.bytesize l = a.unpack "C#{a.bytesize}" res = 0 b.each_byte { |byte| res |= byte ^ l.shift } res == 0 end module_function :secure_compare end class KeyGenerator def initialize(secret, options = {}) @secret = secret # The default iterations are higher than required for our key derivation uses # on the off chance someone uses this for password storage @iterations = options[:iterations] || 2**16 end def generate_key(salt, key_size=64) OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size) end end class CachingKeyGenerator def initialize(key_generator) @key_generator = key_generator @cache_keys = Concurrent::Map.new end # Returns a derived key suitable for use. def generate_key(*args) @cache_keys[args.join] ||= @key_generator.generate_key(*args) end end class MessageVerifier class InvalidSignature < StandardError; end def initialize(secret, options = {}) raise ArgumentError, 'Secret should not be nil.' unless secret @secret = secret @digest = options[:digest] || 'SHA1' @serializer = options[:serializer] || Marshal end def valid_message?(signed_message) return if signed_message.nil? || !signed_message.valid_encoding? || signed_message.blank? data, digest = signed_message.split("--".freeze) data.present? && digest.present? && SecurityUtils.secure_compare(digest, generate_digest(data)) end def verified(signed_message) if valid_message?(signed_message) begin data = signed_message.split("--".freeze)[0] @serializer.load(decode(data)) rescue ArgumentError => argument_error return if argument_error.message =~ %r{invalid base64} raise end end end def verify(signed_message) verified(signed_message) || raise(InvalidSignature) end def generate(value) data = encode(@serializer.dump(value)) "#{data}--#{generate_digest(data)}" end private def encode(data) ::Base64.strict_encode64(data) end def decode(data) ::Base64.strict_decode64(data) end def generate_digest(data) require 'openssl' unless defined?(OpenSSL) OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@digest).new, @secret, data) end end class MessageEncryptor module NullSerializer #:nodoc: def self.load(value) value end def self.dump(value) value end end class InvalidMessage < StandardError; end OpenSSLCipherError = OpenSSL::Cipher::CipherError def initialize(secret, *signature_key_or_options) options = signature_key_or_options.extract_options! sign_secret = signature_key_or_options.first @secret = secret @sign_secret = sign_secret @cipher = options[:cipher] || 'aes-256-cbc' @verifier = MessageVerifier.new(@sign_secret || @secret, digest: options[:digest] || 'SHA1', serializer: NullSerializer) @serializer = options[:serializer] || Marshal end def encrypt_and_sign(value) verifier.generate(_encrypt(value)) end def decrypt_and_verify(value) _decrypt(verifier.verify(value)) end def _encrypt(value) cipher = new_cipher cipher.encrypt cipher.key = @secret # Rely on OpenSSL for the initialization vector iv = cipher.random_iv encrypted_data = cipher.update(@serializer.dump(value)) encrypted_data << cipher.final "#{::Base64.strict_encode64 encrypted_data}--#{::Base64.strict_encode64 iv}" end def _decrypt(encrypted_message) cipher = new_cipher encrypted_data, iv = encrypted_message.split("--".freeze).map {|v| ::Base64.strict_decode64(v)} cipher.decrypt cipher.key = @secret cipher.iv = iv decrypted_data = cipher.update(encrypted_data) decrypted_data << cipher.final @serializer.load(decrypted_data) rescue OpenSSLCipherError, TypeError, ArgumentError raise InvalidMessage end def new_cipher OpenSSL::Cipher.new(@cipher) end def verifier @verifier end end #key generate encrypted_cookie_salt = 'encrypted cookie' encrypted_signed_cookie_salt = 'signed encrypted cookie' def key_generator secret_key_base = 'db1c366b854c235f98fc3dd356ad6be8dd388f82ad1ddf14dcad9397ddfdb759b4a9fb33385f695f2cc335041eed0fae74eb669c9fb0c40cafdb118d881215a9' key_generator = KeyGenerator.new(secret_key_base, iterations: 1000) CachingKeyGenerator.new(key_generator) end # encrypt secret = key_generator.generate_key(encrypted_cookie_salt || '') sign_secret = key_generator.generate_key(encrypted_signed_cookie_salt || '') encryptor = MessageEncryptor.new(secret, sign_secret, digest: 'SHA1', serializer: MessageEncryptor::NullSerializer) value = "{\"session_id\":\"6022d05887d2ab9c1bad8a87cf8fb949\",\"_csrf_token\":\"OPv/LxbiA5dUjVsbG4EllSS9cca630WOHQcMtPxSQUE=\"}" encrypted_message = encryptor.encrypt_and_sign(value) #encrypted_message = encryptor._encrypt(value) p '-----------encrypted value-------------' p encrypted_message # decrypt encrypted_message = 'bDhIQncxc2k0Rm9QS0VBT0hWc3M4b2xoSnJDdkZNc1B0bGQ2YUhhRXl6SU1oa2c5cTNENWhmR0ZUWC9zN05mamhEYkFJREJLaDQ3SnM3NVNEbFF3ZVdiaFd5YXdlblM5SmZja0R4TE9JbDNmOVlENHhOVFlnamNVS2g1a05LY0FYV3BmUmRPRWtVNUdxYTJVbG5VVUlRPT0tLXd1akRqOU1lTTVneU9LTWszY0I5bFE9PQ==--b0a57266c00e76e0c7d9d855b25d24b242154070' p '-----------decypted value-------------' puts encryptor.decrypt_and_verify encrypted_message p '---------------------------------------' 이 과정을 자바로 구현한 소스는 생략 깃헙에 올려두었습니다. 이 코드를 이용해서 서블릿 세션과 연동하는 방법은 추후 사측(?)과 협의되는 대로 공유할 예정입니다. 물론, 그 전에 쿠키를 공유할 필요가 없어지면(or 공유할 쿠키가 없어지면) 더 좋겠죠 :D
조회수 1089

[인공지능 in IT] 인사가 만사다

기술기업으로 인재의 중요성은 거듭 강조해도 지나치지 않다. 특히, 요즘처럼 어디에나 인공지능이 적용되는 시점에 넓은 인공지능 전문가 풀을 보유하는 것은 강력한 무기다. 2000년대초까지만 해도 대한민국은 전세계가 부러워하는 IT 강국으로 위상을 떨쳤지만, 현재 상황은 많이 달라졌다. IT 인재에 대한 편견뿐만 아니라 경쟁력을 상실한 처우 등 여러 악조건 등으로 경쟁 국가에 비해 조금씩 뒤쳐지고 있는 상황이다.필자가 속해있는 스켈터랩스의 상황을 빌려 기술 기업의 인재에 대해 설명해보자. 스켈터랩스의 미션은 'To innovate machine intelligence for understanding, assisting and improving daily lives anywhere and anytime'으로, 번역하자면 '언제 어디서나 우리의 일상을 이해하고, 도와주고, 더 나아지게 하는 머신 인텔리전스의 혁신을 이룬다'이다.스켈터랩스는 인공지능 기술을 개발하는 회사지만, 중심은 결국 인간이라는 뜻이다. 자고로 기술 기업, 특히 인공지능에 주력하는 기업은 인간을 위한 기술을 개발하기 위해 인재를 모으고, 팀마다 다양한 배경의 재능있는 멤버로 구성한다. 인간의 지능을 근간으로 인간을 위한 기술을 개발하는 데에 주력해야 하기 때문이다. 다시 말해, 우리는 모두의 삶의 질을 향상시킬 수 있는 기술을 개발할 수 있는 인재의 중요성에 대해 깊이 자각해야 한다는 것이다.< 스켈터랩스 >경영인들에게 가장 귀감이 되는 인물을 꼽으라면, 많은 사람이 GE의 잭 웰치 前 회장을 거론한다. GE를 세계적인 기업으로 탈바꿈시킨 잭 웰치의 경영 방식 중심은, 단연코 인재 관리다. 회장으로 취임할 당시 '고쳐라, 매각하라, 아니면 폐쇄하라'라는 본인의 철학을 필두로, 퇴임을 앞두기 직전까지 인재의 중요성을 강요했다. 퇴임할 당시 잭 웰치는 인재를 통한 4가지 주요 전략을 발표했는데, 첫째로 GE의 세계화 전략은 곧 인적 자산의 세계화라는 것이며, 둘째로 지식과 학습을 통한 서비스 전략 창출, 셋째로 6시그마 전략의 도입, 마지막으로 리더를 위한 e비즈니스의 도입이었다. 전설적인 경영인으로서, 위기를 성공으로 탈바꿈하는 기업인으로서 잭 웰치의 업적이 입에 오고 내리는 이유는 그가 인재 육성의 가치를 경영과 직접 연계시켰기 때문이다. 본인 업무의 70%는 인재에 쓴다고 했을 정도다. 훌륭한 기업으로 성장하기 위해서 그만큼 사람이 재산이라는 것을 일찍이 깨달은 것이다.< GE>수 년전부터 4차산업혁명, IoT 그리고 현재의 인공지능까지 IT 기술은 비약적으로 발전함했다. 이에 기업의 모든 전략은 '얼마나 빠르게 신기술을 도입할 수 있는가', '당장 적용할 수 있는 기술은 무엇인가', '신기술을 통해 얼마나 비용을 절감할 수 있을 것인가' 등 기술 자체에 과하게 집중되어 있다. 그러나 새로운 기술을 개발하는 주체는 누구인지, 어떤 것을 위해 집약적인 노동력을 동원하고 있는지 다시 한번 생각해봐야 한다. 스스로 학습하고 문제를 해결해나갈 수 있을 것이라는 인공지능이라는 기술 역시 결국에는 'Artificial Intelligence', 인간이 만들어내는 지능이다. 이토록 인재에 대해 신경을 써야 하는 이유다.잭 웰치의 어록 중에 이런 말이 있다. 'People First, Strategy Second'다. 전략보다 사람을 우선한다는 이 말처럼 뛰어난 기업으로 발돋움하기 위해서는 사람이 중심이어야 하고, 기술 기업에 있어 사람에 대한 가치는 그만큼 중요하다. 어떤 프로젝트를 진행하느냐와 상관없이 인공지능 기술을 개발하는 길목에는 항상 뛰어난 인재가 함께 해야 할 것이고, 이를 통해 인간을 위한 진정한 인공지능을 구현하는 것이 사명일 것이다.이호진, 스켈터랩스 마케팅 매니저조원규 전 구글코리아 R&D총괄 사장을 주축으로 구글, 삼성, 카이스트 AI 랩 출신들로 구성된 인공지능 기술 기업 스켈터랩스에서 마케팅을 담당하고 있다#스켈터랩스 #기업문화 #인사이트 #경험공유 #조직문화 #인공지능기업 #기술기업 #HR #인재의중요성
조회수 1161

영화관에서 ‘치킨’ 어때요? CJ CGV F&B사업팀 이홍철 님

코미디 영화 사상 1,500만 명 관객을 기록한 <극한직업>. 극장 밖을 나선 순간 치킨이 생각나는 건 어쩌면 당연한 일. 이에 발맞춰 CJ CGV에서 ‘BBQ 직화구이 치킨’을 선보였다. 영화관에서 치느님 영접을 가능케 주인공을 만나보았다.  유학파 출신 셰프가 극장으로 온 이유? ▲ ‘BBQ 직화구이 치킨’을 탄생시킨 CJ CGV F&B사업팀 이홍철 님지난 1월 24일, CJ CGV에서 야심 차게 출시한 ‘BBQ 직화구이 치킨’. 부드러운 순살 치킨에 바비큐 소스, 쫄깃한 떡꼬치를 더해 남녀노소의 입맛을 사로잡기 충분했다. 마성의 ‘BBQ 직화구이 치킨’을 탄생시킨 이는 CJ CGV F&B사업팀 이홍철 님이다. 이홍철 님은 프랑스요리학교 ‘르 꼬르동 블루(Le Cordon Bleu)’를 졸업한 유학파 출신으로 프랑스 엠배서더 호텔, 국내 웨스틴 조선호텔을 거쳐 지난 2010년, CJ CGV로 오게 됐다. 셰프로서 이름을 알릴 수 있는 유명 호텔을 마다하고, CJ CGV로 오게 된 이유가 궁금해졌다.음식과 엔터테인먼트가 결합하면 재미있겠다는 생각이 들었습니다. 그래서 CJ CGV로 오게 됐죠.CJ CGV F&B사업팀은 CJ CGV에서 판매하는 모든 식음 제품의 기획, 개발, 마케팅, 프로모션 등을 총괄하고 있다. 타 극장과 다른 점이라면? 차별화된 제품을 기획하고 개발하는 이홍철 님이 있다는 것! 해외를 비롯 대부분의 극장 사업자가 매점 메뉴를 수급 받아 판매하는 방식을 택한 것과 달리,  CJ CGV는 국내 유일 극장 매점 메뉴 개발자인 이홍철 님을 통해 자체적으로 맛 좋은 매점 먹거리를 만들고 있다. 그만큼 CJ CGV에서 그는 없어서는 안 될 중요한 존재인 셈. 그 동안 CJ CGV는 이홍철 님과 함께 다양한 메뉴 출시를 통해 극장에서 이색 먹거리를 접할 수 있도록 다변화를 꾀했다. 대표 제품으로는 지난 2012년, 프리미엄 팝콘 문화를 만든 고메 팝콘을 시작으로 죠스떡볶이와 콜라보해 튀김범벅과 라볶이를, 스쿨푸드와 손잡고 대표 메뉴인 ‘모짜렐라 스팸계란마리’를 냉동김밥 형태로 세계 최초로 출시했다.왜 이렇게 팝콘이 맛있어지는 건데?  ▲ 팝콘의 ‘맛’을 업그레이드하기 위해 불철주야 노력하고 있는 이홍철 님이색 먹거리의 첫 신호탄은 ‘팝콘’이다. 이홍철 님의 첫 완성작이라 말할 수 있는 팝콘의 시작은 팝콘의 ‘맛’ 업그레이드 연구였다. 그는 기존 팝콘보다 더 맛있는 제품을 만들기 위해 연구에 연구를 거듭했다. 시중에 판매하는 국내외 팝콘은 다 먹었고, 다양한 종류의 옥수수로 직접 팝콘을 튀겨보기도 했다. 이뿐만이 아니었다. 팝콘에 고소한 맛을 더하기 위해 기존에 사용했던 팜유 대비 원가가 30%나 비싼 코코넛 오일을 사용하기도 했다. 그 다음 스텝이라 할 수 있는 고메 팝콘 개발은 두 세배 노력이 더해졌다. 팝콘 표면에 치즈와 초콜릿 등 다양한 원재료를 사용했는데, 열이 가해지면서 그대로 녹아버렸던 것. 이홍철 님은 이를 보완하기 위해 온도와 습도를 함께 조절하는 쇼케이스까지 제작했단다. 밤낮없이 제품을 개발했지만, 곧바로 출시하진 못했다. 기존 팝콘보다 만들기도 어렵고, 원가도 비싸고, 취급도 까다롭다는 게 이유였다. 그렇다고 포기할 수는 없을 터. 많은 사람을 설득시키기 위해선 ‘맛’으로 승부를 볼 수밖에 없었다. 임원분들께서 자주 다니는 동선을 찾아 고메 팝콘을 올려놨어요. 하나씩 드셔보시라고요. 맛있다고 하시더니 한번 판매해보라고 기회를 주셨죠.▲ ‘뭘 좋아할지 몰라서 다 준비했어!’ CJ CGV에서만 만날 수 있는 고메 팝콘2012년 마침내 고메 팝콘이 출시됐고, 제대로 통했다. 프리미엄 팝콘을 취향에 따라 골라 먹을 수 있다는 점이 고객에게 매력적으로 다가온 것. 고메 팝콘을 먹기 위해 일부러 CJ CGV를 찾거나 배달해 먹는 고객도 있었다. CJ CGV에서는 ‘매점’ 대신 ‘팝콘 팩토리’라는 이름을 사용하였고, 국내 최초 새로운 팝콘 문화를 형성했다. ▲ 신제품 출시 전, 품평회는 필수!물론, 모든 팝콘이 성공했던 것만은 아니었다. 와사비 열풍이 불던 4년여전. 이홍철 님은 와사비 팝콘을 만들기로 했다. 와사비 향을 내는 원재료를 구하기 위해 가까이로는 아시아부터 멀리로는 유럽까지 샅샅이 찾아보았다. 와사비 팝콘에 대한 내부 평가는 매우 긍정적이었다. 마지막 고객 품평회 날. 이홍철 님은 와사비 팝콘의 초록색이 마치 푸른곰팡이 같다는 청천벽력 같은 이야기를 듣게 되었다. 결국 충격을 받고 출시를 접었다고. 망고 맛, 불닭 맛 등 7가지 시즈닝을 뿌려 먹는 쉐이크 팝콘을 판매했을 때. 기대했던 것보다 고객의 반응이 좋지 않아 판매를 접어야만 했다. 실패를 통해 그가 얻은 해답은? 바로 제품의 이름을 듣고 그 맛을 상상했을 때 ‘먹고 싶다’는 생각이 들어야 한다는 것. 거듭되는 실패에도 이홍철 님이 계속 도전할 수 있었던 건 CJ CGV의 아낌없는 지원이 뒷받침되었기 때문이란다. 극장에서 치느님을? 한국형 매점 메뉴는 현재 진행 중!CJ CGV와 이홍철 님의 도전은 팝콘에만 국한하지 않았다. 전 세계 극장 메뉴가 팝콘, 콜라, 핫도그 등 미국식 메뉴로만 구성되어 있다는 점을 주목했고, 국내 고객들이 선호할 수 있는 한국형 매점 메뉴를 개발하기로 했다. 한국인들이 좋아하는 음식을 ‘한국형 매점 메뉴’라 재정의하고 한국인들이 최애 메뉴인 치킨과 분식 등을 극장 환경에 맞게 개발했습니다.▲ 출시 후 뜨거운 인기를 끌고 있는 ‘BBQ 직화구이 치킨’ 이렇게 탄생한 게 바로 ‘BBQ 직화구이 치킨’이다. 아이디어는 좋지만, 현실화를 끌어내기까지 쉽지 않았다. 특히 치킨 특유의 냄새가 가장 큰 장애물. 취식을 보다 쉽게 하는 방법도 고려해야 했다. ‘맛’을 놓치고 싶지 않았던 그는 직화구이 치킨에 인공 훈연제를 첨가하는 대신 직접 불에 일일이 굽는 방법을 선택했다. 또한 순살 닭고기로만 구성하면 식감이 단조로울 수 있어 떡꼬치를 추가했다. 제품 기획부터 출시까지 14개월 동안 고생한 결과물이 나왔을 때 가장 보람찼다고 말한다. ’BBQ 직화구이 치킨 전국 15개 직영매장 중심으로 선 오픈 한 후 오는 3월 말 전국 직영 극장 중심으로 확대할 예정이다. 또한 CGV에서는 지역 상생의 일환으로 ‘춘천 닭갈비’도 판매 중이다. 앞으로 CGV에서는 비장의 한국형 메뉴를 매년 선보이겠다는데 벌써 내년 제품이 무엇이 될지 설레게 된다.   ▲ 이젠 CJ CGV에서 먹는 즐거움도 누려보세요!고객들이 더 만족할 수 있는 제품을 만들고자 고민하고 노력하겠습니다.매점 메뉴라는 고정관념을 깨고 꾸준하게 제품을 확장하고 있는 이홍철 님. 그가 만들어 낸 다양한 제품을 통해 보는 즐거움을 넘어 먹는 즐거움까지 만끽할 수 있었던 것이 아닐까. 앞으로 CJ CGV와 이홍철 님이 선보일 새로운 제품을 기대해본다.[채널 CJ] #CJ #CGV #BBQ직화구이치킨 #CGV고메팝콘 #CGV치킨 #영화관치킨 #구성원인터뷰 #직무소개 #직무정보 #F&B사업팀 #이홍철님 #기업문화 #CGV채용 #CGV공채
조회수 1244

브랜딩은 틀린 말이다?!

일단 명백하게 짚고 넘어가야 할 것이 있습니다. 브랜딩이라는 단어가 남발하는 요즘, 사실 이 단어자체가 올바른 표현인지 다시 생각해 볼 필요가 있다는 것이죠. 당초 Brand라는 어휘는 피부에 새긴 화상과 같은 낙인이나 흔적을 의하는 burn의 어원과 그 맥을 함께합니다. 브랜드라는 뜻이 라틴어로는 '불태우다' 라는 뜻이기 때문이죠.이는 당연히 무언가를 구별/식별하기 위한 '표식' 의 의미로 쓰인 것입니다. 그러니까 그냥 로고를 의미했던 것이었죠. 하지만, 요즘엔 그 의미가 많이 확장/변형되었습니다. 이유는 단순해요. 너무 많은 표식들이 생겨났기 때문입니다. 게다가 오래전엔 죄수나 사형수, 범죄자, 이상한애들에게 부여했던 것이 '낙인' 이었기에 사람들에게 매력을 어필할 필요가 없었어요. 그냥 그런 표식을 지닌 애들을 피하면 그만이었죠. 그러나 요즘의 브랜드는 비지니스자체이니 사람들의 마음과 지갑을 열게 해야합니다. '낙인'의 역할이 완전히 바뀌게 된 것이죠. 예전엔 낙인을 '구별' 하기만 하면 되었지만요즘엔 낙인을 '선택' 해야하는 시대가 되었습니다.구별과 선택은 다른 개념이예요. 구별은 인식의 개념이기 때문에 '아 그렇구나' 하고 끄덕이기만 하면 됩니다. 하지만 선택은 행동의 개념이라서 '하나를 선택하고 나머지를 포기하게끔' 해야 하죠. 이 때 기회비용이 발생하면서(심리적이든, 실물적이든) 브랜드는 그것 이상의 가치를 제공해야 하는 입장이 되었습니다. 그래서 수많은 눈요기와 정책, 장점, 특징들을 내세우며 "우린 가치가 있어!!" 라고 소리지르고 있는 상태가 바로 요즘입니다.자, 하지만 여기서 함정이 발생합니다. 위에서 말했듯 고객은 무언가를 선택할 때 얻는 이득과 기회비용 사이의 가치를 저울질합니다. 그리고 더 합리적인 선택을 하겠죠. 적어도 이론적으론 말입니다. 그러나 현실은 엉망진창입니다. 사람은 그리 합리적인 존재도 아니고 이득과 기회비용 사이의 가치를 정확히 판단하지도 못합니다. 게다가 그 판단의 기준은 지극히 개인적인 성향과 가치관에 좌우되기도 하고, 심지어 그 성향과 가치관이란 것은 트렌드와 다수의 압박 등 예상치 못한 변수들에 의해 기묘하게 변질되기도 합니다.상황이 이렇다보니, 일관적인 기묘하게 이상한 포인트에서 대박치는 회사가 있는가 하면, 정석대로 해도 영 반응이 시원찮은 경우도 많습니다. 때문에 브랜드를 하는 사람들이나 그걸 원하는 회사나 도무지 갈피를 잡기가 힘들어졌죠.  물론 데이터가 쌓이면서 일정 패턴이 발생했던 것은 사실입니다. 인지/사회심리학의 도움으로 인간 행동의 불특정성을 어느정도 규명해나가고 있는 것이죠. 그러나 그것이 규명되는 속도보다 사람과 시대의 변화속도가 훨씬 빠르다는 것입니다.사람의 행동이 이렇게 가변적이니 전략을 짜는 사람 입장에선 그것에 일일이 맞추다가 늙어죽을 것 같았을 겁니다. 그러다 누군가가 이런생각을 했겠죠. 사실 생각을 했다기보단 천성적인 마이웨이가 있던 사람이었을 겁니다. 그냥 하던거나 계속 해야겠다...라고. 그리곤 그냥 해오던 걸 꾸준히 계속 묵묵히 했더니. 생각지도 못했던 평가들이 등장하기 시작합니다. 부정적이든 긍정적이든 꾸준한 일관성은 캐릭터를 만들어냈고, 그들은 예측가능한 존재가 되었습니다. 보통 이러면 매력이 사라져야 맞는데, 오히려 그 일관성에 열광하는 팬층이 발생하기 시작했습니다. 그리고 그 팬층을 동경하던 어중간한 포지션에 있던 사람들이 그들을 따라서 유입되기도 했죠. 굳이 어디라고 얘기하지 않아도 익히 알려진 대부분의 성공사례의 기업들의 브랜딩 전략을 떠올려볼 수 있을 것 같습니다.이런 프로세스가 성공사례로 속속 등장하기 시작하면서 브랜딩은 더이상 '우리가 그들에게 무언가를 하는 것' 의 개념이 아니게 되었습니다. 나는 그냥 하던걸 잘하는 것이고, 브랜딩은 그것을 통해 "되어지는 것" 이죠. 그래서 브랜딩은 그 자체가 목적이 아니라 일종의 부수효과라고 하는 편이 오히려 맞을 것 같습니다.그러니 "Branding" ..브랜딩을 한다! 라는 능동적표현보단 "Branded" 브랜딩 되어진다.라는 수동적표현이 오히려 적절하지 않을까 싶네요.물론 반론의 여지가 있긴 합니다. 예를 들어 키엘의 경우 Lab느낌의 화장품매장을 컨셉화했고, 직원들에게 기본적인 의학적지식을 교육시키는 등 어떤 전략에 의해서 움직이고 있습니다. 또한 이것이 키엘의 브랜드를 명확하게 만들었으니, 이것은 화장품전문가를 원하던 고객들의 니즈를 파악해서 그에 응답한 것이 아니냐?! 라는 의견이 나올 수 있겠죠.Kiehl's : 약국에서 화장품을 판다!..라는 컨셉으로 직원들은 약사복을 입고있습니다. 맞는 말입니다. 물론 키엘은 수많은 서칭과 서베이, 내부회의를 거쳐서 최초컨셉을 기획하고 확장시켰을 것입니다. 그러나, 애플도 그랬고 다이슨도 그랬고 키엘이나 이니스프리, 에뛰드하우스도 그렇듯 고객이 이걸 원하니까 이걸하자! 라고 시작하진 않았습니다. 오히려 그렇게 색깔이 분명한 곳들은 최초의 리스크가 엄청났을 텐데 그런 관점에서 본다면 합리적이거나 효율적인 선택은 아니었겠죠. 그걸 원하지 않는 대다수의 사람들을 포기해야 했을 테니까요.  대신 그들이 선택한 것은 이게 시장이 원하든 원치 않든 내가 옳다고 생각되는 색깔을 일관성있게 밀어붙이고 유지하는 것이었습니다.  "너희가 원하니까 이걸 하겠습니다.." 가 아니고 "우린 이런 기업입니다." 라고 무심하고 담담하게 걸어가는 편을 택한 것이죠"너희가 원하니까 이걸 하겠습니다.." 가 아니고"우린 이런 기업입니다." 라고 무심하고 담담하게 걸어가는 편을 택한 것이죠.그러니, 브랜드라는 것은 이제 한 순간의 낙인과 표식의 의미가 아닙니다. 그것은 꾸준한 행동과 신념의 일관성을 의미하는 단어가 되었습니다. 그들은 모두가 아닌, 우리를 사랑하고 지지해주는 고객들을 위해 최선을 다했습니다. 사회적책임을 다하고 제품이면 제품, 서비스면 서비스 그 자체에 충실했습니다. 브랜드는 이런 일련의 과정과 시간을 통해 자연스럽게 축적되어가는 것이 아닐까 싶습니다.그러니 우리가 지금부터 알아볼 것은, 고객의 마음을 사로잡기 위해 안간힘을 쓰는 그런 종류의 것이 아니라 우리가 하던 일을 어떻게 꾸준히 지속시키고 깊이 있게 만들것인가를 고민해보도록 하겠습니다.#애프터모멘트크리에이티브랩 #브랜드 #브랜딩 #마케터 #마케팅 #디자인 #디자이너 #인사이트 #조언 #꿀팁
조회수 530

데이터 검증이 중요한 이유

데이터 검증은 system error 또는 human error에 의해 garbage data가 쌓이고 있진 않은지, 정상적으로 데이터가 수집되는지 여부를 확인하는 매우 중요한 단계인데요. 오늘은 왜 데이터 검증 단계가 중요한지를 최근 경험을 통해 설명드리고자 합니다.한 고객사에서 데이터 검증 과정 중 GA(Google Analytics for Mobile Apps) 대비 저희가 공급한 툴(와이즈트래커)의 세션수(방문수)가 너무 낮다는 문의를 주셨습니다. 그 수치는 무려 3배 가량의 차이로 acceptable이 힘든 데이터였습니다.사실 세션은 설정이 요하는 분석 항목이 아니기 때문에 측정기준으로 비교해 봐야 했지만, 세션 기준 역시 30분으로 GA와 와이즈트래커와 동일했습니다. 이에 저는 GA에서 over counting되는 요인이 있을거라 생각하고 열심히 구글링 하다 흥미로운 아티클을 발견했습니다. GA SDK V4 적용했더니 세션수 2배 이상 증가했다?>> Link이 문의에 한 사람이 답변을 달기를, GA에는 activity auto tracking 기능이 있는데, 이를 사용할 경우 앱을 백그라운드에 내리거나 프로세스 킬하고 재실행하면 30분 세션 유지기간에 상관없이 세션이 증가한다는 내용이었습니다. 이 말인즉, 사용자가 앱과의 인터렉션이 없어도 GA SDK가 자동으로 새로운 세션을 발급한다는 건데요. 설마했지만 사실 확인을 위해 테스트를 진행했습니다.1) 테스트 앱 개발2) GA SDK v4 적용3) 앱 실행4) 앱 프로세스 종료 후 30분 이내 재실행 or 백그라운드 처리이는 불과 1분 안에 일어난 현상테스트 전 데이터는 사용자 1, 세션 6건이었고, 3단계 앱을 실행하는 시점에 사용자 2, 세션 7이 되었습니다. 정상적으로 사용자 1건, 세션 1건이 증가한 것입니다. 여기서 앱을 종료하고 바로 앱을 다시 재실행 해보았습니다. 그리고 데이터를 보니 오잉? 정말 세션이 증가했습니다. 정말인가 싶어 여러 번 했지만, 아래 캡쳐시간을 보시면 알겠지만, 불과 1분도 채 안되서 3건의 신규세션이 발생한 것입니다.그렇다면 도대체 왜 이렇게 처리한 것일까? 오류일까?정확히 알 수는 없지만 이 기준 자체는 데이터 해석에 큰 오해를 일으킬 수 있습니다. 우리는 보통 평균 값을 갖는 파생지표를 세션을 기준으로 산정합니다. 그래서 보시는 것 처럼, 평균 세션당 화면, 평균 세션 시간이 세션수를 기준으로 나눠진 것을 알 수 있습니다.평균 세션당 화면, 평균 세션 시간, 사용자당 방문횟수와 같은 지표는 사용자의 앱 인게이지먼트를 판단하는 척도로 활용하는 사용성 높은 지표인데, 사용자와 앱 간의 실질적인 인터렉션이 전혀 없는 허수의 세션이 증가하니 세션수와 연관있는 모든 파생지표 데이터가 실제보다 낮은 수치로 표기되고, 이를 가지고 잘못된 해석을 하고 잘못된 액션까지 취할 수 있다는 것입니다.해당 고객은 안타깝게도 세션 뿐만 아니라 세션과 관련된 파생지표 모두 잘못된 기준의 KPI를 보았다고 할 수 있는데요, 사실 아직까지 국내는 GA에서 추출하는 기본 데이터 수준으로 KPI를 활용하는 경우가 많고, 특히 GA의 activity auto tracking 기능을 대부분 true로 설정하여 활용하고 있을 것이기 때문에 데이터 해석의 문제는 생각보다 굉장히 범용적으로 발생하고 있을 것으로 예상됩니다.!! 데이터 검증은 선택이 아닌 필수 과정데이터 분석을 잘하기 위한 전제 조건은 좋은 데이터를 수집하는 것입니다. 하지만 보통 3rd party tracking 업체는 툴을 제공하는 것 까지만 수행하지, 클라이언트의 개발자가 제대로 적용했는지, 적용한 데이터가 정상 수집되고 있는지 등의 과정까지 support 하지 않습니다. 그럼 클라이언트가 직접해야 하는데 이건 현실상 더더욱 힘들 수 밖에 없습니다.그래서 툴을 선택할 때는 반드시 도입 단계에 데이터 검증을 지원하는지 여부를 확인해야 합니다. 2012년부터 빅데이터 분석 바람이 불고 있지만, 현실은 기업에 전문 분석가 1명이 없는 기업이 아직 대부분입니다. 또한 비전문가가 쉽게 배우고 커버할 수 있는 업무도 아니기 때문에 전문 업체의 지원을 받아야 합니다. 안해주면 해달라고 떼 써야 합니다. 초기 도입시에 말이죠. 그래야 이후에 자신감있게 데이터를 신뢰하고 분석하고 액션 플랜을 수립할 수 있습니다.오늘 당장 리포트의 데이터를 의심의 눈으로 한 번 다시 보시는 계기가 되면 좋겠습니다.
조회수 599

궁합이 잘 맞습니까?

궁합을 믿으시나요?사람과 사람 사이에 보이지 않는 기운에 의해서, 서로 끌어당기거나 또는 반대의 기운을 느껴본 적이 있을 겁니다. 그것은 남녀 관계 뿐만 아니라, 친구 사이에서도 마찬가지입니다. 딱히 이유를 설명하기 어렵지만, 서로 이유없이 더 친근하거나, 왠지 이상하게 불편한 사이가 있듯이 말입니다. 단순히 동질성만으로는 설명되지 않습니다. 너무 다르기 때문에 더욱 친밀도가 높아지는 관계 역시 많기 때문이죠. (혈액형이나 사주 얘기는 더더군다나 하지 않겠습니다 -_-)조직 구성원들의 궁합하물며, 개인이 선택할 수도 없으며, 게다가 나와 당사자 한 명이 아닌, 다수의 구성원들이 모인 조직에서 서로의 궁합 이야기는 현실적으로는 꺼내기조차 어려운 문제입니다. 선택할 수도, 파악할 수도, 임의로 조정할 수도 없는 요소이기 때문이죠.그래서 직장인들은 피곤한 하루하루를 숙명처럼 받아들이고 살아가는 것이겠죠.하지만, 정말 해결책이 없을까요?조직의 구성 요소여기서 조직을 구성하는 요소를 간단히 짚어보기로 하겠습니다.조직은 Mission(목표) + Resources(자원) + System(운영방식)으로 구성된다고 볼 수 있습니다.간단히 하나하나 살펴보면, * Mission (목표) : 조직이 달성해야 하는 목표이자 존재의 이유라고 볼 수 있습니다. * Resource (자원) : 인력, 시간, 예산 등을 비롯한 회사가 투입할 수 있는 모든 것이 여기에 해당됩니다. 일종의 하드웨어라고 볼 수 있죠. * System (운영방식) : 목표를 위해 자원을 운영하는 방식이라고 설명할 수 있습니다. 조직이 가진 노하우, 또는 일종의 소프트웨어에 해당한다고 생각할 수 있죠.조직 = 목표 + 자원 + 운영방식동일한 목표를 가진 조직이라도, 자원과 운영방식의 차이 때문에 누구는 성공하고 어디는 실패하게 됩니다. 만약 서로 다른 두 조직이 동일한 성과를 낸다고 가정하더라도, 어떤 조직은 구성원 모두가 신나게 일하면서 성과를 창출하고, 어떤 조직은 우울하고 힘겹게 성과를 꾸역꾸역 만들어내기도 합니다.무엇이 이러한 차이를 만들어낼까요? 특히 인력과 조직 구성에 대한 관점에서 말이죠.조직은 필요한 Job을 수행하는 인력들이 모여서 이루어진 집단입니다. 어떤 조직에 필요한 기능을 우리는 Job description(직무기술서)를 통해서 정의하고, 이런 기능에 부합하는 인력을 채용하고 배치 합니다.동일한 기능을 수행하는 인력이 다수인 경우도 흔합니다. 하지만, 동일한 역량과 경험을 가진 사람일지라도 현실적으로는 누구와 일하느냐에 따라 성과와 성공확률이 달라집니다. 그것은 동일한 knowledge(지식)와 동일한 skill(기술)을 가지고 있더라도, 개인의 attitude(태도)가 조직에서는 굉장히 크게 작용하기 때문입니다.개인역량 = 지식 + 기술 + 태도Attitude (태도, 사고방식)흔히 태도를 얘기할 때, 태도가 좋으냐, 나쁘냐의 기준으로 판단하는 것은 (물론 완전히 배제할 수 없습니다만...) 적절하지 않습니다. 태도(attitude)라는 것을 판단하는 것은 다분히 주관적인 생각이 개입되기 때문이죠. 누군가에게 좋은 태도가 누군가에게는 야비하게 보일 수도 있듯이 이것은 상대적인 것입니다.(솔직히 얘기해서, 누가봐도 잘못된...태도가 있긴 있습니다... 부정하지 못하겠네요 -_- 암튼~)예를 들어, A라는 직원은 매우 신중한 태도를 가지고 있어서, 어떤 일을 처리할 때 서두르지 않지만(시간이 많이 걸리며) 빈틈이 없이 처리를 하고, B라는 직원은 간혹 실수를 하긴 하지만, 바로바로 행동으로 옮기고, 빠른 결과물을 만들어 온다고 합시다. 동일한 일을 처리할 때 누가 옳고 누가 옳지 않은지를 쉽게 결정하기 어렵습니다.한편, C라는 직원은 매우 논리적이고, 지시받은 일은 완벽하게 처리하지만, 스스로 필요한 일을 찾아서 처리하는 경우는 전혀 없는 반면, 허무맹랑한 아이디어가 넘쳐나는 D 직원은 시키지도 않은 일을 벌이고 제안하면서 새로운 기회를 간간히 만들어 내는 성향을 가지고 있다면, 누가 조직에 도움이 되겠습니까? 역시 조직에 따라 상대적이며, 쉽게 답을 내리기 어려운 부분입니다.조직원의 구성제가 속한 조직은 창의적인 업무를 수행해야 하는 Mission을 가지고 있습니다. 많은 스타트업과 같이 새로운 아이디어를 만들고 이를 구체화시키는 일을 하고 있습니다.다양한 구성의 여러 조직에서 일을 하면서 제 머리속에 "이런 조합으로 인원이 구성되면 어떨까?" 하는 이상적인 조직의 조합(궁합)이 하나씩 그려지기 시작했고, (일반화 할 수는 없겠지만) 적어도 새로운 일을 만들어내는 창의적인 조직에서는 시너지를 내는 '드림팀'을 만들 수 있겠구나 하는 생각이 들었습니다.똑똑한 사람들만으로 구성된 조직이 실패하기 쉬운 이유도 여기에 있지 않을까 하는 생각도 합니다. 단지 기능적으로 역할이 나눠져야 할 뿐만 아니라, 구성원들의 성향 역시 궁합을 이루어야 한다는게 제 생각입니다.창의적 조직의 인력 구성(안)1. 스마트한 리더2. 꼼꼼한 계산가3. 냉철한 팩트체커4. 톡톡튀는 발명가5. 감각적인 스토리텔러6. 발빠른 행동가7. 끝을 보는 완벽주의자이 여섯 가지 인력의 콤비네이션은 리더가 중용해야 하는 참모일 수도 실무 인력일 수도 있습니다. 리더를 제외한 6가지 조합의 구성은 개별적으로 구분된 인력일 수도 있고, 그렇지 않을 수도 있습니다. 리더는 이 서로 다른 성향의 인력들을 balance 있게 조율하면서 각기 기질을 발휘할 수 있게 하는 총 책임자 역할을 하지고 있습니다. 각 구성원들에 대한 세부적인 내용을 정리하면 다음과 같습니다.[조직의 중심]* 스마트한 리더 : 공정하고, 합리적 판단을 내릴 수 있어야 한다. 세세한 개입보다는 넓은 시야를 가지고 있고, 어느 시점에 어떤 인력에게 힘을 실어줘야 할지를 빠르게 결정해야 한다. 조직을 움직이게 하는 핵심이다.[좌뇌형 인력]* 꼼꼼한 계산가 : 신중하고, 치밀하고, 빈틈이 없으며, 숫자에 강하면서 현안 파악에 매우 뛰어난 사람이다. 리더에게 현실을 리마인드 해주는 역할을 한다.* 냉철한 팩트체커 : 논리적이고, 분석력이 뛰어나며, 넘쳐나는 정보 가운데 사실 진위 여부를 확인하고, 중요한 정보를 리더에게 전달하는 역할을 한다. 리더의 합리적 판단의 근거를 제시한다.[우뇌형 인력]* 톡톡튀는 발명가 : 독창적이고, 엉뚱하고, 새로운 것에 대한 거부감이 없으며, 남들과 다른 생각에 높은 가치를 두는 사람이다. 이상을 꿈꾸며 새로운 아이디어의 원천으로, 주로 혁신의 초석 역할을 한다.* 감각적인 스토리텔러 : 사람을 잘 이해하고, 작은 사실에도 의미를 발견하고 부여할 수 있는 역량을 가지고 있다. 흩어져있는 정보를 연결하여 하나의 이야기를 만들고, 가치를 만들어 공감할 수 있게 전달하는 역할을 한다.[행동형 인력]* 발빠른 행동가 : 행동대장이다. 추진력이 강하고, 손발이 머리보다 빨리 움직이는 경향이 있다. 남을 의식하기 보다는 주어진 일의 결과에 집중하는 성향을 가진다. 문제를 일으키기도 하지만, 일을 진척시키는 없어서는 안될 중요 인력이다.* 끝을 보는 완벽주의자 : 열정적이고 디테일에 강하다. 큰 그림보다는 구체적인 일에 집중하며, 자신이 하는 일에 대한 자부심이 강한 경향이 있다. 결과로 인정받길 바라며, 묵묵히 문제를 해결하는 실행 인력이다.세상에는 다양한 Mission을 가진 다양한 조직들이 있습니다. 하지만 그 중심에는 항상 '사람'이 있죠. 아니, '사람들'이 있습니다.아무리 훌륭한 인재들이라고 하더라도, 그들을 어떻게 조직하고 운영하느냐에 따라, 최고의 조직이 될 수도, 최악의 조직이 될 수도 있습니다. 그것을 좌우하는 것은 이들을 어떻게 조직화 하는 것이냐 입니다. 단순히 상벌을 포함한 평가나, 동기부여만으로는 조직력을 극대화할 수 없다고 생각합니다.그것이 오랜 조직 경험으로부터 얻은 제 생각입니다.잘난 사람들 아무리 많이 모아놓고도 성과가 안나오는 조직이 있다면, 한번 심각하게 생각해 보시길 바랍니다.혹시, 세계 최고의 골키퍼만 모아놓고 축구팀을 만든게 아닌지, 세계 최고의 투수들만 모아놓고 야구팀을 만든게 아닌지 말입니다.그것이 새해를 맞이하여 조직의 리더가 고민해야 할 중요한 항목 중의 하나가 되길 바랍니다.문고리들만 붙잡고 있는 사람들은... 얼른 정리하시구요~~
조회수 980

사업자 등록, 다시 하면서...

생각해보면 첫 사업자 등록을 했던 때가 96년이다. 세무서를 찾아가서 두근 거리는 마음으로 등록을 하였고 일주일인가 뒤에 방문에서 사업자등록증을 받아왔다. 그렇게, 나의 벤처 생활이 시작됐다.파란만장한 산전 공중전 난장판을 다 겪었고, 만들어진 개인사업체를 법인에 귀속시키기도 하고, 법인을 만들고 부수는 것도 경험했다.어느덧 20년이 지난 2016년 필요에 의해서 사업자등록증을 만들어야 했고, 세무서를 방문해서 신청을 하려고 하니, 간단한 몇 가지 정보를 입력하고 그 자리에서 빠르게 사업자등록증을 받아서 나오는 것을 경험하니 정말 격세지감이 들었다.20대의 순진한 마음에 들떠서 사업자 등록증을 만들던 경험과 40대 중반에 사업자등록증을 받아 드는 기분은 매우 새로웠다. 사업자등록증을 받아서 나오면서 느꼈던 몇 가지 느낌은 신기한 기분이다.예전 세무서를 찾아가기 위해서 버스를 타고 걸어서 간 20대의 기억과 작년에 구입한 수입차를 타고 세무서 주차장에 주차를 하는 기분도 새로웠다. 물론, 그 사이 내가 만든 기업이 10여 개는 되지만, 처음 회사를 설립할 때에 직접 세무서를 방문한 이후로는 대부분 대리인을 보내거나 법무사를 통해서 법인을 설립했던 것이니, 직접 사업자등록증을 만들려고 세무서를 방문한 것은 정말 20년 만이다.처음 만든 회사의 이름은 '스핀 테크'라는 당시에 유행하던 테크를 붙였고, 'SPIN'은 Software, Programming, Internet, Network를 나열한 단어의 첫 단어를 결합한 단어였다. 그리고, 지금 등록한 사업자명은 요 근래 내가 하고 있는 일을 곰곰이 생각하면서 결정했다.헬스케어와 금융, 자동차 등에 사용되는 연동되어지는 정보들을 고민하고 생각하는 일을 하고 있기 때문에 Connected Information Lab이라는 이름을 만들었다. 미묘하게 등록되어진 사업자 명칭을 보면서 기분이 매우 새롭게 느껴진다.과거에 느껴지던 사업자의 무게감보다는 매우 당연하게 1인 기업을 지향하는 나 자신에 대해서 무언가 이정표를 하나 만든 것 같다.이런 미묘한 느낌은 역시, 사업자 등록을 직접 해봐야 느끼는 것 같다. 개인적으로 스타트업을 시작하는 후배들은 자신이 아무리 바쁘더라도 직접 사업자 등록을 해보기를 권장한다. 자기가 만든 이름에 대한 책임감이나 그 뉘앙스에 대해서 오랫동안 머릿속에 남을 것이다.얼마나 이름을 만들기 위해서 고민하고, 얼마나 그 이름을 위해서 일할 것인가에 대해서 생각했느냐는 결국, 해당 기업을 만들고 사멸하기까지 생사고락을 같이하는 새로운 생명체의 탄생이라는 것을 느끼게 될 것이다.아주 오래간만에 느끼는 이 기분... 그냥, 글로 남겨 본다.생각해보면 사업, 스타트업은 가장 최소한의 인원, 가장 쥐어짜듯 가장 적인 리소스로 운영이 가능하도록 해야 한다는 것을 다시 한번 생각하면서 사업자등록을 하도록 하자. ~.~ 생각해보니, 그런 마음을 가지게 된 것도 직접 사업자 등록을 하면서 그 책임감을 느낀 것 같다.사업을 시작하는 모든 사람들에게 권하고 싶다.직접, 사업자 등록을 해보자. 법인 등록이라고 하더라도 모두 대리인을 통해서 만들더라도, 서류를 챙겨 들고 세무서에 직접 다녀오기를 권장한다. 그 무게감과 느낌을 받아보시기를...

기업문화 엿볼 때, 더팀스

로그인

/