13 5월 2999

Web Cloud & mobile App Business working Link

Web Cloud & mobile App Business working Link

  1. Biz Design Workplace
  2. Biz marketing tools Workplace
  3. Biz reference datas
    1. 프리렌서 업무 [크몽] : https://kmong.com/
    2. 모바일 앱 시장조사 [와이즈앱] : https://www.wiseapp.co.kr/
    3. 프리렌서 업무 [위시켓] : https://www.wishket.com
    4. 프리랜서 업무 [프리모아] : http://www.freemoa.net/
    5. 프리렌서 업무 [이렌서] : http://www.elancer.co.kr/
  4. Biz online Developing tool
  5. cloud developer console
    1. microsoft azure : https://azure.microsoft.com/ko-kr
    2. google developer console : https://console.cloud.google.com/?hl=ko
    3. amazon AWS : https://aws.amazon.com/ko/console/
  6. Mobile App Biz market
    1. android developer console : https://play.google.com/apps/publish/?hl=ko
    2. onestore (T Store) : http://dev.onestore.co.kr/devpoc/index.omp
    3. apple app store : https://developer.apple.com/app-store/
  7. 지적재산권 등록
    1. 특허정보검색(KIPRIS) : http://www.kipris.or.kr/khome/main.jsp
    2. 특허로(특허출원) : http://www.patent.go.kr/portal/Main.do

 

 

 

 9,298 total views,  8 views today

13 5월 2999

매일 들르는 곳 : nooksurfer : ホームページの閲覧えつらん者しゃ

매일 들르는 곳 : nooksurfer : ホームページの閲覧えつらん者しゃ

 

 

자주 들르는 곳 : Frequent stop :

 

모바일 (게임)개발툴 사이트

 

 

 웹 (사이트) 개발

 

 

디지털 마켓

 

 

멀티미디어 리소스 (마켓)

 

인문학과 사회와 재경학에 관심을 가져보자

 

오프라인 교육 기관

 

 10,057 total views,  3 views today

26 1월 2023

[산업] “AI의 저작권 침해 더 못참아”… 인간, 마침내 칼 빼들다

“AI의 저작권 침해 더 못참아”… 인간, 마침내 칼 빼들다

게티이미지, 그림 생성툴 만든 英 ‘스태빌리티 AI’에 소송 제기

 
워터마크까지 버젓이_이미지 생성 인공지능(AI) 스테이블 디퓨전에서 찾아볼 수 있는 이미지. 오른쪽에 저작권을 나타내는 ‘게티이미지’의 워터마크가 흐리게 보인다. 이미지를 유료로 제공하는 게티이미지의 사용 허가를 받지 않은 사진이나 그림을 생성 AI가 이용했을 가능성이 있다는 얘기다. /스테이블 디퓨전

인터넷을 통해 이미지·동영상을 제공하는 미국 회사 게티이미지가 AI(인공지능) 업체를 상대로 저작권 침해 소송을 제기했다. 게티이미지는 4억7000만장 이상 이미지를 유료로 제공하고 있는 미국 최대 규모 이미지 플랫폼이다. 이 회사는 이미지 생성 인공지능(AI) 스테이블 디퓨전을 개발한 스태빌리티 AI가 자신들의 허락을 받지 않고 수백만장의 이미지를 AI 이미지 생성에 도용했다고 주장한다. 게티이미지는 “우리는 수많은 AI 기업에 알고리즘 훈련을 위한 이미지 라이선스를 제공해왔다. 스테빌리티 AI는 상업적인 이익을 위해 우리가 소유한 이미지의 라이선스를 적합한 절차를 거치지 않은 채 사용했다”라고 밝혔다.

올해 가장 각광받을 기술로 손꼽힌 생성 AI가 저작권 문제로 법정에 서게 됐다. 생성 AI는 글, 문장, 오디오, 이미지 같은 기존 데이터를 활용해 유사한 콘텐츠를 새롭게 만들어 내는 AI다. 하지만 생성 AI가 콘텐츠를 만들어내는 과정에서 기존의 창작물을 대량으로 학습하면서 저작권 문제가 생겨났고, 결국 소송까지 가게 된 것이다. 블룸버그는 “지난해가 생성 AI에게 영광의 한 해였다면, 올해는 생성 AI 를 둘러싼 소유권, 저작권과 진정성에 대한 법적 갈등이 본격적으로 시작되는 한 해가 될 것”이라고 했다.

◇화가도, 프로그래머도 생성 AI에 줄소송

생성 AI의 등장으로 가장 먼저 위협을 느낀 창작자들도 올 들어 소송을 제기했다. 일러스트레이터·만화가인 사라 안데르센, 켈리 매커넌, 칼라 오티즈는 “AI 기업이 막대한 양의 저작물을 원작자 동의 없이 생성 AI 훈련에 사용하고 있다”고 주장하며 스태빌리티AI와 이미지 생성 AI인 미드저니 관계자들을 고소했다. 이들은 생성 AI로 발생한 피해를 창작자들에게 보상하고, 추가적인 피해를 막기 위한 사용 중지 가처분을 요구하고 있다. 소송에 참여한 매커넌은 “‘내가 생성 AI 학습에 이용이 됐을까(haveibeentrained.com)’란 사이트에서 내 이름을 검색했을 때 내 작품이 셀 수 없이 등장하는 것을 보고 소송을 결심했다”고 했다. 그가 검색한 사이트는 화가나 사진작가들이 자신의 작품이 생성 AI의 학습에 사용됐는지 확인하기 위해 사용하는 곳이다.

생성 AI의 개발이 빠르게 이뤄지면서 이와 관련된 법적 분쟁은 그림이나 사진뿐만 아니라 영상, 글, 목소리, 초상권, 코드까지 확산할 것으로 보인다. 지난해 11월에는 마이크로소프트(MS)의 소스 코드 생성 AI ‘깃허브 코파일럿’의 이용자들이 마이크로소프트를 상대로 집단소송을 제기했다. 깃허브 코파일럿은 수십억줄의 코드를 학습해 코드를 생성해주는 도구다. 프로그래머가 코드의 일부를 작성하면, AI가 어떤 코드가 들어갈지 판단해 자동완성된 코드를 알려주는 방식으로 프로그래머를 도와준다. 깃허브 사용자들은 프로그래머가 직접 만들어 깃허브에 공유한 수십억줄의 오픈소스 코드를 MS의 깃허브 코파일럿이 불법 복제하고 있다고 주장하며 손해배상을 요구하고 있다.

 

◇ “인간 창작성을 가늠할 기념비적 소송”

게티이미지에 소송을 당한 스태빌리티AI의 본사가 영국 런던에 있기 때문에 이들의 법정 다툼은 영국 법원에서 이뤄질 예정이다. 저작권 문제에 엄격한 편인 영국 법원이 인간과 생성 AI의 분쟁에서 첫 선례를 남기는 것이기 때문에 생성 AI에 막대한 투자를 하고 있는 MS나 구글과 같은 빅테크의 눈도 여기에 쏠릴 예정이다. 영국 파이낸셜타임스(FT)는 “인간이 가진 창작성의 가치를 가늠할 기념비적인 소송이 될 것”이라며 “앞으로 생성 AI가 어떻게 살아남아야 할지 결정해줄 판결이기도 하다”라고 평가했다.

국내에서도 일러스트레이터와 만화가를 중심으로 생성 AI에 대한 불만이 쏟아져 나오고 있지만 생성 AI와 관련한 저작권 규정은 아직 명확하게 정해지지 않았다. 국회와 정부는 인공지능 학습과 빅데이터 분석을 위해서 인터넷에 공개되어 있는 저작물을 사용할 때에는 저작권자의 이용 허락을 받지 않아도 된다는 내용을 저작권법 개정안에 포함하려는 시도를 하고 있다. FT는 “각국 정부는 기술 기업을 규제하고픈 입장과 AI 같은 핵심 기술을 육성해주고 싶은 입장 사이에서 고민하고 있을 것”이라고 했다.

[출처] https://www.chosun.com/economy/tech_it/2023/01/26/SYRGM7QCQ5DDXEOHG7ROYVVD2Q/

 24 total views,  2 views today

22 1월 2023

[산업] “주식 뭐 살까?” AI에 물어보니

[산업] “주식 뭐 살까?” AI에 물어보니

“주식 뭐 살까?” AI에 물어보니

[편집자 레터]

 

이번 주 위클리비즈엔 인공지능(AI)과 관련한 기사를 두 건 실었습니다. 각국에서 AI 규제가 본격화되고 있다는 소식(B8면)과 저명한 노동경제학자인 데이비드 오터 MIT 교수 인터뷰(B11면)입니다. AI 관련 기사를 많이 실은 건 그만큼 이 분야에서 놀라운 일들이 연달아 벌어지고 있기 때문입니다. 특히 지난해 말 발표된 대화형 AI ‘챗GPT’는 놀라움을 넘어 충격적인 수준입니다. 전문가들도 구분해낼 수 없는 수준으로 논문 초록을 써내는가 하면, 셰익스피어 스타일의 시(詩)나 노래 가사도 뚝딱 만들어냅니다. 프로그램 코딩도 할 줄 압니다.

저도 시험 삼아 챗GPT에 몇 가지 질문을 던졌더니, 과연 어떤 질문이든 막힘없이 술술 대답합니다. 가령 한국의 주적은 누구인지 물었더니 “한국의 주적은 북한”이라며 남북한 관계의 약사(略史)를 서술합니다. UAE의 주적은 누구냐고 묻자 “UAE는 특정한 주적을 갖고 있지 않으나, 이란과는 영토 분쟁으로 긴장 관계를 유지하고 있다”고 하는군요. 지금 어떤 주식을 사는 게 좋겠냐고 묻자 “미안하지만 투자 관련 조언은 할 수 없다”며 “최고의 주식은 개개인의 투자 성향이나 시장 상황에 따라 다르므로 알아서 연구하고 전문가 도움을 받으라”는 모범 답안을 내놓습니다.

이런 놀라운 성능 때문에 챗GPT가 조만간 튜링 테스트를 통과할 수 있을 것이라는 관측도 나옵니다. 기계가 인간에 필적하는 지능을 가졌는지 판별하는 시험인데, 지금까지 이 테스트를 통과한 AI는 없습니다. 챗GPT에게 직접 물어보니 이렇게 답변합니다. “제가 튜링 테스트를 통과하려면 인간 같은 양심과 자의식, 정서지능, 그리고 인간 정신의 복잡성을 이해하는 능력이 필요합니다. 하지만 저는 훈련받은 패턴에 근거해 텍스트를 생성하는 AI일 뿐입니다.”

내친김에 AI가 언젠가 인간의 일자리를 대체할 수 있을 것 같냐고 묻자 “창의력이나 판단력이 필요한 일들은 인간의 고유 영역이며, 쉽사리 기계로 대체되지 못한다”고 합니다. 영리한 데다 겸손하기까지 한 AI에 감탄하다 문득 이 녀석이 거짓말인들 못 하겠나 싶어 조금 섬뜩했습니다. 좋든 싫든 아마 올해는 AI 관련 뉴스를 계속해서 보고 듣게 될 것 같습니다.

[출처] https://www.chosun.com/economy/mint/2023/01/20/KAJID6DQR5GKXBRZYUMBFOXVL4/

 20 total views,  2 views today

22 1월 2023

[IT 혁신 디바이스][소프트웨어] MIT 노동 경제학 교수의 진단 “이런 사람은 AI에 안 밀려난다”

[IT 혁신 디바이스][소프트웨어] MIT 노동 경제학 교수의 진단 “이런 사람은 AI에 안 밀려난다”

MIT 노동 경제학 교수의 진단 “이런 사람은 AI에 안 밀려난다”

데이비드 오터 MIT 교수 인터뷰

인공지능(AI)과 로봇 기술이 급속히 발전하면서 일자리의 미래에 대한 걱정도 커지고 있다. 전국경제인연합회가 2021년 20·30세대 829명에게 미래사회가 도래하면 일자리가 어떻게 변하게 될 것으로 생각하는지 물었더니 10명 가운데 8명(83%)은 일자리가 줄어들 것이라고 우려했다. 최근엔 ‘미드저니’ ‘달리’ 등 그림 그리는 AI와 대화형 AI인 ‘챗GPT’가 잇따라 등장해 ‘AI가 인간의 일자리를 앗아갈 것’이라는 우려가 더욱 커졌다. 실제로 로봇 한 대가 늘어나면 인간 일자리가 0.1%포인트 줄어든다는 분석(한국은행·2021년)도 있다.

이런 현상에 대해 오랜 기간 자동화와 노동의 관계를 연구해온 데이비드 오터(56) 미국 매사추세츠공대(MIT) 교수는 어떤 생각을 갖고 있을까. MIT 부속 ‘미래의 일자리’ 연구소 공동 의장이자 저명한 노동 경제학자인 오터 교수를 WEEKLY BIZ가 화상으로 인터뷰했다.

 
데이비드 오터(56) 미국 매사추세츠공대(MIT) 교수는 친(親) 로봇, 친(親) 인공지능(AI) 학자로 알려져 있다. 세계화와 기술 변화가 일자리에 끼치는 영향에 대한 연구 업적을 인정받아 지난 2020년 하인즈 재단으로부터 ’25주년 특별공로상’을 수상하기도 했다. /데이비드 오토 교수 제공

◇“AI가 인간 대체한다는 건 과장”

-코로나 팬데믹이 노동시장을 어떻게 바꿨나.

“예상치 못한 구인난이 발생하면서 저학력 근로자에게 매우 좋은 노동시장이 형성되고 있다. 지난 40년간 고학력자가 혜택을 독식해온 노동시장에 극적인 역전이 일어난 것이다. 이런 변화는 고임금 근로자보다 저임금 근로자 임금을 많이 올려 불평등을 줄인다는 점에서 긍정적이다. 다만 이런 상황이 얼마나 지속할지는 불확실하다. AI가 발전하는 속도도 내가 예상했던 것보다 더 빠르다.”

-결국 AI나 로봇의 발전 속도를 인간이 따라갈 수 없는 것 아닌가.

“‘따라간다’는 말은 경쟁을 전제로 한다. 하지만 인간은 AI 같은 기계와 경쟁하는 관계가 아니다. 지난 200여 년간 인간은 놀랄 만한 기술을 개발하고 자동화를 도입했는데, 대부분 인간을 도와주는 역할을 했다. AI도 마찬가지다. 가령 AI가 사람 대신 완전한 글을 쓰지는 못하지만, 보조적인 역할은 충분히 할 수 있다. AI가 만들어주는 문장을 초안 삼아 글을 쓰면 시간을 절약할 수 있을 것이다.”

-그렇다면 AI가 인간의 일자리를 대체할 것이라는 걱정은 기우인가.

“물론 지금까지 기술 발전이 그랬듯 AI도 일부 일자리에 손해를 끼칠 것이다. 예를 들어 미국에서는 매년 세금을 낼 때 모든 수입 내역과 증빙 서류를 당국에 제출해야 하는데, 이 절차가 너무 복잡해서 많은 사람들이 이 일을 세무사에게 맡겼다. 그런데 지금은 이를 처리하는 AI 프로그램이 개발되면서 사람들이 값싼 비용으로 전문적인 서비스를 이용할 수 있게 됐다. 자연히 세무사 수요는 줄어든다. 하지만 아무리 AI가 대세이고 중요한 기술이라고 해도 사람이 하는 모든 일을 완전히 대체할 정도는 아니다. 노동 시장을 완전히 바꾸는 수준은 더더욱 아니다.”

오터 교수는 “AI나 로봇은 인간의 판단에 따라 쓰임새가 결정된다는 점을 기억해야 한다”고 했다. 예를 들어 중국은 전 세계에서 감시나 콘텐츠를 검열하는 데 가장 뛰어난 기술을 갖고 있는데, 이건 중국 당국의 선택과 투자로 인해 가능한 것이지 AI의 고유한 속성 때문은 아니라는 것이다. 그는 “현재로서 우리는 AI가 정확히 어떤 목적으로 사용될지 알 수 없다”며 “그러므로 어느 직업에서 어느 정도까지 인간의 일자리를 빼앗아 갈지 속단하기도 어렵다”고 했다.

 

◇미래에도 읽기·쓰기·말하기·분석이 중요

오터 교수는 다양한 실증 연구를 통해 자동화가 일자리를 빼앗는 게 아니라 오히려 늘린다는 주장을 펴왔다. 2015년 ‘왜 아직도 그렇게 많은 일자리가 있는가’라는 제목의 논문에서도 그는 “자동화와 노동이 상호 보완 작용을 하면서 생산성을 높이고 수입을 증가시키고, 이로 인해 전체 일자리도 늘어날 것”이라고 주장했다. 그런 그도 자동화와 AI가 가져올 양극화에 대해서는 상당한 우려를 갖고 있다. 그는 “현재 소매점 같은 단순 서비스 업종이 구인난에 시달리고 있지만, 장기적으로 이런 일자리는 살아남기 어렵다”며 “전문 지식이 필요 없는 단순 일자리를 줄이고, 법률이나 의료 분야 등 전문 지식을 요구하는 분야에서 일하는 사람을 늘리는 방향으로 가야 한다”고 말했다.

-미래 세대는 어떤 직업이나 전공을 가지는 게 좋을까.

“기계를 잘 활용할 수 있는 사람이 돼야 한다. 의사를 예로 들어 보자. 의사는 전문 지식을 가지고 있지만, 동시에 환자와 꾸준히 소통하는 사람이다. 사람들이 요구하는 것을 지식을 활용해 일종의 ‘번역’을 해야 하는 직업이다. 나는 이를 ‘가치 있는 일’이라고 표현하고 싶다. 이런 일은 기계가 해내지 못한다. 이처럼 앞으로는 전문적인 지식과 사람의 요구를 함께 받아들이고, 자신만의 가치를 만들어낼 수 있는 사람에게 많은 기회가 갈 것이라고 본다. 어떤 전공이 유망할 것이라고 말하기는 어렵다. 사람들이 각자 다른 적성을 갖고 있기 때문이다. 다만 근본적인 것은 바뀌지 않는다. 미래에도 읽기·쓰기·말하기·분석하기가 매우 중요할 것이다. 학교에서 분석적 사고방식을 길러야 하고, 더 나은 추론을 하고 의사 결정을 내릴 수 있도록 정보를 분석하는 능력을 키워야 한다.”

-일각에서는 빅테크 기업들이 AI와 저개발국 노동력을 활용해 이익을 극대화하고 노동력을 착취한다고 비판한다.

“과거 무역이 활발해졌을 때도 부자 나라가 자신들의 이익을 위해 가난한 나라를 착취한다는 비판이 나왔다. 하지만 무역은 한때 개도국이었던 한국이나 중국, 일본 등 많은 나라를 부자로 만들었다. 물론 현재 개도국들이 아마존이나 테슬라 같은 빅테크 기업이 발주하는 단순 업무를 하다 보니 일부 학대당하거나 낮은 임금을 받는 경우도 있다. 하지만 모두가 그런 것은 아니며, 그것이 플랫폼 노동의 본질도 아니다.

오히려 기술이 부족한 나라는 기술력 있는 나라가 무역하고 싶지 않을 정도로 자급자족하는 상황을 경계해야 한다. 예를 들어 선진국이 방글라데시에 ‘우리는 옷을 만들어줄 로봇이 있으니까 더는 당신네 나라에서 옷 살 필요가 없다’든지 ‘이제는 로봇 간호사에게 일을 시키면 된다’며 필리핀에 간호사 수입을 하지 않겠다고 나설 수 있다. 이렇게 되면 하고 싶어도 무역을 하지 못하는 상황이 발생한다. 실제로 미국 의회에서는 로봇이 발전하고 있기 때문에 이민자가 필요 없다는 주장을 하는 사람들이 있다. 이것이 진짜 비극이다.”

-자동화 시대에 정부는 어떻게 대응해야 하나.

“AI와 로봇이 가져올 변화에 대처하려면 교육, 건강, 안전 등 사회안전망을 잘 구축해야 한다. 이런 점에서 미국은 초·중등 교육 시스템에 많은 문제가 있다. 지난 40여 년간 미국은 사람에 대한 투자를 정부가 아닌 민간 기업에 맡겨야 한다는 생각에 이끌렸다. 그러다 보니 교육이나 의료 서비스 부족에 직면해 있다. 안정성이 부족하다 보니 국민은 자신의 잠재력을 발휘하지 못한다. 시장이 중요하고, 정부가 모든 걸 통제해선 안 된다는 말은 맞다. 하지만 현재 미국은 비간섭주의에 지나치게 경도돼 있다고 생각한다.”

[출처] https://www.chosun.com/economy/mint/2023/01/19/NVXUO65PORDQPADJBT3MSKTB74/

 28 total views,  4 views today

1 1월 2023

[ 一日30分 인생승리의 학습법] 일 안 해도 생기는 수입? 그런 ‘패시브 인컴’은 없다

[ 一日30分 인생승리의 학습법] 일 안 해도 생기는 수입? 그런 ‘패시브 인컴’은 없다

코칭을 하다 보면 ‘패시브 인컴’ 얘기를 가끔 듣습니다.

“매일 같은 일을 반복하는 게 힘들다. 그간 진짜 열심히 일해서 사업은 좀 안정된 것 같은데, 이젠 여유를 갖고 싶다. 패시브 인컴을 만들 수 있으면 좀 나아질 것 같다.”

패시브 인컴에 관한 ‘착각’ 

패시브 인컴(Passive Income, 수동 소득)이란 잠자는 동안에도 들어오는, 일을 하지 않아도 따박따박 들어오는 수입을 얘기합니다. 자본 소득, 저작권료, 임대료, 로열티 등이 여기에 속합니다. 많은 사람들의 로망이죠.

마치 휴양지 해변에 누워서 가만히 쉬고 있어도 돈이 계속 들어오는 걸 생각합니다. 그래서 사람들은 패시브 인컴을 일 안 해도 들어오는 돈이라고 착각을 합니다.

근데, 가만히 생각해보면 그런 의미의 패시브 인컴은 존재할 수가 없습니다. 자본 소득과 금융 소득에 중요한 은행 이자만 봐도 고정되어 있지 않고 계속해서 변합니다. 높아질 때도 있고 낮아질 때도 있습니다. 그리고 펀드나 주식은 원금 손실의 리스크가 있습니다.

한마디로 끊임없이 관리하지 않으면 안 됩니다. 임대료 수익도 건물 관리, 공실 관리, 임차인 관리 등 기본적인 관리에 들어가는 노력이 만만치 않습니다. 로열티는 당연히 지급 회사의 실적에 따라 좌우되며, 음악과 서적 등과 같은 저작권료도 지속적인 활동을 하지 않으면 점점 잊히면서 감소할 수밖에 없습니다.

그렇기 때문에, 우리가 막연하게 생각하는 불로소득 같은 패시브 인컴은 존재하지 않습니다. 단기적인 패시브 인컴은 가능하겠지만 지속적인 패시브 인컴은 불가능합니다. 패시브 인컴처럼 보이는 수익 대부분은 물 위에 떠있는 백조와 같습니다. 겉으로는 우아하게 떠 있지만, 물밑에서는 부지런히 발을 움직이고 있습니다.

물속에서도 우아한 백조는 없습니다.

스트레스 없이 돈 버는 방법? 

사람들이 패시브 인컴을 추구하는 이유는 하기 싫은 일을 돈 때문에 억지로 하고 싶지 않기 때문입니다. 나아가 돈에 대한 스트레스 없이 살고 싶기 때문입니다. 그래서 스트레스 없이 일상을 보내는데 돈은 꼬박꼬박 들어오는 것. 모두가 이걸 생각합니다.

그러면 어떻게 하면 스트레스를 받지 않으면서도 돈이 꼬박꼬박 들어올 수 있을까요? 그것은 돈 버는 일이 일상이 되면 됩니다. 스트레스 없이 내가 하고 싶은 일을 하며 사는 데 돈이 들어오는 것입니다. 스트레스란 의식적으로 뭔가를 할 때 발생합니다. 그런데 루틴이 생기고, 어떤 일이 익숙해지고 나면 그부분에 대한 스트레스가 없어집니다.

어릴 때는 을 먹는 일, 처음으로 걸음마를 떼는 일, 아침에 일어나 이를 닦는 일, 이런 것들이 다 스트레스였습니다. 그래서 이런 일에 익숙해지기 위해 생활 습관 훈련을 했습니다. 그러다 그게 익숙해지면 그냥 무의식적으로 하는 일상이 되어버립니다.

어릴 때는 양치질도 스트레스였습니다. 하지만 습관을 통해 익숙해졌죠. 지금은 가끔 귀찮을 수는 있지만, 양치질에 스트레스를 받진 않습니다. 그냥 하는, 해야 하는 일상이니까요. 일도 마찬가지입니다.

일도 마찬가지입니다. 우선은 내가 하는 일이 돈으로 바뀔 수 있는 비즈니스 시스템을 만들고, 그 시스템을 돌리는 일을 일상으로 만드는 것이 중요합니다.

창업해서 성공한 후 엑시트(Exit, 탈출) 하려는 이유는 그 일을 내가 일상으로 할 수 없거나, 그렇게 만들지 못했기 때문입니다. 사업이 잘돼서 돈을 좀 벌고 나면 그 돈으로 여기저기 투자해 놓고 편안하게 살고 싶어집니다. 하지만 투자하는 일 역시도 또 하나의 일입니다. 투자에 대해서 배워야 하고, 투자 대상을 지속해서 관리해야 합니다. 투자에 익숙해지기까지 또 다른 스트레스를 견뎌야 합니다.

창업해서 돈 좀 벌고 나면 다른 곳에 투자해서 마음 편히 살자! ‘엑시트’를 꿈꾸시는 여러분, 그런 탈출은 대개 허상입니다.

패시브 인컴이란 결국 마음의 문제입니다. 내가 돈을 벌고 있는 행위를 패시브하게 만들면 패시브 인컴이 됩니다. 그런 관점에서 보면 취업도, 창업도, 투자도 패시브 인컴으로 만들 수 있습니다. 직장 생활도 루틴이 잡히면 월급이 따박따박 들어오는 패시브 인컴입니다.

패시브 인컴을 얻는 방법은 내가 하고 싶은 일을 찾고, 그 일을 통해서 돈을 벌 수 있는 방법을 찾아 익숙한 일상으로 만들어 버리는 것입니다. 그것이 취업이든, 창업이든, 투자든 상관없습니다.

저는 지속 가능성과 주도권을 위해 나만의 시스템을 만드는 사업을 권장하지만, 그 형태는 결국 내 스타일에 맞는가 아닌가의 문제일 뿐입니다. 다른 곳에서 패시브 인컴을 찾지 말고, 현재 내가 하는 일을 패시브 인컴으로 만들어 보길 바랍니다.

 

이 글은 작가·출판사와의 협의 하에 [창업가의 습관: 시작하고 3년, 사업 시스템을 만드는 법] (이상훈, 좋은습관연구소, 2022)에서 발췌한 내용을 정리한 것입니다.

[출처] https://slownews.kr/85162

 70 total views,  2 views today

31 12월 2022

[profit] 유튜브 VS 블로그 성공방정식 3가지

[profit] 유튜브 VS 블로그 성공방정식 3가지

유튜브 VS 블로그 성공방정식 3가지

어디선 4만뷰 VS 어디선 100뷰가 나온 이유
마케터 초인
2022-09-30

많은 사람들이 시도하고 뛰어들고 있는 유튜브 VS 블로그의 생생한 비교

유튜브와 블로그를 운영하며 경험한 생생한 비교를 통해서 남들이 알려주지 않는 차이점과 노하우를 담아봅니다. 같은 소재와 주제를 가지고 어느 채널에서는 왜 4만 뷰가 나오는지, 어디서는 100뷰가 나오는지 직접 실험을 통해 알게 된 생생한 인사이트. 비즈니스나 개인 채널을 위한 콘텐츠 기획이나 운영에 도움 될 이야기를 전해 드립니다.


지금은 1인 미디어의 시대입니다. 개인이 인플루언서가 되고, 전업 크리에이터가 되어 회사원보다 많은 돈을 버는 시대가 도래했죠. 많은 사람들이 나만의 채널과 콘텐츠를 가지고 자신의 브랜드와 영향력을 만들고 싶어 합니다. 하지만 그만큼 많은 사람들이 부푼 꿈을 안고 시작했다가 좌절을 마주합니다.

가장 많은 사람들이 시도하고 뛰어들고 있는 유튜브 VS 블로그의 생생한 비교를 실제 진행했던 사례를 통해 요긴한 노하우는 담아가고 피해야 할 것을 기억하여 본인이 만들고 있는 또는 앞으로 만들 채널과 콘텐츠에 녹여 빠른 성공을 앞당겨보시기를 바랍니다.


13년 차 마케터의 실험

커리어를 쌓으며 지금까지 ‘본업 외’ 약 14개의 디지털 채널을 운영해오며 여러 실험을 지속하고 있습니다. 유튜브의 경우에는 작은 채널이지만 구독자 대비 20배가 넘는 뷰를 기록하며 쏠쏠한 반응을 얻었던 콘텐츠들이 여럿 있었고, 블로그의 경우에는 지금까지 누적 기준 23만명이 넘는 방문객을 기록하며 2차례 네이버 메인에 오른 적도 있었습니다. (현재는 브런치로 옮겨 블로그 운영은 쉬고 있는 상태)

유튜브와 블로그, 이 두 채널은 어떤 차이가 있을까요?

✅ 유튜브와 블로그, 두 가지 채널의 특징

젊어지고 있는 올드 미디어, 블로그

네이버 블로그가 가장 대표적으로 강력한 포털을 기반으로 오랫동안 이어져 오고 있습니다. 한때는 수익화로 이어지기 어려운 한계가 있어 티스토리나 유튜브 등 다른 채널로 인플루언서들이 많이 이탈하였지만, 여전히 검색과 연계해 가장 많은 트래픽을 일으킬 수 있는 채널로서 네이버의 적극적인 프로모션 공세와 함께 최근 다시 상승하는 추세입니다. 

❗️TMI : 2021년 네이버 블로그 포스팅 수는 전년 대비 50% 상승세를 거두었다고 하고, 주간일기 챌린지 프로모션 등을 통해 타깃을 확장하고 있는데 실제 전체 사용자 수의 70%가 MZ세대라고 합니다.

세대불문 트래픽의 제왕, 유튜브

키즈부터 영어덜트, 시니어에 걸쳐 가장 많은 사용 시간과 트래픽을 모으고 있는 전 세대의 플랫폼입니다. 수십, 수백만 팔로워를 만들며 강력한 영향력을 가진 채널로 만들 수도 있고 한번 터지는 콘텐츠 역시도 큰 포텐셜을 가지고 있기 때문에 가장 많은 사람이 이용하고 있습니다.

❗️TMI : 계속해서 신규 채널이 생겨나 주제별로 다양해지고 있는데, 한편으로는 영상 기반의 플랫폼이기 때문에 블로그 대비 콘텐츠 제작 시간이 더 오래 걸리는 특성을 가지고 있습니다.


✅ 유튜브에서 실패하는 블로거들

블로그에서 더 큰 수익의 꿈을 안고 유튜브로 넘어왔던 많은 블로거들이 유튜브에서 실패를 거두고 있는데 어떤 이유에서 일까요? 그건 두 채널의 차이를 모르기 때문입니다. 직접 블로그와 유튜브 채널을 운영하고 실험하면서 얻은 인사이트 3가지를 담아봅니다.

같은 소재로 다른 반응이 나타난 두 가지 케이스

사례1) 유튜브 영끌의 끝을 달리는 남자 10,855뷰VS 블로그 대출전쟁의 시대 201뷰

사례2) 블로그 남자, 힙한 동굴을 만들다 43,175뷰VS 유튜브 집에 BAR를 만든 남자 114뷰

1️⃣ 썸네일? 키워드? 결과를 가르는 시작

 유튜브 VS  블로그에서 각기 좋은 반응을 얻었던 콘텐츠의 유입경로는 어땠을까?

[유튜브] 본인의 채널에서 가장 많은 조회수를 기록한 영상을 보니 홈 화면에 추천으로 노출되어 유입한 경우가 가장 비중이 높습니다. 여기서 클릭을 높이기 위한 썸네일과 제목이 가장 중요하고 수많은 유튜버들이 이를 강조하는 이유이기도 합니다. 먼저 클릭을 할 수 있도록 매력적인 간판을 만드는 과정이 필요합니다. 

[블로그] 특정 분야의 키워드로 띄워야 하고 반복되는 키워드와 첨부 이미지 활용이 중요합니다. 많은 뷰 수를 기록한 포스팅은 5번 이상 핵심 키워드를 포함하고 최소 3~4장 이상의 이미지가 함께 있었고 이는 기존 포스팅보다 최대 10배의 조회수를 기록할 수 있었습니다. 그리고 네이버 메인에 올랐던 2번의 케이스도 모두 매력적인 이미지를 기반으로 메인에 노출될 수 있었습니다.

이미지와 키워드로 메인에 노출된 여러 사례들 @본인의 블로그

2️⃣ 롱텀? 숏텀? 터지는 콘텐츠의 차이

유튜브 VS  블로그에서 각각 가장 반응이 좋았던 콘텐츠의 추이는 어땠을까?

유튜브는 알고리즘! 노출과 반응이 롱텀으로 지속

한 영상을 살펴보니 유튜브 업로드 후 2달간 조회수 600을 기록했고, 이후 유튜브 알고리즘을 타고 꾸준히 유입이 지속되어 총 1만이 넘는 조회수를 만들 수 있었습니다. 특히 이제 막 시작하는 유튜버는 철저하게 알고리즘을 활용해야 합니다. 알고리즘을 타면 구독자보다 훨씬 높은 조회수를 얻을 수 있고, 더 나아가 콘텐츠 공개 이후 시간이 지난 후에도 상승의 순간을 맞이할 수도 있습니다.

블로그는 검색 키워드! 노출과 반응이 상대적으로 숏텀

블로그는 검색 키워드에 걸리는 것이 중요합니다. 검색창의 1페이지에 걸리거나 메인에 걸리게 된다면 뷰수를 극대화할 수 있습니다. 블로그 포스팅은 시간이 지나 다른 누군가의 포스팅으로 키워드 상단과 메인으로 바뀌기 때문에 계속해서 뷰 수를 쌓아가기에는 어려움이 있습니다. 

3️⃣ 기승전결? 스토리텔링? 결정적 한방!

어느 채널이나 공통적으로 기승전결의 구조화가 필요합니다. 잘 된 콘텐츠는 이 구조가 탄탄하게 갖춰져 있었고, 잘 안된 콘텐츠는 이 구조가 잘 짜여 있지 않았던 것을 확인할 수 있었습니다. 여기에 더해 스토리텔링까지 결합시킨다면 결과는 크게 차이가 날 수 있습니다. 실제로 같은 소재를 가지고 유튜브와 블로그에서 1만 VS 200뷰, 50배의 차이가 나는 결과를 얻게 되기도 하였습니다.

잘 된 유튜브 콘텐츠의 구조 – ‘대출’을 소재로 한 유튜브 콘텐츠

(목표) 대출의 숨겨진 의미를 알고, 투자의 무기로 활용해보자!

(기) 10억의 대출을 가진 남자 > 어쩌다 저렇게 대출을 많이 가지게 되었지? > 클릭!

(승) 요즘 30대가 영끌 대출로 투자를 하고 있다? > 시청자 공감

(전) 돈이란 무얼까? 대출은 권력이다! (하고 싶은 이야기) > 인사이트의 습득

(결) 10억의 대출로 투자를 하게 된 사연과 앞으로의 계획 > 긍정적 인식의 변화

결과 : 1만 조회수 / 댓글 48개

한끗을 가르는 팔리는 비결은
기승전결의 구조화였습니다.

이렇게 콘텐츠를 만들 때 잘 짜여진 구조에 기반해 스토리를 더해 유입시키고 이어 흥미와 공감을 일으키고, 변화의 과정까지 만들어내면 실패의 가능성을 낮추고, 좀 더 빠르게 성장하는 채널을 구축할 수 있을 것입니다. 아래 요약을 잘 기억하시고 이후에 활용하시면 더 높은 반응의 콘텐츠를, 팔리는 콘텐츠를 만드시는 데 도움이 되실 수 있을 것 같습니다. 


⚠️ 기억해야 할 유튜브 VS 블로그의 차이 요약

1️⃣ 뷰어가 접근하는 방식의 차이

✔️유튜브는 클릭을 높이기 위한 썸네일과 제목으로 추천 영상 유입하기

✔️블로그는 검색에 노출되기 위한 반복 키워드와 이미지 활용하기

2️⃣ 터지는 콘텐츠 추이의 차이

✔️유튜브는 알고리즘에 태워서 장기적으로 조회수 높이기

✔️블로그는 검색 상단과 메인 노출로 단기간에 조회수 극대화

3️⃣ 콘텐츠 기획할 때 접근하는 방식 차이

✔️콘텐츠의 시작과 끝, 기승전결의 구조화

✔️스토리텔링을 활용한 공감 높이기

[출처] https://wepick.kr/editor/4344480/

 88 total views

31 12월 2022

[ 一日30分 인생승리의 학습법] 파이토치로 딥러닝해야 하는 5가지 이유

[ 一日30分 인생승리의 학습법] 파이토치로 딥러닝해야 하는 5가지 이유

파이토치가 최근 1.3 및 1.4 릴리스를 통해 풍부한 성능 개선과 모바일 플랫폼용 개발자 친화적인 지원을 제공하면서 강력하게 부상하고 있다. 과연 MX넷, 체이너(Chainer), 텐서플로우(TensorFlow) 등의 다른 프레임워크 대신 파이토치를 선택할 만한 이유가 있을까? 파이토치를 사용해야 할 5가지 이유를 살펴보자.
 
먼저, 기사를 시작하기도 전에 분노의 트윗과 이메일을 보내려 준비하고 있는 텐서플로우 사용자들에게 할 말이 있다. 물론 파이토치가 아닌 텐서플로우를 선택할 이유는 많고, 특히 모바일 또는 웹 플랫폼을 대상으로 작업할 경우에는 텐서플로우가 확실히 유리하다. 이 기사의 주제는 “텐서플로우가 열등하고 파이토치가 뛰어나다”는 것이 아니라, 필자가 파이토치를 가장 먼저 선택하는 이유를 정리하는 것이다. 텐서플로우가 그 나름대로 훌륭하다는 점은 필자도 인정하므로, 너무 분노하지 말기를 바란다.
 

파이토치는 파이썬이다

사람들이 파이토치를 선택하는 주된 이유 중 하나는 코드를 이해하기가 쉽기 때문이다. 파이토치 프레임워크는 파이썬과 씨름하는 것이 아니라, 함께 작동하도록 설계, 제작되었기 때문이다. 모델과 계층뿐 아니라 다른 모든 것, 옵티마이저, 데이터 로더, 손실 함수, 변환 등도 다름아닌 파이썬 클래스다.
 
파이토치는 전통적인 텐서플로우의 정적 실행 그래프가 아닌 즉시 실행 모드로 작동하므로(텐서플로우 2.0은 즉시 실행을 제공하지만 매끄럽지 않은 부분이 있음) 맞춤형 파이토치 클래스를 추론하기가 매우 쉽고 텐서보드(TensorBoard) 또는 print() 문에 이르기까지의 표준 파이썬 기법으로 디버깅하고 스택 트레이스 샘플에서 플레임(flame) 그래프를 생성할 수 있다. 덕분에 판다스(Pandas), 사이킷-런(Scikit-learn)과 같은 다른 데이터 과학 프레임워크에서 딥 러닝으로 넘어온 사람들에게도 상당히 친숙하게 느껴진다.
 
초기 릴리스에서 버전 1.3에 이르기까지 중대한 변경이 하나뿐인(변수에서 텐서로의 변화) 안정적인 API도 파이토치의 장점이다. 물론 가장 큰 이유는 파이토치가 아직 젊은 프레임워크라는 데 있지만, 어쨌든 작성된 버전에 관계없이 대다수 파이토치 코드를 알아보고 이해할 수 있다.
 

파이토치는 즉시 사용할 수 있다

 “바로 사용 가능” 철학이 파이썬의 전유물은 아니지만 파이토치를 설정하고 실행하기는 무척 쉽다. 파이토치 허브를 사용하면 다음과 같은 한 줄의 코드로 된 사전 학습된 ResNet-50 모델을 얻을 수 있다.
 

model = torch.hub.load('pytorch/vision', 'resnet50', pretrained=True)

또한 파이토치 허브는 여러 영역에 걸쳐 통합되므로 텍스트와 오디오, 비전을 모두 다룰 수 있는 원스톱 아키텍처로 적합하다.
 
파이토치에는 모델 외에 풍부한 손실 함수와 옵티마이저도 기본으로 제공된다. 특징은 데이터를 로드하고 내장 변환을 연결하기가 쉽다는 점이다. 또한 자기만의 로더 또는 변환을 만들기도 비교적 간단하다. 모든 것이 파이썬이므로 표준 클래스 인터페이스를 구현하기만 하면 된다.
 
한 가지 사소하지만 주의할 점은 파이토치에 포함된 많은 편의 기능이 비전 문제(토치비전 패키지에서 발견된 문제)에 편향되며 텍스트 및 오디오 지원 중 일부는 부족하다는 점이다. 다행히 1.0 이후부터 토치텍스트와 토치오디오 패키지가 상당히 개선되고 있다.
 

연구에 주도적으로 사용되는 파이토치

파이토치는 연구자들에게는 천국과 같다. 모든 주요 딥 러닝 컨퍼런스의 자료에서도 그 사실을 알 수 있다. 파이토치는 2018년에도 빠르게 성장했지만 2019년에는 CVPR, ICLR, ICML 등의 주요 프레임워크로 부상했다. 이러한 전면적인 도입의 이유는 위에 언급한 점, 즉 파이토치가 곧 파이썬이라는 데 기인한다.
 
표준 파이썬 클래스의 간편하고 안정적인 하위 클래스로 새 맞춤형 구성요소를 만들 수 있으므로 새로운 개념을 실험하기가 훨씬 더 쉽다. 또한 유연하므로 텐서보드, 일래스틱서치(ElasticSearch) 또는 아마존 S3 버킷으로 매개변수 정보를 보내는 계층을 간단히 만들 수 있다. 난해한 라이브러리를 가져와서 네트워크 학습과 함께 사용하거나 학습 루프에서 특이한 새로운 시도를 하고자 하는가? 여기서도 파이토치가 걸림돌이 되는 경우는 없다.
 
그동안 파이토치의 발목을 잡은 한 가지는 연구에서 프로덕션에 이르는 명확한 경로의 부재다. 파이토치가 연구 분야에서 강세라 해도, 실제로 프로덕션 용도는 여전히 텐서플로우가 주도하고 있다. 그러나 파이토치 1.3이 나오고 토치스크립트가 확장되면서 JIT 엔진을 사용해 연구 코드를 그래프 표현으로 컴파일하는 파이썬 주석을 사용하기가 쉬워졌으며 그 결과 속도가 향상되고 C++ 런타임으로 쉽게 내보낼 수 있게 됐다. 또한 지금은 파이토치와 셀던 코어(Seldon Core), 큐브플로우(Kubeflow)의 통합이 지원되므로 텐서플로우에 미치진 못해도 거의 필적할 만큼 간편하게 쿠버네티스에 프로덕션 배포가 가능하다.
 

딥 러닝을 쉽게 배울 수 있다는 장점

딥 러닝 교육 과정은 많지만 그 중에서 fast.ai 과정이 가장 좋다. 게다가 무료다! 과정의 첫 해에는 케라스(Keras)에 상당히 집중했지만 fast.ai 팀(제레미 하워드, 레이첼 토마스, 실바인 구거)은 두 번째 해에 파이토치로 전환했고 그 이후 지금까지 이어오고 있다. (참고로 fast.ai는 텐서플로우용 스위프트에도 상당히 긍정적이다.)
 
fast.ai의 최근 교육 과정에서는 텍스트 및 비전 영역에서 분류, 세그먼테이션, 예측과 같은 작업에 대한 최신 결과를 달성하는 방법을 알아보고, GAN에 대한 모든 것을 배우고 전문가도 눈이 번쩍 뜨일 만한 풍부한 트릭과 통찰력을 찾을 수 있다.
 
fast.ai 과정은 파이토치 위에서 부가적인 추상화를 더 제공하는 fasi.ai의 자체 라이브러리를 사용하지만(덕분에 딥 러닝을 배우기가 더욱 쉬움), 기초적인 부분에 대해서도 심층적으로 다루면서 파이토치와 비슷한 라이브러리를 처음부터 새로 만든다. 따라서 파이토치가 내부적으로 어떻게 움직이는지 잘 이해할 수 있게 된다. fast.ai 팀은 이 과정에서 주 파이토치의 몇 가지 버그도 수정한다.
 

우수한 커뮤니티도 장점

마지막으로, 파이토치 커뮤니티는 정말 유익하다. pytorch.org 웹사이트에는 파이토치 릴리스와 충실히 보조를 맞추는 문서와 함께, 파이토치의 주 기능부터 맞춤형 C++ 연산자를 통해 라이브러리를 확장하는 세부적인 방법에 이르기까지 모든 주제에 관한 자습서도 준비돼 있다. 이 자습서는 학습/검증/테스트 스플릿과 학습 루프 등에 대한 표준화 측면에서 다소 아쉬운 면이 있지만 특히 새로운 기능이 도입될 때 매우 유용한 리소스로 활용할 수 있다.
 
공식 문서 외에, discuss.pytorch.org의 디스코스(Discourse) 기반 포럼은 핵심 파이토치 개발자와 손쉽게 대화하고 도움을 받을 수 있는 훌륭한 리소스다. 매주 1,500개 이상의 글이 올라오며 분위기가 우호적이고 활발하다. 이 포럼에서는 주로 fast.ai의 자체 라이브러리지에 대해 토론하지만 forums.fast.ai에 있는 비슷한 포럼 역시 텃세(슬픈 일이지만 많은 딥 러닝 토론장의 문제) 없이 초보자를 적극적으로 도와주는 훌륭한 커뮤니티이며, 다른 주제도 많이 다룬다.
 

파이토치의 현재와 미래

여기까지 파이토치를 사용할 5가지 이유를 살펴봤다. 처음에 언급했듯이 이 중에는 경쟁 프레임워크 대비 파이토치의 전유물이 아닌 요소도 있지만 이러한 모든 이유의 조합은 필자가 딥 러닝 프레임워크로 파이토치를 선택하는 근거가 된다. 파이토치가 현재 부족한 영역도 있다. 예를 들어 모바일, 희소 네트워크, 쉬운 모델 양자화 등이다. 그러나 빠른 개발 속도를 감안하면 올해 말 정도면 이러한 영역에서도 파이토치가 지금보다 훨씬 더 강세를 보이게 될 것이다.
 
마무리하기에 앞서 두 가지 예만 더 살펴보자. 첫째, 지난 12월에 실험적 기능으로 도입된 파이토치 일래스틱이다. 파이토치의 기존 분산 학습 패키지를 확장해서 대규모 모델 학습을 더 강화한다. 이름에서 알 수 있듯이 이를 위해 탄력성 있는 여러 머신에서 실행되며, 전체 작업을 멈추거나 중단하지 않으면서 언제든 학습 작업에서 노드를 넣고 뺄 수 있다.

두 번째는 오픈AI가 주 개발 플랫폼으로 파이토치를 도입한다고 발표한 것이다. 파이토치에는 매우 중대한 성과다. 오픈AI가 파이토치를 채택했다는 것은 GPT-2(질문에 답하기, 기계 번역, 독해, 요약을 위한 최신 언어 모델)를 만든 사람들이 아이디어를 반복 개발하는 데 있어 파이토치가 텐서플로우보다 더 생산적인 환경을 제공한다고 여긴다는 것을 의미하기 때문이다.
 
프리퍼드 네트웍스(Preferred Networks)가 딥 러닝 프레임워크인 체이너를 유지보수 모드로 전환하고 파이토치로 이전한 데 이어 오픈AI가 파이토치를 도입하기로 결정한 것은 파이토치가 지난 2년 사이 얼마나 많이 발전했는지 잘 보여주며, 파이토치가 앞으로도 계속 개선을 거듭하면서 사용자를 흡수할 것임을 예고한다. AI 영역을 주도하는 이들이 파이토치를 선호한다면 다른 사람들에게도 파이토치가 좋다는 의미일 것이다. editor@itworld.co.kr 

[출처] https://www.itworld.co.kr/news/144936

 191 total views

29 11월 2022

[python][머신러닝] Scikit-learn Tutorial: Machine Learning in Python

[python][머신러닝] Scikit-learn Tutorial: Machine Learning in Python

Scikit-learn Tutorial: Machine Learning in Python

Scikit-learn is a free machine learning library for Python. It features various algorithms like support vector machine, random forests, and k-neighbours, and it also supports Python numerical and scientific libraries like NumPy and SciPy.

In this tutorial we will learn to code python and apply Machine Learning with the help of the scikit-learn library, which was created to make doing machine learning in Python easier and more robust.

To do this, we’ll be using the Sales_Win_Loss data set from IBM’s Watson repository. We will import the data set using pandas, explore the data using pandas methods like head()tail()dtypes(), and then try our hand at using plotting techniques from Seaborn to visualize our data.

Then we’ll dive into scikit-learn and use preprocessing.LabelEncoder() in scikit-learn to process the data, and train_test_split() to split the data set into test and train samples. We will also use a cheat sheet to help us decide which algorithms to use for the data set. Finally we will use three different algorithms (Naive-Bayes, LinearSVC, K-Neighbors Classifier) to make predictions and compare their performance using methods like accuracy_score() provided by the scikit-learn library. We will also visualize the performance score of different models using scikit-learn and Yellowbrick visualization.

To get the most out of this post, you should probably already be comfortable with:

  • pandas fundamentals
  • Seaborn and matplotlib basics

If you need to brush up on these topics, check out these pandas and data visualization blog posts.

The data set

For this tutorial, we will use the Sales-Win-Loss data set available on the IBM Watson website. This data set contains the sales campaign data of an automotive parts wholesale supplier.

We will use scikit-learn to build a predictive model to tell us which sales campaign will result in a loss and which will result in a win.

Let’s begin by importing the data set.

Importing the data set

First we will import the pandas module and use a variable url to store the url from which the data set is to be downloaded.

#import necessary modules
import pandas as pd
#store the url in a variable
url = "https://community.watsonanalytics.com/wp-content/uploads/2015/04/WA_Fn-UseC_-Sales-Win-Loss.csv"

Next, we will use the read_csv() method provided by the pandas module to read the csv file which contains comma separated values and convert that into a pandas DataFrame.

# Read in the data with `read_csv()`
sales_data = pd.read_csv(url)

The code snippet above returns a variable sales_data where the dataframe is now stored.

For those who are new to pandas, the pd.read_csv() method in the above code creates a tabular data-structure known as a Dataframe, where the first column contains the index which marks each row of data uniquely and the first row contains a label/name for each column, which are the original column names retained from the data set. The sales_data variable in the above code snippet will have a structure similar to the diagram represented below.

dataframe-1

Source: Stack Overflow

In the above diagram the row0, row1, row2 are the index for each record in the data set and the col0, col1, col2 etc are the column names for each columns(features) of the data set.

Now that we have downloaded the data set from its source and converted that into a pandas Dataframe, let’s display a few records from this dataframe. For this we will use the head() method.

# Using .head() method to view the first few records of the data set
sales_data.head()
  Opportunity Number Supplies Subgroup Supplies Group Region Route To Market Elapsed Days In Sales Stage Opportunity Result Sales Stage Change Count Total Days Identified Through Closing Total Days Identified Through Qualified Opportunity Amount USD Client Size By Revenue Client Size By Employee Count Revenue From Client Past Two Years Competitor Type Ratio Days Identified To Total Days Ratio Days Validated To Total Days Ratio Days Qualified To Total Days Deal Size Category
0 1641984 Exterior Accessories Car Accessories Northwest Fields Sales 76 Won 13 104 101 0 5 5 0 Unknown 0.69636 0.113985 0.154215 1
1 1658010 Exterior Accessories Car Accessories Pacific Reseller 63 Loss 2 163 163 0 3 5 0 Unknown 0.00000 1.000000 0.000000 1
2 1674737 Motorcycle Parts Performance & Non-auto Pacific Reseller 24 Won 7 82 82 7750 1 1 0 Unknown 1.00000 0.000000 0.000000 1
3 1675224 Shelters & RV Performance & Non-auto Midwest Reseller 16 Loss 5 124 124 0 1 1 0 Known 1.00000 0.000000 0.000000 1
4 1689785 Exterior Accessories Car Accessories Pacific Reseller 69 Loss 11 91 13 69756 1 1 0 Unknown 0.00000 0.141125 0.000000 4

As can be seen from the above display, the head() method shows us the first few records from the data set. The head() method is a very nifty tool provided by pandas that helps us to get a feel of the content of a data set. We will talk more about the head() method in the next section.

Data Exploration

Now that we have got the data set downloaded and converted into a pandas dataframe, lets do a quick exploration of the data see what stories the data can tell us so that we can plan our course of action.

Data exploration is a very important step in any Data Science or Machine Learning project. Even a quick exploration of the data set can give us important information that we might otherwise miss, and that information can suggest important questions we can try to answer through our project.

For exploring the data set, we will use some third party Python libraries to help us process the data so that it can be effectively used with scikit-learn’s powerful algorithms. But we can start with the same head() method we used in the previous section to view the first few records of the imported data set, because head() is actually capable of doing much more than that! We can customize the head() method to show only a specific number of records as well:

# Using head() method with an argument which helps us to restrict the number of initial records that should be displayed
sales_data.head(n=2)
  Opportunity Number Supplies Subgroup Supplies Group Region Route To Market Elapsed Days In Sales Stage Opportunity Result Sales Stage Change Count Total Days Identified Through Closing Total Days Identified Through Qualified Opportunity Amount USD Client Size By Revenue Client Size By Employee Count Revenue From Client Past Two Years Competitor Type Ratio Days Identified To Total Days Ratio Days Validated To Total Days Ratio Days Qualified To Total Days Deal Size Category
0 1641984 Exterior Accessories Car Accessories Northwest Fields Sales 76 Won 13 104 101 0 5 5 0 Unknown 0.69636 0.113985 0.154215 1
1 1658010 Exterior Accessories Car Accessories Pacific Reseller 63 Loss 2 163 163 0 3 5 0 Unknown 0.00000 1.000000 0.000000 1

In the code snippet above, we used an argument inside the head() method to display only the first two records from our data set. The integer ‘2’ in the argument n=2 actually denotes the second index of the Dataframe Sales_data. Using this we can get a quick look into the kind of data we have to work with. For example, we can see that columns like ‘Supplies Group’ and ‘Region’ contain string data, while columns like Opportunity Result, Opportunity Number etc. contain integers. Also, we can see that the ‘Opportunity Number’ column contains unique identifiers for each record.

Now that we have viewed the initial records of our dataframe, let’s try to view the last few records in the data set. This can be done using the tail() method, which has similar syntax as the head() method. Let’s see what the tail() method can do:

# Using .tail() method to view the last few records from the dataframe
sales_data.tail()
  Opportunity Number Supplies Subgroup Supplies Group Region Route To Market Elapsed Days In Sales Stage Opportunity Result Sales Stage Change Count Total Days Identified Through Closing Total Days Identified Through Qualified Opportunity Amount USD Client Size By Revenue Client Size By Employee Count Revenue From Client Past Two Years Competitor Type Ratio Days Identified To Total Days Ratio Days Validated To Total Days Ratio Days Qualified To Total Days Deal Size Category
78020 10089932 Batteries & Accessories Car Accessories Southeast Reseller 0 Loss 2 0 0 250000 1 1 3 Unknown 0.0 0.0 0.0 6
78021 10089961 Shelters & RV Performance & Non-auto Northeast Reseller 0 Won 1 0 0 180000 1 1 0 Unknown 0.0 0.0 0.0 5
78022 10090145 Exterior Accessories Car Accessories Southeast Reseller 0 Loss 2 0 0 90000 1 1 0 Unknown 0.0 0.0 0.0 4
78023 10090430 Exterior Accessories Car Accessories Southeast Fields Sales 0 Loss 2 0 0 120000 1 1 0 Unknown 1.0 0.0 0.0 5
78024 10094255 Interior Accessories Car Accessories Mid-Atlantic Reseller 0 Loss 1 0 0 90000 1 1 0 Unknown 0.0 0.0 0.0 4

The tail() method in the code snippet above returns us the last few records from the dataframe sales_data. We can pass an argument to the tail() method to view only a limited number of records from our dataframe, too:

# Using .tail() method with an argument which helps us to restrict the number of initial records that should be displayed
sales_data.tail(n=2)
Opportunity Number Supplies Subgroup Supplies Group Region Route To Market Elapsed Days In Sales Stage Opportunity Result Sales Stage Change Count Total Days Identified Through Closing Total Days Identified Through Qualified Opportunity Amount USD Client Size By Revenue Client Size By Employee Count Revenue From Client Past Two Years Competitor Type Ratio Days Identified To Total Days Ratio Days Validated To Total Days Ratio Days Qualified To Total Days Deal Size Category
78023 10090430 Exterior Accessories Car Accessories Southeast Fields Sales 0 Loss 2 0 0 120000 1 1 0 Unknown 1.0 0.0 0.0 5
78024 10094255 Interior Accessories Car Accessories Mid-Atlantic Reseller 0 Loss 1 0 0 90000 1 1 0 Unknown 0.0 0.0 0.0 4

We can now view only the last two records from the dataframe, as indicated by the argument n=2 inside the tail() method. Similar to the head() method, the integer ‘2’ in the argument n=2 in the tail() method points to the second index from the last two records in the data set sales_data.

What story do these last two records tell us? Looking at the ‘Opportunity Number’ column of the trailer records from the dataframe, it becomes clear to us that a total of 78,024 records are available. This is evident from the ‘index’ number of the records displayed with the tail() method.

Now, it would be good if we could see the different datatypes that are available in this data set; this information can be handy in case we need to do some conversion later on. We can do that with the dtypes() method in pandas:

# using the dtypes() method to display the different datatypes available
sales_data.dtypes
Opportunity Number int64
Supplies Subgroup object
Supplies Group object
Region object
Route To Market object
Elapsed Days In Sales Stage int64
Opportunity Result object
Sales Stage Change Count int64
Total Days Identified Through Closing int64
Total Days Identified Through Qualified int64
Opportunity Amount USD int64
Client Size By Revenue int64
Client Size By Employee Count int64
Revenue From Client Past Two Years int64
Competitor Type object
Ratio Days Identified To Total Days float64
Ratio Days Validated To Total Days float64
Ratio Days Qualified To Total Days float64
Deal Size Category int64
dtype: object

As we can see in the code snippet above, using the dtypes method, we can list the different columns available in the Dataframe along with their respective datatypes. For example, we can see that the Supplies Subgroup column is an object datatype and the ‘Client Size By Revenue’ column is an integer datatype. So, now we know which columns have integers in them and which columns have string data in them.

Data Visualization

Now that we’ve done some basic data exploration, let’s try to create some nice plots to visually represent the data and uncover more stories hidden in the data set.

There are many python libraries that provide functions for doing data visualization; one such library is Seaborn. To use Seaborn plots, we should make sure that this python module is downloaded and installed.

Let’s set up the code to use the Seaborn module:

# import the seaborn module
import seaborn as sns
# import the matplotlib module
import matplotlib.pyplot as plt
# set the background colour of the plot to white
sns.set(style="whitegrid", color_codes=True)
# setting the plot size for all plots
sns.set(rc={'figure.figsize':(11.7,8.27)})
# create a countplot
sns.countplot('Route To Market',data=sales_data,hue = 'Opportunity Result')
# Remove the top and down margin
sns.despine(offset=10, trim=True)
# display the plotplt.show()

output_16_0

Now that we’ve got Seaborn set up, let’s take a deeper look at what we just did.

First we imported the Seaborn module and the matplotlib module. The set() method in the next line helps to set different properties for our plot, like ‘styles’, ‘color’ etc. Using the sns.set(style="whitegrid", color_codes=True) code snippet we set the background of the plot to a light color. Then we set the plot size with the sns.set(rc={'figure.figsize':(11.7,8.27)})code snippet, which defines the plot figure size to be 11.7px and 8.27px.

Next, we create the plot using sns.countplot('Route To Market',data=sales_data,hue = 'Opportunity Result'). The countplot() method helps us to create a countplot and it exposes several arguments to customize the countplot per our needs. Here, in the first argument of the countplot() method, we defined the X-axis as the column ‘Route To Market’ from our data set. The second argument is the data source, which in this case is the dataframe sales_data that we created in the first section of this tutorial. The third argument is the color of the barplots which we assigned to ‘blue’ for the label ‘won’ and ‘green’ for the label ‘loss’ from the ‘Opportunity Result’ column of the sales_data dataframe.

More details about Seaborn countplots can be found here.

So, what does the countplot tell us about the data? The first thing is that the data set has more records of the type ‘loss’ than records of the type ‘won’, as we can see from the size of the bars. Looking at the x axis and the corresponding bars for each label on the x axis, we can see that most of the data from our data set is concentrated towards the left side of the plot: towards the ‘Field Sales’ and ‘Reseller’ categories. Another thing to notice is that the category ‘Field Sales’ has more losses than the category ‘Reseller’.

We selected the Route To Market column for our plot because it seemed like it would provide helpful information after our initial study of the head() and tail() methods’ output. But other fields like ‘Region’ , ‘Supplies Group’ etc. can also be used to make plots in the same manner.

Now that we have got a pretty good visualization of what our overall data looks like, let’s see what more information can we dig out with the help of other Seaborn plots. Another popular option is violinplots, so let’s create a violin plot and see what that style of plot can tell us.

We will use the violinplot() method provided by the Seaborn module to create the violin plot. Let’s first import the seaborn module and use the set() method to customize the size of our plot. We will seet the size of the plot as 16.7px by 13.27px:

# import the seaborn module
import seaborn as sns
# import the matplotlib module
import matplotlib.pyplot as plt
# setting the plot size for all plots
sns.set(rc={'figure.figsize':(16.7,13.27)})

Next, we will use the violinplot() method to create the violinplot and then use the show() mehtod to display the plot –

# plotting the violinplot
sns.violinplot(x="Opportunity Result",y="Client Size By Revenue", hue="Opportunity Result", data=sales_data);
plt.show()
output_20_0

Now, that our plot is created, let’s see what it tells us. In its simplest form, a violin plot displays the distribution of data across labels. In the above plot we have labels ‘won’ and ‘loss’ on the x-axis and the values of ‘Client Size By Revenue’ in the y-axis. The violin plot shows us that the largest distribution of data is in the client size ‘1’, and the rest of the client size labels have less data.

This violin plot gives us very valuable insight into how the data is distributed and which features and labels have the largest concentration of data, but there is more than what meets the eye in case of violin plots. You can dig deeper into the additional uses of violin plots via the official documentation of the Seaborn module

Preprocessing Data

Now that we have a good understanding of what our data looks like, we can move towards preparing it to build prediction models using scikit-learn.

We saw in our initial exploration that most of the columns in our data set are strings, but the algorithms in scikit-learn understand only numeric data. Luckily, the scikit-learn library provides us with many methods for converting string data into numerical data. One such method is the LabelEncoder() method. We will use this method to convert the categorical labels in our data set like ‘won’ and ‘loss’ into numerical labels. To visualize what we are trying to to achieve with the LabelEncoder() method let’s consider the images below.

The image below represents a dataframe that has one column named ‘color’ and three records ‘Red’, ‘Green’ and ‘Blue’.

dataframe_before-1

Since the machine learning algorithms in scikit-learn understand only numeric inputs, we would like to convert the categorical labels like ‘Red, ‘Green’ and ‘Blue’ into numeric labels. When we are done converting the categorical labels in the original dataframe, we would get something like this:

dataframe_after-1

Now, let’s start the actual conversion process. We will use the fit_transform() method provided by LabelEncoder() to encode the labels in the categorical column such as ‘Route To Market’ in the sales_data dataframe and convert them into numeric labels similar to what we visualized in the above diagrams. The fit_transform() function takes user defined labels as input and then returns encoded labels. Let’s go through a quick example to understand how the encoding is done. In the code example below we have a list of cities i.e. ["paris", "paris", "tokyo", "amsterdam"] and we will try to encode these string labels into something similar to this – [2, 2, 1,3].

#import the necessary module
from sklearn import preprocessing
# create the Labelencoder object
le = preprocessing.LabelEncoder()
#convert the categorical columns into numeric
encoded_value = le.fit_transform(["paris", "paris", "tokyo", "amsterdam"])
print(encoded_value)
[1 1 2 0]

Voila! We have successfully converted the string labels into numeric labels. How’d we do that? First we imported the preprocessing module which provides the LabelEncoder() method. Then we created an object which represents the LabelEncoder() type. Next we used this object’s fit_transform() function to differentiate between different unique classes of the list ["paris", "paris", "tokyo", "amsterdam"] and then return a list with the respective encoded values, i.e. [1 1 2 0].

Notice how the LabelEncoder() method assigns the numeric values to the classes in the order of the first letter of the classes from the original list: “(a)msterdam” gets an encoding of ‘0’ , “(p)aris gets an encoding of 1” and “(t)okyo” gets an encoding of 2.

There are many more functions provided by LabelEncoder() that are handy under a variety of encoding requirements. We won’t need them here, but to learn more, a good place to start is the official page of scikit-learn where the LabelEncoder() and its related functions are described in detail.

Since, we now have a good idea of how the LabelEncoder() works, we can move forward with using this method to encode the categorical labels from the sales_data dataframe and convert them into numeric labels. In the previous sections during the initial exploration of the data set we saw that the following columns contain string values: ‘Supplies Subgroup’, ‘Region’, ‘Route To Market’, ‘Opportunity Result’, ‘Competitor Type’, and ‘Supplies Group’. Before we start encoding these string labels, let’s take a quick look into the different labels that these columns contain:-

print("Supplies Subgroup' : ",sales_data['Supplies Subgroup'].unique())
print("Region : ",sales_data['Region'].unique())
print("Route To Market : ",sales_data['Route To Market'].unique())
print("Opportunity Result : ",sales_data['Opportunity Result'].unique())
print("Competitor Type : ",sales_data['Competitor Type'].unique())
print("'Supplies Group : ",sales_data['Supplies Group'].unique())
Supplies Subgroup' : ['Exterior Accessories' 'Motorcycle Parts' 'Shelters & RV'
'Garage & Car Care' 'Batteries & Accessories' 'Performance Parts'
'Towing & Hitches' 'Replacement Parts' 'Tires & Wheels'
'Interior Accessories' 'Car Electronics']
Region : ['Northwest' 'Pacific' 'Midwest' 'Southwest' 'Mid-Atlantic' 'Northeast'
'Southeast']
Route To Market : ['Fields Sales' 'Reseller' 'Other' 'Telesales' 'Telecoverage']
Opportunity Result : ['Won' 'Loss']
Competitor Type : ['Unknown' 'Known' 'None']
'Supplies Group : ['Car Accessories' 'Performance & Non-auto' 'Tires & Wheels'
'Car Electronics']

We have now laid out the different categorical columns from the sales_data dataframe and the unique classes under each of these columns. Now, it’s time to encode these strings into numeric labels. To do this, we will run the code below and then do a deep dive to understand how it works:

#import the necessary module
from sklearn import preprocessing
# create the Labelencoder object
le = preprocessing.LabelEncoder()
#convert the categorical columns into numeric
sales_data['Supplies Subgroup'] = le.fit_transform(sales_data['Supplies Subgroup'])
sales_data['Region'] = le.fit_transform(sales_data['Region'])
sales_data['Route To Market'] = le.fit_transform(sales_data['Route To Market'])
sales_data['Opportunity Result'] = le.fit_transform(sales_data['Opportunity Result'])
sales_data['Competitor Type'] = le.fit_transform(sales_data['Competitor Type'])
sales_data['Supplies Group'] = le.fit_transform(sales_data['Supplies Group'])
#display the initial records
sales_data.head()
  Opportunity Number Supplies Subgroup Supplies Group Region Route To Market Elapsed Days In Sales Stage Opportunity Result Sales Stage Change Count Total Days Identified Through Closing Total Days Identified Through Qualified Opportunity Amount USD Client Size By Revenue Client Size By Employee Count Revenue From Client Past Two Years Competitor Type Ratio Days Identified To Total Days Ratio Days Validated To Total Days Ratio Days Qualified To Total Days Deal Size Category
0 1641984 2 0 3 0 76 1 13 104 101 0 5 5 0 2 0.69636 0.113985 0.154215 1
1 1658010 2 0 4 2 63 0 2 163 163 0 3 5 0 2 0.00000 1.000000 0.000000 1
2 1674737 5 2 4 2 24 1 7 82 82 7750 1 1 0 2 1.00000 0.000000 0.000000 1
3 1675224 8 2 1 2 16 0 5 124 124 0 1 1 0 0 1.00000 0.000000 0.000000 1
4 1689785 2 0 4 2 69 0 11 91 13 69756 1 1 0 2 0.00000 0.141125 0.000000 4

So what did we just do? First we imported the preprocessing module which provides the LabelEncoder() method. Then we created an object le of the type labelEncoder(). In the next couple of lines we used the fit_transform() function provided by LabelEncoder() and converted the categorical labels of different columns like ‘Supplies Subgroup’, ‘Region’, Route To Market’ into numeric labels. In doing this, we successfully converted all the categorical (string) columns into numeric values.

Now that we have our data prepared and converted it is almost ready to be used for building our predictive model. But we still need to do one critical thing:

Training Set & Test Set

A Machine Learning algorithm needs to be trained on a set of data to learn the relationships between different features and how these features affect the target variable. For this we need to divide the entire data set into two sets. One is the training set on which we are going to train our algorithm to build a model. The other is the testing set on which we will test our model to see how accurate its predictions are.

But before doing all this splitting, let’s first separate our features and target variables. As before in this tutorial, we will first run the code below, and then take a closer look at what it does:

# select columns other than 'Opportunity Number','Opportunity Result'cols = [col for col in sales_data.columns if col not in ['Opportunity Number','Opportunity Result']]
# dropping the 'Opportunity Number'and 'Opportunity Result' columns
data = sales_data[cols]
#assigning the Oppurtunity Result column as target
target = sales_data['Opportunity Result']
data.head(n=2)
  Supplies Subgroup Supplies Group Region Route To Market Elapsed Days In Sales Stage Sales Stage Change Count Total Days Identified Through Closing Total Days Identified Through Qualified Opportunity Amount USD Client Size By Revenue Client Size By Employee Count Revenue From Client Past Two Years Competitor Type Ratio Days Identified To Total Days Ratio Days Validated To Total Days Ratio Days Qualified To Total Days Deal Size Category
0 2 0 3 0 76 13 104 101 0 5 5 0 2 0.69636 0.113985 0.154215 1
1 2 0 4 2 63 2 163 163 0 3 5 0 2 0.00000 1.000000 0.000000 1

OK, so what did we just do? First, we don’t need the ‘Opportunity Number’ column as it is just a unique identifier for each record. Also, we want to predict the ‘Opportunity Result’, so it should be our ‘target’ rather than part of ‘data’. So, in the first line of the code above, we selected only the columns which didn’t match ‘Opportunity Number’and ‘Opportunity Result’ and assigned them to a variable cols. Next, we created a new dataframe data with the columns in the list cols. This will serve as our feature set. Then we took the ‘Opportunity Result’ column from the dataframe sales_data and created a new dataframe target.

That’s it! We are all set with defining our features and target into two separate dataframes. Next we will divide the dataframes data and target into training sets and testing sets. When splitting the data set we will keep 30% of the data as the test data and the remaining 70% as the training data. But keep in mind that those numbers are arbitrary and the best split will depend on the specific data you’re working with. If you’re not sure how to split your data, the 80/20 principle where you keep 80% of the data as training data and use the remaining 20% as test data is a decent default. However, for this tutorial, we are going to stick with our earlier decision of keeping aside 30% of the data as test data. The train_test_split() method in scikit-learn can be used to split the data:

#import the necessary module
from sklearn.model_selection import train_test_split
#split data set into train and test setsdata_train, data_test, target_train, target_test = train_test_split(data,target, test_size = 0.30, random_state = 10)

With this, we have now successfully prepared a testing set and a training set. In the above code first we imported the train_test_split module. Next we used the train_test_split() method to divide the data into a training set (data_train,target_train) and a test set (data_test,data_train). The first argument of the train_test_split() method are the features that we separated out in the previous section, the second argument is the target(‘Opportunity Result’). The third argument ‘test_size’ is the percentage of the data that we want to separate out as training data . In our case it’s 30% , although this can be any number. The fourth argument ‘random_state’ just ensures that we get reproducible results every time.

Now, we have everything ready and here comes the most important and interesting part of this tutorial: building a prediction model using the vast library of algorithms available through scikit-learn.

Building The Model

There’s a machine_learning_map available on scikit learn’s website that we can use as a quick reference when choosing an algorithm. It looks something like this:

ML-cheat-sheet-1

We can use this map as a cheat sheet to shortlist the algorithms that we can try out to build our prediction model. Using the checklist let’s see under which category we fall:

  • More than 50 samples – Check
  • Are we predicting a category – Check
  • We have labeled data? ( data with clear names like opportunity amount etc.) – Check
  • Less than 100k samples – Check

Based on the checklist that we prepared above and going by the machine_learning_map we can try out the below mentioned algorithms.

  • Naive Bayes
  • Linear SVC
  • K-Neighbours Classifier

The real beauty of the scikit-learn library is that it exposes high level APIs for different algorithms, making it easier for us to try out different algorithms and compare the accuracy of the models to see what works best for our data set.

Let’s begin trying out the different algorithms one by one.

Naive-Bayes

Scikit-learn provides a set of classification algorithms which “naively” assumes that in a data set every pair of features are independent. This assumption is the underlying principle of Bayes theorem. The algorithms based on this principle are known as Naive-Bayes algorithms.

On a very high level a Naive-Bayes algorithm calculates the probability of the connection of a feature with a target variable and then it selects the feature with the highest probability. Let’s try to understand this with a very simple problem statement: Will it rain today? Suppose we have a set of weather data with us that will be our feature set, and the probability of ‘Rain’ will be our target. Based on this feature set we can create a table to show us the number of times a particular feature/target pair occur. It would look something like this:

NB_occurancetable-1

In the table above the feature (column) ‘Weather’ contains the labels (‘Partially Cloudy’ and ‘Cloudy’) and the column ‘Rain’ contains the occurrence of rain coinciding with the feature ‘Weather’ (Yes/No). Whenever a feature lcoincides with rain, it’s recorded as a ‘Yes’ and when the feature didn’t lead to rain it is recorded as a ‘No’. We can now use the data from the occurrence table to create another table known as the ‘Frequency table’ where we can record the number of ‘Yes’ and the number of ‘No’ answers that each feature relates to:

NB-Frequency_Table

Finally, we combine the data from the ‘occurrence table’ and the ‘frequency table’ and create a ‘likelihood table’. This table lists the amount of ‘Yes’ and ‘No’ for each feature and then uses this data to calculate the probability of contibution of each feature towards the occurrence of rain:

NB-Probability_Table

Notice the ‘Individual Probability’ column in the table above. We had 6 occurrences of the features ‘Partially Cloudy’ and ‘Cloudy’ from the ‘Occurrence table’ and from the ‘Likelihood table’ it was clear that the feature ‘Partially Cloudy’ had 4 occurrences (2 for ‘No’ and 2 for ‘yes’). When we divide the number of occurrences of ‘No’ and ‘Yes’ of a particular feature with the ‘total’ of the ‘occurrence table’, we get the probability of that particular feature. In our case if we need to find out that which feature has the strongest probability of contributing to the occurrence of Rain then we take the total number of ‘No’ of each feature and add it to their respective number of ‘Yes’ from the ‘frequency table’ and then divide the sum with the ‘Total’ from the óccurances table’. This gives us the probability of each of these features coinciding with rain.

The algorithm that we are going to use for our sales data is the Gaussian Naive Bayes and it is based on a concept similar to the weather example we just explored above, although significantly more mathematically complicated. A more detailed explanation of ‘Naive-Bayes’ algorithms can be found here for those who wish to delve deeper.

Now let’s implement the Gaussian Naive Bayes or GaussianNB algorithm from scikit-learn to create our prediction model:

# import the necessary module
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score
#create an object of the type GaussianNB
gnb = GaussianNB()
#train the algorithm on training data and predict using the testing data
pred = gnb.fit(data_train, target_train).predict(data_test)
#print(pred.tolist())
#print the accuracy score of the model
print("Naive-Bayes accuracy : ",accuracy_score(target_test, pred, normalize = True))
Naive-Bayes accuracy : 0.759056732741

Now let’s take a closer look at what we just did. First, we imported the GaussianNB method and the accuracy_score method. Then we created an object gnb of the type GaussianNB. After this, we trained the algorithm on the testing data(data_train) and testing target(target_train) using the fit() method, and then predicted the targets in the test data using the predict() method. Finally we printed the score using the accuracy_score() method and with this we have successfully applied the Naive-Bayes algorithm to build a prediction model.

Now lets see how the other algorithms in our list perform as compared to the Naive-Bayes algorithm.

LinearSVC

LinearSVC or Linear Support Vector Classification is a subclass of the SVM (Support Vector Machine) class. We won’t go into the intricacies of the mathematics involved in this class of algorithms, but on a very basic level LinearSVC tries to divide the data into different planes so that it can find a best possible grouping of different classes. To get a clear understanding of this concept let’s imagine a data set of ‘dots’ and ‘squares’ divided into a two dimensional space along two axis, as shown in the image below:

SVM-1
Source:StackOverflow

In the image above a LinearSVC implementation tries to divide the two-dimensional space in such a way that the two classes of data i.e the dots and squares are clearly divided. Here the two lines visually represent the various division that the LinearSVC tries to implement to separate out the two available classes.

A very good writeup explaining a Support Vector Machine(SVM) can be found here for those who’d like more detail, but for now, let’s just dive in and get our hands dirty:

#import the necessary modules
from sklearn.svm import LinearSVC
from sklearn.metrics import accuracy_score
#create an object of type LinearSVC
svc_model = LinearSVC(random_state=0)
#train the algorithm on training data and predict using the testing data
pred = svc_model.fit(data_train, target_train).predict(data_test)
#print the accuracy score of the model
print("LinearSVC accuracy : ",accuracy_score(target_test, pred, normalize = True))
LinearSVC accuracy : 0.777811004785

Similar to what we did during the implementation of GaussianNB, we imported the required modules in the first two lines. Then we created an object svc_model of type LinearSVC with random_state as ‘0’. Hold on! What is a “random_state” ? Simply put the random_state is an instruction to the built-in random number generator to shuffle the data in a specific order.

Next, we trained the LinearSVC on the training data and then predicted the target using the test data. Finally, we checked the accuracy score using the accuracy_score() method.

Now that we have tried out the GaussianNB and LinearSVC algorithms we will try out the last algorithm in our list and that’s the K-nearest neighbours classifier

K-Neighbors Classifier

Compared to the previous two algorithms we’ve worked with, this classifier is a bit more complex. For the purposes of this tutorial we are better off using the KNeighborsClassifier class provided by scikit-learn without worrying much about how the algorithm works. (But if you’re interested, a very detailed explanation of this class of algorithms can be found here)

Now, let’s implement the K-Neighbors Classifier and see how it scores:

#import necessary modules
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
#create object of the lassifier
neigh = KNeighborsClassifier(n_neighbors=3)
#Train the algorithm
neigh.fit(data_train, target_train)
# predict the response
pred = neigh.predict(data_test)
# evaluate accuracy
print ("KNeighbors accuracy score : ",accuracy_score(target_test, pred))
KNeighbors accuracy score : 0.814550580998

The above code can be explained just like the previous implementations. First we imported the necessary modules, then we created the object neigh of type KNeighborsClassifier with the number of neighbors being n_neighbors=3. Then we used the fit() method to train our algorithm on the training set, then we tested the model on the test data. Finally, we printed out the accuracy score.

Now that we have implemented all the algorithms in our list, we can simply compare the scores of all the models to select the model with the highest score. But wouldn’t it be nice if we had a way to visually compare the performance of the different models? We can use the yellowbrick library in scikit-learn, which provides methods for visually representing different scoring methods.

Performance Comparison

In the previous sections we have used the accuracy_score() method to measure the accuracy of the different algorithms. Now, we will use the ClassificationReport class provided by the Yellowbrick library to give us a visual report of how our models perform.

GaussianNB

Let’s start off with the GaussianNB model:

from yellowbrick.classifier import ClassificationReport
# Instantiate the classification model and visualizer
visualizer = ClassificationReport(gnb, classes=['Won','Loss'])
visualizer.fit(data_train, target_train) # Fit the training data to the visualizer
visualizer.score(data_test, target_test) # Evaluate the model on the test data
g = visualizer.poof() # Draw/show/poof the data

output_38_0

In the code above, first we import the ClassificationReport class provided by the yellowbrick.classifier module. Next, an object visualizer of the type ClassificationReport is created. Here the first argument is the GaussianNB object gnb that was created while implementing the Naive-Bayes algorithm in the ‘Naive-Bayes’ section. The second argument contains the labels ‘Won’ and ‘Loss’ from the ‘Opportunity Result’ column from the sales_data dataframe.

Next, we use the fit() method to train the visualizer object. This is followed by the score() method, which uses gnb object to carry out predictions as per the GaussianNB algorithm and then calculate the accuracy score of the predictions made by this algorithm. Finally, we use the poof() method to draw a plot of the different scores for the GaussianNB algorithm. Notice how the different scores are laid out against each of the labels ‘Won’ and ‘Loss’; this enables us to visualize the scores across the different target classes.

LinearSVC

Similar to what we just did in the previous section, we can also plot the accuracy scores of the LinearSVC algorithm:

from yellowbrick.classifier import ClassificationReport
# Instantiate the classification model and visualizer
visualizer = ClassificationReport(svc_model, classes=['Won','Loss'])
visualizer.fit(data_train, target_train) # Fit the training data to the visualizer
visualizer.score(data_test, target_test) # Evaluate the model on the test data
g = visualizer.poof() # Draw/show/poof the data

output_41_0

In the code above, first we imported the ClassificationReport class provided by the yellowbrick.classifier module. Next, an object visualizer of the type ClassificationReport was created. Here the first argument is the LinearSVC object svc_model, that was created while implementing the LinearSVC algorithm in the ‘LinearSVC’ section. The second argument contains the labels ‘Won’ and ‘Loss’ from the ‘Opportunity Result’ column from the sales_data dataframe.

Next, we used the fit() method to train the ‘svc_model’ object. This is followed by the score() method which uses the svc_model object to carry out predictions according to the LinearSVC algorithm and then calculate the accuracy score of the predictions made by this algorithm. Finally, we used the poof() method to draw a plot of the different scores for the LinearSVC algorithm.

KNeighborsClassifier

Now, let’s do the same thing for the K-Neighbors Classifier scores.

from yellowbrick.classifier import ClassificationReport
# Instantiate the classification model and visualizer
visualizer = ClassificationReport(neigh, classes=['Won','Loss'])
visualizer.fit(data_train, target_train) # Fit the training data to the visualizer
visualizer.score(data_test, target_test) # Evaluate the model on the test data
g = visualizer.poof() # Draw/show/poof the data

output_43_0

Once again, we first import the ClassificationReport class provided by the yellowbrick.classifier module. Next, an object visualizer of the type ClassificationReport is created. Here the first argument is the KNeighborsClassifier object neigh, that was created while implementing the KNeighborsClassifier algorithm in the ‘KNeighborsClassifier’ section. The second argument contains the labels ‘Won’ and ‘Loss’ from the ‘Opportunity Result’ column from the sales_data dataframe.

Next, we use the fit() method to train the ‘neigh’ object. This is followed by the score() method which uses the neigh object to carry out predictions according to the KNeighborsClassifier algorithm and then calculate the accuracy score of the predictions made by this algorithm. Finally we use the poof() method to draw a plot of the different scores for the KNeighborsClassifier algorithm.

Now that we’ve visualized the results, it’s much easier for us to compare the scores and choose the algorithm that’s going to work best for our needs.

Conclusion

The scikit-learn library provides many different algorithms which can be imported into the code and then used to build models just like we would import any other Python library. This makes it easier to quickly build different models and compare these models to select the highest scoring one.

In this tutorial, we have only scratched the surface of what is possible with the scikit-learn library. To use this Machine Learning library to the fullest, there are many resources available on the official page of scikit-learn with detailed documentation that you can dive into. The quick start guide for scikit-learn can be found here, and that’s a good entry point for beginners who have just started exploring the world of Machine Learning.

But to really appreciate the true power of the scikit-learn library, what you really need to do is start using it on different open data sets and building predictive models using these data sets. Sources for open data sets include Kaggle and Data.world. Both contain many interesting data sets on which one can practice building predictive models by using the algorithms provided by the scikit-learn library.

[출처] https://www.dataquest.io/blog/sci-kit-learn-tutorial/

 103 total views