반응형

7개월 된 아기와 첫 가족여행!

서울 근교 풀빌라를 검색하다가 달빛베베풀빌라를 찾게되었어요

수많은 숙소 중에 이 풀빌라를 선택한 이유는 1. 온수풀 2. 멋진 뷰 3. 장난감 외 유아용품 구비 였어요

 

 
 

개별 온수풀이 있어서 저희 가족끼리만 사용할 수 있었던 점이 좋았어요

사장님이 매일 매일 청소 하시고 새 물로 받아주신다니 안심하고 쓸 수 있었답니다

바로 샤워실이 있어 수영 후 씻기도 편했어요

구비되어있는 튜브와 비치볼도 잘 썼구요 유아 전용 참방이존에서도 무척 즐거워했어요

숙소 가기 전부터 저의 마음을 빼앗은 멋진 뷰!

아이낳고 여행가본지가 언제인지.. 숙소 분위기도 놓칠 수 없겠더라구요

넓은 통창과 바다 풍경이 정말 마음에 들었어요

숙소에 놀거리가 많아 따로 장난감을 챙길 필요가 없는 것도 좋았어요

아직 배밀이만 하는 아기라 좀더 커서 오면 더 잘 놀겠죠?

체크아웃 아침에 찍은 사진이라 조금 부산해보이지만 첫인상은 매우 깔끔했어요

또 젖병 세척솔, 소독기, 세정제가 있어서 짐을 덜 수 있었죠 센스 짱짱

마지막으로 침실!

호텔식 침구를 매일 새 것으로 교체한다고 하셨는데 정말 깔끔하고 편안한 잠자리였습니다

청결과 안전을 최우선으로 관리하는 숙소인만큼 머무르는 동안 몸과 마음이 편안한 여행이었어요

가족여행숙소로 추천해요!!

 

반응형
반응형

[목차]

 

1. 아기는 생각보다 너무 예쁘다. 

2. 평소의 체력이 이 때 쓰인다.

3. 오롯이 부부 둘이서 해나가는 것도 나쁘지 않다.

4. 늘 신경써주기

5. 순간의 행복을 실감한다.

 

 

1. 아기는 생각보다 너무 예쁘다. 


나도 아내도 몰랐다. 둘 다 이렇게 팔불출이 될 줄은

이쁠거라고 예상정도만 했지 이렇게 엎어질 줄은 몰랐다.

아내는 아이를 낳기 전까지 아이들이 별로 귀엽지 않아서 내 아이도 안 예뻐하면 어쩌지 하는 쓸데없는 걱정도 했다.

 

똥을 싸도 예쁘고, 내 옷에 오줌을 싸도 예쁘고, 토해도 예쁘다.

아들이어도 너무 예쁘고 귀엽다. (내심 딸을 바랐다.)

 

중요한 것은 결혼하고 아이를 낳기 전까지, 절대로 이 기분을 상상할 수 없었다는 것이다.

진정한 경험의 세계이다. 육아의 국면에 들어서기 전까지는, 이 기쁨을 절대로 알 수가 없다.

 

 

2. 평소의 체력이 이 때 쓰인다.


육아는 잠과의 사투다.

밤에 2~3시간에 한 번씩 깨는 아이를 달래고 먹이고 재우는 과정을 하다보면, 두 사람이 번갈아가면서 해도 지치게 되어 있다.

 

더불어서 집안일, 새롭게 아이를 케어하며 생기는 모든 일들을 부부가 나눠서 하다보면 집안일이 끝나지를 않는다.

출근하는 사람은 그 피곤을 갖고 그대로 일터로 나가게 되어있다.

 

지치고 피곤하면 날이 서기 쉽고, 한 사람의 평온함이 다른 사람의 분노가 되기도 한다.

그래서 체력이 중요하다. 남는 체력으로 최대한 배우자의 짐을 덜겠다는 마인드를 지녀야 한다.

 

그리고 이 때 피곤을 이겨내며 지켜낸 아내의 한시간의 잠이 가정의 평화를 이룩한다.

체력은 정말 중요하다. 평소에 길러놓지 않으면, 더더욱이나 힘들다.

 

 

3. 오롯이 부부 둘이서 해나가는 것도 나쁘지 않다.


우리는 친정이나 시댁의 도움을 받지 않는다.

엄밀히 말하면 받지 못하기 때문에 둘이서 해나가는 것이지만, 100일의 기적을 3주 정도 앞둔 지금 시점에서 되돌아보면 이 과정이 오히려 더 좋았다고도 볼 수 있다.

 

그 이유로 첫째, 자족감이 생긴다.

우리 둘이가 온전히 이 과정을 겪어내고 서로 의지하며 지나왔다는 사실이 뿌듯하다. 그리고 서로를 바라보는 애틋함, 그리고 약간 짠함이 섞이며 돈독해진다.

 

둘째, 양가에 부담을 느끼지 않는다.

어떤 식으로든 도움을 구한다는 것은 빚을 지는 일처럼 느껴지기 마련이다. 부모님들은 기꺼이 해주실 수 있으나, 우리 부부 마음 속 깊은 곳에서는 부채감이 생길 수밖에 없다. 공짜는 없다. 부모님들이 도와주신다면, 돈이든 마음이든 발걸음이든 그들께서 원하시는 것을 우리가 맞춰드리는 것이 인지상정이다. 그래서 온전히 둘이 이 초반 육아를 감당해나가는 사실이 우리를 오히려 더 자유롭게 하는 측면이 있다.

 

 

4. 늘 서로 신경써주기


나는 아내를 바라보며 그녀가 겪어야 하는 커다란 변화를 상상했다.

몸의 변화, 마음의 변화, 그리고 호르몬의 변화, 환경의 변화들을 상상하며 그녀가 겪을 혼란과 적응할 시간이 필요함을 이해하려고 하다보니, 자연히 아내의 필요를 찾아 움직이게 되는 것 같다.

나의 아내도 좋은 사람인지라, 그런 나의 마음을 금방 알아채고 내게도 더 잘해주려고 한다. 서로 짠한가보다.

아내도 새벽에 두어번씩 깨며, 꾸벅꾸벅 눈을 감고 아이를 달래고 아침에 출근하는 나를 보며 비슷한 생각을 하는 듯하다.

 

서로 밖에 없다. 내가 아내를 물심양면 챙기고 내가 맞추는 삶이 행복한 삶이다.

 

 

 

5. 순간의 행복을 실감한다.


아이를 안고 미소를 지으며 행복이 지금임을 실감한다.

늘 허상같은 행복을 좇지만, 실은 행복은 이미 내 곁에 있는 것, 이미 주어진 것이다.

 

아이가 있음으로써 이 사실을 더욱 실감할 수 있다.

 

 

 

결론적으로 육아는 추천한다. 걱정했던 것보다는 덜 힘들고, 즐거움은 더 많은 것 같다.

반응형

'Other Topics > 육아일기' 카테고리의 다른 글

달빛베베풀빌라 숙소 후기  (0) 2023.01.29
반응형

[목차]

 

1. 현재 상태

2. 내 커리어 여정

3. 취업준비생으로서 겪었던 어려움

4. 내가 추천하는 방법

5. 앞으로의 커리어

 

1. 현재 상태


나는 현재 국내 회계법인 컨설팅 회사의 데이터 관련 조직에서 일하고 있다.

 

이 조직에서 하는 일은 크게는 Data Science와 Data Platform / Governance / Road Map 수립 등이 있다.

 

Data Science는 고객의 문제를 정의 후 알고리즘, 통계 등을 이용하여 해결하는 업무이다.

Data Platform은 빅데이터 플랫폼 수립, 데이터 인프라 등과 관련된 전반적인 컨설팅 업무를 의미한다.

그 외 Governance / Road Map 등은 데이터를 어떻게 관리하고, 프로젝트를 시작할 지 모르는 기업들을 컨설팅하는 서비스이다.

 

2. 내 커리어 여정


나는 BI(Business Intelligence) 부문에서 커리어를 시작했다.

쉽게 얘기하자면, 시각화 개발이고, QlikView를 내 처음 Tool로써 접했다.

 

개인적으로 시각화 툴로써 데이터를 접했던 과정이, 어떻게 데이터를 핸들링하고 가공해야 하는지 이해하고 그 과정을 직접 시각화로 확인할 수 있어서 좋은 시작점이었다고 본다.

 

그리고 회사를 현재의 컨설팅 회사로 옮겨 지표 설계 ~ 개발까지의 업무를 모두 진행해보고 있다.

추가된 것은, 내가 고객의 비즈니스를 최대한 이해하고, 회사의 Asset을 활용하여 고객에게 선제시 한다는 점이다.

 

3. 취준생으로서 겪었던 어려움


취업 준비를 할 당시만 해도 데이터 분야의 정보가 너무 적었다.

 

다들 개발 얘기를 하거나, 머신러닝이나  AI 이야기를 했을 뿐이고,

그리고 Python이 얼마나 중요하고 시각화를 만드는 기술이 어떻고라는 기술에 대해서 주로 이야기가 오갔다.

 

그래서 "진짜 데이터로 Business를 어떻게 해결한다는걸까?" 라는 질문에 대답을 해줄 수 있는 사람이 극히 드물었다. 드문 정도가 아니라 내게는 없었다.

 

그래서 면접 때마다 공허한 얘기를 늘어놓아야 했는데, 이게 내가 맞닥드린 가장 큰 어려움이었다.

 

더불어 나는 대학시절을 탱탱 놀다가 취업전선에 뛰어들어 Tool 들에 익숙하지 못했는데, 이게 무척 높은 허들이었다.

 

4. 내가 추천하는 지원 방법


그럼에도 불구하고 내가 적용했던 방법은 바닥부터 시작하는 일이었다.

 

BI 개발을 시작했던 회사의 면접 때가 생각나는데, 나는 연속 낙방을 하느라 조금 지쳐있었다.

일부 회사에서는 내가 아무것도 없으면서, 무언가를 만들어본양 허풍을 늘어놓기도 했다.

 

그러나 면접관들은 거짓을 잘 분별할 줄 안다.

내가 이 업에서 조금만 있어봐도 누가 허황된 말을 하는지 금방 판별할 수 있다.

 

그래서 나는 면접에서 나를 내려놓고, 나는 아무것도 아는 게 없지만 열정을 가지고 배워볼 자신이 있다고 스스로를 어필했다. 그리고 이 점을 당시 나를 뽑아주셨던 본부장님께서 좋게 보신 모양이다.

일은 들어와서 배워도 되지만, 얼마나 열심히 하려고 하는지, 진실하게 원하는 지를 평가하신 것 같았다.

 

결론을 얘기하자면, 어떤 회사라도 첫 커리어로 괜찮다.

너무 대기업에 들어가려고 하거나, 네카라쿠배당토에 목 맬 필요는 없지 싶다.

 

어느 회사든 들어가서 일을 하고, 공부하면서 기술과 데이터를 이해하기 시작하면 그 다음 길은 점점 넓어질 것이기 때문이다. 나는 그렇게 느끼고 있으며, 앞으로도 그렇게 될 것이라 생각한다.

 

5. 앞으로의 커리어


사실 나 역시도 너무나 많은 고민을 하고 있다. 특히 아래와 같은 고민을 하며 살고 있다.

 

개발자의 끝은 무엇인가? 컨설턴트의 끝은 무엇인가? 데이터 분석가는 20년 30년 분석가로서 남을 수 있는가? 앞으로 나는 살아남을 직업을 선택하고 있는가? 

 

과거 선배들의 말은 이미 지나간 과거에 유효하며, 세상은 너무 빨리 바뀌고 기술도 자꾸 변한다. 그래서 그들의 말을 참고는 하되 너무 맹신할 필요는 없다. 그들도 모르게 낡았을 수도 있기 때문이다.

 

따라서 Data를 무기로 가져가되, 여러 기술에 관심을 가지고 Business에 이런 기술들을 접목할 지 계속 고민하는 것 만이 앞으로의 변화에 대응하는 길이라고 본다.

반응형
반응형

개요


  • 결혼을 준비하면서 2022년 2월 16일 전세계약을 체결했고 "서울시 신혼부부 임차보증금 이자지원"사업을 신청하였음
  • 지금 살고 있는 집이 2억 정도이므로 약 1.8억을 대출받았으며(90%), 최종 1.5% 정도의 이자율을 책정받았고, 월 약 25만원 정도를 매달 내고 있음
  • 2023.2 기준, 이율이 올라 2.12%, 32만원 정도를 납부중
  • 신혼부부이고, 서울시에 거주 예정이고, 전세로 시작한다면 가장 좋은 조건으로 전세대출을 받을 수 있는 정책

사업소개



서울시주거포털 - 신혼부부 임차보증금 이자지원

사업개요 | 신혼부부 임차보증금 이자지원 | 청년·신혼부부 지원 | 주거 정책 | 서울주거포털

서울주거포털,신혼부부들의 행복한 미래를 위해 더 나은 주거환경과 소득대비 높은 주거비 부담을 완화하기 위해 신혼부부 임차보증금 지원사업을 시행합니다.   ※ 신청 전 유의사항 : 서울시

housing.seoul.go.kr


img

  • 핵심 조건
    • 신혼부부 또는 예비 신혼부부
    • 부부합산 소득 9,700만원 이하
    • 서울시 관내의 임차보증금 7억원 이하의 주택, 오피스텔, 다세대 주택 등 (상세 내용은 PDF 참조)
  • 취급은행
    • 국민, 신한, 하나
      • 나는 주거래은행이었던 신한은행에서 했으며, 당시 국민은행은 지원자 TO가 없다고 했음

진행순서


  1. 전세매물 찾기
    • 네이버 부동산으로 열심히 전세 매물을 찾는다.
    • 마음 속의 금액을 중심으로 찾으며 목표하는 매물들의 대략적인 대출금액을 알아둔다.
  2. 은행 방문
    • 은행에 방문하여 본인이 해당 사업의 대출이 가능한지 알아본다.
    • 예비 배우자의 전세 상황도 공유하여 대출이 가능한지 등등을 꼼꼼히 따지고 다음 스탭을 진행한다.
    • 개인적으로 은행을 여러 번 방문하여 등기를 보여주며 해당 매물이 가능할지 물어보았다. 처음이라 불안함이 컸다.
  3. 전세매물 계약
    • 전세매물을 찾고 전세대출이 가능한 매물인지 반드시 확인. 불법건출물은 아닌지, 해당 매물에 과도한 빚은 없는지 등등
    • 매물이 확정되면 계약을 하되, 전체 계약금의 5% 이상을 지불했다는 지급 영수증을 반드시 챙긴다. (부동산 중개인이 전세대출한다고 하면 서류를 대부분 챙겨준다.)
    • 계약하면 그 이후 바로 확정일자를 받으러 간다. 등기소로 가거나 해당 주민센터로 가면 확정일자를 받아준다. 확정일자가 찍혀있어야 은행에서 대출을 실행해준다.
  4. 서울주거포털 신청
    • 서울시 주거포털융자신청서 신청
    • 3일 정도 걸린다고 하나, 보통 다음날이면 담당자가 확인해줌
    • 나는 2번 정도 반려되었었는데 대부분 오타나 잘못 기입한 정보였으므로 처음부터 꼼꼼하게 작성할 것을 추천
    • 추천서가 발급되면 출력해서 나머지 서류들과 함께 챙기기
  5. 은행 방문
    • 은행 방문은 배우자와 함께 가야 함
    • 같이 못가는 경우 사업소개공고문을 확인하여 적절한 서류들을 챙겨야 한다.
    • 서류는 아래와 같이 챙겨야 한다.
      • 신분증
      • 주민등록등본
      • 가족관계증명서
      • 혼인관계증명서(예비부부의 경우 혼인관계증명서를 예식장 계약서로 갈음)
      • 임대차계약서(확정일자부)
      • 지급영수증
      • 융자추천서
      • 건물등기사항전부증명서
      • 근로소득원천징수영수증(or 월급여명세서 12개월치)
      • 재직증명서(or 건강보험자격득실확인서)
  6. 대출 실행 및 잔금 치르기
    • 대출이 승인되면 잔금일에 맞춰 은행에서 집주인 계좌로 송금하게 된다.
    • 잔금을 치르고 잔금일에 전입신고를 해준다.

주의사항


  • 서류가 정말 많다. 일시에 따라 서류가 바뀔 수도 있으니 꼭 공고문을 다시 확인하고 서류를 챙겨가길 바람
  • 임대차계약서의 확정일자는 잔금일이 아니라 계약일에 받아야 한다. 확정일자가 안찍혀있으면 대출을 실행할 수 없다.
  • 각자 사정에 따라 궁금한 부분이 많을텐데, QnA문서를 꼼꼼히 읽어보면 대부분 해결할 수 있다. 나는 해당 문서를 프린트해서 형관펜으로 확인해가며 세부사항을 확인했다.
  • 애매한 부분이 있다면 협약은행에 반드시 문의할 것을 당부드린다.

대환하는 경우



아내가 중소기업청년전세대출이 있어서 대환의 형식을 거쳤다.(당연히 중복해서 대출하는 기간이 있으면 안된다.) 우리 부부가 대환을 진행한 순서는 아래와 같다.

  1. 아내가 살던 방 내놓고 들어올 세입자와의 잔금일 확인
    • 해당 잔금일은, 우리 부부가 들어갈 잔금일보다 1주일 정도 빨라서 기간이 조금 촉박했다.
    • 은행에 방문해서 어떻게 해야 하는지 자주 물어봤다. 신한은행의 모바일톡도 애용했다.
  2. 위 대출 순서 중 5번, 은행방문 시에 아내의 대출금이 먼저 상환될 것임을 알리고 대출을 진행한다.
    • 대출이 상환되면, 일정 영업일이 지나야 상환된 내역이 데이터로 남는다고 한다.
    • 상환이 확인되면 곧바로 다음 대출 승인이 진행된다.
    • 단점은 1주일정도 거주할 공간이 없는 일자가 생기는데, 이는 각자의 사정에 맞게 해결이 필요하다.
반응형
반응형

경사하강법 정의


경사 하강법(傾斜下降法, Gradient descent)은 1차 근삿값 발견용 최적화 알고리즘이다. 기본 개념은 함수의 기울기(경사)를 구하고 경사의 반대 방향으로 계속 이동시켜 극값에 이를 때까지 반복시키는 것이다
위키피디아

이 개념을 숙지하기 위해서는 비용함수라는 개념을 먼저 알아두면 좋다.

비용함수

$$y = w_1*x_1 + w_0$$ 라는 회귀식이 있을 경우, 이 함수의 *_비용함수 RSS**는 다음과 같다. (약간의 회귀분석에 대한 개념이 필요)

$$RSS(w_0, w_1) = \frac{1}{N}\sum_{i=1}^{N}(y_i-(w_0+w_1*x_i))^2$$

여기서 N은 학습데이터의 총 건수이며, i는 각 데이터포인트이다. 회귀에서는 이 RSS는 비용이라고 하며 w변수로 구성되는 RSS를 비용함수, 또는 손실함수(loss function)라고 한다. 머신러닝 회귀 알고리즘에서는 데이터를 계속 학습하면서 이 비용함수가 반환되는 값을 지속해서 감소시키고, 최종적으로는 더이상 감소하지 않는 최소의 오류값을 구하고자 한다.
오류값을 지속해서 작아지게 하는 방향으로 W값을 계속 업데이트해 나가며, 오류값이 더 이상 작아지지 않으면 그 오류값을 최소 비용으로 판단하고 그 W를 최적의 파라미터로 판단한다.

머신러닝에서 쓰이는 이유

그럼 비용함수가 최소가 되는 W파라미터를 어떻게 구할 수 있을까? 하는 대답에 경사하강법이 사용되는 것이다. 모든 변수(x)를 미분하여 최소값을 가지는 계수를 찾아내는 방법이 있을 수 있으나 아래의 이유로 경사하강법이 쓰인다.

  • 실제 분석에서는 함수의 형태가 복잡하므로 미분계수와 그 근을 계산하기 어려움
  • 컴퓨터로는 미분계산과정의 구현보다 경사하강법 구현이 더 쉬움
  • 데이터 양이 많을 수록 경사하강법이 계산량 측면에서 효율적임

경사하강법의 수식, 유도 및 원리

경사하강법을 유도하는 원리는 아래 사이트가 잘 정리되어 있어 참고했다.
https://angeloyeo.github.io/2020/08/16/gradient_descent.html

파이썬 코드 구현

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

np.random.seed(0)

# y = 4X + 6을 근사, 임의의 값은 노이즈를 위해 부여
X = 2 * np.random.rand(100,1) # 0~1 사이의 random 소수 
y = 6 + 4*X+ np.random.randn(100,1)
plt.scatter(X,y)

png

def get_cost(y, y_pred):
    N = len(y)
    cost = np.sum(np.square(y - y_pred))/N
    return cost
# w1과 w0를 업데이트할 w1_update, w0_update를 반환
def get_weight_updates(w1, w0, X, y, learning_rate=0.01):
    N = len(y)

    w1_update = np.zeros_like(w1)
    w0_update = np.zeros_like(w0)

    y_pred = np.dot(X, w1.T) + w0
    diff = y - y_pred

    w0_factors = np.ones((N,1))

    # w1과 w0를 업데이트할 w1_update와 w0_update 계산
    w1_update = -(2/N)*learning_rate*(np.dot(X.T, diff))
    w0_update = -(2/N)*learning_rate*(np.dot(w0_factors.T, diff))

    return w1_update, w0_update
def gradient_descent_stpes(X, y, iters=10000):
    # 초기값 0으로 설정
    w0 = np.zeros((1,1))
    w1 = np.zeros((1,1))

    # 인자로 주어진 iters 만큼 반복적으로 get_weight_updates() 호출해 w1, w0 업데이트
    for ind in range(iters):
        w1_update, w0_update = get_weight_updates(w1, w0, X, y, learning_rate=0.01)
        w1 = w1 - w1_update
        w0 = w0 - w0_update

    return w1, w0
def get_cost(y, y_pred):
    N = len(y)
    cost = np.sum(np.square(y - y_pred))/N
    return cost

w1, w0 = gradient_descent_stpes(X,y, iters=1000)
print(f"w1 : {w1[0,0]:.3f}, w0 : {w0[0,0]:.3f}")
y_pred = w1[0, 0]*X + w0
print("GD Total Cost", round(get_cost(y, y_pred),4))
w1 : 4.022, w0 : 6.162
GD Total Cost 0.9935
plt.scatter(X,y)
plt.plot(X, y_pred)

png

확률적 경사하강법


확률적 경사 하강법(Stochastic Gradient Descent)는 경사 하강법과 다르게 한번 학습할 때 모든 데이터에 대해 가중치를 조절하는 것이 아니라, 램덤하게 추출한 일부 데이터에 대해 가중치를 조절함. 결과적으로 속도는 개선되었지만 최적 해의 정확도는 낮다.

img1

출처: 흰고래의꿈

파이썬 코드 구현

def stochastic_gradient_descent_stpes(X, y, batch_size=10, iters=1000):
    w0 = np.zeros((1,1))
    w1 = np.zeros((1,1))
    prev_cost = 100000
    iter_index = 0

    for ind in range(iters):
        np.random.seed(ind)
        # 전체 X,y 데이터에서 랜덤하게 batch_size만큼 데이터 추출하여 sample_X, sample_y로 저장
        stochastic_random_index = np.random.permutation(X.shape[0])
        sample_X = X[stochastic_random_index[0:batch_size]]
        sample_y = y[stochastic_random_index[0:batch_size]]
        # 랜덤하게 batch_size만큼 추출된 데이터 기반으로 w1_update, w0_update 계산 후 업데이트
        w1_update, w0_update = get_weight_updates(w1, w0, sample_X, sample_y, learning_rate = 0.01)
        w1 = w1 - w1_update
        w0 = w0 - w0_update

    return w1, w0
w1, w0 = stochastic_gradient_descent_stpes(X, y, iters= 1000)
print("w1 :", round(w1[0,0], 3), "w0:", round(w0[0,0], 3))
y_pred = w1[0, 0]*X + w0
print("Stochastic Gradient Descent Total cost : ",get_cost(y, y_pred))
w1 : 4.028 w0: 6.156
Stochastic Gradient Descent Total cost :  0.9937111256675345

참고 사이트

반응형
반응형

고유값과 고유벡터

고유값과 고유벡터는 앞서 활용한 공분산행렬, 그리고 앞에 설명할 주성분 분석과 뗄 수 없는 관계이다. 따라서 PCA의 메커니즘을 제대로 이해하기 위해서는 고유값과 고유벡터가 의마하는 바를 제대로 이해하는 게 좋다.

고유값과 고유벡터 설명


$$X=\begin{bmatrix} 1 \\ 1 \end{bmatrix}$$ 이라는 행렬이 있다고 가정해보자. 이 행렬에 만약 $$A=\begin{bmatrix} 2&1 \\ 1&2 \end{bmatrix}$$를 선형변환하면 이렇게 계산할 수 있다.

  • $$AX= \begin{bmatrix} 2&1 \\ 1&2 \end{bmatrix}\begin{bmatrix} 1 \\ 1 \end{bmatrix}=\begin{bmatrix} 3 \\ 3 \end{bmatrix}$$
    즉 어떤 벡터에 A를 곱하니 벡터의 방향은 그대로이고 길이만 변하였다고 표현할 수 있다. 다시 말하면 아래 좌표평면에 있는 (1,1) 벡터가 (3,3)가지 방향의 변환 없이 그대로 이동한 것이다.

img

여기서 $$AX = \lambda X$$ 가 되는 $$\lambda$$ 값이 바로 고유값(eigen value)이다. 조금 더 정리를 해보자

  • $$AX - \lambda IX = (A - \lambda I)X = 0$$
  • $$det(A - \lambda I) = 0$$ (det는 determinant이며, $$ad-bc$$의 형태로 행렬값을 계산하는 수식임)
  • $$det(A - \lambda I) = det\begin{bmatrix} 2-\lambda&1 \\ 1&2-\lambda \end{bmatrix} = 0$$
  • $$(2-\lambda)^2 -1 = (\lambda-1)(\lambda-3) = 0 $$
  • $$\lambda =2$$ or $$\lambda =3$$
  • 즉 고유값은 2 또는 3이다

그럼 여기서 고유벡터를 구하면 아래와 같이 볼 수 있다

  • 고유값이 3인 경우, $$\begin{bmatrix} 2&1 \\ 1&2 \end{bmatrix}\begin{bmatrix} X_1 \\ X_2 \end{bmatrix} = 3\begin{bmatrix} X_1 \ X_2 \end{bmatrix}$$
    • $$2X_1 + X_2 = 3X_1$$
    • $$X_1 + 2X_2 = 3X_2$$
    • $$X_1 = X_2$$
    • 가장 쉬운 형태의 고유행렬로 $$\begin{bmatrix} X_1 \\ X_2 \end{bmatrix} = \begin{bmatrix} 1 \\ 1 \end{bmatrix} $$로 볼 수 있다.
  • 고유값이 1인 경우도 동일하게 구할 수 있다

고유값과 고유벡터의 의미


$$A$$ 행렬을 공분산 행렬(covariance matrix)이라고 생각해보자.

  • $$\begin{bmatrix} 2&1 \\ 1&2 \end{bmatrix}$$ 행렬의 고유값은 1과 3이다
  • 고유값의 합은 4로, 두 분산의 합(2+2)과 같다
  • 고유값의 곱은 $$det(A) = (2_2 - 1_1)$$과 동일
  • 분산정보는 최대한 해치지 않으면서 차원을 축소하기 위해 고유값과 고유벡터를 찾아낸 것
  • 고유벡터는 행렬 A를 곱하더라도 방향이 변하지 않고 그 크기만 변하는 벡터를 의미함

주성분 분석(PCA)

주성분 분석의 목적


주성분 분석의 목적 및 핵심은 아래와 같다.

  • 고차원의 데이터를 저차원으로 줄이는 것
  • 공통된 변수들을 줄여서 주성분을 찾는 것
    • 사용된 변수의 개수 > 주성분의 개수
  • 하지만 전체 데이터의 분산에 영향을 주어서는 안됨

주성분 뽑아낼 때 원칙


  • 분산이 가장 커지는 축을 첫 번째 주성분으로 두고, 그 다음 분산이 두번째로 커지는 축을 두 번째 주성분으로 두는 식으로 주성분은 추출

  • 각 주성분은 서로간 90도 직교함

    • 공분산 행렬의 고유벡터 개념임
  • 위에서 고유값 3일 때 계산되는 첫 번째 고유벡터가 바로 첫 번째 주성분(PC1)이 된다. 즉, $$ \begin{bmatrix} 1 \ 1 \end{bmatrix} $$ 고유벡터가 첫 번째 주성분 축이 된다는 의미임

  • 원본 데이터가 있을 경우 먼저 표준화가 진행된다

  • 표준화가 되었다고 가정하고, $$ \begin{bmatrix} 70&80 \\ 50&40 \\ 70&90 \end{bmatrix} \begin{bmatrix} 1 \\ 1 \end{bmatrix} $$ 이 계산 되어 최종 $$\begin{bmatrix} 150 \\ 90 \\ 160 \end{bmatrix} $$이 되어 새로운 축으로 반영되는 것이다. 이 축은 국어와 영어점수를 설명하는 '언어능력점수' 정도로 해석해 볼 수 있다.

  • 2차원 좌표평면에서 설명해야 이해가 빠른데, 해당 설명은 참고유튜브를 참조하자

  • 고유값이 1일 때 나왔던 주성분 PC2(고유벡터)는 분산의 설명도에 따라 사용할 수도, 안 할 수도 있다

  • PC1과 PC2의 상관관계는 0이다(고유값의 계산관계 상 0이 될 수 밖에 없다.)

주성분 분석을 사용할 때


  • 주성분 분석은 언제나 가능한가?
    • 주성분 분석은 데이터의 이면에 보이지 않는 원인이 있음을 전제
    • 즉 국어점수와 영어점수를 설명하는 '언어능력'이 있음을 생각하는 것
  • 주성분 분석에 적합한 데이터란 무엇인가?
    • 구형성 검증(Bartlett's test of sphericity)
    • "상관관계가 0이라면 주성분이 존재할 수 있는가?"를 생각하는 것
    • 즉 상관관계가 업는 형태라면 주성분 분석을 할 수 없음

PCA 실습


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns # seaborn
import warnings
warnings.filterwarnings("ignore") # 경고메세지 무시

df = pd.read_excel("./data/pca_credit_card/card.xls", header=1).iloc[:,1:]
print(df.shape)
df.head(3)
(30000, 24)
LIMIT_BAL SEX EDUCATION MARRIAGE AGE PAY_0 PAY_2 PAY_3 PAY_4 PAY_5 ... BILL_AMT4 BILL_AMT5 BILL_AMT6 PAY_AMT1 PAY_AMT2 PAY_AMT3 PAY_AMT4 PAY_AMT5 PAY_AMT6 default payment next month
0 20000 2 2 1 24 2 2 -1 -1 -2 ... 0 0 0 0 689 0 0 0 0 1
1 120000 2 2 2 26 -1 2 0 0 0 ... 3272 3455 3261 0 1000 1000 1000 0 2000 1
2 90000 2 2 2 34 0 0 0 0 0 ... 14331 14948 15549 1518 1500 1000 1000 1000 5000 0

3 rows × 24 columns

default payment next month가 Target 이며 1이면 "다음달 연체", 0이면 "정상납"임

df.rename(columns={"PAY_0":"PAY_1", "default payment next month":"default"}, inplace=True)
y_target = df["default"]
X_features = df.drop("default", axis=1)
corr = X_features.corr()
plt.figure(figsize=(14,14))
sns.heatmap(corr, annot=True, fmt='.1g')

img

  • PAY_1 ~ 6까지의 상관도와 BILL_AMT1 ~ 6까지의 상관도가 각각 높음
  • PCA로 변환을 시행
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

# BILL
cols_bill = ["BILL_AMT" + str(i) for i in range(1,7)]
print("대상 속성명 :", cols_bill)

# PCA 객체 생성 후 변환
scaler = StandardScaler()
df_cols_scaled = scaler.fit_transform(X_features[cols_bill])
pca = PCA(n_components=2)
pca.fit(df_cols_scaled)
print("PCA Component 별 변동성 :", pca.explained_variance_ratio_)
대상 속성명 : ['BILL_AMT1', 'BILL_AMT2', 'BILL_AMT3', 'BILL_AMT4', 'BILL_AMT5', 'BILL_AMT6']
PCA Component 별 변동성 : [0.90555253 0.0509867 ]
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score

rcf = RandomForestClassifier(n_estimators=300, random_state=156)
scores = cross_val_score(rcf, X_features, y_target, scoring="accuracy", cv=3)

print("개별 정확도 :", scores)
print("평균정확도:", np.round(np.mean(scores),3))
개별 정확도 : [0.8083 0.8196 0.8232]
평균정확도: 0.817
# 원본 데이터 세트에 먼저 StandardScaler
scaler = StandardScaler()
df_scaled = scaler.fit_transform(X_features)

# 6개의 컴포넌트를 가진 PCA 변환 수행 cross_val_score()로 분류 예측 수행
pca = PCA(n_components=6)
df_pca = pca.fit_transform(df_scaled)
scores_pca = cross_val_score(rcf, df_pca, y_target, scoring="accuracy", cv=3)

print("개별 정확도 :", scores_pca)
print("평균정확도:", np.round(np.mean(scores_pca),3))
개별 정확도 : [0.7905 0.7976 0.8021]
평균정확도: 0.797
# 6개의 변수만으로도 성능의 차이가 크게 없음
pca.explained_variance_ratio_
array([0.28448215, 0.17818817, 0.06743307, 0.06401153, 0.04457547,
       0.04161736])
  • 결론적으로 PCA를 사용할 때는 변수가 많고, X변수 간의 상관관계가 있다 싶을 때 사용한다
  • 그리고 원본 데이터를 돌려보고 시간이 많이 걸린다 싶을 때 차원 축소를 고려해볼 수 있다
  • 대신 각 변수의 해석의 문제가 남는다.
반응형
반응형

차원축소(Dimension Reduction)


변수의 개수를 줄이는 것을 의미함

차원축소를 하는 이유


  • 변수가 많으면 다 사용하는 것이 비효율적인 경우
  • 간혹 변수의 개수보다 관찰값의 개수가 적은 경우
  • 변수 간 상관관계가 있는 경우
    • 국어, 영어, 사회 -> 인문영역
    • 수학, 물리 -> 수리탐구영역
    • 위와 같이 5개의 변수를 두 가지의 변수로 축소하여 표현 가능

차원축소를 하는 방법


  • 상관관계가 높은 변수들을 묶어보기
  • 공분산행렬을 이용
  • Covariance Matrix는 Corrlation Matrix와 유사
  • 두 변수의 공변(covariate)량과 관계가 있음

치원축소를 할 때 주의사항


  • 원 데이터의 분산을 최대한 유지하는 것이 중요(분산이 커지거나 작아지는 것은 지양)
  • 원 데이터와 다른 새로운 데이터가 생성되는 것
  • 분석자의 의도대로 축소되지 않거나 해석이 어려운 경우도 발생함

공분산과 상관관계

공분산


공분산 공식은 아래와 같다.

$$\frac{1}{n-1}\sum_{i=1}^{N}(x_i-\bar{x})(y_i-\bar{y})$$

  • 두 변수의 방향을 의미함
  • 두 변수의 공분산행렬은 다음과 같이 표현된다. 여기서 a는 첫 번째 변수의 분산, b는 공분산, c는 두 번째 변수의 분산으로 표현된다. 만약 국어와 영어점수가 있다고 한다면 a는 국어의 분산, c는 영어의 분산, 그리고 b는 공분산이 된다.

$$\begin{pmatrix}a & b \\ b & c \end{pmatrix}$$

  • 분산은 언제나 양수이나 공분산은 음수일 수도 있음
  • 공분산이 양수라면 X와 Y는 같은 방향으로 움직인다는 의미
  • 반대로 공분산이 음수라면 X,Y는 음의 상관관계를 갖는다는 의미
  • 공분산이 0이라면? -> 상관관계가 없다는 뜻
  • 다만 상관관계가 얼마나 큰지는 제대로 설명하지 못함
    참고유튜브

상관관계


상관계수(p)는 아래와 같이 계산이 된다.
$$p = $$ $$Cov(x,y) \over \sqrt{Var(x)*Var(y)}$$

  • 공분산을 각각의 분산으로 나누어 표준화한 개념
  • 상관계수는 -1에서 1 사이의 값을 가지며 각 -1과 1에 근접할수록 상관관계가 있는 것을 판단 가능
반응형
반응형

Matplotlib를 항상 까먹어서 다시 정리하였음!

Matplotlib

# 패키지
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

가장 간단한 예제

  • plt.show()의 역할은 print의 역할과 동일하다고 보면 된다.
  • 즉 결과를 Out으로 내는 게 아니라 Print한다는 의미이나, 실질적으로 큰 차이는 없다고 본다.
  • r-을 통해 빨간색 라인 타입을 보일 수 있음
fig, ax = plt.subplots()  # Create a figure containing a single axes.
ax.plot([1,2,3,4], [1,4,2,3] ,'r-') # 꺾은선
ax.scatter([1,2,3,4], [1,4,2,3]) # 산점도
plt.xlabel("X Label") # X 축
plt.ylabel("Y Label") # Y 축
ax.set_title("test") # 제목
plt.show()

img

Figure의 구성

  • figure는 ax를 담는 그릇이다. 각 ax는 하나의 차트, 또는 좌표평면이라고 보면 될 것 같다.
fig = plt.figure()  # 빈 Figure
fig, ax = plt.subplots()  # 하나의 ax를 가진 Figure
fig, axs = plt.subplots(2, 2)  # 2X2 Grid의 Figure
<Figure size 432x288 with 0 Axes>

png

Axes

  • Ax는 Figure안에 담기는 차트 객체를 의미한다.
  • 각 Ax는 set_title()함수를 통해 이름을 정할 수도 있고, set_xlabel(), set_ylabel()을 통해 축 이름을 정할 수 있다.

Subplots 연습

  • Subplot은 현실 시각화 분석에서 가장 많이 쓰이는 함수이다.
  • plt.tight_layout()은 subplot끼리 겹치는 경우 이를 해결해 줄 수 있다.
x = np.linspace(0, 10, 6)
y = x ** 2

plt.subplot(1,2,1)
plt.plot(x,y,'r')

plt.subplot(1,2,2)
plt.plot(y,x,'b')
[<matplotlib.lines.Line2D at 0x129ae2c3940>]

png

fig, axes = plt.subplots(nrows=1, ncols=2)
plt.tight_layout() # Layout을 화면에 맞춰주는 함수

for ax in axes:
    ax.plot(x,y)

png

  • axes를 쳐보면 array 객체임을 알 수 있음, 따라서 위 명령어 처럼 ax를 반복문으로 루프를 돌릴 수 있음
axes
array([<AxesSubplot:>, <AxesSubplot:>], dtype=object)

Plot function이 받는 데이터 형태

  • nmupy.array 형태를 기본적으로 받음
  • ax.scatter에서 c인자는 color를 의미하고 s인자는 size를 의미한다.
  • 그래서 c인자에넌 0~49까지의 사이의 값이 들어가고, size는 d도 마찬가지이다.
b = np.matrix([[1,2],[3,4]])
b_asarray = np.asarray(b)
np.random.seed(19680801)  # seed
data = {'a': np.arange(50),
        'c': np.random.randint(0, 50, 50),
        'd': np.random.randn(50)}
data['b'] = data['a'] + 10 * np.random.randn(50)
data['d'] = np.abs(data['d']) * 100

fig, ax = plt.subplots(figsize=(5, 2.7))
ax.scatter('a', 'b', c='c', s='d', data=data)
ax.set_xlabel('entry a')
ax.set_ylabel('entry b');

png

코딩 스타일

코딩 스타일은 크게 아래와 같이 두 가지로 나눈다.

1. OO 스타일 : fig와 ax를 정확히 정의하고 들어감

2. pyplot자동화 : pyplot이 알아서 figure와 ax를 컨트롤하도록 함

# OO 스타일
x = np.linspace(0, 2, 100)  # Sample data.

# Note that even in the OO-style, we use `.pyplot.figure` to create the Figure.
fig, ax = plt.subplots(figsize=(5, 2.7))
ax.plot(x, x, label='linear')  # Plot some data on the axes.
ax.plot(x, x**2, label='quadratic')  # Plot more data on the axes...
ax.plot(x, x**3, label='cubic')  # ... and some more.
ax.set_xlabel('x label')  # Add an x-label to the axes.
ax.set_ylabel('y label')  # Add a y-label to the axes.
ax.set_title("Simple Plot")  # Add a title to the axes.
ax.legend();  # Add a legend.

png

# pyplot  스타일
x = np.linspace(0, 2, 100)  # Sample data.

plt.figure(figsize=(5, 2.7))
plt.plot(x, x, label='linear')  # Plot some data on the (implicit) axes.
plt.plot(x, x**2, label='quadratic')  # etc.
plt.plot(x, x**3, label='cubic')
plt.xlabel('x label')
plt.ylabel('y label')
plt.title("Simple Plot")
plt.legend();

png

Plot Styling

  • plot에 color인자와 linewidth, linestyle등을 지정해서 스타일링 가능하다.
  • alpha를 통해 투명도도 조정 가능
data1, data2, data3, data4 = np.random.randn(4, 100)  

fig, ax = plt.subplots(figsize=(5, 2.7))
x = np.arange(len(data1))
ax.plot(x, np.cumsum(data1), color='blue', linewidth=3, linestyle='--')
l, = ax.plot(x, np.cumsum(data2), color='orange', linewidth=2)
l.set_linestyle(':');

png

colors

  • facecoloredgecolor등을 설정 가능합
fig, ax = plt.subplots(figsize=(5, 2.7))
ax.scatter(data1, data2, s=50, facecolor='C0', edgecolor='k');

png

fig = plt.figure()

ax = fig.add_axes([0,0,0.5,0.5])
ax.plot(x,y, color='r', marker='o', markersize=10, markerfacecolor="yellow", markeredgecolor="green") # 색 부여, 마커 부여
plt.show()

png

marker

fig, ax = plt.subplots(figsize=(5, 2.7))
ax.plot(data1, 'o', label='data1')
ax.plot(data2, 'd', label='data2')
ax.plot(data3, 'v', label='data3')
ax.plot(data4, 's', label='data4')
ax.legend();

png

Labeling Plots

  • fontsizecolor이용 가능하다.
mu, sigma = 115, 15
x = mu + sigma * np.random.randn(10000)
fig, ax = plt.subplots(figsize=(5, 2.7))
# the histogram of the data
n, bins, patches = ax.hist(x, 50, density=1, facecolor='C0', alpha=0.75)

# ax.set_xlabel('Length [cm]')
ax.set_xlabel('my data', fontsize=14, color='red')
ax.set_ylabel('Probability')
ax.set_title('Aardvark lengths\n (not really)')
ax.text(75, .025, r'$\mu=115,\ \sigma=15$')
ax.axis([55, 175, 0, 0.03])
ax.grid(True);

png

Limit

  • set_xlim, set_ylim을 통해 X축과 y축의 범위를 정의할 수 있다.
  • 작게 설정 시, Zoom-In 효과가 있다
fig = plt.figure()

ax = fig.add_axes([0,0,0.5,0.5])
ax.plot(x,y, color='r', marker='o', markersize=10, markerfacecolor="yellow", markeredgecolor="green") # 색 부여, 마커 부여
ax.set_xlim([0,10]) # x limit
ax.set_ylim([0,25]) # y limit
plt.show()

png

Legend(범례)

  • loc인자를 통해 위치를 정할 수 있으며 0일 때 자동 조정이며 0~10까지 숫자에 따라 위치를 조정 가능하다.
fig, ax = plt.subplots(figsize=(5, 2.7))
ax.plot(np.arange(len(data1)), data1, label='data1')
ax.plot(np.arange(len(data2)), data2, label='data2')
ax.plot(np.arange(len(data3)), data3, 'd', label='data3')
# ax.legend(loc=10); #10이면 한 가운데로 옴
ax.legend(loc=(0.76,0.63)) # 숫자로 부여 가능
<matplotlib.legend.Legend at 0x129b0480eb0>

png

참고사이트 : https://matplotlib.org/stable/tutorials/introductory/usage.html#types-of-inputs-to-plotting-functions

반응형

'Data > Python' 카테고리의 다른 글

Python seaborn 시각화 기본 정리  (0) 2022.04.02

+ Recent posts