오늘은 Udacity의 Microsoft Azure Machine Learning 장학금 프로그램에 대한 이야기를 공유하고 싶습니다.
1단계 프로그램은 2020년 7월 8일부터 9월 30일까지 진행되었는데요, 전 세계 10,000명의 학생들이 Microsoft와 Udacity의 큰 지원을 받아 참여하는 프로그램입니다.
10,000명이 참여하는 프로그램이다보니 정말 엄청나게 열정적으로 다양한 아이디어가 공유되는 것을 체험할 수 있었습니다. 저는 마치 대학생 시절로 돌아간 느낌을 받았는데요, 그만큼 학생들과 같이 공부하면서 성장하는 “커뮤니티 리더십”이 모토인 프로그램이기 때문에 그동안의 온라인 코스들 중에서 가장 인상깊었던 프로그램이었습니다.
감사하게도 1단계와 2단계 장학금 프로그램을 모두 참여할 수 있게 되었는데요, 이 프로그램에 대한 간단한 소개 및 배웠던 점을 공유하고자 합니다. 이 글을 읽으시는 분들에게 조금이나마 도움이 되었으면 좋겠습니다 🙂
1. Microsoft Azure Machine Learning Scholarship 프로그램 1단계, 2단계 소개
이 장학금 프로그램에는 두 단계가 있습니다. 첫 번째 단계에서 지원자는 Data Science에 대한 사전 지식과, 이 프로그램에 참여해야하는 이유에 대해서 제출합니다. 첫번째 단계에서는 전세계에서 10,000명이 선발됩니다.
” 이 새로운 Nanodegree 프로그램은 학생들에게 기계 학습 (ML)에서 심화된 기술 능력을 개발할 수있는 기회를 제공합니다. 학생들은 Azure Machine Learning을 사용하여 정교한 ML 모델을 구축하고 배포하여 기술을 강화합니다. ML 모델을 트레이닝하고, ML 파이프 라인을 관리하고, 하이퍼파라미터를 조정하여 모델 성능을 개선하는 방법을 배웁니다. 모델이 준비되면 학생들은 자동화, CI / CD 및 모니터링을 포함한 올바른 MLOps 사례를 사용하여 모델을 운영하는 방법을 배우게 됩니다. “
2. 1단계에서 배웠던 Lessons Learned
전세계 다양한 나라에서 온 열정적인 학생들, 집단지성의 힘
이 프로그램을 진행하는 동안 저는 두 개의 스터디 그룹에 참여했었는데요, 그곳에서 정말 열정적인 다양한 배경을 지닌 분들을 만날 수 있었습니다. 한국, 미국, 모로코, 인도 등 다양한 나라에서 온 Data Science 컨설턴트, 로봇 공학 엔지니어, 헬스케어 Tech Lead, Tableau 전문가, 클라우드 솔루션 아키텍트 전문가 등 정말 다양한 배경의 분들을 만나면서 다양한 영감을 얻었습니다. 매주 일요일 오전 9시부터 오전 11시까지 온라인 스터디 그룹에서 머신 러닝 책 한 권과 Kaggle Competition Challenge를 공부했는데요, 혼자라면 하기 어려웠을 공부를 함께하면서 프로그램이 진행되는 동안 끝까지 같이 마무리할 수 있었습니다.
그 외에도 많은 슬랙 채널에서 활동하는 학생들의 메세지를 읽으면서 배울 수 있었는데요, Kaggle, 커리어, 머신러닝 등 여러 주제에 대해서 토론하는 많은 채널이 있었습니다. 이런 게 있었구나 싶을 정도로 다양하게 의견 교류를 하고 유용한 정보를 활발하게 공유하는 학생들을 보면서, 단기간 내에 이렇게 결속력이 강한 Learning Group에 속해있다는 게 너무 놀랍고 신기했던 순간이 많았습니다.
이 프로그램에서 진행하는 “Student Story Challenge” 이야기도 정말 좋았었는데요, 요즘 상황이 힘들지만 다양한 나라에서 온 많은 분들이 어려운 상황 속에서도 열심히 공부하는 이야기도 많았고, 이 프로그램이 전 세계 사람들을 하나의 커뮤니티로 만들었구나 하는 느낌을 프로그램을 진행하면서 많이 받았습니다.
영감을 주는 다양한 이벤트와 적극적인 서포트
보통 온라인 코스를 수강 할 때는 자기 페이스대로 공부하고 학생들 간의 교류가 많지 않은데요,
특히 이 프로그램은 슬랙을 통해서 굉장히 많은 사람 간의 상호작용이 있습니다. Palak Sadani는 이 프로그램의 커뮤니티 매니저인데요, 1단계가 진행하는 동안 전 세계 만 명의 학생들과 정말 적극적으로 소통했습니다. 저도 이 프로그램 1단계가 진행되는 기간동안 그분으로부터 많은 영감을 주는 공지를 받았었는데 동기부여가 되었습니다.
위의 슬랙 메시지에서 볼 수 있듯이, 학생들을 위한 동기부여 이벤트나 챌린지가 많았기 때문에 꾸준히 학습을 지속하는 것에 도움을 받았습니다.
그리고 학생들은 필요한 경우 스스로 이벤트들을 만들어서 진행했기 때문에, 위에 메세지에 표시된 이벤트 외에도 다양한 이벤트들이 있었습니다.
마이크로소프트 머신러닝 플랫폼 학습 기회
학생들은 클라우드 플랫폼에서 머신러닝 이론과 Microsoft Azure 솔루션을 배울 수 있습니다. 예를 들어, 머신러닝 분야에서 매우 핫한 분야 중에 하나인 Automated Machine Learning과 AI Explainability와 관련된 솔루션을 직접 Hands-On하면서 배울 수 있는 기회가 제공됩니다.
Automated Machine Learning
그리고 Microsoft 전문가를 만날 수 있는 특별한 QnA 라이브 웨비나 시간도 있었습니다. 나중에 녹화본도 제공하지만, 라이브로 참여하고 싶어서 한국 시간으로 새벽 2시에 참여했던 기억이 생생합니다 🙂
3. 마무리하며
이 프로그램에 참여하면서 전세계의 많은 사람들이 배움을 통해 삶을 변화시켜나간다는 것을 느꼈습니다. 팬데믹으로 인해 전 세계적으로 매우 어려운 상황이지만 많은 분들이 Microsoft Udacity Machine Learning Scholarship과 같은 좋은 취지의 프로그램을 통해서 많은 영감을 받으실 수 있었으면 좋겠습니다.
끝으로 Microsoft 사장이신 Satya Nadella의 유명한 명언을 공유하고 싶습니다.
“Finally, I truly believe that each of us must find meaning in our work. The best work happens when you know that it’s not just work, but something that will improve other people’s lives.”
I’d like to share stories for the Machine Learning Scholarship Program for Microsoft Azure in Udacity. The Phase 1 program ran from July 8th to September 30th in 2020.
It was one of the most motivational programs in Udacity since 10,000 students all around the world participated with great supports from Microsoft and Udacity. Because “Community Leadership” is the goal of this program, I was able to naturally learn the positive atmosphere that emphasized learning together energy.
Can you imagine how many ideas can be shared among enthusiastic 10,000 students? 🙂
I was very moved by sincere supports from Microsoft and Udacity. They made miracles for 10,000 students. Palak Sadani is the community leader of this program and she has done awesome works during this 3 months journey. The interactions between people were very special and great advantages here compared to any other learning programs. I felt like I was back in university since there were many special learning events with students.
Thanks to this program, I’ve learned very much by following the learning activities here and I could get the Phase 2 scholarship. I’d like to introduce this program and want to share my personal story during this journey. I hope this post can provide some helpful information to people who are interested in this program.
1. A Brief Introduction for Phase 1 & Phase 2
There are 2 phases for this special scholarship program. In the first phase, applicants will submit about their current knowledge in data science and why they need to particiate in this program. 10,000 students won the 1st phase scholarship.
You can find more information for this scholarship program by referring to the below link.
In the 1st phase, students will learn about machine learning concepts and Azure cloud platforms. Also students can do the hands-on within the Azure environments.
Here, slack is the very important communication channel so students can follow interesting events and learn together. There are great official events but also students voluntarily have created their own learning events.
After the completion of 1st phase, 300 students will win the 2nd phase scholarships for Microsoft Machine Learning Engineer Nanodegree program. This time the program began on October 13th.
“This new Nanodegree program offers students the opportunity to develop deeper technical skills in machine learning (ML). Students will strengthen their skills by building and deploying sophisticated ML models using Azure Machine Learning. They will learn how to train ML models, manage ML pipelines, and tune hyperparameters to improve model performance. Once the model is ready, students will learn how to operationalize the model with the right MLOps practices, including automation, CI/CD, and monitoring” according to the Julia White Corporate Vice President, Microsoft Azure.
2. Special Highlights in Phase 1
There were special highlights in Phase 1.
Enthusiastic Students with Diverse Backgrounds, the Community Power
I’ve joined in two study groups during this program and I could meet interesting people there. A Data Science Consultant, a Robotics Engineer, a Healthcare Tech-Lead, a Tableau Expert, a Cloud Solution Architect Expert …etc from the US, Morocco, India, Korea …etc. Every Sunday from 9 am to 11 am, I studied one machine learning book and one Kaggle competition challenge in the study group. We’ve learn many things by studying together, which would be difficult to do if I were alone.
There were many many active students in many slack channels. For several topics such as kaggle, career, learning subjects, technical issues … there were many slack channels to support all the brilliant ideas. Various youtube links, technical posts … are shared for many times.
There is such a saying in the proverb, “Two heads are better than one”. How about 10,000 students ideas? Creativity exploded 🙂
Also I really loved the stories from “Student Story Challenge” of this program. There are many great people even though situations are hard these days but keep studying hard. I felt that this program made people all over the world into one community.
Motivational Events & Supports
Usually when students take online courses, they study by themselves. There are not many human interactions.
But here, there are many many many human interactions on slack. Palak, who is the community manager of this program, has actively communicated with students all around the world. I’ve often gotten many motivational announcements from her during this program.
As you can see the above slack message, there were many motivational events or challenges for students so it’s easier to keep the learning progress steadily.
Also students can create more official / unofficial events if needed, so actually there were more events.
Microsoft Azure Machine Learning Opportunity
Students can learn machine learning theories and also Microsoft Azure solutions on their cloud platform. Since Microsoft is one of the leading IT companies in the world, the concepts are really interesting and trendy. For example, Automated Machine Learning and AI Explainability are really important topics in Machine Learning. Students can take relevant courses and can do hands-on to practice those important solutions on Azure.
Automated Machine Learning
Also there was a special QnA live webinar to meet Microsoft experts.
3. Conclusion
As I participated in this program, I felt that many people are changing their lives through learning. It is a very difficult situation around the world because of the pandemic, but I hope that many people could find good inspiration and empowerment to create new opportunities from this motivational scholarship program which strongly emphasizes the community during the learning journey.
I would like to conclude this post with one famous quote from Microsoft President Satya Nadella,
“Finally, I truly believe that each of us must find meaning in our work. The best work happens when you know that it’s not just work, but something that will improve other people’s lives.”
이번 포스트에서는 Kaggle의 Real or Not NLP with Disaster Tweet 캐글 컴퍼티션에서 Most Votes를 받은 주피터 노트북 코드를 정리해보려고 합니다. 참고한 코드는 현재 포스트에 표시된 하이퍼링크를 클릭하시면, 보실 수 있습니다. 코드는 그대로 사용하지는 않고, 설명을 위해 약간의 수정을 하였습니다.
이번 포스트의 전체 목차는 크게 4가지로 구성되어 있습니다.
Data Column & Row
Tweet Words Distribution
Tweet Stop Words Distribution
Tweet Most Common Words Distribution
1. Data Column & Row
먼저 데이터를 살펴보도록 하겠습니다.
Columns
id – a unique identifier for each tweet
text – the text of the tweet
location – the location the tweet was sent from (may be blank)
keyword – a particular keyword from the tweet (may be blank)
target – in train.csv only, this denotes whether a tweet is about a real disaster (1) or not (0)
총 5개의 칼럼으로 이루어져 있는데요, id는 각각의 트위터 레코드의 식별자이고, text는 트윗 텍스트, location은 트위터를 보낸 장소, keyword는 트윗의 특정 키워드, target은 트위터가 실제로 재난인지 (1) 아닌지 (0) 를 표시한 것입니다.
location과 keyword는 경우에 따라 null일 수 있고, target은 트레이닝 데이터에만 있습니다. 참고로 캐글 컴퍼티션의 경우 예측하려는 목표 칼럼은 트레이닝 데이터에만 표시가 되어있고, 테스트 데이터에는 그 부분은 비어있어서 컴퍼티션 참여자가 직접 그 부분을 채워서 제출하면 정답은 알 수 없지만 score를 통해 자신이 제출한 답의 정확성을 가늠할 수 있게 되어있습니다.
tweet = pd.read_csv('../input/nlp-getting-started/train.csv')
test = pd.read_csv('../input/nlp-getting-started/test.csv')
tweet.head(3)
pandas 라이브러리를 통해 상위 3개의 레코드를 살펴보면 다음과 같은 데이터가 보입니다. 여기서 tweet은 트레이닝 데이터이고 test는 테스트 데이터입니다. head()는 디폴트로 상위 5개의 레코드를 보여주는데 예시에서는 괄호 안에 3을 명시함으로써 상위 3개의 데이터를 출력합니다.
keyword, location 정보는 비어있고 target의 값은 모두 1로 재난에 대해서 얘기하고 있는 트윗입니다. 내용을 읽어보아도 earthquake (지진), Forest fire (산불), shelter (대피소) 등 재난과 관련성이 깊은 단어들입니다.
print('There are %d rows and %d columns in train' %(tweet.shape[0],tweet.shape[1]))
print('There are %d rows and %d columns in train' %(test.shape[0],test.shape[1]))
트레이닝 데이터 tweet과 테스트 데이터 test 데이터 프레임에서 각각의 row와 column 수를 출력해보면, 다음과 같이 나옵니다. 트레이닝 데이터의 경우 7613개의 row와 5개의 column으로 이루어져있고, 테스트 데이터는 3263개의 row와 4개의 column 입니다. test 칼럼이 4개인 이유는 target 칼럼이 없기 때문입니다. 즉, 정답지는 트레이닝 데이터에만 있고 테스트 데이터는 없습니다.
value_counts()를 통해 전체 데이터에서 target 칼럼에 있는 1,0의 갯수가 어떻게 되는지 알 수 있고, 이를 barplot으로 그리면 다음과 같습니다.
x = tweet.target.value_counts()
sns.barplot(x.index,x)
plt.gca().set_ylabel('samples')
0 (재난이 아님) 의 경우 1 (재난임) 일 때보다 더 많은데요, 실제 세계에서 트윗 전체를 본다면 0이 1보다는 훨씬 더 많지 않을까 싶습니다. 즉, 재난이라는 비상사태에 대해서 말하는 트윗보다는 다른 주제에 대한 트윗의 비중이 높을 것 같습니다.
코드를 좀 더 설명하자면, tweet==0]['text'].str.split() 은 각 트윗에 있는 단어 스트링을 기준으로 split을 한 리스트입니다. ['I', 'love', 'fruits'] 처럼 I love fruits 라는 원 문장을 단어 string 기준으로 쪼갠 리스트입니다. 여기에 map(lambda x: len(x)) 을 적용하면 한 트윗 안에 단어가 몇 개 있는지 알 수 있습니다. ['I', 'love', 'fruits']의 경우는 한 트윗 안에 단어가 3개 있습니다.
전체적으로 보면, 한 트윗 안에 주로 10 ~ 20개 단어 정도 있는 것을 볼 수 있습니다.
한 트윗 내 개별 단어의 길이를 살펴보겠습니다.
fig,(ax1,ax2)=plt.subplots(1,2,figsize=(10,5))
word = tweet[ tweet['target']==1 ]['text'].str.split().apply(lambda x : [len(i) for i in x])
sns.distplot(word.map(lambda x: np.mean(x)),ax=ax1,color='red')
ax1.set_title('disaster')
word = tweet[ tweet['target']==0 ]['text'].str.split().apply(lambda x : [len(i) for i in x])
sns.distplot(word.map(lambda x: np.mean(x)),ax=ax2,color='green')
ax2.set_title('Not disaster')
fig.suptitle('Average word length in each tweet')
Diaster 트윗과 Not Diasaster의 모두 주로 대략 length가 5~6 정도 되는 단어들이 많은 것을 알 수 있습니다.
3. Tweet Stop Words Distribution
이제 stop word가 얼마나 많은지 살펴보려고 하는데, 그 전에 corpus, 말뭉치 리스트를 만들어주는 함수를 정의하여 사용할 것입니다.
def create_corpus(target):
corpus=[]
for x in tweet[ tweet['target']==target ]['text'].str.split():
for i in x:
corpus.append(i)
return corpus
이 함수를 살펴보면, 특정 target 칼럼의 트윗을 string 기준으로 split해서 단어 리스트를 만든 후에, 그 리스트 안에 들어있는 개별 단어를 corpus 라는 리스트에 append를 합니다. 그렇게 해서, 예를 들어 target이 0인 트윗들에 들어있는 모든 단어를 corpus라는 리스트에 전부 append를 하여 target이 0일 때의 전체 단어 리스트를 만드는 것입니다. corpus = create_corpus(0) 이 바로 target이 0인 (즉, 재난이 아닌 경우) 트윗들에 들어있는 모든 단어 리스트를 생성하는 것입니다. 여기에다가 dic이라는 딕셔너리를 생성하여, 만약 corpus 안에 있는 word가 stop이라는 nltk.corpus 말뭉치에서 영어 stop words set 안에서 발견되면, dic에서 word 키를 기준으로 value를 1씩 증가시켜서 해당 word가 전체 단어 리스트에서 얼마나 있는지 카운트를 합니다.
corpus=create_corpus(0)
dic = defaultdict(int)
for word in corpus:
if word in stop:
dic[word]+=1
top=sorted(dic.items(), key=lambda x:x[1],reverse=True)[:10]
참고로 영어 stop words는 from nltk.corpus import stopwords >> stop=set(stopwords.words('english')) 이렇게 정의해서 얻어지는 set 입니다. Python에서 set이란 중복되는 값이 없고, 정렬되지 않는 자료형입니다. 즉, stop이라는 set에는 중복되지 않고 정렬되지 않은 영어 stop words가 들어있습니다.
여기서 top은 stop words dictionary를 value를 기준으로 내림차순으로 정렬하여, 그 중 위에서 10개를 뽑은 리스트입니다. top을 그래프로 나타내면 다음과 같은데, the, a, to 등 재난 여부를 판단할 때 의미없는 단어들의 분포 수를 알 수 있습니다.
x,y = zip(*top)
plt.bar(x,y)
target 1인 트윗들도 위와 같은 방식을 통해서 stop words의 분포를 살펴볼 수 있습니다.
이제 punctuation 문자의 분포를 살펴보겠습니다.
plt.figure(figsize=(10,5))
corpus = create_corpus(1)
dic = defaultdict(int)
import string
special = string.punctuation
for i in (corpus):
if i in special:
dic[i]+=1
x,y=zip(*dic.items())
plt.bar(x,y)
이번에는 target이 1인 트윗들의 총 단어 리스트에서 특수 문자 분포를 살펴보았는데요, 보시면 - 라는 특수문자가 제일 많습니다. target이 0인 경우도 비슷한 방식으로 해보면 - 라는 특수문자가 제일 많습니다.
4. Tweet Most Common Words Distribution
이제 가장 흔한 단어를 살펴보겠습니다. 우선 target이 0인 트윗들의 전체 단어 리스트에서 가장 많은 단어 40개를 고르고, 그 중에서 stop word와 punctuation이 아닌 단어만 뽑아서 barplot을 그려보면 다음과 같습니다.
corpus = create_corpus(0)
counter = Counter(corpus)
most = counter.most_common()
x=[]
y=[]
for word,count in most[:40]:
if (word not in stop and word not in special) :
x.append(word)
y.append(count)
주로 재난 여부와 무관한 단어들이 전체 단어에서 많은 비중을 차지하는 것을 알 수 있습니다. 데이터 클렌징 대상으로 파악될 수 있습니다.
여기까지 데이터 탐색을 해보았고, 다음 포스트에서 Ngram 분석을 진행해보도록 하겠습니다. Ngram이란 n개의 연속적인 단어 나열입니다. 예를 들어, “The book is really interesting” 이라는 문장이 있을 때, n=2인 bigrams로 구분하면 “The book”, “book is”, “is really”, “really interesting”이 됩니다. 다음 포스트는 n=2인 Ngram 분석에 대한 내용입니다.
두 배열에 대해 처리할 때, numpy는 두 배열의 shape을 element-wise 하게 비교합니다. 이때 차원을 살펴보는데, 두 배열이 호환 가능할 때는 다음과 같습니다.
1. 두 축이 똑같거나 또는 2. 둘 중 하나의 축이 1일때 입니다
이 조건이 충족되지 않으면, ValueError: operands could not be broadcast together라는 에러가 발생하면서 배열이 서로 호환되지 않는 shape임을 나타냅니다.
배열은 반드시 같은 차원의 수를 가질 필요는 없습니다. 예를 들어, RGB 값인 256x256x3 배열의 경우, 이미지에 있는 각 컬러를 다른 값에 의해서 확장하고 싶을 때, 그 이미지를 3개의 값으로 이루어진 1차원 배열과 곱할 수 있습니다. 브로드캐스트 규칙에 따라 이러한 배열의 크기에 대해서 다음과 같이 호환가능함을 알 수 있습니다:
Image (3d array): 256 x 256 x 3
Scale (1d array): 3
Result (3d array): 256 x 256 x 3
둘 중 하나의 차원이 1차원인데, 이 1차원이 확장되어서 다른 배열의 차원과 호환이 가능해집니다.
다음 예시를 보면, A와 B 배열 모두 브로드캐스트를 적용할 때 확장이 가능한 길이인 1을 축으로 가지고 있습니다:
A (4d array): 8 x 1 x 6 x 1
B (3d array): 7 x 1 x 5
Result (4d array): 8 x 7 x 6 x 5
브로드캐스트가 가능한 더 많은 예시는 다음과 같습니다:
A (2d array): 5 x 4
B (1d array): 1
Result (2d array): 5 x 4
A (2d array): 5 x 4
B (1d array): 4
Result (2d array): 5 x 4
A (3d array): 15 x 3 x 5
B (3d array): 15 x 1 x 5
Result (3d array): 15 x 3 x 5
A (3d array): 15 x 3 x 5
B (2d array): 3 x 5
Result (3d array): 15 x 3 x 5
A (3d array): 15 x 3 x 5
B (2d array): 3 x 1
Result (3d array): 15 x 3 x 5
아래 예시는 브로드캐스트가 적용이 안 되는 경우입니다:
A (1d array): 3
B (1d array): 4 # 축의 길이가 다릅니다
A (2d array): 2 x 1
B (3d array): 8 x 4 x 3 # A의 축 길이 2와 B의 축 길이 4가 맞지 않습니다
실제 브로드캐스트 예시입니다:
>>> x = np.arange(4)
>>> xx = x.reshape(4,1)
>>> y = np.ones(5)
>>> z = np.ones((3,4))
>>> x.shape
(4,)
>>> y.shape
(5,)
>>> x + y
ValueError: operands could not be broadcast together with shapes (4,) (5,)
>>> xx.shape
(4, 1)
>>> y.shape
(5,)
>>> (xx + y).shape
(4, 5)
>>> xx + y
array([[ 1., 1., 1., 1., 1.],
[ 2., 2., 2., 2., 2.],
[ 3., 3., 3., 3., 3.],
[ 4., 4., 4., 4., 4.]])
>>> x.shape
(4,)
>>> z.shape
(3, 4)
>>> (x + z).shape
(3, 4)
>>> x + z
array([[ 1., 2., 3., 4.],
[ 1., 2., 3., 4.],
[ 1., 2., 3., 4.]])
브로드캐스트는 두 배열의 간단한 outer product(외적) 또는 outer operation을 제공합니다. 다음의 예시는 두 개의 1차원 배열의 outer addition operation을 보여줍니다.
안녕하세요, 머신러닝은 이 세상에서 가장 빠르게 성장하는 분야입니다. 매일 새로운 알고리즘들이 출시되고, 그 중 몇 개는 실패하고 몇 개는 성공합니다. 오늘, 저는 그 중에서도 가장 성공적인 알고리즘 중 하나인, Light GBM을 소개하려고 합니다.
무엇이 저로 하여금 LightGBM에 대한 블로그를 작성하도록 동기부여했을까요?
Kaggle 데이터 분석 경진대회에서 작업할 동안, 저는 여러 개의 강력한 알고리즘들을 접하게 되었습니다. LightGBM은 그 중 하나였죠. LightGBM은 상대적으로 새로운 알고리즘이었고, 인터넷에 공식 문서를 제외하고는 읽기 자료가 많이 없었습니다. 그래서 다큐먼트 상의 길게 나열된 파라미터들로부터 초보자가 파라미터를 선택하는 것은 어려웠죠. 신규 입문자분들을 돕기 위해 저는 이 블로그 글을 쓰게 되었습니다.
수백 개의 불필요한 정보를 추가하는 것은 배우는 입장에서 혼란스러울 수 있기 때문에 이 블로그 글을 간결하게 작성하기 위해 최선을 다하겠습니다.
Light GBM은 무엇일까요?
Light GBM은 Gradient Boosting 프레워크로 Tree 기반 학습 알고리즘입니다.
기존의 다른 Tree 기반 알고리즘과 어떻게 다를까요?
Light GBM은 Tree가 수직적으로 확장되는 반면에 다른 알고리즘은 Tree가 수평적으로 확장됩니다, 즉 Light GBM은 leaf-wise 인 반면 다른 알고리즘은 level-wise 입니다. 확장하기 위해서 max delta loss를 가진 leaf를 선택하게 되는 것이죠. 동일한 leaf를 확장할 때, leaf-wise 알고리즘은 level-wise 알고리즘보다 더 많은 loss, 손실을 줄일 수 있습니다.
아래 다이어그램은 LightGBM와 다른 Boosting 부스팅 알고리즘의 구현을 나타내고 있습니다.
Light GBM 작동 방식다른 Boosting 알고리즘 작동 방식
Light GBM은 어떤 이유로 엄청난 인기를 얻게 되었을까요?
데이터 사이즈는 날이 갈수록 커지고 있고 전통적인 데이터 분석 알고리즘으로 빠른 결과를 얻기란 더욱 어려워졌습니다. Light GBM은 말 그대로 “Light” 가벼운 것인데요, 왜냐면 속도가 빠르기 때문입니다. Light GBM은 큰 사이즈의 데이터를 다룰 수 있고 실행시킬 때 적은 메모리를 차지합니다. Light GBM이 인기있는 또 다른 이유는 바로 결과의 정확도에 초점을 맞추기 때문입니다. LGBM은 또한 GPU 학습을 지원하기 때문에 데이터 사이언티스트가 데이터 분석 어플리케이션을 개발할 때 LGBM을 폭넓게 사용하고 있습니다.
Light GBM은 어디서나 사용할 수 있을까요?
아닙니다. LGBM을 작은 데이터 세트에 사용하는 것은 추천되지 않습니다. Light GBM은 overfitting (과적합)에 민감하고 작은 데이터에 대해서 과적합하기 쉽습니다. row (행) 수에 대한 제한은 없지만 제 경험상 10,000 이상의 row (행) 을 가진 데이터에 사용하는 것을 권유해드립니다.
Light GBM에 대한 컨셉에 대해 대략적으로 논의해보았는데요, 구현은 어떻게 하면 될까요?
Light GBM 구현은 쉽습니다. 다만 한 가지 복잡한 것은 파라미터 튜닝입니다. Light GBM은 100개 이상의 파라미터를 커버하고 있기 때문입니다. 그러나 걱정 마세요 모든 것을 배워야하는 것은 아닙니다.
Light GBM의 가장 베이직한 파라미터를 아는 것이 구현 시 매우 중요합니다. 아래 소개되는 파라미터들을 주의깊게 따라가다보면, 이토록 강력한 알고리즘이 여러분께 매우 쉬운 영역이라는 것을 말씀드립니다.
이제 파라미터에 대한 논의로 넘어가보도록 하겠습니다.
Parameters
파라미터 소개
max_depth : Tree의 최대 깊이를 말합니다. 이 파라미터는 모델 과적합을 다룰 때 사용됩니다. 만약 여러분의 모델이 과적합된 것 같다고 느끼신다면 제 조언은 max_depth 값을 줄이라는 것입니다.
min_data_in_leaf : Leaf가 가지고 있는 최소한의 레코드 수입니다. 디폴트값은 20으로 최적 값입니다. 과적합을 해결할 때 사용되는 파라미터입니다.
feature_fraction : Boosting (나중에 다뤄질 것입니다) 이 랜덤 포레스트일 경우 사용합니다. 0.8 feature_fraction의 의미는 Light GBM이 Tree를 만들 때 매번 각각의 iteration 반복에서 파라미터 중에서 80%를 랜덤하게 선택하는 것을 의미합니다.
bagging_fraction : 매번 iteration을 돌 때 사용되는 데이터의 일부를 선택하는데 트레이닝 속도를 높이고 과적합을 방지할 때 주로 사용됩니다.
early_stopping_round : 이 파라미터는 분석 속도를 높이는데 도움이 됩니다. 모델은 만약 어떤 validation 데이터 중 하나의 지표가 지난 early_stopping_round 라운드에서 향상되지 않았다면 학습을 중단합니다. 이는 지나친 iteration을 줄이는데 도움이 됩니다.
lambda : lambda 값은 regularization 정규화를 합니다. 일반적인 값의 범위는 0 에서 1 사이입니다.
min_gain_to_split : 이 파라미터는 분기하기 위해 필요한 최소한의 gain을 의미합니다. Tree에서 유용한 분기의 수를 컨트롤하는데 사용됩니다.
max_cat_group : 카테고리 수가 클 때, 과적합을 방지하는 분기 포인트를 찾습니다. 그래서 Light GBM 알고리즘이 카테고리 그룹을 max_cat_group 그룹으로 합치고 그룹 경계선에서 분기 포인트를 찾습니다. 디폴트 값은 64 입니다.
Core Parameters
핵심 파라미터 소개
Task : 데이터에 대해서 수행하고자 하는 임무를 구체화합니다. train 트레이닝일 수도 있고 predict 예측일 수도 있습니다.
application : 가장 중요한 파라미터로, 모델의 어플리케이션을 정하는데 이것이 regression 회귀분석 문제인지 또는 classification 분류 문제인지를 정합니다. Light GBM에서 디폴트는 regression 회귀분석 모델입니다.
regression: 회귀분석
binary: 이진 분류
multiclass: 다중 분류
boosting : 실행하고자 하는 알고리즘 타입을 정의합니다. 디폴트값은 gdbt 입니다.
gdbt : Traditional Gradient Boosting Decision Tree
rf : Random Forest
dart : Dropouts meet Multiple Additive Regression Trees
goss : Gradient-based One-Side Sampling
num_boost_round : boosting iteration 수로 일반적으로 100 이상입니다.
learning_rate : 최종 결과에 대한 각각의 Tree에 영향을 미치는 변수입니다. GBM은 초기의 추정값에서 시작하여 각각의Tree 결과를 사용하여 추정값을 업데이트 합니다. 학습 파라미터는 이러한 추정에서 발생하는 변화의 크기를 컨트롤합니다. 일반적인 값은 0.1, 0.001, 0.003 등등이 있습니다.
num_leaves : 전체 Tree의 leave 수 이고, 디폴트값은 31입니다.
device : 디폴트 값은 cpu 인데 gpu로 변경할 수도 있습니다.
Metric parameter
지표 파라미터
metric : 모델을 구현할 때 손실을 정하기 때문에 중요한 변수 중에 하나입니다. regression과 classification 을 위한 일반적인 손실 값이 아래에 나와있습니다.
mae : mean absolute error
mse : mean squared error
binary_logloss : loss for binary classification
multi_logloss : loss for multi classification
IO parameter
IO 파라미터
max_bin : feature 값의 최대 bin 수를 의미합니다.
categorical_feature : 범주형 feature의 인덱스를 의미합니다. 만약 categorical_features 가 0, 1, 2 이면 column 0, column 1, column 2 가 범주형 변수들입니다.
ignore_column : categorical_features와 동일한 것인데 범주형 feature로써 특정 칼럼을 고려하지 않는 것입니다. 그 변수들을 무시하는 것입니다.
save_binary : 데이터 파일의 메모리 사이즈를 처리해야 한다면 이 파라미터 값을 True로 설정하십시오. 이 값을 True로 세팅하면 데이터 세트를 바이너리 파일로 저장할 것이고, 이 바이너리 파일은 다음에 데이터를 읽어올 때 그 속도를 줄여줄 것입니다.
위에 설명드린 파라미터들을 알고 사용하는 것은 모델을 구현할 때 도움이 될 것입니다. LightGBM 모델 구현은 쉽지만 파라미터 튜닝은 어렵다는 것을 앞서 말씀드렸습니다. 이제 구현을 시작해보도록 하겠습니다. 제가 파라미터 튜닝에 대한 아이디어를 그 과정에서 드리도록 하겠습니다.
저는 Anaconda를 사용하고 있고 LightGBM을 아나콘다에 설치하는 것은 가능합니다. 단지 Anaconda 명령 프롬프트 창에서 다음의 명령어를 실행시켜주시면 됩니다.
conda install -c conda-forge lightgbm
데이터 세트:
이 데이터는 400개의 행과 5개의 칼럼으로 구성된 매우 작은 데이터입니다. (학습 목적으로 특별히 사용되는 것입니다.) classification 분류 문제로, 웹사이트 광고에 나온 제품을 살지를 예측하는 문제입니다. 데이터 세트는 여기서 다운로드가 가능합니다.
Note: 이 데이터 세트는 깨끗하고 결측치가 없습니다. 매우 단순한 데이터를 고른 이유는 튜토리얼이 단순하고 이해가 쉽도록 하기 위해서입니다.
저는 이 설명을 읽는 분들이 Python의 기본을 안다고 가정하겠습니다. 데이터 전처리 스텝을 쉽게 따라가실 수 있지만 만약 코멘트란에 물어보고 싶은 것이 있으시다면 답변을 드리도록 하겠습니다.
데이터 전처리 :
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# Importing the dataset
dataset = pd.read_csv('...input\Social_Network_Ads.csv')
X = dataset.iloc[:, [2, 3]].values
y = dataset.iloc[:, 4].values
# Splitting the dataset into the Training set and Test set
from sklearn.cross_validation import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 0)
# Feature Scaling
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
x_train = sc.fit_transform(x_train)
x_test = sc.transform(x_test)
모델 빌드 및 트레이닝 :
트레이닝 데이터를 LightGBM에 맞는 데이터 세트 포맷으로 변환해야합니다. (LightGBM 트레이닝에 있어서 필수적입니다.)
변환된 데이터 세트 생성 이후에, 파라미터와 그 값으로 구성된 Python Dictionary 파이썬 딕셔너리를 생성했습니다. 모델의 정확도는 설정된 파라미터 값에 전적으로 달려 있습니다.
“binary” 가 objective 로 사용됨 (이것이 classification 분류 문제라는 것을 기억해주십시오)
“binary_logloss”가 metric 으로 사용됨 (마찬가지 이유로, binary classification 문제라는 것을 기억해주십시오)
num_leaves 는 10 (왜냐면 작은 데이터이기 때문입니다)
boosting type 은 gbdt 인데, gradient boosting 을 구현하고 있기 때문입니다. (random forest 를 시도하실 수 있습니다.)
모델 예측 :
예측을 위한 몇 줄의 코드를 작성해야합니다.
결과는 확률 리스트일 것입니다. 저는 확률을 binary prediction으로 변환했고 threshold 값은 0.5로 유지했습니다.
#Prediction
y_pred=clf.predict(x_test)
#convert into binary values
for i in range(0,99):
if y_pred[i]>=.5: # setting threshold to .5
y_pred[i]=1
else:
y_pred[i]=0
결과 :
confusion matrix 나 또는 바로 accuracy를 계산해서 결과를 확인할 수 있습니다.
Code :
#Confusion matrix
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)
#Accuracy
from sklearn.metrics import accuracy_score
accuracy=accuracy_score(y_pred,y_test)
결과 스크린샷 :
Confusion MatrixAccuracy 정확도 점수
어떤 분들은 데이터 세트가 작았는데 모델 정확도가 92%나 되었다고 생각하실 수도 있겠습니다. 과적합은 왜 발생하지 않았을까요? 가장 단순한 이유는 모델 파라미터를 튜닝했기 때문입니다.
이제 파라미터 튜닝 문제로 넘어가도록 하겠습니다.
파라미터 튜닝 :
데이터 사이언티스트는 언제나 어떤 파라미터를 언제 사용할지 그리고 어떤 값이 최적의 파라미터 값일지 결정하기 위해 고민합니다.
아래 소개되는 기법들은 모델 정확도를 향상시키기 위해 사용될 수 있습니다.
num_leaves : Tree 모델의 복잡성을 컨트롤하는 주요 파라미터입니다. 이상적으로 num_leaves 값은 2 ^ (max_depth) 값보다 적거나 같아야 합니다. 이것보다 많은 값은 과적합을 유발할 것입니다.
min_data_in_leaf : 큰 값으로 세팅하는 것은 Tree가 너무 깊게 확장되는 것을 막을 수 있지만 under-fitting 언더 피팅이 발생할 수도 있습니다. 관행적으로, 수백 또는 수천 개로 정하는 것이 큰 데이터 세트에 충분합니다.
max_depth : Tree 깊이를 명확하게 제한하기 위해 max_depth 값을 설정할 수도 있습니다.
더 빠른 속도를 위하여 :
bagging_fraction과 baggin_freq 을 설정하여 bagging 을 적용하십시오
feature_fraction을 설정하여 feature sub-sampling을 하십시오
작은 max_bin 값을 사용하십시오
save_binary 를 값을 통해 다가오는 학습에서 데이터 로딩 속도를 줄이십시오
parallel learning 병렬 학습을 적용하십시오
더 나은 정확도를 위해 :
큰 max_bin 값을 사용하십시오 (아마 속도는 느려질 수 있습니다)
작은 learning_rate 값을 큰 num_iterations 값과 함께 사용하십시오
큰 num_leaves 값을 사용하십시오 (아마 과적합을 유발할 수도 있습니다)
더 큰 트레이닝 데이터를 사용하십시오
dart 를 사용하십시오
범주형 feature를 사용하십시오
과적합을 해결하기 위해 :
작은 max_bin 값을 사용하십시오
작은 num_leaves 값을 사용하십시오
min_data_in_leaf 와 min_sum_hessian_in_leaf 파라미터를 사용하십시오
bagging_fraction 과 bagging_freq 을 사용하여 bagging 을 적용하십시오
feature_fraction을 세팅하여 feature sub-sampling을 하십시오
lambda_l1, lambda_l2 그리고 min_gain_to_split 파라미터를 이용해 regularization (정규화) 를 적용하십시오
max_depth 를 설정해 Deep Tree 가 만들어지는 것을 방지하십시오
결론 :
저는 다양한 데이터 세트에서 LightGBM 을 구현해보았고 다른 부스팅 알고리즘보다 정확도가 좋다는 것을 발견하였습니다. 제 경험상, 이 알고리즘을 적어도 한 번은 시도해보는 것을 추천드립니다.
이 블로그를 읽는 것이 도움이 되었으면 좋겠습니다. 이 블로그를 발전시키기 위한 제안을 주시면 감사하겠습니다.
Xgboost 알고리즘! 오늘은 Xgboost 알고리즘 공부한 내용에 대해 공유하려고 합니다.
Xgboost는 Extreme Gradient Boost라고 해서 Decision Tree 기반 앙상블 머신러닝 알고리즘인데 Gradient Boosting 프레임워크를 사용합니다. Structured Data (정형 데이터)를 가지고 예측할 때 매우 우수한 성능을 보이는 알고리즘으로 주목을 받았습니다. Regression 또는 Classification 같은 예측 분석에 사용됩니다.
Datacamp라는 웹사이트에서 Xgboost라는 알고리즘에 대해서 굉장히 잘 정리해주어서 이 글을 살펴보시는 것을 추천드려봅니다 🙂
Xgboost 알고리즘 메소드는 다음과 같습니다. Regression 모델인 경우, 모델 오브젝트를 아래와 같이 생성해서 predict 할 수 있는데요, 자세한 내용은 Datacamp의 튜토리얼 링크에서 보면 좋습니다. 여기서 아래 code snippet에 사용된 parameter 값에 대한 summary를 하려고 합니다.
objective 는 loss function 손실함수입니다. reg:linear라는 부분은 linear regression 모델의 손실함수를 사용한다는 의미겠죠. 이 부분은 gradient boosting이 적용되어서 그런 것 같습니다. 즉 예측한 값과 실제 값의 차이를 줄이는 프레임워크이다보니 loss function의 개념이 들어간 것 같습니다.
2. colsample_bytree
각 tree별 사용된 feature의 퍼센테이지라고 합니다. 값이 높을수록 오버피팅이 됩니다.
3. learning_rate
학습속도
4. max_depth
Boosting 시에 얼마나 각각의 tree가 깊게 커질 수 있는지에 대한 정도
5. alpha
L1 regularization 값인데 큰 값일 수록 더 regularization 하는 것입니다. (모델의 복잡도를 줄이고 over fitting을 줄이기 위해서)
6. n_estimators
빌드하고 싶은 tree의 수입니다.
다른 분들도 혹시 공부하시다가 글을 보면서 가볍게 정리할 수 있으면 좋을 것 같아 글을 작성해보았습니다. 이상입니다. 감사합니다 🙂
데이터 분석을 공부하다보면 흔하게 마주치는 이름들이 있습니다. Linear, Ridge, Lasso, elasticNet… 회귀모델 4인방입니다. 어디선가 한 번 쯤 들어본 듯한 이분들(?)에 대해 최대한 쉬운 언어로 + Python 핸즈온 코드로 정리해보도록 노력하였습니다.
Ridge, Lasso, elasticNet의 경우는 수식을 전부 이해하시지 않더라도 sklearn에서 세 모델을 돌리기위해서 조정하는 값은 alpha 하나이기 때문에 코드를 돌리시는 데는 무리가 없지만 그래도 alpha라는 값이 모델에서 어떤 의미인지 이해하기 위해서는 수식에 대한 설명을 따라오시면 좋을 것 같습니다.
+ 이 글에서 Ridge 회귀모델을 잘 이해할 수 있다면 나머지 Lasso, elasticNet은 응용되는 개념이기 때문에 좀 더 순조롭게 이해하실 수 있습니다. 수식이 이해가 되지 않으시더라도 괜찮습니다!! 지금은 이해 안 가셔도 나중에 갑자기 이해가 되실 수 있으니 편안하게 읽어주시면 좋습니다.
위에 공식은 위키백과에서 복사 붙여넣기를 한 것인데요, 쉽게 얘기하면 y라는 종속변수와 한 개 이상의 설명 변수(=독립변수) x들과의 선형 상관관계를 모델링하는 회귀 분석 모델이 바로 Linear Regression, 선형 회귀 모델입니다.
좀 더 쉽게 예시를 들어보겠습니다. 파운드와 킬로그램은 선형적 상관 관계를 가지고 있습니다. 7개 데이터를 가지고 점을 찍어보면 파운드 x와 킬로그램 y는 대략적으로 선형적 관계를 가지고 있다는 것을 확인할 수 있습니다. 즉 파운드 x 값에 어떤 weight를 곱하고 bias를 더해주면 킬로그램 y 값이 나오는 것입니다.
이제 sklearn 사이킷런 라이브러리의 LinearRegression 모델을 임포트해서 pound 데이터를 x, kilogram 데이터를 y로 학습시킨 후 해당 모델로 30 pounds가 몇 kilograms인지 예측해보도록 하겠습니다.
# load library
import numpy as np
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
%matplotlib inline
import warnings warnings.filterwarnings("ignore", category=DeprecationWarning)
# define data
kilograms = np.array([49, 10, 0, 21, 44, 2, 100], dtype=float).reshape((-1,1))
pounds = np.array([108.027, 22.0462, 0, 46.2971, 97.0034, 4.40925, 220.462], dtype=float).reshape((-1,1))
for i,c in enumerate(kilograms):
print("%s Kilograms = %s Pounds" %(c, pounds[i]))
이렇게 하면 결과가 아래와 같이 출력됩니다. 49 킬로그램은 108.027 파운드이구요, 10 킬로그램은 22.0462 파운드입니다. 이 데이터를 그래프로 그린 게 바로 위에 보여지는 scatter plot 산점도입니다.
이제 이 데이터를 가지고 선형회귀 모델로 학습을 해서 과연 30 파운드는 몇 킬로그램인지를 예측해보도록 하겠습니다~!
from sklearn.linear_model import LinearRegression
# create a linear regression model
model = LinearRegression()
# train data
model.fit(pounds, kilograms)
# predict data - 30.0 pounds to kilograms
result_kilograms = model.predict([[30.0]])
print('30.0 pounds >> %s kilograms' %(result_kilograms[0][0]))
30 파운드가 바로 아래처럼 약 13.6078 킬로그램인 것을 알 수 있습니다.
30.0 pounds >> 13.607745297753652 kilograms
구글에 pounds to kg 로 쳐보시면 놀랍도록!! 선형회귀로 예측한 결과가 정확하신 것을 보실 수 있습니다.
# print weights and bias
print(model.coef_[0][0])
print(model.intercept_[0])
weights와 bias를 출력해보면 값은 아래와 같습니다.
0.4535926229261759
-3.3390031624946914e-05
이를 다시 공식화 해보면, 아래 수식이 됩니다.
y (kilograms) = 0.4535926229261759 * x (pounds) + (-3.3390031624946914e-05)
이 수식으로 다시 계산해보면 모델이 예측한 값과 동일한 것을 더블 체크해볼 수 있습니다.
# re-calculate based on the weights and bias
# output y kilograms = input x pounds * weights + bias
# 13.607745297753652 = 30.0 * 0.4535926229261759 + -3.3390031624946914e-05
30.0*model.coef_[0][0]+model.intercept_[0]
13.607745297753652
위에서 점으로 그렸던 실제 데이터 산점도 위에 모델로 예측한 값이 얼마나 일치하는지 그래프로 시각화 해보겠습니다.
# draw data with linear regression model
plt.title('Kilograms and Pounds')
plt.xlabel('Pounds')
plt.ylabel('Kilograms')
plt.plot(pounds, kilograms,'k.')
plt.grid(True)
plt.plot(pounds, model.predict(pounds))
보시면 실제 데이터 (점) 과 예측한 모델 (선) 이 겹치는 것을 보실 수 있습니다.
이제 회귀분석 몸풀기로 Linear Regression을 살펴보았으니~~ 그 다음으로 Ridge, Lasso, elasticNet Regression 모델을 살펴보겠습니다.
Ridge, Lasso, elasticNet 회귀 분석에서는 multicollinearity 다중공선성 문제와 over-fitting 과적합 문제 방지를 위해 아래와 같은 정규화 방식이 적용되었습니다.
Ridge 회귀 모델은 L2 정규화
Lasso 회귀모델은 L1 정규화
elasticNet은 Ridge의 L2와 Lasso의 L1 정규화 혼합
+ 여기서 multicollinearity 다중공선성이란 독립변수 x들간의 강한 상관관계가 나타나서, 독립변수들이 독립적이지 않는 문제가 발생하게 되는 현상을 말합니다. 이 경우 coefficient 추정치가 부정확해지고 standard error 값이 높아지게 됩니다.
참고로 Ridge, Lasso 수식에 대한 설명은 Saptashwa Bhattacharyya 님의 글을 참고하였습니다.
Cost Function 비용함수는 간단하게 말하면 y (실제 결과값)과 y^ (모델로 추정한 결과값)의 차이(에러)를 제곱해서 합한 것입니다. 차이를 그냥 다 더하지 않고 제곱한 이유는 그냥 전부 더하면 0이 되버리기 때문에 차이에 대한 제곱을 더한 것입니다. 실제로 손수 계산해서 해보시면 제곱 안 하고 다 더하는 경우 0이 되는 것을 확인하실 수 있습니다.
+ 참고로 MSE라고 흔히 줄여서 말하는 Mean Squared Error는 Cost Function을 데이터 수 n만큼 나눠준 것이라고 보시면 됩니다.
Mean Squared Error
Ridge 릿지 회귀는 Linear Regression 선형 회귀모델의 Cost Function 비용함수에 페널티를 적용한 것입니다. 여기서 페널티는 Lambda * 계수 coefficient 제곱의 합입니다. 이때 Lambda 값이 0에 가까워지면 Ridge는 본래 Linear Regression의 Cost Function에 가까워지게 됩니다.
반면에 Lambda의 값이 어느 정도 크다면, coefficient의 크기가 줄어서(0에 가까워져서) 모델의 복잡도가 줄어들고 multicollinearity 문제의 영향을 줄어들게 할 수 있게 됩니다. 왜냐면 서로 영향을 미치는 독립변수들의 weight가 줄어드는 것이기 때문입니다.
Ridge 릿지의 Cost Function 비용함수
이제 Lasso 라쏘 회귀를 살펴보겠습니다.
Lasso 라쏘의 Cost Function 비용함수
Ridge와 수식은 비슷하지만 한 가지 차이점은, 페널티의 계산이 Lambda * coefficient 제곱합이 아니라 Lambda * coefficient 절대값의 합이라는 것입니다. 이 계산은 L1 정규화 방식이고, zero coefficient 를 만드는 것이 가능해집니다. 즉, 어떤 독립변수의 경우 아예 사라지게 될 수도 있게 되면서 feature selection, 상대적으로 더 중요한 독립변수를 선택할 수 있게 됩니다.
Lasso는 특정 독립변수의 coefficient 값을 0으로 만들 수 있고 Ridge는 0에 가까워지게 하지만 Lasso처럼 0으로 만들 수는 없다는 차이점이 있습니다.
즉 Ridge의 L2, Lasso의 L1을 합쳐서 비용함수를 계산한 것이라고 보면 됩니다.
alpha가 0에 가까우면 elasticNet은 Ridge에 가까워지고, alpha가 1에 가까우면 elasticNet은 Lasso에 가까워지게 됩니다. elasticNet을 사용하게 되면 Ridge처럼 coefficient의 크기를 줄이면서 Lasso처럼 특정 coefficient를 0으로 만들어 버리면서 특정 독립변수를 사라지게 하는 feature selection 효과를 누릴 수 있게 됩니다.
이제 sklearn 사이킷런의 관련 라이브러리들을 임포트해서 간단한 데이터로 핸즈온을 해보도록 하겠습니다. 참고한 코드는 아래 주석에 출처 표시가 되어있습니다. Ridge에 대해서만 코드를 살펴보도록 하겠습니다. 나머지 Lasso, elasticNet 구현은 비슷한 로직으로 되어있기 때문에 제 Github을 참고해주시면 됩니다.
# Reference
# https://www.datatechnotes.com/2019/08/elasticnet-regression-example-in-python.html
# https://towardsdatascience.com/ridge-and-lasso-regression-a-complete-guide-with-python-scikit-learn-e20e34bcbf0b
#load library
from sklearn.datasets import load_boston
from sklearn.linear_model import Ridge, RidgeCV, Lasso, LassoCV, ElasticNet,ElasticNetCV
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np
# load boston house price data
boston=load_boston()
x, y = boston.data, boston.target
xtrain, xtest, ytrain, ytest = train_test_split(x, y, test_size=0.2,random_state=3)
alphas = [0.0001, 0.001, 0.01, 0.1, 0.3, 0.5, 0.7, 1]
# Ridge Regression
# select alpha 0.0001 or 0.001 or 0.01 by checking R2, MSE, RMSE
for a in alphas:
model = Ridge(alpha=a).fit(x,y)
score = model.score(x, y)
pred_y = model.predict(x)
mse = mean_squared_error(y, pred_y)
print("Alpha:{0:.4f}, R2:{1:.2f}, MSE:{2:.2f}, RMSE:{3:.2f}"
.format(a, score, mse, np.sqrt(mse)))
위 코드를 보시면 alpha를 0.0001 또는 0.001 또는 0.01 로 선택해야겠다는 판단을 할 수 있는데요 R2는 제일 높고(제일 설명력이 좋고), MSE(Mean Squared Error)와 RMSE(Root Mean Squared Error)는 제일 낮은 값을 기준입니다.
이렇게 봤을 때 좀 애매할 수 있어서 Cross Validation 을 돌려서 최적의 alpha를 출력해보도록 하겠습니다.
+ Cross Validation이란 데이터 세트를 여러 등분을 해서 반복적으로 교차 검증 (트레이닝 및 테스트)를 돌리는 것입니다. 나중에 기회가 되면 Cross Validation Test에 대해서 정리해보도록 하겠습니다.
# run Ridge cross validation test to find the best alpha based on training data
ridge_cv=RidgeCV(alphas=alphas, cv=5)
model = ridge_cv.fit(xtrain, ytrain)
print(model.alpha_)
cv를 5로 했다는 것은 5등분을 해서 교차검증을 5번 했다고 보시면 됩니다. 위에 코드를 실행시키면 결과적으로 alpha는 0.0001이 출력되는데요, 이 말은 alpha를 0.0001로 했을 때 테스트 세트에 대한 예측이 확률적으로 좋았다는 것입니다.
class sklearn.preprocessing.StandardScaler(copy=True, with_mean=True, with_std=True)에 있는 fit_transform() 메소드는 말 그대로 fit()한 다음에 transform() 하는 것입니다. 여기서 fit()이란 정규화 즉, 통계에서 정규분포를 만들게 하기 위해서 𝑥 값에서 평균을 빼고 그 값을 다시 표준편차로 나누어주는 작업을 하는데 이 작업을 하기 위해 평균 𝜇과 표준편차 𝜎를 계산하는 작업이 fit() 이고, transform()은 정규화 작업을 해주는 것입니다. (𝑥-𝜇)/𝜎 ==> 새로운 𝑥′ 생기는 것이죠
트레이닝 데이터에 대해서 fit 작업과 transform 작업을 적용해주는 것이 fit_transform이고 여기서 계산된 평균 𝜇과 표준편차 𝜎를 동일하게 테스트 데이터에 적용해서 정규화 작업을 해주는 경우는 transform()만 적용합니다. 테스트 세트에도 트레이닝 데이터에 적용되었던 동일한 평균과 표준편차를 적용하기 위해서 이전에 fit_transform()에서 계산된 값들이 저장된 상태에서 transform()에 적용되는 것입니다.
아래 출처를 따라가 보시면 fit_transform의 파라미터들을 자세히 살펴보실 수 있습니다.