<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>nary_kim.log</title>
        <link>https://velog.io/</link>
        <description>나는 무엇이 될것인가!!</description>
        <lastBuildDate>Wed, 06 Nov 2024 14:03:43 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>nary_kim.log</title>
            <url>https://velog.velcdn.com/images/nary_kim/profile/1dae69c6-935c-4f4e-a89f-a9e6cff82280/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. nary_kim.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/nary_kim" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[취업완성 - Recsys 경진대회 정리 ]]></title>
            <link>https://velog.io/@nary_kim/Recsys</link>
            <guid>https://velog.io/@nary_kim/Recsys</guid>
            <pubDate>Wed, 06 Nov 2024 14:03:43 GMT</pubDate>
            <description><![CDATA[<h2 id="1-competiton-info">1. Competiton Info</h2>
<h3 id="overview">Overview</h3>
<p>&#39;Commerce Behavior Purchase Prediction&#39; 대회는 사용자의 쇼핑 패턴을 분석하여 향후 1주일 동안 구매할 상품을 추천하는 것을 목표로 한다. 추천 시스템은 개인의 쇼핑 습관과 과거 구매 이력을 분석해 맞춤형 상품을 제안함으로써, 사용자의 경험을 개선하고 기업의 매출을 증가시킨다. 이커머스 추천 시스템 구축 과정은 데이터 전처리부터 모델 선택, PyTorch와 라이브러리 활용, Feature Engineering 및 예측 수행을 포함한다. 대회에서는 평가 지표에 최적화된 파이프라인을 개발하는 것이 중요하다. 또한, 현업에서는 어려울 수 있는 복잡한 구조나 다중 모델 앙상블도 높은 점수를 위해 고려할 수 있다.</p>
<h3 id="timeline">Timeline</h3>
<ul>
<li>2024년 10월 02일 : 대회시작</li>
<li>2024년 10월 08일 : 개별적으로 강의수강, EDA 진행</li>
<li>2024년 10월 10일 ~ 10월 23일 : 여러 모델 선정 및 파인 튜닝</li>
<li>2024년 10월 24일, 25일 : 결과 앙상블</li>
<li>2024년 10월 25일 : 대회 종료</li>
</ul>
<h2 id="2-data-descrption">2. Data descrption</h2>
<h3 id="dataset-overview">Dataset overview</h3>
<ul>
<li><p>학습데이터 : train.parquet</p>
<ul>
<li>19년 11월 1일부터 20년 2월 29일까지 4개월간의 데이터</li>
<li>8,350,311개의 행으로 이루어져 있다.</li>
<li>user_id : 유저 id</li>
<li>item_id : 아이템 id</li>
<li>user_session : 사용자의 세션 ID. 사용자가 오랜 일시 중지 후 온라인 스토어로 돌아올 때마다 변경된다.</li>
<li>event_time : 이벤트가 일어난 시각(UTC기준)</li>
<li>category_code : 아이템의 카테고리 분류입니다.</li>
<li>brand : 아이템의 brand</li>
<li>price : 아이템의 가격</li>
<li>event_type : 이벤트의 종류</li>
</ul>
</li>
<li><p>평가데이터</p>
<ul>
<li>20년 3월 1일부터 20년 3월 7일까지 일주일 간의 데이터.</li>
<li>해당 기간 동안 유저가 구입한(event_type = &#39;purchase&#39;) 아이템 이력에 대한 데이터로 user_id와 item_id로 구성된다.</li>
<li>평가데이터는 무작위 (50:50 random split)로 public, private dataset으로 나뉨.</li>
<li>public dataset</li>
<li>대회 기간중 리더보드 점수 계산에 활용되는 정답 데이터.</li>
</ul>
</li>
<li><p>private dataset</p>
<ul>
<li>대회 종료후 최종 점수 계산에 활용되는 정답 데이터.</li>
<li>평가 데이터에는 학습데이터에 포함된 유저와 아이템으로만 이뤄져 있다.</li>
</ul>
</li>
</ul>
<h3 id="data-processing">Data Processing</h3>
<ul>
<li>중복 데이터 18개 존재하여 제거.</li>
</ul>
<h2 id="3-modeling">3. Modeling</h2>
<h3 id="사용-모델">사용 모델</h3>
<ul>
<li>XGBoostRanker</li>
<li>CatboostRanker</li>
<li>ALS</li>
<li>GRU4Rec</li>
<li>SASRec</li>
</ul>
<h3 id="boost-모델을-위한-feature-engineering">Boost 모델을 위한 Feature engineering</h3>
<ul>
<li>핵심적인 생각<ul>
<li>한 유저가 한 아이템을 어떻게 생각하는지 수치화 해보자. </li>
<li>event_type을 아이템별로 묶을 수 있도록 각각 값에 가중치를 부여한 후 합하여, 이 값을 타겟으로 삼아 공략.</li>
</ul>
</li>
<li>event_weight :<ul>
<li>view, cart, purchase를 전체의 갯수 대비 비율의 역수로 하여 각각의 weight를 다르게 부여함.</li>
<li>한 유저가 view만 많이 했다면, 가중치를 적게 받고 한번이라고 구매를 했다면 높은 가중치를 받게된다.</li>
<li>구매를 하지 않고 view나 cart만 있는 사용자들은 event_weight가 높은 3개의 아이템만을 두고 나머지는 삭제.</li>
<li>결과적으로 좋은 점 중 하나는 데이터의 수가 줄어든다는 것임. (약 800만개 -&gt; 약 160만개)</li>
</ul>
</li>
<li>date_weight :<ul>
<li>event_type을 수치화하면서 시간과 아이템과의 관계를 정립할 필요가 생김. </li>
<li>event_time으로 정렬 후, 2월에 상호작용이 일어난 것에 대해 weight를 주는 열인 date_weight를 설정함.</li>
<li>date_weight를 설정할 때, view, cart는 5점을, purchase는 50달러 이상이면 2점, 50달러 미만이면 5점을 부여. - 재구매에 대한 가능성.</li>
</ul>
</li>
<li>위가 item에 관한 정보라면 아래는 user에 관한 정보.</li>
<li>monetary : 각각의 user_id가 구매한  총 금액.</li>
<li>frequency : 각각의 user_id가 상호작용한 횟수 (type과 item에 상관없이 셈.)</li>
<li>cluseter : monetary, frequency를 이용하여 k-mean clustering 하여 0,1,2 이렇게 3그룹으로 나누고, 이상치들은 묶어서 3을 부여함.</li>
<li>brand</li>
</ul>
<p><img src="https://raw.githubusercontent.com/UpstageAILab3/upstage-ai-advanced-rs3-private/refs/heads/main/narykim/clustering.png?token=GHSAT0AAAAAACX7W7IRGOHJRURKEO7B5L5WZY2K57Q" alt="">
<img src="https://raw.githubusercontent.com/UpstageAILab3/upstage-ai-advanced-rs3-private/refs/heads/main/narykim/feature_importance.png?token=GHSAT0AAAAAACX7W7IQF7OLZZ3YFWFKJ3QYZY2K6RQ" alt=""></p>
<h3 id="특이사항">특이사항?</h3>
<ul>
<li>XGBoostRanker와 CatboostRanker<ul>
<li>event_weight값을 타겟으로 할 경우 한 아이디당 10개미만의 아이템들과 상호작용하는 경우가 많이 있어서, 이럴 경우 결과값이 아이디당 딱 10개로 떨어지지 않음.</li>
<li>10개를 채우기 위해서는 앙상블이 불가피함. - 초반에는 베이스코드에서 제공해준 als를 이용, 대회가 진행되면서 리더보드의 점수가 좋은 output으로 대체.</li>
<li>연산시간이 16시간정도로 오래걸려, 하이퍼파라미터 튜닝시에는 valid data를 2월 27, 28, 29일의 구매자 아이디로만 구성하여 빠르게 테스트. </li>
</ul>
</li>
<li>recbole을 이용하여 GRU4Rec과 SASRec을 손쉽게 다룰수 있었음.</li>
<li>GRU4Rec<ul>
<li>세션 기반 추천 시스템에 자주 사용되는 모델임. GRU(게이트 순환 유닛)를 사용해 순차적인 사용자 행동을 학습하고, 세션 내의 사용자 아이템 상호작용을 기반으로 다음에 추천할 아이템을 예측함. 즉, 세션 안에서 시간 순서대로 발생하는 행동들을 고려해 다음에 사용자가 클릭할 아이템을 예측하는 방식임.</li>
<li>그래서 위의 피쳐들을 사용하지 않고, user_id, item_id, event_time, event_session을 이용하여 연산함.</li>
</ul>
</li>
<li>SASRec은 베이스코드와 다르게 Feature engineering에서 소개한 feature들을 사용하여 연산해봄.</li>
</ul>
<h3 id="결과-실험한-시간순으로-정리">결과 (실험한 시간순으로 정리)</h3>
<ul>
<li><p>als (base code) : 0.0846 (0.0853)</p>
</li>
<li><p>XGBRanker + als : 0.1211 (0.1210)</p>
</li>
<li><p>XGBRanker(params tune) + als : 0.1221 (0.1214)</p>
</li>
<li><p>CatRanker(params tune) + als : 0.1208 (0.1200)</p>
</li>
<li><p>als(params tune) : 0.1059 (0.1058)</p>
</li>
<li><p>CatRanker(params tune) + als(params tune) : 0.1219 (0.1205)</p>
</li>
<li><p>XGBRanker(params tune) + als(params tune) : 0.1232 (0.1219)</p>
</li>
<li><p>GRU4Rec + populer top10 : 0.0980 (0.0980)</p>
</li>
<li><p>GRU4Rec + als(params tune) : 0.0929 (0.0929)</p>
</li>
<li><p>SASRec + populer top10 : 0.0870 (0.0876)</p>
</li>
<li><p>LMF(params v1) :0.0944 (0.0925)</p>
</li>
<li><p>LMF(params v2) :0.1141 (0.1132)</p>
</li>
<li><p>LMF(params v3) : 0.1214 (0.1213)</p>
</li>
<li><p>CatRanker + LMF : 0.1313 (0.1304)</p>
</li>
<li><p>XGBRanker + LMF : 0.1325 (0.1318) BEST!</p>
</li>
<li><p>XGBRanker_als + CatRanker_als + LMF using ranking : 0.1324 (0.1317)</p>
</li>
</ul>
<h2 id="4-result">4. Result</h2>
<h3 id="leader-board">Leader Board</h3>
<ul>
<li>1등 : 0.1325 (0.1318)</li>
</ul>
<h3 id="시도한-점">시도한 점</h3>
<ul>
<li>처음부터 우리조의 목표가 최대한 많은 모델을 돌려보자였기 때문에 많이 돌려보려고 노력하였고, 모두 각자의 모델을 잘 돌려서 좋은 결과가 나왔던것 같다.</li>
</ul>
<h3 id="아쉬운-점">아쉬운 점</h3>
<ul>
<li>Boost 계열이 시간이 오래걸려서 개인적으로는 CF, MF 모델들에 대한 여러 실험을 못해봤는 데, 해보고 싶다.</li>
<li>마지막에 피드백을 받을 때, date_weight 피쳐에 대해, 합리적인 이유없이 나의 임의로 가중치값을 정했다는 것을 지적해주셨다. 내가 왜 그랬을까 하고 돌아보니, 임의로 넣은 가중치값을 이용하여 얻은 결과가 생각보다 너무 좋아서였다고 생각한다. 만약에 같이 대회에 참여한 다른조에서 좋은 결과들을 내놓았다면 아마 이것을 수정해보지 않았을까.</li>
<li>다른 조들도 좀더 열심히 해줬다면, 많은 인사이트를 얻어갈 수 있었을 텐데 그 점이 많이 아쉽다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Data centric AI]]></title>
            <link>https://velog.io/@nary_kim/Data-centric-AI</link>
            <guid>https://velog.io/@nary_kim/Data-centric-AI</guid>
            <pubDate>Fri, 04 Oct 2024 01:11:42 GMT</pubDate>
            <description><![CDATA[<p>근래 3개월동안 계속 대회를 진행하였는 데, 그때마다 드는 생각은 </p>
<blockquote>
<p>&quot; 데이터를 이렇게 전처리하면 훨씬 좋은 결과가 있었을 것이다.&quot;</p>
</blockquote>
<p>좋은 결과를 내는 데에는 물론 모델의 선택도 매우 중요한 요소이지만, 그보다 선행되어야 하는 것이 주제, 목적에 맞는 좋은 데이터로 기존의 데이터를 정제하는 것 이라고 생각한다. Data-Centric AI는 이것에 대한 좀더 심화된 이야기를 해주고, 산업에서는 어떻게 적용되는지 김남혁 강사님을 통하여 좀더 자세하게 들을 수 있는 기회가 되었다. </p>
<p>확실히 좋은 모델들의 접근이 좋아진 지금, 결국 경쟁력을 가지려면 데이터의 적절한 가공이 아닐까 생각된다. 아래는 Data-Centric AI에 대한 대략적 설명이다.</p>
<hr>
<h2 id="data-centric-ai"><strong>Data-Centric AI</strong></h2>
<p><strong>데이터</strong>를 중심으로 AI 시스템을 개발하고 개선하는 접근 방식이다. 기존의 AI 개발은 모델 아키텍처나 알고리즘의 개선에 중점을 두었지만, <strong>데이터 중심 AI</strong>는 고품질 데이터를 확보하고 이를 관리하는 데 초점을 맞춘다.</p>
<p>주요 개념과 특징은 다음과 같다:</p>
<h3 id="1-데이터-품질-향상">1. <strong>데이터 품질 향상</strong></h3>
<ul>
<li>AI 모델 성능을 높이기 위해서는 데이터의 질을 개선하는 것이 핵심이다. 불필요하거나 오류가 있는 데이터를 제거하고, 주석 오류를 수정하며, 데이터의 다양성과 균형을 맞추는 것이 중요하다.</li>
<li>예를 들어, 데이터가 불균형할 경우(특정 클래스의 데이터가 지나치게 많거나 적은 경우), 데이터를 증강하거나 추가로 수집해 성능을 높일 수 있다.</li>
</ul>
<h3 id="2-라벨링-개선">2. <strong>라벨링 개선</strong></h3>
<ul>
<li>데이터 중심 AI에서는 라벨링의 정확성과 일관성이 매우 중요하다. 라벨링 오류를 줄이고, 일관성 있게 데이터를 주석화하는 것이 모델 성능 향상에 직접적으로 기여한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[일상 대화 요약대회]]></title>
            <link>https://velog.io/@nary_kim/dialogue-summary</link>
            <guid>https://velog.io/@nary_kim/dialogue-summary</guid>
            <pubDate>Wed, 25 Sep 2024 03:35:39 GMT</pubDate>
            <description><![CDATA[<h1 id="1-대회설명">1. 대회설명</h1>
<h3 id="overview">Overview</h3>
<ul>
<li><p>소개
Dialogue Summarization 경진대회는 일상 대화를 효과적으로 요약할 수 있는 모델을 구축하는 대회이다. 대화 중 요약의 필요성과 이를 통해 주관적 오류를 최소화하는 것이 목표이다. 우리는 이번 대회를 통해 대화 요약 모델 개발을 완성할 것이다.</p>
</li>
<li><p>모든 데이터는 .csv 형식으로 제공되고 있으며, 각각의 데이터 건수는 다음과 같습니다.</p>
<p>  train : 12457
  dev : 499
  test : 250
  hidden-test : 249</p>
</li>
</ul>
<h3 id="timeline">Timeline</h3>
<ul>
<li>2024.08.29 ~ 2024.09.02 - 대회 시작, 데이터 EDA와 Baseline 분석</li>
<li>2024.09.03 ~ 2024.09.06 - 모델 설정, 학습 및 파인튜닝</li>
<li>2024.09.09 ~ 2024.09.11 - inference 튜닝</li>
</ul>
<h3 id="model-descrition">Model descrition</h3>
<ul>
<li>Kobart (digit82/kobart_summarization)</li>
<li>T5-Large (lcw99/t5-large-korean-text-summary)</li>
<li>Llama3 (beomi/Llama-3-Open-Ko-8B)</li>
</ul>
<h1 id="2-목표와-결과">2. 목표와 결과</h1>
<h3 id="kobart-완전정복하기">Kobart 완전정복하기</h3>
<ul>
<li><p>KoBART는 한국어에 특화된 BART 모델이다. BART는 Facebook AI에서 개발한 sequence-to-sequence 모델로, 주로 텍스트 생성, 요약, 번역 등에 사용된다. KoBART는 이 BART 모델을 바탕으로 하여, 한국어 데이터를 사용해 사전 학습된 모델이다.</p>
</li>
<li><p>BART의 구조는 인코더와 디코더로 이루어져 있는데, 인코더는 입력된 텍스트를 분석하고, 디코더는 그 텍스트를 바탕으로 새로운 텍스트를 생성한다. KoBART는 이러한 구조를 기반으로 하여, 한국어 텍스트의 요약, 생성 등에서 우수한 성능을 보인다.</p>
</li>
<li><p>이를 바탕으로 digit82/kobart_summarization은 KoBART를 활용해 한국어 텍스트 요약 작업을 수행하는 프로젝트이다. </p>
</li>
</ul>
<h4 id="장점">장점:</h4>
<ul>
<li><p>한국어 특화: KoBART는 한국어 데이터를 바탕으로 학습되었기 때문에, 한국어 문장을 다루는 다양한 작업에서 높은 성능을 보인다. 특히 한국어의 어순이나 문법적 특성을 잘 이해하여 자연스러운 요약과 생성이 가능하다.</p>
</li>
<li><p>범용성: KoBART는 BART의 인코더-디코더 구조를 따르기 때문에, 요약뿐만 아니라 번역, 텍스트 생성 등 다양한 자연어 처리 작업에 적용할 수 있다.</p>
</li>
<li><p>사전 학습된 모델 활용: 이미 대규모 데이터로 학습된 모델이기 때문에, 추가 학습(fine-tuning)을 통해 특정 도메인에 쉽게 적용할 수 있다. 예를 들어 뉴스 요약이나 문서 생성 같은 작업에 특화된 모델로 빠르게 변환 가능하다.</p>
</li>
<li><p>Pretrained 모델 지원: KoBART는 이미 공개된 사전 학습된 모델이기 때문에, 별도의 대규모 학습 없이도 바로 사용할 수 있어 효율적이다.</p>
</li>
</ul>
<h4 id="단점">단점:</h4>
<ul>
<li><p>대규모 학습 데이터 필요: KoBART를 특정 작업에 맞춰 미세 조정(fine-tuning)할 때, 여전히 대규모의 학습 데이터가 필요하다. 데이터가 부족하면 모델의 성능이 떨어질 수 있다.</p>
</li>
<li><p>한국어 외의 언어 한정성: KoBART는 한국어에 특화되어 있기 때문에, 다른 언어를 다룰 때는 성능이 크게 떨어질 수 있다. 다국어 작업에는 적합하지 않다.</p>
</li>
<li><p>메모리와 연산 자원 소모: BART 모델의 특성상 인코더와 디코더가 모두 사용되기 때문에, 훈련 및 추론 과정에서 많은 메모리와 연산 자원이 필요하다. 특히 긴 문장이나 대규모 데이터를 처리할 때 이 문제가 더 두드러질 수 있다.</p>
</li>
<li><p>모델 크기: KoBART는 대규모의 파라미터를 가지고 있기 때문에, 실제로 모델을 배포하거나 실시간 작업에 사용하려면 최적화 작업이 필요할 수 있다.</p>
</li>
</ul>
<h3 id="kobart로-시도한-것들">kobart로 시도한 것들</h3>
<ul>
<li>번역어투임을 감안하여 영어로 번역후 bart 요약 후 다시 번역. -&gt; 번역에서의 오류 + 요약에서의 오류가 가중되어 좋은 결과를 얻지 못함. </li>
<li>rouge 점수를 이용하여 모델을 업데이트 시키기 위해 강화학습 알고리즘을 이용하여 모델학습 </li>
<li>kfold</li>
<li>kfold + 강화학습</li>
</ul>
<h4 id="위의-모든-것들이-baseline을-넘지-못하였다">위의 모든 것들이 baseline을 넘지 못하였다.</h4>
<ul>
<li>private 기준으로 가장 좋은 점수를 받았던 모델은 baseline에서 max_length를 1024/512로 바꾼것이다.</li>
<li>그리고 오히려 gogamza/kobart-summarization의 점수가 private에서 좋게 나왔다!!!</li>
</ul>
<h3 id="아쉬웠던-점">아쉬웠던 점</h3>
<ul>
<li>개인적으로는 계속 kobart만을 파인튜닝하려고 노력했는데, 결과적으로는 잘되지 않았다. 데이터증강을 시도하다가 하지 않았는데 그게 아쉽다. </li>
</ul>
<h1 id="3-새로운-시도">3. 새로운 시도</h1>
<h3 id="이번엔-엑셀-점수저장을-좀더-잘했다">이번엔 엑셀 점수저장을 좀더 잘했다!</h3>
<ul>
<li>마지막에 가서는 내가 막 올려서 점수저장을 잘 못한건 있지만, 다른 조원들이 훌륭히 완벽히 해주었다. 나도 좀더 확실히 올릴 필요가 있다.</li>
</ul>
<h1 id="4-프로젝트-후기">4. 프로젝트 후기</h1>
<ul>
<li>다른 조원들이 LLAMA나 T5등을 파인튜닝하면서 많은 것을 배우신 것 같았다. 대회는 끝나지만, 남은 온라인 수업과 함께 요즘 유행하는 모델들을 공부하고 직접 다루고 싶다. 그렇지만 kobart 만큼은 정말 많이 알고가서 뿌듯하다.</li>
</ul>
<h1 id="5-다음-대회에서-할-일">5. 다음 대회에서 할 일</h1>
<h3 id="마지막-대회에는-다시-열정-탑재가-필요">마지막 대회에는 다시 열정 탑재가 필요!</h3>
<ul>
<li>솔직히 이번대회를 열심히 한다고는 했지만, 아이들의 여름방학이 시작되어 대회가 계속되면서 많이 지쳤었다. 그래서 마지막 튜닝을 하는거에서 좀 더 시간을 할애하지 못한 부분도 있었다. 게다가 현재는 코로나일지도 모른다는 진단까지 받은 상태 ㅎㅎㅎ 대회 시작전에 충분히 앓고 충분히 마음을 다 잡은 후 다시 새로운 마음으로 마지막을 열심히 공부하고 끝내고 싶다.<h2 id="화이팅">화이팅!!</h2>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Computer Vision 도메인 학습]]></title>
            <link>https://velog.io/@nary_kim/Computer-Vision-domain</link>
            <guid>https://velog.io/@nary_kim/Computer-Vision-domain</guid>
            <pubDate>Wed, 21 Aug 2024 08:51:56 GMT</pubDate>
            <description><![CDATA[<p>오늘까지 업스테이지에서 제공하는 Computer Vision 도메인 학습을 공부하였다. 중간에 대회도 함께 하면서 배운걸 바로 써먹을 수 있어서 좋았던 경험이였다.</p>
<p>수업들었던 것 중에서 swin Tranformer를 대회에서 잘 썼었는 데, 여기에는 이것에 대해 정리해보고자 한다.</p>
<h1 id="swin-shifted-window-모델">&lt;SWIN (Shifted Window) 모델&gt;</h1>
<p>SWIN은 컴퓨터 비전 태스크를 위한 딥 러닝 아키텍처입니다. CNN의 지역성과 Transformer의 전역 정보 처리 능력을 결합하여 효율적이고 강력한 성능을 제공합니다.</p>
<p><img src="https://github.com/UpstageAILab3/upstage-cv-classification-cv12-pub/blob/main/cho/teaser.png?raw=true" alt="대체 텍스트"></p>
<h2 id="이미지-분할-및-임베딩">이미지 분할 및 임베딩</h2>
<ul>
<li>입력 이미지 (H×W×3)를 작은 패치로 분할</li>
<li>각 패치를 선형 임베딩으로 고차원 벡터로 변환</li>
</ul>
<h2 id="계층적-특징-추출">계층적 특징 추출</h2>
<p>모델은 4개의 stage로 구성되며, 각 stage에서 이미지 해상도와 채널 수가 변화합니다:</p>
<table>
<thead>
<tr>
<th>Stage</th>
<th>해상도</th>
<th>채널 수</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>H/4 × W/4</td>
<td>48C</td>
</tr>
<tr>
<td>2</td>
<td>H/8 × W/8</td>
<td>2C</td>
</tr>
<tr>
<td>3</td>
<td>H/16 × W/16</td>
<td>4C</td>
</tr>
<tr>
<td>4</td>
<td>H/32 × W/32</td>
<td>8C</td>
</tr>
</tbody></table>
<h2 id="swin-transformer-block">Swin Transformer Block</h2>
<p>각 stage의 핵심 구성 요소:</p>
<ul>
<li>Window Multi-head Self Attention (W-MSA)</li>
<li>Shifted Window Multi-head Self Attention (SW-MSA)</li>
<li>Multi-Layer Perceptron (MLP)</li>
<li>Layer Normalization (LN)</li>
</ul>
<h2 id="윈도우-기반-self-attention">윈도우 기반 self-attention</h2>
<ul>
<li>전체 이미지 대신 작은 윈도우 내에서 self-attention 수행</li>
<li>계산 복잡도: $O(n^2)$에서 $O(n)$으로 감소<ul>
<li>n: 전체 토큰 수</li>
<li>M: 윈도우 크기</li>
</ul>
</li>
</ul>
<h2 id="shifted-window-메커니즘">Shifted Window 메커니즘</h2>
<ul>
<li>연속된 층에서 윈도우 위치를 교대로 이동</li>
<li>윈도우 간 정보 교환 가능</li>
</ul>
<h2 id="패치-병합-patch-merging">패치 병합 (Patch Merging)</h2>
<ul>
<li>각 stage 사이에 적용</li>
<li>공간 해상도를 줄이고 채널 수를 증가</li>
<li>인접한 2×2 패치의 특징을 연결하고 선형 변환 적용</li>
</ul>
<h2 id="수학적-표현">수학적 표현</h2>
<p>$$
\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d}}\right)V
$$</p>
<p>여기서:</p>
<ul>
<li>$Q$, $K$, $V$는 각각 Query, Key, Value 행렬</li>
<li>$d$는 임베딩 차원</li>
</ul>
<h2 id="모델-복잡도">모델 복잡도</h2>
<ul>
<li>파라미터 수와 계산량이 이미지 크기에 선형적으로 비례</li>
<li>기존 Vision Transformer의 제곱 복잡도보다 효율적</li>
</ul>
<p>SWIN 모델은 효율성과 성능을 모두 고려한 설계로, 다양한 컴퓨터 비전 태스크에서 우수한 결과를 보여줍니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[문서분류대회 회고]]></title>
            <link>https://velog.io/@nary_kim/docu-classification</link>
            <guid>https://velog.io/@nary_kim/docu-classification</guid>
            <pubDate>Tue, 13 Aug 2024 18:39:01 GMT</pubDate>
            <description><![CDATA[<h1 id="1-대회설명">1. 대회설명</h1>
<h3 id="overview">Overview</h3>
<ul>
<li>소개
이번 대회는 computer vision domain에서 가장 중요한 태스크인 이미지 분류 대회이다. 보험보상과 관련된 이미지들이 주어지고 이것을 17개의 클래스로 분류하는 모델을 만든다.</li>
<li>input : 1570개의 이미지</li>
<li>output : 3140개 이미지의 클래스</li>
</ul>
<h3 id="timeline">Timeline</h3>
<ul>
<li>2024년 7월 29일 : 대회시작 각자 데이터 EDA</li>
<li>2024년 7월 30일 ~ 8월 2일 : 온라인 강의, 데이터 Augmentation을 이용한 모델링, Baseline code 학습</li>
<li>2024년 8월 5일 : Swin Tranform, Convnext v2 적용</li>
<li>2024년 8월 6일 : OCR, Augrapy 코드 공유 적용</li>
<li>2024년 8월 7일 : 데이터 오프라인 증강, Test data의 Denoising 적용</li>
<li>2024년 8월 8일 : 각자의 모델 Hyper parameter tuning, LM3 적용</li>
<li>2024년 8월 9일 ~ 11일 : 각자의 모델 학습시키면서 리더보드 올리기</li>
</ul>
<h3 id="model-descrition">Model descrition</h3>
<ul>
<li>EfficientNet_b4</li>
<li>SWIN(Shifted Window)</li>
<li>ConvNeXt</li>
<li>OCR</li>
</ul>
<h1 id="2-목표와-결과">2. 목표와 결과</h1>
<h3 id="학습데이터를-테스트데이터와-비슷하게-만들자">학습데이터를 테스트데이터와 비슷하게 만들자</h3>
<ul>
<li>학습데이터들은 깔끔하고 정돈된 형태로 스캔된 형식들이였는 데, 테스트데이터들은 회전, 플립, 노이즈, 믹스 등등 많은 형태로 변형되어있었다.</li>
<li>결과 <ul>
<li>Augmentation으로 데이터증강하여 3개의 모델 실험 (flip, noise, rotation)</li>
<li><blockquote>
<p>과적합의 문제, 0.91이상으로는 잘 오르지 않음</p>
</blockquote>
</li>
<li><blockquote>
<p>두개의 모델들을 앙상블한 결과도 0.92정도</p>
</blockquote>
</li>
</ul>
</li>
</ul>
<h3 id="swin-t의-하이퍼파라미터를-튜닝하였다">Swin t의 하이퍼파라미터를 튜닝하였다.</h3>
<ul>
<li><p>swin t 모델은 생각모다 수렴도 잘 되지 않고 어느 순간 리더보드에 올린 결과값들도 0.91후반으로 오르지 않앟다.</p>
<ul>
<li>wandb의 sweep을 사용하여 하이퍼파라미터를 모니터링하였고, 그중  ㅣloss 값이 작고 f1값이 크면서도 epoch을 길게 가져가는 하이퍼파라미터를 선택하였다.</li>
</ul>
</li>
<li><p>결과</p>
<ul>
<li>0.92후반대까지 오를 수 있었다.
[wandb 실험결과]
(<a href="https://api.wandb.ai/links/narykkim/p2l1gyy0">https://api.wandb.ai/links/narykkim/p2l1gyy0</a>)<h3 id="test-데이터의-denoising">test 데이터의 Denoising</h3>
</li>
</ul>
</li>
<li><p>test이미지들 중에 문서이미지들의 회전을 바르게 돌려놓기위해 노력했다. <img src="https://velog.velcdn.com/images/nary_kim/post/2e663c3e-b3c1-4fc0-822e-056f16e083f0/image.png" alt=""></p>
</li>
<li><h2 id="결과">결과</h2>
<ul>
<li>0.0011정도의 값이 올랐다. </li>
<li>점수가 좀처럼 오르지 않았을 때 값이 오른 것이여서 이것을 좀더 적극적으로 이용해야 겠다고 생각했다.</li>
</ul>
</li>
</ul>
<h3 id="test-denosing에-맞는-학습데이터-다시-구축">test Denosing에 맞는 학습데이터 다시 구축</h3>
<ul>
<li>test이미지들이 Denoising 되면서 그에 맞는 학습데이터를 만들면 좋겠다고 생각했다. 그래서 일부러 원래의 학습데이터에 노이즈와 회전을 주어서 오프라인으로 25,000개정도를 저장하고, 이 이미지들을 다시 Denoising하는 과정을 거쳐 test 이미지와 비슷하게 만들도록 노력했다.</li>
<li><h2 id="결과-1">결과</h2>
<ul>
<li>이것때문인건지 많은 데이터를 학습한 덕분인지는 알수 없으나, ocr을 적용하기 전 가장 높은 점수인 0.9386을 얻을 수 있었다. (swin + conv)</li>
</ul>
</li>
</ul>
<h3 id="ocr을-사용하여-데이터를-postprocessing하였다">OCR을 사용하여 데이터를 Postprocessing하였다.</h3>
<ul>
<li><p>test데이터와 가장 비슷하게 만든 학습데이터 중 헷갈리는 몇몇 클래스의 문서에서 Paddleocr을 사용하여 단어들을 추출하였다.</p>
</li>
<li><p>단어들을 정제하여 각 클래스 별 단어사전을 만들었다.</p>
</li>
<li><p>test데이터에서도 단어를 추출한 후, 단어사전을 이용하여 클래스를 재분류하였다.</p>
</li>
<li><p>결과</p>
<ul>
<li>40여개의 이미지가 클래스를 변환했고, f1값은 0.013정도 오르게 되었다.</li>
</ul>
</li>
</ul>
<h1 id="3-새로운-시도">3. 새로운 시도</h1>
<h3 id="파일을-나눠서-저장">파일을 나눠서 저장</h3>
<ul>
<li>전에는 하나의 ipynb파일에 여러모델들을 만들고 저장하였는데, 이번부터는 모델마다, 실험내용마다 모두 다른 파일에 만들어서 실수를 줄이도록 노력했다.</li>
<li>결과 : 확실히 실수가 줄었고, 관리가 오히려 쉬웠다. 그러나 파일명의 체계성이 없어서 이 부분은 개선이 필요하다.<h3 id="wandb의-sweep-사용">wandb의 sweep 사용</h3>
</li>
<li>sweep으로 하이퍼파라미터를 모니터링해보았다. sweep은 어느정도 정보가 모이면 하이퍼파라미터의 중요도를 알아서 보여준다. 그래서 어떻게 하이퍼파라미터를 조정해야하는지에 대한 감을 알려주었고, 이로 인해 모델에 대한 이해도도 같이 높일 수 있었다.<h3 id="nohup으로-py-파일-돌리기">nohup으로 py 파일 돌리기</h3>
</li>
<li>nohup을 사용하여 백그라운드로 py파일을 돌려보았다. 이것은 log파일을 만들어서 모니터링도 쉽게 해주었고, 컴퓨터를 켜고 끄는 것에 대한 자유도 주어 굉장히 편하게 할 수 있었다. 다만 메모리 관리를 좀더 열심히 해주어야 한다. 아니면 cuda에러가 나서 잘 하던 것들이 날라갈 수 있다.<h3 id="팀장과-발표를-하였다">팀장과 발표를 하였다!</h3>
</li>
<li>발표는 떨렸지만 재밌었다. 팀장으로써는 아직 개선해야할 점들이 보인다.</li>
</ul>
<h1 id="4-프로젝트-후기">4. 프로젝트 후기</h1>
<ul>
<li>데이터증강할 때 10만개정도로 더더 많이 해볼꺼 하는 아쉬움이 남는다.</li>
<li>팀별로 운영되어지는 대회의 경우, 가장 필요한 것이 팀안에서의 체계성인것 같다. 정보를 공유하고 모델링을 하는 과정에서 서로서로 겹쳐지는 부분을 최소화하기 위해 이와 같은 것이 필요한 데, 우리는 아침에 모여 열띤 토론을 하고 토론 내용도 매일 슬랙에 올려놓았지만, 서로 무엇을 하는 지에 대한 정말 구체적인 정보가 없기 때문에 서로에 대한 피드백을 정확히 할수 었었던 것 같다.</li>
<li>나의 파일관리에 대한 체계성도 아직 부족함을 느꼈다. 이름짓기 너무 어렵다.</li>
<li>여러모델을 많이 다뤄보았다. 확실히 수업만 듣는 것보다 이렇게 수업듣고 바로 대회를 하니, 많은 부분들이 체화되는 것을 느꼈다.</li>
<li>postprocessing을 할 때, &#39;어 모델링 대회인데 이런걸 해도 되나&#39; 하는 생각을 했는 데, 결국 이것으로 인해 점수를 잘 받았게 되었고 현업에서도 이런 식의 일이 진행된다는 것을 듣고 생각을 바꾸게 되었다.</li>
</ul>
<h1 id="5-다음-대회에서-할-일">5. 다음 대회에서 할 일</h1>
<h3 id="팀-단위-체계성">팀 단위 체계성</h3>
<ul>
<li>현재 진행하고 있는 모델링이나 데이터전처리에 대한 구체적인 정보를 기재하는 구글 엑셀시트를 만들어 서로 공유하며 진행해보려한다.<h3 id="개인의-체계성">개인의 체계성</h3>
</li>
<li>파일 분리까지는 잘했으나, 파일명에서 아직 부족함을 느꼈다. 파일명의 체계를 구성하고 개인 엑셀파일도 만들어서 기재하는 방향으로 진행하려한다.<h3 id="모델-선정-기준잡기">모델 선정 기준잡기</h3>
</li>
<li>지금까지는 막연히 좋을 것이라고 생각한 여러모델을 모두 돌려보는 방향으로 진행하였는데, 다음에는 모델에 대한 서치를 충분히 한 후, 그 중 학습데이터에 맞는 모델을 선정하는 것에 대해 공부하고 적용해보고 싶다. </li>
</ul>
<p>이번에도 4위라는 아주 만족스러운 결과를 낼수 있었다. (5위안에만 들자는 것이 나의 목표다.) 너무 재미있었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ML regression 대회 회고]]></title>
            <link>https://velog.io/@nary_kim/ML-regression-review</link>
            <guid>https://velog.io/@nary_kim/ML-regression-review</guid>
            <pubDate>Wed, 24 Jul 2024 03:59:46 GMT</pubDate>
            <description><![CDATA[<h2 id="1-대회정보">1. 대회정보</h2>
<ul>
<li>Overview
House Price Prediction 경진대회는 주어진 데이터를 활용하여 서울의 아파트 실거래가를 효과적으로 예측하는 모델을 개발하는 대회이다.</li>
<li>Dataset<blockquote>
<p>train : 200701 ~ 202306 까지의 아파트 정보 데이터 - 1118822개
test : 202307 ~ 202309 까지의 아파트 정보 데이터 - 9272개</p>
</blockquote>
</li>
<li>Timeline
2024년 7월 09일 (화) ~ 7월 15일 (월) - 온라인 수업
2024년 7월 15일 (월) - 회의 후, 회의 결과를 바탕으로 데이터 전처리
2024년 7월 16일 (화) - 각자 EDA 및 Feature Engineering
2024년 7월 17일 (수) - 최종 데이터셋 설정 및 Modeling
2024년 7월 18일 (목) - Feature Selection 및 Modeling Hyper-parameter tuning
2024년 7월 19일 (금) - 최고 성능 모델 추가 처리 및 최종 제출 기한</li>
</ul>
<h2 id="2-나의-목표와-결과">2. 나의 목표와 결과</h2>
<h3 id="결측치를-줄여보자">결측치를 줄여보자.</h3>
<p>대회에서 제공된 학습 데이터의 가장 큰 문제는 너무도 많은 결측치였다.</p>
<ul>
<li>결과 :<ul>
<li>결측치를 크롤링으로 채우기에는 전문적인 정보들이 많아서 데이터셋들을 제공하는 사이트들을 집중 검색했고, 적절한 외부데이터를 찾았다.</li>
<li>80만개의 결측치를 25만개정도까지 줄일수 있었다.<h3 id="좌표에-대한-결측치는-0으로-만들자">좌표에 대한 결측치는 0으로 만들자.</h3>
다른 수치형 변수들은 선형보간한다고 해도, 위도경도는 그렇게 하면 나중에 지하철과의 거리계산에서 큰 오류를 만들것이라고 생각하여 좌표 결측치를 0으로 만들도록 하였다.</li>
</ul>
</li>
<li>결과 :<ul>
<li>위의 자료를 통해서 이미 결측치는 25만개 정도로 줄어있었다.</li>
<li>여러 작업을 걸쳐 약 100개의 자료를 수동으로 수집하였다.</li>
<li>사람이 판단해야 하는 부분이기 때문에 자동화로 넘기기엔 어려움이 많다고 생각한다. </li>
<li>다만 100개가 아니고 1000개였다면 부분 자동화는 시도했을 것이다. <h3 id="의미있는-변수를-찾자">의미있는 변수를 찾자.</h3>
</li>
</ul>
</li>
<li>결과 :<ul>
<li>이자율 : 이자율에 따라 사람들의 매매에 대한 생각이 변할 것이라는 생각에 한국은행데이터셋 사이트에서 대한 데이터를 찾았다.<ul>
<li>catboost로 계산한 변수 중요도에서 30개의 변수 중 9위로 꽤 높은 기여도를 보여주었다.<ul>
<li>LGBM으로 계산한 변수 중요도에서는 18위정도로 중간정도의 기여도를 보여주었다. </li>
</ul>
</li>
</ul>
</li>
<li>subway_count : 1km 반경 안에 지하철의 갯수가 몇개인지 세어보는 변수를 만들었다.<ul>
<li>변수 중요도가 30위가 넘으면서, 가격과는 상관없는 변수임을 확인했다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="여러가지-모델을-실험해보자">여러가지 모델을 실험해보자</h3>
<ul>
<li>결과 :<ul>
<li>다른 팀원들은 도전하지 않았던 catboost에 대해 도전하였고, 나의 결과와 LGBM을 실험한 데이터를 앙상블하여 좋은 결과를 얻을 수 있었다.</li>
<li>optuna는 한번에 적은 trial을 해보면서 하이퍼파라미터의 값의 범위를 줄여나가는 것이 효율적임을 알았다.</li>
<li>kfold, TimeSeriesSplit, Stratified KFold등 여러가지 시도를 하였고, kfold가 그 중 효과적이였으나, 전체적으로 rmse를 줄이는 데는 성공하지 못했다. 그 이유를 생각해보건데, 훈련데이터가 테스트데이터의 양에 비해 어마어마하게 크고 가격의 분포 또한 엄청 다양하여, 과적합을 염려할 상황은 아니였음으로 판단된다.</li>
</ul>
</li>
</ul>
<h2 id="3-나의-새로운-시도">3. 나의 새로운 시도</h2>
<h3 id="wandb">wandb</h3>
<ul>
<li>새로운 것에 대한 도전이 쉽지 않았는데, 팀장님의 소스코드와 wandb결과물을 보면서 나름의 공부를 하였고, 지금은 한층 더 여유롭게 wandb를 내 코드에 녹여서 작업할 수 있게 되었다.</li>
<li>하이퍼파라미터의 최적화를 추적할 때 효과적인 툴이다.<h3 id="서버-사용하기">서버 사용하기</h3>
</li>
<li>서버 사용이 괜히 무서워서 사용하지 않고 있었는 데, 팀장님께서 하나도 어렵지 않다는 말에 도전하였고, 정말 빠르고 쾌적함을 느낄수 있었다. 좀더 빨리 사용했다면 좋았을 것이라는 아쉬움이 남는다.</li>
</ul>
<h2 id="4-프로젝트-회고">4. 프로젝트 회고</h2>
<h3 id="아쉬운-점">아쉬운 점</h3>
<ul>
<li>역시 시간이다.</li>
<li>처음에 평수를 나누어서 모델을 만드려는 시도를 했었다. 20평 단위로 나눠서 계산했었는데, 생각보다 에러가 너무 커 실험을 중단하였다. </li>
<li>대회마감 전날에서야 데이터를 너무 잘게 나누면 나눈 데이터들의 경계의 에러가 커지기 때문에 규모의 데이터를 적당하게 나눠야함을 알았다.</li>
<li>이 대회를 앞으로 하실 분에게 힌트를 드리자면, 메타 모델을 사용한다.</li>
<li>데이터를 위와 같이 적절히 나눈후 각기 모델로 학습을 시켜서 나온 결과들을 그냥 모아서는 에러가 크고, 그 데이터들을 모아서 rigde 같은 선형모델에 한번 더 돌려주면 에러가 많이 감소함을 알 수 있다.<h3 id="나만의-마무리">나만의 마무리</h3>
</li>
<li>마지막날에 알아서 제대로 코딩하지 못했던 모델링을 대회후 주말에 열심히 만들어서 결과를 내었다. </li>
<li>여태것 catboost의 val rmse가 5900에서 6000초반 대였는데, 다시 만들어서 실험 한 결과 5060대가 나왔다!!!</li>
<li>이걸 꼭 리더보드에 한번 제출해보고 싶은데 그렇게는 안해주시려나. </li>
</ul>
<h2 id="5-다음-대회에서-할-일">5. 다음 대회에서 할 일</h2>
<h3 id="체계적인-데이터-관리">체계적인 데이터 관리</h3>
<ul>
<li>모델링을 할때, 계속 같은 ipynb파일에서 하곤 했는 데, 그렇게 되니 너무 주먹구구식으로 관리가 되고 wandbd의 이름이나 그룹이 잘못 설정되는 경우들도 허다하게 되었다. </li>
<li>다음 대회에서는 한 모델링에 대해서 하나의 파일로 작업을 하고 철저히 확인하고 작업하도록 하여 혼선을 최대한 막으려고 한다.</li>
<li>파일이름에 대한 체계성도 만드려고 한다. 아웃풋에 대한 이름체계가 확실해야 실험을 돌릴때 유실되는 파일을 막을 수 있다. 그리고 시간대를 넣어주면 wandb와 비교하여 찾기 쉬워진다.</li>
<li>방금 생각난 것인데, wandb가 알아서 생성해주는 이름을 파일명으로 쓰는 방법도 찾아봐야겠다. 그럼 매칭이 쉬워서 관리가 좋을 것이다.</li>
</ul>
<p>요즘도 아쉬워서 서버 접속해서 맨날 이것저것 돌려보면서 생각해보고 있다. 간단한 것 같으면서도 어려웠던 대회였고 그래서 그런지 자꾸 미련이 남는다. 결론은 재미있었다!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ML - Upstage 심화]]></title>
            <link>https://velog.io/@nary_kim/ML-Upstage-advance</link>
            <guid>https://velog.io/@nary_kim/ML-Upstage-advance</guid>
            <pubDate>Mon, 22 Jul 2024 23:50:57 GMT</pubDate>
            <description><![CDATA[<p>ML을 또 배워?라고 생각했었다.</p>
<p>나의 오만. 앞에꺼 대충 들었어도 이거 잘 들으면 전문가적인 포스를 내뿜을 수 있다.</p>
<p>예시코드들이 여태까지 예시로 보았던 보스턴, 타이타닉의 문제 예측이 중심이 아니고 현업에 쓰이는 ML 패키지들의 샘플코드들이 많이 담겨져있어, 나중에 프로젝트에 쓰기 좋겠다고 생각했다. </p>
<p>코드들을 잘 보관하여 잘 써먹어야지.</p>
<p>ML을 하면 우리가 많이 쓰게 될 LightGBM, XGBoost, CatBoost의 장단점과 차이를 정리해본다.</p>
<h3 id="lightgbm">LightGBM</h3>
<h4 id="장점">장점:</h4>
<ul>
<li>대용량 데이터에서 빠름. </li>
<li>메모리 효율적.</li>
<li>카테고리형 변수 자동 처리 가능.<h4 id="단점">단점:</h4>
</li>
<li>작은 데이터셋에서는 오히려 느릴 수 있음.</li>
<li>과적합 우려 있음.<h3 id="xgboost">XGBoost</h3>
<h4 id="장점-1">장점:</h4>
</li>
<li>성능 좋고 튜닝 많이 됨.</li>
<li>다양한 파라미터 제공으로 유연한 모델링 가능.</li>
<li>병렬 처리 지원.<h4 id="단점-1">단점:</h4>
</li>
<li>큰 데이터셋에서 느릴 수 있음.</li>
<li>파라미터 튜닝 복잡함.<h3 id="catboost">CatBoost</h3>
<h4 id="장점-2">장점:</h4>
</li>
<li>카테고리형 데이터 처리에 강점 있음.</li>
<li>기본값으로도 좋은 성능 발휘.</li>
<li>자동으로 데이터 셔플링 해서 과적합 방지.<h4 id="단점-2">단점:</h4>
</li>
<li>학습 속도가 LightGBM보다 느림.</li>
<li>파라미터 문서화 부족.<h3 id="차이점">차이점</h3>
</li>
<li>LightGBM: 리프 중심 트리 분할 방식 사용. 대용량 데이터에서 빠르고 메모리 효율적임.</li>
<li>XGBoost: 전통적 부스팅 알고리즘 사용. 다양한 파라미터와 병렬 처리 지원.</li>
<li>CatBoost: 카테고리형 데이터에 강점 있음. 과적합 방지 기능 내장.</li>
<li>세 모델 모두 각자 장단점 있어서 데이터 특성 및 목적에 맞게 선택해야 함.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[딥러닝과 Pytoch 기초 온라인강의]]></title>
            <link>https://velog.io/@nary_kim/DL-Pytoch-Basic</link>
            <guid>https://velog.io/@nary_kim/DL-Pytoch-Basic</guid>
            <pubDate>Wed, 03 Jul 2024 08:29:57 GMT</pubDate>
            <description><![CDATA[<p>딥러닝의 역사부터 원리까지 조근조근 설명해 주어서 좋은 강의였다.
온라인 강의의 이점을 살려, 역전파와 손실함수에 대한 수학적 설명도 여러번 돌려보면서 이해할 수 있었다.</p>
<h3 id="1-deep-learning">1. Deep Learning</h3>
<blockquote>
<p>딥러닝 발전 5단계 I : 1단계 ~ 3단계
딥러닝 발전 5단계 II : 4단계 ~ 5단계
딥러닝 기술 종류들 I : 학습 방식에 의한 구분
딥러닝 기술 종류들 II : 데이터 형식, 태스크 종류에 의한 구분
딥러닝 개요
모델 학습법 I : 다층 퍼셉트론
모델 학습법 II : 경사 하강법
모델 학습법 III : 역전파 (기초)
모델 학습법 III : 역전파 (심화)
모델 학습법 IV : 손실 함수
모델 학습법 실습
성능 고도화 방법 I : 과적합, 편향과 분산, 지역/전역 최소값, 네트워크 안정화
성능 고도화 방법 II : 가중치 초기화, 규제화, 학습률
성능 고도화 방법 III : 다양한 최적화 알고리즘
성능 고도화 방법 IV : 데이터 증강 및 그 외 방법들
성능 고도화 방법 실습
CNN
RNN</p>
</blockquote>
<h3 id="2-pytorch">2. Pytorch</h3>
<blockquote>
<p>파이토치 소개
환경 설정
텐서 조작의 개념
텐서 조작(1)
텐서 조작(2)
딥러닝을 위한 파이토치가 어떻게 동작하는가?
DNN 구현(1)
DNN 구현(2)
DNN 구현(3)
CNN 구현
RNN 구현
전이학습이란?
timm과 Hugging Face을 통한 전이 학습
모니터링을 위한 TensorBoard와 Wandb
디버깅
파이토치 라이트닝 소개
파이토치 코드를 파이토치 라이트닝 코드로 변환하기
하이드라 소개
파이토치 라이트닝과 하이드라</p>
</blockquote>
<p>나중에 혼자 공부할 때 찾아볼 수 있게, 목차를 올려둔다.</p>
<h2 id="💡apple-silicon-사용을-위한-설정">💡Apple silicon 사용을 위한 설정</h2>
<p>공부를 하다가 gpu 사용을 위해 device를 cuda로 설정하는 부분이 있는데, 나는 맥북을 쓰기 때문에 쓸수가 없었다. 그래서 Apple Silicon을 사용할 수 있는 방법을 찾아보았고, 여기에 남겨두려고 한다.</p>
<p>우선 새로운 가상환경을 설정하도록 한다.</p>
<pre><code>&gt;&gt;&gt;conda create -n pytorch_m1 python=3.10
&gt;&gt;&gt;conda activate pytorch_m1
&gt;&gt;&gt;pip install torch torchvision torchaudio --pre</code></pre><p>그리고 xcode, Jupyter 및 ipywidgets은 최신버전으로 업데이트한다.</p>
<p>그런 후 </p>
<pre><code class="language-python">device = torch.device(&quot;mps&quot; if torch.backends.mps.is_available() else &quot;cpu&quot;)</code></pre>
<p>이렇게 device를 설정하면 된다. 그러나 커다란 문제가 하나 있는데, mps를 쓰는 것보다 cpu를 쓰는게 더 빠르다!!
찾아보니 batch 갯수가 많거나, 실습에서 돌렸던 문제보다 더 복잡한 구조를 가져야 mps를 쓸때, 시간의 차이가 난다고 한다. 
참고로 실습에서 batch는 32였고, 4개의 레이어를 사용하였으며, 48000개의 데이터를 train했다. </p>
<p>아래에는 cpu보다 gpu가 빨랐던 샘플코드이다.</p>
<pre><code class="language-python">import time
import torch
import torch.nn as nn
import torch.optim as optim

# 모델 정의
class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()
        self.fc = nn.Sequential(
            nn.Linear(2048, 1024),
            nn.ReLU(),
            nn.Linear(1024, 512),
            nn.ReLU(),
            nn.Linear(512, 256),
            nn.ReLU(),
            nn.Linear(256, 128),
            nn.ReLU(),
            nn.Linear(128, 10),
            nn.LogSoftmax(dim=1)
        )

    def forward(self, x):
        return self.fc(x)

# 더미 데이터 생성 (배치 크기 증가)
inputs = torch.randn(1024, 2048)
labels = torch.randint(0, 10, (1024,))

# 훈련 함수 정의
def train(device, model, inputs, labels, num_epochs=10):
    model.to(device)
    model.train()

    start_time = time.time()

    for epoch in range(num_epochs):
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

    end_time = time.time()
    return end_time - start_time

# 손실 함수 및 옵티마이저 정의
criterion = nn.NLLLoss()
optimizer = optim.Adam(SimpleNN().parameters(), lr=0.001)

# CPU에서 훈련
cpu_device = torch.device(&quot;cpu&quot;)
cpu_model = SimpleNN()
cpu_inputs = inputs.to(cpu_device)
cpu_labels = labels.to(cpu_device)
cpu_time = train(cpu_device, cpu_model, cpu_inputs, cpu_labels)
print(f&quot;CPU Training Time: {cpu_time:.2f} seconds&quot;)

# MPS에서 훈련
if torch.backends.mps.is_available():
    mps_device = torch.device(&quot;mps&quot;)
    mps_model = SimpleNN()
    mps_inputs = inputs.to(mps_device)
    mps_labels = labels.to(mps_device)
    mps_time = train(mps_device, mps_model, mps_inputs, mps_labels)
    print(f&quot;MPS Training Time: {mps_time:.2f} seconds&quot;)
else:
    print(&quot;MPS device is not available.&quot;)</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[ML Basic - Regression]]></title>
            <link>https://velog.io/@nary_kim/MLbasic-regression</link>
            <guid>https://velog.io/@nary_kim/MLbasic-regression</guid>
            <pubDate>Wed, 05 Jun 2024 07:15:49 GMT</pubDate>
            <description><![CDATA[<p>회귀, 분류, 클러스터링
개인적으로는 ML수업은 실시간 강의보다 온라인 강의가 나에게 더 맞았음.</p>
<p>근데 어려움. 개념이 와닿지가 않아서 이번 블로그는 챗gpt에 각 개념을 물어보면서 개념 세우기를 해보려함.</p>
<h2 id="💡-회귀">💡 회귀</h2>
<h4 id="회귀분석이란">회귀분석이란?</h4>
<p>회귀분석은 어떤 숫자를 예측하는 방법이에요. 예를 들어, 집의 크기와 위치를 알고 있을 때 그 집의 가격을 예측하는 것과 같아요.</p>
<h4 id="어떻게-작동하나요">어떻게 작동하나요?</h4>
<p>회귀분석은 데이터의 패턴을 찾아서, 새로운 데이터가 주어졌을 때 그 숫자를 예측할 수 있도록 도와줘요. 예를 들어, 과거의 집 가격 데이터를 사용해서 새로운 집의 가격을 예측할 수 있는 모델을 만드는 거예요.</p>
<h4 id="회귀분석의-종류">회귀분석의 종류</h4>
<ol>
<li>단순 회귀(Simple Regression):</li>
</ol>
<ul>
<li>단순 선형 회귀(Simple Linear Regression): 독립 변수 하나(예: 집 크기)로 종속 변수 하나(예: 집 가격)를 예측하는 방법이에요.</li>
<li>이 경우, 데이터 점들을 가장 잘 설명할 수 있는 직선(선을 그려서)을 찾는 거예요. 이 선을 통해 새로운 집 크기 데이터를 넣으면 그 집의 가격을 예측할 수 있어요.</li>
</ul>
<ol start="2">
<li>다중 회귀(Multiple Regression):</li>
</ol>
<ul>
<li>여러 개의 독립 변수(예: 집 크기, 방의 개수, 위치 등)로 하나의 종속 변수(예: 집 가격)를 예측하는 방법이에요.</li>
<li>여러 특성을 동시에 고려해서 더 정확한 예측을 할 수 있어요.</li>
</ul>
<h4 id="예시로-설명">예시로 설명</h4>
<ol>
<li>단순 회귀 예시:</li>
</ol>
<ul>
<li>여러분이 과일 가게를 운영한다고 생각해보세요.</li>
<li>지난 몇 주 동안 과일 판매량(독립 변수)과 매출액(종속 변수)을 기록했어요.</li>
<li>이제 다음 주에 과일을 얼마나 팔면 매출이 얼마나 될지 예측하고 싶어요.</li>
<li>단순 선형 회귀를 사용하면, 과일 판매량과 매출액 사이의 관계를 찾아서, 다음 주 판매량을 입력하면 예상 매출을 예측할 수 있어요.</li>
</ul>
<ol start="2">
<li>다중 회귀 예시:</li>
</ol>
<ul>
<li>이번엔 집 가격을 예측해보아요.</li>
<li>집의 크기, 방의 개수, 위치 등의 정보를 가지고 있어요.</li>
<li>이 정보를 이용해서 집 가격을 예측하고 싶어요.</li>
<li>다중 회귀를 사용하면, 집 크기, 방 개수, 위치 등을 모두 고려해서 집 가격을 예측할 수 있어요.<h4 id="요약">요약</h4>
</li>
<li>회귀분석은 숫자를 예측하는 데 사용되는 방법이에요.</li>
<li>단순 회귀는 하나의 변수를 사용하고, 다중 회귀는 여러 변수를 사용해요.</li>
<li>이 방법을 통해 데이터를 분석하고, 새로운 데이터를 예측할 수 있어요.</li>
</ul>
<h3 id="feature-selection이란">Feature Selection이란?</h3>
<ul>
<li>Feature Selection은 머신러닝에서 데이터의 여러 특성(컬럼) 중에서 중요한 것들만 고르는 작업입니다. 예를 들어, 친구의 키, 나이, 학년, 좋아하는 과목을 알고 있을 때, 친구의 성적을 예측하려고 한다면, 꼭 필요한 정보(특성)만 고르는 것이 Feature Selection입니다.</li>
</ul>
<h4 id="왜-feature-selection이-중요한가요">왜 Feature Selection이 중요한가요?</h4>
<ul>
<li>성능 향상: 중요한 정보만 사용하면 더 정확한 예측이 가능해요.</li>
<li>과적합 방지: 불필요한 정보를 제거하면 모델이 데이터를 너무 잘 외워서 새로운 데이터에 대해 잘못 예측하는 것을 막을 수 있어요.</li>
<li>시간 절약: 적은 특성으로 모델을 학습시키면 더 빨리 학습할 수 있어요.</li>
<li>이해하기 쉬움: 중요한 특성만 남기면 왜 그런 예측이 나왔는지 이해하기 더 쉬워요.</li>
</ul>
<h4 id="어떻게-feature-selection을-하나요">어떻게 Feature Selection을 하나요?</h4>
<ol>
<li>필터 방법:</li>
</ol>
<ul>
<li>각각의 특성을 개별적으로 평가해서 중요한 것들을 고릅니다.</li>
<li>예를 들어, 과일의 색깔과 무게가 과일의 맛을 예측하는 데 얼마나 중요한지 각각 평가해요.</li>
</ul>
<blockquote>
<pre><code class="language-python">from sklearn.feature_selection import SelectKBest, f_classif </code></pre>
</blockquote>
<h1 id="예시-데이터">예시 데이터</h1>
<p>X = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]  # 특성 데이터
y = [1, 2, 3]  # 목표 변수</p>
<h1 id="가장-중요한-2개의-특성-선택">가장 중요한 2개의 특성 선택</h1>
<p>selector = SelectKBest(score_func=f_classif, k=2)
X_new = selector.fit_transform(X, y)
print(X_new)</p>
<pre><code>
2. 래퍼 방법:

- 특성들의 조합을 만들어서 가장 좋은 조합을 찾습니다.
- 예를 들어, 무게와 크기를 함께 고려하면 더 정확하게 예측할 수 있을지 확인해요.

&gt;```python
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
rfe = RFE(model, n_features_to_select=2)  # 2개의 중요한 특성 선택
X_new = rfe.fit_transform(X, y)
print(X_new)</code></pre><ol start="3">
<li>임베디드 방법:</li>
</ol>
<ul>
<li>모델을 학습하면서 동시에 중요한 특성을 고릅니다.</li>
<li>예를 들어, 랜덤 포레스트 모델이 자동으로 중요한 특성을 찾아내는 방식이에요.</li>
</ul>
<pre><code class="language-python">from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
model.fit(X, y)
importances = model.feature_importances_
print(importances)  # 특성 중요도 출력</code></pre>
<h4 id="간단한-예시">간단한 예시</h4>
<ul>
<li><p>친구들의 성적을 예측하는 예를 들어 볼게요:</p>
</li>
<li><p>데이터: 친구들의 키, 나이, 학년, 좋아하는 과목 등.</p>
</li>
<li><p>목표: 성적 예측.</p>
</li>
<li><p>필터 방법
각각의 특성을 성적과 비교해서 중요한 것만 고릅니다. 예를 들어, 키가 성적과 관련이 적다면 제거하고, 나이와 학년이 중요하다면 이 둘을 선택합니다.</p>
</li>
</ul>
<ol>
<li><p>래퍼 방법
특성들의 여러 조합을 만들어서 가장 좋은 조합을 찾습니다. 예를 들어, 키와 나이를 함께 고려하면 더 정확하게 예측할 수 있는지 확인합니다.</p>
</li>
<li><p>임베디드 방법
모델이 학습하면서 자동으로 중요한 특성을 고릅니다. 랜덤 포레스트 같은 모델은 자체적으로 어떤 특성이 중요한지 판단합니다.</p>
</li>
</ol>
<h3 id="penalty-term">Penalty Term</h3>
<ul>
<li>패널티 항은 머신러닝 모델을 학습할 때 모델이 너무 복잡해지는 것을 막기 위해 추가하는 항목입니다. 이는 모델이 데이터에 과적합(overfitting)되는 것을 방지하는 데 도움이 됩니다.</li>
</ul>
<h4 id="왜-패널티-항이-중요한가요">왜 패널티 항이 중요한가요?</h4>
<ol>
<li>과적합 방지: 모델이 학습 데이터에 너무 잘 맞아 새로운 데이터에 대해서는 잘못된 예측을 하지 않도록 도와줍니다.</li>
<li>모델 단순화: 너무 많은 특성이나 복잡한 모델을 사용하는 것을 방지하여, 모델을 더 단순하게 만듭니다.<h4 id="패널티-항의-종류">패널티 항의 종류</h4>
</li>
<li>L1 패널티 (라쏘 회귀, Lasso Regression):</li>
</ol>
<ul>
<li>각 특성의 가중치(계수)의 절대값을 합한 값을 패널티로 추가합니다.</li>
<li>결과적으로 중요하지 않은 특성의 가중치를 0으로 만들어, 특성 선택의 역할도 합니다.</li>
</ul>
<ol start="2">
<li>L2 패널티 (릿지 회귀, Ridge Regression):</li>
</ol>
<ul>
<li>각 특성의 가중치(계수)의 제곱을 합한 값을 패널티로 추가합니다.</li>
<li>모든 특성의 가중치를 조금씩 감소시키지만, 0으로 만들지는 않습니다.</li>
</ul>
<h4 id="예시로-이해하기">예시로 이해하기</h4>
<ol>
<li>기본 회귀 모델</li>
</ol>
<ul>
<li>회귀 모델은 데이터를 통해 어떤 결과를 예측하는 모델입니다. 예를 들어, 집의 크기와 가격 데이터를 사용해서 새로운 집의 가격을 예측할 수 있습니다.</li>
</ul>
<ol start="2">
<li>패널티 항이 없는 경우</li>
</ol>
<ul>
<li>모델이 집의 크기뿐만 아니라 너무 많은 세부 정보를 고려하면, 데이터에 과적합될 수 있습니다. 즉, 모델이 학습 데이터에 너무 잘 맞아서 새로운 데이터에 대한 예측이 부정확해질 수 있습니다.</li>
</ul>
<h4 id="l1-패널티-라쏘-회귀">L1 패널티 (라쏘 회귀)</h4>
<ul>
<li>라쏘 회귀는 모델의 복잡성을 줄이기 위해 가중치의 절대값 합을 추가로 고려합니다. 이는 중요하지 않은 특성의 가중치를 0으로 만들어, 모델이 더 단순해지고, 중요한 특성만 남게 합니다.</li>
</ul>
<pre><code class="language-python">from sklearn.linear_model import Lasso
# 라쏘 회귀 모델
model = Lasso(alpha=0.1)
model.fit(X_train, y_train)
predictions = model.predict(X_test)</code></pre>
<h4 id="l2-패널티-릿지-회귀">L2 패널티 (릿지 회귀)</h4>
<ul>
<li>릿지 회귀는 모델의 복잡성을 줄이기 위해 가중치의 제곱 합을 추가로 고려합니다. 이는 모든 가중치를 조금씩 감소시키지만, 0으로 만들지는 않아서 모든 특성을 고려하게 합니다.</li>
</ul>
<pre><code class="language-python">from sklearn.linear_model import Ridge
# 릿지 회귀 모델
model = Ridge(alpha=0.1)
model.fit(X_train, y_train)
predictions = model.predict(X_test)</code></pre>
<h4 id="요약-1">요약</h4>
<ul>
<li>패널티 항: 모델이 너무 복잡해지지 않도록 추가하는 항목입니다.</li>
<li>L1 패널티 (라쏘 회귀): 가중치의 절대값 합을 추가하여 중요하지 않은 특성의 가중치를 0으로 만듭니다.</li>
<li>L2 패널티 (릿지 회귀): 가중치의 제곱 합을 추가하여 모든 가중치를 조금씩 감소시킵니다.</li>
<li>목적: 모델의 과적합을 방지하고, 더 좋은 예측을 하기 위해 사용됩니다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[코딩 테스트 - 노정호 강사님]]></title>
            <link>https://velog.io/@nary_kim/coding-test</link>
            <guid>https://velog.io/@nary_kim/coding-test</guid>
            <pubDate>Tue, 21 May 2024 01:24:31 GMT</pubDate>
            <description><![CDATA[<ul>
<li><p>코딩 테스트를 공부해야 하는 이유</p>
<ul>
<li>대기업은 취업할때 대부분 코딩테스트를 실시.</li>
<li>내 포트폴리오가 아무리 좋아도 코테를 통과하지 못하면 포폴을 보여줄 수도 없음.</li>
</ul>
</li>
<li><p>요즘 트렌트는 문제길이가 길어지면서 문해력파트가 중요해짐.</p>
</li>
<li><p>문제풀이 절차
  (1) 문제 이해하기 문제 분석
  (2) 접근 방법 - 자료구조 알고리즘 이론 학습
  (3) 코드설계 시간 복잡도
  (4) 코드 구현 언어숙련도(필수 코드 외우기) 구현연습</p>
</li>
<li><p>코테 효율적인 공부방법</p>
<ul>
<li>시간복잡도</li>
<li>자주나오는 필수 자료구조/알고리즘</li>
<li>면접과 코테 내용은 다르다.</li>
<li>이론을 제대로 이해하고 문제 접근</li>
<li>구현이 중요하다. 주력 언어를 정하고 체화</li>
<li>스터디 꼭꼭. </li>
</ul>
</li>
</ul>
<h3 id="1일차">1일차</h3>
<ul>
<li><p>시간 복잡도</p>
</li>
<li><p>메모리 구조</p>
</li>
<li><p>자료구조 </p>
<ul>
<li>List, queue, stack, dictionary, graph, tree, heapq</li>
</ul>
</li>
<li><p>알고리즘 </p>
<ul>
<li><strong>완전탐색(+백트레킹)</strong>, 재귀, 반복문, </li>
<li><strong>DFS, BFS</strong>, DP, </li>
<li><strong>Dijkstra(heapq)</strong>, sort()</li>
</ul>
</li>
</ul>
<hr>
<h4 id="💡-오늘의-하이라이트는-재귀함수">💡 오늘의 하이라이트는 재귀함수</h4>
<pre><code class="language-python">def solution(nums, target):
    n = len(nums)
    def recur(ans, start):
        if len(ans) == 2:
            if nums[ans[0]] + nums[ans[1]] == target:
                return ans
            return False

        for i in range(start, n):
            ans.append(i)
            if recur(ans, i+1):
                return ans
            ans.pop()

    return recur([], 0)


print(solution(nums = [4,9,7,5,1], target = 14))</code></pre>
<hr>
<ul>
<li>Stack - LIFO (프링글스)
&lt; 괄호문제는 stack으로 &gt;<pre><code class="language-python">def solution(s):
  stack=[]
  for p in s:
      if p==&#39;(&#39;:
          stack.append(p)
      else:
          if not stack:
              return False
          else:
              stack.pop()
  return not stack</code></pre>
</li>
</ul>
<h3 id="2일차">2일차</h3>
<h4 id="💡-bfs-dfs">💡 BFS, DFS</h4>
<pre><code>    - 그래프의 길찾기 문제.
    - DFS는 재귀를 이용한 알고리즘.
    - BFS는 최단거리를 알수 있다.</code></pre><ul>
<li>BFS - queue를 사용한다.<ul>
<li>Queue - FIFO<ul>
<li>deque.append()</li>
<li>deque.popleft()<pre><code class="language-python">from collections import deque
def bfs(graph, start_v):
q = deque()
# 시작점 예약
q.append(start_v)
# 방문 표시
visited = {start_v: True}
while q:
cur_v = q.popleft()
print(cur_v,&quot; &quot;, end=&#39;&#39;)
for next_v in graph[cur_v]:
    if next_v not in visited:
        q.append(next_v)
        visited[next_v] = True
</code></pre>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>graph = {
    0: [1, 3, 6],
    1: [0, 3],
    2: [3],
    3: [0, 1, 2, 7],
    4: [5],
    5: [4, 6, 7],
    6: [0, 5],
    7: [3, 5],
}
bfs(graph, start_v=0)</p>
<pre><code>---
- DFS : 재귀 사용
```python
def gogo(graph, start_v):
    visited = {}
    visited[start_v]=True
    def dfs(cur_v):
        print(cur_v,&quot; &quot;, end=&#39;&#39;)
        for next_v in graph[cur_v]:
            if next_v not in visited:
                visited[next_v] = True
                dfs(next_v)
    dfs(start_v)

graph = {
    0: [1, 3, 6],
    1: [0, 3],
    2: [3],
    3: [0, 1, 2, 7],
    4: [5],
    5: [4, 6, 7],
    6: [0, 5],
    7: [3, 5],
}
gogo(graph, start_v=0)</code></pre><h3 id="3일차">3일차</h3>
<h4 id="💡-암시적-그래프-dijkstra">💡 암시적 그래프, Dijkstra</h4>
<pre><code>    - 암시적 그래프는 행렬에 지도를 표시하는 방식
    - 4방향 또는 8방향을 탐색하면서 문제를 해결
    - 그 안에서 길을 찾는 것은 BFS, DFS를 사용.
    - Dijkstra는 그래프에 가중치를 더한 것.
    - heapq를 사용.</code></pre><ul>
<li>암시적 그래프
&lt; DFS예시&gt; : BFS도 마찬가지의 구조를 갖는다.<pre><code class="language-python">from collections import deque
class Solution:
  def numIslands(self, grid):
      row_len, col_len = len(grid), len(grid[0])
      visited = [[False] * col_len for _ in range(row_len)]
      def dfs(r,c):
          visited[r][c]=True
          for i in range(4):
              next_r = r + dr[i]
              next_c = c + dc[i]
              if 0 &lt;= next_r &lt; row_len and 0 &lt;= next_c &lt; col_len:
                  if grid[next_r][next_c]==&quot;1&quot;:
                      if not visited[next_r][next_c]:
                          dfs(next_r,next_c)
              cnt = 0        
              for i in range(row_len):
          for j in range(col_len):
              if grid[i][j] == &quot;1&quot;
                  if not visited[i][j]:
                      dfs(i,j)
                      cnt += 1
      return cnt
</code></pre>
</li>
</ul>
<p>grid = [
    [&quot;1&quot;, &quot;1&quot;, &quot;0&quot;, &quot;0&quot;, &quot;0&quot;],
    [&quot;1&quot;, &quot;1&quot;, &quot;0&quot;, &quot;0&quot;, &quot;0&quot;],
    [&quot;0&quot;, &quot;0&quot;, &quot;1&quot;, &quot;1&quot;, &quot;0&quot;],
    [&quot;0&quot;, &quot;0&quot;, &quot;0&quot;, &quot;1&quot;, &quot;1&quot;],
]</p>
<p>dr = [0, 1, 0, -1]
dc = [1, 0, -1, 0]
s=Solution()
s.numIslands(grid)</p>
<pre><code>---
- Dijkstra : 이해해면서 외우자
```python
def dijkstra(graph, start_v, dest, n):
    distances = [INF] * (n + 1)
    distances[start_v] = 0
    pq = [(0, start_v)]

    while pq:
        cur_dist, cur_v = heapq.heappop(pq)
        if distances[cur_v] &lt; cur_dist:
            continue
        for next_v, cost in graph[cur_v]:
            next_dist = distances[cur_v] + cost
            if next_dist &lt; distances[next_v]:
                distances[next_v] = next_dist
                heapq.heappush(pq, (next_dist, next_v))
    return distances[dest]

graph = { … }
dijkstra(graph, 1, 8, len(graph))</code></pre><ul>
<li><a href="https://leetcode.com/problems/network-delay-time/description/">Dijkstar 실전문제</a><pre><code class="language-python">from collections import defaultdict
import heapq
import sys

</code></pre>
</li>
</ul>
<p>class Solution:
    def networkDelayTime(self, times, n, k):
        # 입력값 변환
        # 가중치 단방향 그래프를 인접리스트로 구현하기
        graph = defaultdict(list)
        for u, v, time in times:
            graph[u].append((time, v))</p>
<pre><code>    # 1부터 n까지 총 n개의 노드의 cost를 적어 놓는다.
    costs = [sys.maxsize for _ in range(n + 1)]
    pq = [(0, k)]
    costs[k] = 0
    while pq:
        travel_time, cur_v = heapq.heappop(pq)
        for time, next_v in graph[cur_v]:
            next_cost = travel_time + time
            if next_cost &lt; costs[next_v]:
                costs[next_v] = next_cost
                heapq.heappush(pq, (next_cost, next_v))

    # index 0번째에는 sys.maxsize값이 무조건 들어 있으므로 이를 제외한 나머지 값들만 다시 떼어준다.
    new_costs = costs[1:]

    # costs에 sys.maxsize와 같은 크기의 값이 저장되어 있다면 도달하지 못했다는 뜻이므로 -1를 반환한다.
    for cost in new_costs:
        if cost == sys.maxsize:
            return -1

    # 모든 노드를 방문하기 위한 최소 시간을 구해야 한다.
    # 각 노드까지 도달할 수 있는 최소 시간은 이미 costs에 저장해두었다.
    # 따라서 모든 노드를 방문하기 위해서는 가장 높은 시간을 반환해야 한다.
    return max(new_costs)</code></pre><pre><code>### 수업시간 문제들
- [1번문제: two sum](https://leetcode.com/problems/two-sum/)    
- [3번문제: combinations](https://leetcode.com/problems/combinations/)    
- [4번문제: 괄호 유효성 문제](https://school.programmers.co.kr/learn/courses/30/lessons/12909)   
- [7번문제: keys and rooms](https://leetcode.com/problems/keys-and-rooms/description/)

- [10번문제: number of islands](https://leetcode.com/problems/number-of-islands/)   
- [11번 문제: shortest path](https://leetcode.com/problems/shortest-path-in-binary-matrix/description/)   
- [13번 문제: network delay time](https://leetcode.com/problems/network-delay-time/description/)


### 추천문제들
1. [네트워크](https://school.programmers.co.kr/learn/courses/30/lessons/43162?language=python3)
2. [거리두기 확인](https://school.programmers.co.kr/learn/courses/30/lessons/81302)
3. [스타트 택시](https://www.acmicpc.net/problem/19238)





</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Python EDA를 위한 기초]]></title>
            <link>https://velog.io/@nary_kim/Python-EDA-library</link>
            <guid>https://velog.io/@nary_kim/Python-EDA-library</guid>
            <pubDate>Wed, 01 May 2024 07:56:47 GMT</pubDate>
            <description><![CDATA[<p>python EDA를 하기 위해서는 numpy와 pandas 그리고 seaborn 세 라이브러리가 가장 많이 사용되므로 이것에 대한 사용법들을 배웠다.</p>
<p>전에 배웠던 내용들이여서 정리하면서 듣지 않고 좀 교양처럼 들었더니, 블로그 쓰기가 힘들어졌다..
내가 몰랐던 것 위주로 다시 정리해본다.</p>
<blockquote>
<p>Numpy as np</p>
</blockquote>
<ul>
<li>np.array는 python의 array와는 다르다. 덧셈이 벡터의 덧셈처럼 된다. np는 matlab과 비슷하다는 얘기를 들은 적이 있는 데, 그런 것도 같다.</li>
<li>python의 리스트처럼 합쳐지는 걸 하고 싶다면, np.vstack 이나 np.hstack과 같은 것을 쓰면 된다.</li>
<li>근데 곱셈은 각각 곱해진다. (벡터의 곱과는 다르다.) </li>
<li>dot product는 @를 사용.(v1 @ v2)</li>
<li>선형대수관련한 계산에는 라이브러리가 따로 존재한다.(np.linalg)</li>
<li>shape을 다시 조립할 수 있는 reshape이 있어서 좋다.</li>
<li>np.argmin, np.argmax는 해당하는 값의 인덱스를 반환한다.</li>
<li>우리가 직접 구현하는 것보다 Universal Function을 사용하는 것이 훨씨니 빠른 성능을 낸다. (괜히 깝치지 말고 우선 검색하자.)</li>
</ul>
<blockquote>
<p>Pandas as pd</p>
</blockquote>
<ul>
<li>DataFrame이 pandas의 꽃이지 않을까.</li>
<li>나 근데 이건 전부터 열심히 해서 진짜 좀 잘 한다.</li>
<li>pd.pivot_table을 사용했는데, groupby도 연습해두자.</li>
</ul>
<blockquote>
<p>seaborn as sns</p>
</blockquote>
<ul>
<li>모든 라이브러리가 그렇지만 seaborn도 잘 바뀌는 라이브러리라서 체크가 필요하다.</li>
<li>안되면 설명서 찾아서 읽어본다.</li>
<li>요소 중에 multiple=&#39;stack&#39;은 값이 쌓이는 모습을 다른 색들을 사용하여 잘 보여준다.</li>
<li>아래는 그래프의 이름이며 이름만 봐도 직관적으로 무엇을 나타내는지 드러난다. </li>
<li>Histplot</li>
<li>Displot</li>
<li>Barplot</li>
<li>Countplot</li>
<li>Boxplot</li>
<li>Violinplot</li>
<li>Lineplot</li>
<li>Pointplot</li>
<li>Scatterplot</li>
<li>Pairplot</li>
<li>Heatmap</li>
</ul>
<p>이제 EDA 프로젝트에 들어가는데 나는 주식관련으로 선택했다.
다행히 팀을 잘 만나서 데이터만 잘 모은다면 좋은 인사이트를 얻을수 있을 것이라고 생각한다.
화이팅!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[확률통계]]></title>
            <link>https://velog.io/@nary_kim/statistics</link>
            <guid>https://velog.io/@nary_kim/statistics</guid>
            <pubDate>Fri, 26 Apr 2024 08:46:11 GMT</pubDate>
            <description><![CDATA[<p>나는 수학과 출신이라서 한번 공부한 것들이라
확률통계에 대한 자세한 내용보다는
무엇을 공부해야 좋은지에 대해 정리해보도록 하겠다.</p>
<p>*** ICTMA 학회 수학적 모델링 학회(최적화인듯) - 찾아보자.</p>
<ul>
<li><p>교재</p>
<ul>
<li>모두의 인공지능 기초수학</li>
<li>현대 기초통계학 : 이해와 적용</li>
<li>머신러닝을 위한 통계학 : 박성호저</li>
<li>머신러닝 수학 바이블</li>
<li>제대로 시작하는 기초 통계학</li>
</ul>
</li>
<li><p>데이터를 가지고 할 일들.</p>
<ul>
<li>데이터 특성 요약 정리 : 기술통계</li>
<li>모집단의 특성 추론 : 추리통계</li>
<li>불확실한 미래의 사건 예측 : 회귀와 분류</li>
</ul>
</li>
<li><p>데이터분석, 패턴 인식, 의사결정</p>
</li>
</ul>
<blockquote>
<p>다른 것들도 중요하지만, 아래의 항목들이</p>
</blockquote>
<h4 id="중요한-것들">중요한 것들.</h4>
<ol>
<li><p>가설과 가설검정의 의미를 설명할 수 있다.</p>
<ul>
<li>귀무가설 $H_0$ &lt;-&gt; 대립가설(연구가설) $H_1$</li>
</ul>
</li>
<li><p>가설검정의 오류에 대해 설명할 수 있다.</p>
</li>
<li><p>유의수준과 유의확률에 대해 설명할 수 있다.</p>
</li>
<li><p>검정방법에 대해 설명할 수 있다.</p>
</li>
</ol>
<blockquote>
<p>그리고 가장 잘 쓸것 같은 것은 </p>
</blockquote>
<h4 id="t-분포">t-분포!</h4>
<ol>
<li><p>t검정에 대하여 설명할 수 있다.</p>
</li>
<li><p>단일표본 t검정, 독립표본 t검정에 대하여 설명할 수 있다.</p>
</li>
<li><p>파이썬을 사용하여 단일표본 t검정,독립표본 t검정을 실행할 수 있다.</p>
</li>
</ol>
<blockquote>
<p>그리고 ANOVA ( 일원분산분석, 이원분산분석 ), 상관관계, 선형회귀, Gradient Descent,
시그모이드 함수.</p>
</blockquote>
<p>이것들을 좀 잘 찾아보자!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[git - 이제 진짜 실전 ]]></title>
            <link>https://velog.io/@nary_kim/git-02</link>
            <guid>https://velog.io/@nary_kim/git-02</guid>
            <pubDate>Mon, 22 Apr 2024 15:19:56 GMT</pubDate>
            <description><![CDATA[<h4 id="💡-git-branch-관련-명령어">💡 git branch 관련 명령어</h4>
<ul>
<li><p>head - 가장 최근에 작업한 곳 최신의 브랜치</p>
</li>
<li><p>git branch {name} 현재 공간상태 복제</p>
</li>
<li><p>git switch</p>
</li>
<li><p>git merge</p>
</li>
<li><p>git branch -D {name} 삭제</p>
</li>
<li><p>브렌치의 이름은 쓰임이 명확하게 드러나도록</p>
</li>
<li><p>쓰임을 다한 브렌치는 제때 지워줌</p>
</li>
<li><p>일반적으로 브렌치는 푸쉬는 안하고 나중에 잘 쓰고 메인이랑 머지하고 지움.</p>
</li>
<li><p>merge conflict - 사용자가 확인 후 잘 고치면 됨.</p>
</li>
<li><ul>
<li>만약 알아서 잘 merge가 되서 merge conflict가 발생하지 않았지만 내가 원하는 대로 코드가 바뀌지 않았을 때는 코드를 바꾸고 나서 main에서 다시 add, commit을 해줘야 log가 남아서 무엇을 했는지 남기고 파악 할 수 있다.</li>
</ul>
</li>
<li><p>git lg 하면 브렌치가 들어간 시각화가 가능해짐.
<img src="https://velog.velcdn.com/images/nary_kim/post/799d720d-feef-417f-b93b-0f05bd97f1df/image.png" alt=""></p>
</li>
</ul>
<h4 id="💡-git-flow">💡 git flow</h4>
<ul>
<li>master 버전 사용자가 쓸 버전 - 팀장 관리자 급</li>
<li>develop 다음 버전 개발</li>
<li>hotfix 긴급 수정 </li>
<li>모바일앱 버전의 개념이 뚜렷</li>
<li>웹상은 좀 더 유연한 형태</li>
<li>검증은 github!</li>
</ul>
<h4 id="💡-github-flow">💡 github flow</h4>
<ul>
<li><p>편하고 단순한 구조 - 우리가 많이 작업할 구조.</p>
</li>
<li><p>issue 발행: 다 같이 개발 할 때 필요</p>
</li>
<li><p>깃헙 플로우에서는 메인에서 머지하지 않고 바로 푸쉬 </p>
</li>
<li><p>git push -u origin {branch_name} (-u : upstream 옵션 : local과 remote간의 링크. 첫 푸쉬에서만 해주면 됨.)</p>
</li>
<li><p>pull request에서 title을 쓰는 것이 중요함.</p>
</li>
</ul>
<h4 id="💡-트러블-슛">💡 트러블 슛</h4>
<ul>
<li><p>이름바꾸기</p>
<ul>
<li>git mv name name 하면 알아서 commit까지 진행.</li>
</ul>
</li>
<li><p>add 에서 내리기</p>
<ul>
<li>git reset HEAD</li>
<li>git restore --staged README.md</li>
</ul>
</li>
<li><p>최근 commit 수정</p>
<ul>
<li>git commit --amend</li>
</ul>
</li>
<li><p>지금부터 앞에 3개의 commit 전으로 돌아간다.</p>
<ul>
<li>git revert --no-commit HEAD~3..</li>
</ul>
</li>
</ul>
<h4 id="💡-project를-협업을-진행해보자">💡 Project를 협업을 진행해보자!</h4>
<p>관련 동영상: <a href="https://www.youtube.com/watch?v=g3GEnjppUV0">https://www.youtube.com/watch?v=g3GEnjppUV0</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[git - 코드 관리를 위한 git 사용법]]></title>
            <link>https://velog.io/@nary_kim/git-01</link>
            <guid>https://velog.io/@nary_kim/git-01</guid>
            <pubDate>Mon, 22 Apr 2024 15:10:44 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="우선-shell-과-vi의-사용법을-익히자">우선 shell 과 vi의 사용법을 익히자.</h3>
</blockquote>
<ul>
<li><p>shell에서의 주요 명령어.</p>
<ul>
<li>shell: 운영체제의 커널과 사용자를 이어주는 소프트웨어</li>
<li>pwd: print working direct 나의 현재 위치 출력</li>
<li>ls : list -a, -l, -al</li>
<li>mkdir : 새로운 디렉토리 생성</li>
<li>touch : 새로운 파일 생성</li>
<li>mv : 저장 위치 옮기기(move). 이걸로 이름을 바꾸기도 한다.</li>
<li>cp : 파일 복사. 이걸로도 이름을 바꾼다.</li>
</ul>
</li>
<li><p>vim 고수의 냄새. 카페에서 간지를 지킬 수 있다.🤣</p>
<ul>
<li>~ : 텍스트의 마지막을 표시하는 것 </li>
<li>&quot;:&quot;(콜론)을 찍어 여러 명령어를 입력한다.</li>
<li>i : insert. 이것만 알아도 다 할수 있다.</li>
</ul>
</li>
</ul>
<blockquote>
<h3 id="이제-진짜-git">이제 진짜 Git</h3>
</blockquote>
<ul>
<li><p>Blob : 파일 하나의 내용에 대한 정보</p>
</li>
<li><p>다음의 그림이 굉장히 중요한 그림이다.
<img src="https://velog.velcdn.com/images/nary_kim/post/ee53afe0-f4c5-447d-a28e-d11a30353d17/image.jpeg" alt=""></p>
</li>
<li><p>local과 remote는 실시간 상호작용하지 않는다. -&gt; 중간 작업이 꼭 필요.(push, pull)</p>
</li>
</ul>
<ul>
<li>breaking change : 해당 커밋 이후로 지원이 중단되는 경우등의 아주 중요한 변경사항.</li>
</ul>
<h4 id="💡-commit-message-convention">💡 Commit Message Convention</h4>
<ol>
<li>commit의 제목은 commit을 설명하는 문장형이 아닌 구나 절의 형태로 작성</li>
<li>importanceofcapitalize <code>Importance of Capitalize</code></li>
<li>prefix 꼭 달기</li>
</ol>
<ul>
<li>feat: 기능 개발 관련</li>
<li>fix: 오류 개선 혹은 버그 패치</li>
<li>docs: 문서화 작업</li>
<li>test: test 관련</li>
<li>conf: 환경설정 관련</li>
<li>build: 빌드 작업 관련</li>
<li>ci: Continuous Integration 관련</li>
<li>chore: 패키지 매니저, 스크립트 등</li>
<li>style: 코드 포매팅 관련</li>
</ul>
<h4 id="💡-gitignore">💡 .gitignore</h4>
<ul>
<li>gitignore.io (<a href="https://www.toptal.com/developers/gitignore/">https://www.toptal.com/developers/gitignore/</a>)</li>
<li>git이 무시하길 바라는 부분을 .gitignore에 넣어주면 알아서 무시해준다.</li>
<li>위의 주소로 들어가면 알아서 .gitignore에 들어갈 내용을 만들어준다.</li>
</ul>
<h4 id="💡-git은-습관이-가장-중요">💡 git은 습관이 가장 중요!</h4>
<p>• TIL(Today I Learned..) repository에 오늘 배운 것을 정리
• 매일 git으로 업로드를 해야하기 때문에 강제 커맨드 학습 가능
• github blog
• hexo 로 정적 블로그를 만들어 정리하는 습관을 만들고 Markdown과 친해지기
• Side Project
• 짧은 단위의 프로젝트를 자주 수행하여 생성-완성까지의 과정을 자주 반복</p>
<h4 id="💡-daily-project-for-me">💡 Daily project for me</h4>
<ul>
<li>아래의 예시를 참고하여 git을 자꾸 쓰도록 노력한다.
mkdir TIL
mkdir TIL/git
mkdir TIL/python
touch git/240419-git-first.md
touch python/240420-lambda-expressions.ipynb</li>
</ul>
<h4 id="💡-github-pages">💡 github pages</h4>
<ul>
<li><p>프로젝트 설명을 위한 웹사이트 호스팅 서비스
• username.github.io repo 생성 혹은 프로젝트 별 pages 생성
• <a href="https://www.upstage.ai/blog">https://www.upstage.ai/blog</a> (ghost)
• <a href="https://woowabros.github.io">https://woowabros.github.io</a>
• <a href="https://spoqa.github.io/">https://spoqa.github.io/</a></p>
</li>
<li><p>동적 페이지 구성이 불가 -&gt; 정적페이지 구성. 강사님은 hexo 추천.</p>
</li>
</ul>
<h4 id="💡-static-site-generator">💡 Static Site Generator</h4>
<ul>
<li><p>정적 페이지를 생성해주는 도구
• github pages는 파일 저장소이기 때문에 완성된 페이지만 제공 가능
• 모든 페이지가 독립적으로 존재해야함 -&gt; 컨텐츠 관리의 어려움 발생
• jekyll( <a href="https://jekyllrb-ko.github.io/">https://jekyllrb-ko.github.io/</a> ): Ruby 기반 정적 사이트 생성기
• 설치와 사용이 쉬움(많은 튜토리얼)
• 사용자가 많았음
• Hugo( <a href="https://gohugo.io/">https://gohugo.io/</a> ): Go 기반 정적 사이트 생성기
• 빠른 속도로 사이트 빌드 가능
• 사용자 증가 중
• Hexo( <a href="https://hexo.io/ko/index.html">https://hexo.io/ko/index.html</a> ): node.js 기반 정적 사이트 생성기
• 쉬운 사용성과 사용자 개인화</p>
</li>
<li><p>ghblog</p>
</li>
<li><p>poetry 찾아보기(패키지 관리자)</p>
</li>
</ul>
<ul>
<li><p><a href="https://hexo.io/docs/">https://hexo.io/docs/</a></p>
</li>
<li><p>새 포스트 작성은 다음과 같은 명령어로 하는 데,</p>
<pre><code>$ hexo new [layout] &lt;title&gt; </code></pre></li>
<li><p>title로 url을 만들기 때문에 웹상의 노출을 원한다면 영어로 하는 것이 유리. title은 포스트 작성을 위한 편집화면에서 한글로 바꿀 수 있다. 위와 같은 명령어로는 title을 사용한 url을 만들어 주기 위함인 듯.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[마인드셋 후기-박기수님, 김남혁님]]></title>
            <link>https://velog.io/@nary_kim/speciallecture12</link>
            <guid>https://velog.io/@nary_kim/speciallecture12</guid>
            <pubDate>Mon, 22 Apr 2024 14:54:52 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="박기수님-마인드-셋">박기수님 마인드 셋</h2>
</blockquote>
<p>경진대회시 과정을 블로그에 정리하는 것이 나중에 도움이 됨. 그렇지 않으면 남는 기억들이 휘발될 수 있음.</p>
<p>그룹스터디 활용에서는 기본 규칙을 잘 정해서 지키도록 하고, 사이드 프로젝트 진행을 하는 것이 좋음. 인원수 너무 많지 않게.</p>
<h4 id="💡-프로젝트-진행">💡 프로젝트 진행</h4>
<ol>
<li>파이썬 프로젝트
팀플.</li>
<li>EDA 프로젝트
팀플-대쉬보드
너무 어려운 주제 하지말자.
데이터가 없는 것은 피하자.</li>
<li>ML Learing 프로젝트
submission하는 것부터 연습해보자.
팀 분위기가 중요하다.</li>
</ol>
<h4 id="💡-경진대회">💡 경진대회</h4>
<p>멘토링도 같이 진행(실시간 &amp; 서면)
순위의 순서로 발표순서 고정. (잔인해!)</p>
<ol>
<li><p>ML 경진대회
데이터 전처리와 파생변수 생성이 핵심!</p>
</li>
<li><p>CV 경진대회
문서타입 분류 경진대회
OCR에 집착하지 않는 것이 큰 핵심.
우선 구현하고 시간이 남으면 OCR을 적용</p>
</li>
<li><p>NLP 경진대회
갑자기 높아지는 레벨
음성대화를 요약 텍스트화.
편협적인 사고를 버리자.
분석보델보다는 데이터 전처리가 관건.</p>
</li>
<li><p>AI 경진대회
한대회에만 집중하여야 함.</p>
</li>
</ol>
<blockquote>
<h2 id="김남혁-특강">김남혁 특강</h2>
</blockquote>
<p>모두가 동일한 커리큘럼을 배우기때문에 차별성을 갖기 어려운 것이 부트캠프의 단점.</p>
<p>ai 대회에 관해서는 4가지 분야중에 모든것을 다 잘할 필요는 없다. 선택과 집중이 더 중요.</p>
<h4 id="💡-공부-방법">💡 공부 방법.</h4>
<ul>
<li><p>키워드를 중심으로 전체적인 흐름을 이해하는 것이 중요.
그러나 키워드를 중심으로 기본기를 쌓는 것도 중요.</p>
</li>
<li><p>코테에 대한 꾸준한 준비가 필요하다.
참고 : 프로그래머스</p>
</li>
</ul>
<h4 id="💡-cs-면접-단골질문">💡 cs 면접 단골질문.</h4>
<ul>
<li>자료구조, 알고리즘, 운영체제, 네트워크, 데이터베이스</li>
<li>정보처리기사로 공부해도 괜찮다.</li>
<li>빅데이터분석기사 크게 추천하진 않지만 그중에는 나쁘지 않다.</li>
<li>백엔드.</li>
</ul>
<h4 id="💡-논문스터디">💡 논문스터디</h4>
<p>부트캠프의 한계를 극복하기 위해 나만의 차별화를 위한 사이드 프로젝트</p>
<ol>
<li>캐글, 데이콘등의 competition<ul>
<li>GitHub Repo를 만들어서 깔끔하게 관리.</li>
<li>자주성을 보여줄 수 있게 하자.</li>
</ul>
</li>
<li>Demo page<ul>
<li>특정 문제를 정의하고, 이를 위해 ai를 활용한 데모 페이지를 구현하는 것.</li>
<li>시각적 이펙트가 큼.</li>
<li>현업과 밀접한 연관이 있기 때문에, 포트폴리오를 더욱 풍성하게 만들어 줌.</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[Python Basic
- 파이썬 수업이면서 인생수업]]></title>
            <link>https://velog.io/@nary_kim/Python-Basic01</link>
            <guid>https://velog.io/@nary_kim/Python-Basic01</guid>
            <pubDate>Thu, 04 Apr 2024 03:08:01 GMT</pubDate>
            <description><![CDATA[<h2 id="하루만에-자료형-반복문-크롤링-다-배웠네">하루만에 자료형, 반복문, 크롤링 다 배웠네?</h2>
<p>8시간 수업하면서 저것들을 다 배웠다. 학부때 생각하면 반복문까지 한달은 배웠던 것 같은 데, 강사님께서 엑기스들만 뽑아서 꼭 알아야 할 부분 위주로 설명해 주셨다. 같이 강의 들으시는 분들이 모두 아나콘다나 미니콘다를 깔고 계신거 보면 이렇게 빨리 수업하는 것이 무리는 아닐 것이라 생각한다.</p>
<h2 id="python과-vsc-셋팅하는-데에-많은-시간을-소비했다">Python과 VSC 셋팅하는 데에 많은 시간을 소비했다!</h2>
<p>나의 올드맥북(late 2009)을 저번 부트캠프에서 사용하면서 여러가지 힘든 점들이 있었다. macos버전이 너무 낮다보니까 아무래도 요즘 마구마구 나오는 여러 프로그램이나 패치들을 까는 게 까다로웠다는 거! 항상 macos 버전에 맞는 패치를 찾아 다니는 하이에나가 되어야했다. 나도 생각 없이 다운로드에서 맨 위에 있는 파일 다운받아서 쓰고 싶었다! 그래서 큰맘 먹고 맥북에어를 이틀전에 구매하였다. </p>
<p> 전에는 수업에서 파이썬과 VSC를 설치 및 세팅 방법을 다루어서 이번에도 그럴줄 알았는 데 여기는 각자 알아서 설치하는 시스템. M2 모델이라서 구글링하며 설치했는 데 하나를 놓쳐서 삽질을 좀 했다.</p>
<blockquote>
</blockquote>
<ul>
<li>Homebrew를 깔고 나서 경로지정을 따로 해줘야한다. 첨에 지정 안해주고 바로 miniforge 깔았는 데 세상 계속 에러나서 너무 힘들었다. 지정해주자마자 바로 되는 거 있지. 하하하<pre><code>echo &#39;eval $(/opt/homebrew/bin/brew shellenv)&#39; &gt;&gt; /Users/본인 홈 이름/.zprofile
eval $(/opt/homebrew/bin/brew shellenv)</code></pre></li>
<li>M2 는 Miniforge를 깔아야한다. 홈페이지 가서 다운받자. sh 파일은 다음과 같이 설치하면 된다. homebrew에서 깔았더니 제대로 안깔아졌다. homebrew 설치시 경로지정을 제대로 안해줘서 그런것 같기도 하다.<pre><code>bash Miniforge3-MacOSX-arm64.sh</code></pre></li>
<li>iTerm2도 깔았는 데 필수는 아니다. 아직까지 더 좋다는 느낌은 없다.</li>
<li>VSC는 새컴터라 그런가 어려움 없이 설치가 가능했다. conda 가상환경 만들어서 세팅해주었다. 전에는 interpreter를 검색해야 했는데 이제는 바로 파이썬 패치를 깔고 나니 화면에 필요한 셋팅들이 나와서 알아서 셋팅하고 주피터 노트북도 안깔았는 데 &#39;이거 필요해!&#39; 하면서 깔더라. 더 편해졌다. 전 맥북은 interperter를 인식을 못하고 난리를 쳤었는 데 이제는 그런거 하나 없다.ㅎ</li>
</ul>
<h2 id="강사님의-인생수업">강사님의 인생수업.</h2>
<p>나도 프로그래밍을 좀 할수 있고 크롤링도 할수 있고 했는 데, 그걸 돈버는 용으로 사용할 생각은 전혀 하지 못했다. 인상 깊은 점을 정리하고 가끔 한번씩 보면서 해보는 시간을 가지면 좋을 것 같다.</p>
<blockquote>
</blockquote>
<ul>
<li>불편함 혹은 호기심이 생기면 바로 해결하려 실행에 옮기시나보다. 진짜 여러가지 분야에서 활동하시는 데 그것들의 공통점은 정보를 모아 정리하여 돈이 되는 포인트를 찾는 것이였다.</li>
<li>나는 보통 &#39;그냥 내가 해줄께&#39; 하고 지나쳤던 부분들을 모두 연봉으로 바꾸셨다고 한다! 자신의 가치를 높이실 줄 아는 모습이 대단히 인상깊었다.</li>
<li>도전을 두려워하지 않으시는 것 같았다. 크게 투자를 따낸 스타트업에 그냥 지원을 하신다는 게 흥미로웠다. 자존감이 높으니까 가능한 일이 아닌가 싶다. </li>
</ul>
<p>강사님은 회사생활 하시면서 이런저런 일들에 대한 인사이트를 얻곤 하지만, 나는 집에서 아이를 돌봐야 하는 입장에서 여러 사람들을 만나기는 쉽지 않다. 그래서 책을 여러분야로 읽어보면 좋을 것 같다. 문천식 아저씨가 무슨 책이든 많이 읽으라고 했다. 책을 읽으면서 세상이 변했다고 하시던데 나의 세상도 좀 능동적으로 변했으면 한다. </p>
<p> 나 같은 선택 장애자한테는 추천 도서목록이 있으면 좋을 것 같아 구글링 해보았다.</p>
<blockquote>
</blockquote>
<ul>
<li>마흔, 40대 도서 책 추천 고민될 때 읽어볼 10권! (Book N Life 님의 블로그)
<a href="https://blog.naver.com/sktkfpt10/221409813104">https://blog.naver.com/sktkfpt10/221409813104</a></li>
</ul>
<p>우선 이거 10권 읽는 게 목표. 리뷰도 쓸수 있을까...
혹시 이 글을 보시는 분들중에 추천하고 싶으신 책들 (총균쇠 빼고)은 추천 부탁!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Upstage AI LAB 시작한닷]]></title>
            <link>https://velog.io/@nary_kim/Upstage-AI-LAB-1</link>
            <guid>https://velog.io/@nary_kim/Upstage-AI-LAB-1</guid>
            <pubDate>Tue, 02 Apr 2024 06:58:42 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>다시 부트캠프를 시작하다.</p>
</blockquote>
<p>2024년도 벌써 3개월이나 지났다.</p>
<p>1월에 인스타 하다가 패스트캠퍼스에서 하는 국비지원교육들을 보게 되었는데 거기에 AI lab이 있더라. 
작년에 했던 제로베이스 프로젝트가 중도하차하게 되어 많이 아쉬웠었던 참이였는 데 잘 되었다 하고 신청하였다.</p>
<blockquote>
<p>내가 잘할 수 있을까?</p>
</blockquote>
<p>사실 나는 주부다. 두 아이가 있고 집은 시골이라 애들 맨날 학교든 학원이든 라이딩을 해줘야하는 데 주변에 도와줄 친인척 하나도 없는 상황이라서 10시부터 19시까지 하는 빡쎈 수업을 내가 해낼 수 있을까 걱정이 앞서긴한다. 어떻게 되겠지. 우선은 신청한다.</p>
<p>나에게는 좀 전환점이 필요했다. 이대로 아이들만 키우고 애들 학교가면 숏츠보면서 집안일을 하는 전형적인 주부가 되는 게 두렵다. 그래서 내 겨드랑이에 팔넣어서 캐리해 줄 무언가가 필요했다.</p>
<p>문제는 신청이 신청이 너무너무 빡쎘다. 나같은 소심이들에게 정말 크나큰 용기를 필요로 하는 비대면 녹화면접까지 있었다!! 진심 너무너무 안하고 싶어서 증말 끝까지 미루고 미루다가 마지막날에 몰아서 했다. </p>
<p>과연 잘한 일이였을까는 한 3개월 후에 다시 말해보도록 하겠다.</p>
<blockquote>
<p>너어어무 친절하다!!!</p>
</blockquote>
<p>어제 OT를 진행하였는 데 내가 느낀 점은 정말 다들 친절하시다는 거다. 다른 부트캠프는 시작할 때 열심히 안하면 드랍시킬꺼야!! 하면서 겁도 많이 주고 했는데 여기는 </p>
<p>&quot; 다 도와줄꺼야. 너만 잘하면 됨!&quot; </p>
<p>요런 느낌! 그리고 슬랙같은 것도 전 부트캠프에서 처음 써봤는 데 어렵고 생소했었다. 여기는 슬랙 쓰는 부분까지도 다 시간을 가지고 설명해주고 블로그 쓰는 것도 마찬가지로 해주다보니 정말 딱 친절하다는 생각이 많이 들었다.</p>
<p> 하튼 지금까지는 괜찮다. PM님 좀 무서워보였는 데 잘 웃으시고 친절하시다. 아 그리고 LM님이 진짜 순둥순둥하시다. </p>
<p>오늘은 입과시험을 치뤘는데 생각보다 너무 어려운거!
작년 8월인가까지 파이썬을 하고 그 이후에는 전혀 저어어어언혀 하지 않았더니 증말 하나도 모르겠드라. 짜내고 짜내고 해서 겨우겨우 시험봤다. 다 못했는 데 그냥 냈다. 다음주에 배우면서 좀 더 채워넣어야 할 것 같다.</p>
<blockquote>
<p>진짜 나만 잘하면 된다.
열심히 해보자 아자아자!</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[<8주_1일> 💡SQL subsquery]]></title>
            <link>https://velog.io/@nary_kim/SQL-subsquery</link>
            <guid>https://velog.io/@nary_kim/SQL-subsquery</guid>
            <pubDate>Tue, 27 Jun 2023 03:55:46 GMT</pubDate>
            <description><![CDATA[<h2 id="💡sql-subsquery">💡SQL subsquery</h2>
<h3 id="scalar-subquary">scalar subquary</h3>
<p>select절에서 사용.
결과는 하나의 column이어야함.</p>
<blockquote>
<h4 id="예제">예제</h4>
<p>oil_price테이블에서 셀프주유소의 평균가격과 SK에너지의 가장 비싼 가격을 조회하시오.</p>
</blockquote>
<pre><code class="language-sql">mysql&gt; select max(가격) SK주유소최대값, 
    -&gt;(select avg(가격) from oil_price where 셀프=&#39;Y&#39;) 셀프주유소평균값 
    -&gt;from oil_price where 상표 like &#39;%SK%&#39;;</code></pre>
<h3 id="inline-view">inline view</h3>
<p>from 절에 사용하는 subquary
mainquary 에서는 inline view에서 조회한 column만 사용가능.</p>
<blockquote>
<h4 id="예제-1">예제</h4>
<p>경찰서 별로 가장 많이 발생한 범죄 건수와 범죄 유형을  조회.</p>
</blockquote>
<pre><code class="language-sql">&gt;mysql&gt;select c.police_station, c.crime_type, c.case_number 
    -&gt;from crime_status c, 
    -&gt;(select police_station, crime_type, max(case_number) count 
    -&gt;from crime_status where status_typ&#39;발생&#39; group by police_station) m  
    -&gt;where c.police_station = m.police_station and c.case_number = m.count;</code></pre>
<h3 id="nested-subquery">nested subquery</h3>
<p>where 절에서 사용하는 서브쿼리.</p>
<ul>
<li>single row : 하나의 행을 검색하는 서브쿼리</li>
<li>multiple row : 하나 이상의 행을 검색하는 서브쿼리</li>
<li>mutiple column : 하나 이상의 열을 검색하는 서브쿼리</li>
</ul>
<h4 id="single-row-subquery">single row subquery</h4>
<p>서브쿼리가 비교연산자와 사용되는 경우, 서브쿼리의 검색 결과는 한 개 행의 결과값을 가져야 한다.</p>
<blockquote>
<h4 id="예제-2">예제</h4>
<p>snl에 출연한 셀럽중에 id가 1인 사람.</p>
</blockquote>
<pre><code class="language-sql">mysql&gt; select name from celeb where name = (select host from snl_show where id = 1);</code></pre>
<h4 id="multiple-row----in">multiple row  - IN</h4>
<ul>
<li>서브쿼리 출력결과와 하나라도 일치하면 참이 된다.</li>
</ul>
<blockquote>
<h4 id="예제-3">예제</h4>
<p>snl에 출연한 영화배우를 조회</p>
<pre><code class="language-sql">mysql&gt; select host
    -&gt; from snl_show
    -&gt; where  host in (select name from celeb where job_title like &#39;%영화배우%&#39;);</code></pre>
</blockquote>
<pre><code>
#### multiple row  - EXISTS

&gt; #### 예제
범죄 검거 혹은 발생 건수가 2000건보다 큰 경찰서 조회
```sql
mysql&gt; select name from police_station p where exists (select police_station from crime_status c where p.name = c.reference and case_number &gt; 2000);</code></pre><h4 id="multiple-row----any">multiple row  - ANY</h4>
<p>커브쿼리 결과 중에 하나라도 만족하면 됨</p>
<blockquote>
<h4 id="예제-4">예제</h4>
<p>snl 에 출연한 적이 있는 연예인 이름 조회</p>
</blockquote>
<pre><code class="language-sql">mysql&gt; select name from celeb where name = any (select host from snl_show);</code></pre>
<h4 id="multiple-row----all">multiple row  - ALL</h4>
<p>서브쿼리 결과를 모두 만족하면 (비교연산자 사용)</p>
<blockquote>
<h4 id="예시">예시</h4>
</blockquote>
<pre><code class="language-sql">mysql&gt; select name from celeb 
    -&gt; where name = all ( select host from snl_show where id = 1);</code></pre>
<h4 id="multi-column-subquery">multi column subquery</h4>
<p>서브쿼리 내에 메인쿼리 컬럼이 같이 사용되는 겅우</p>
<blockquote>
<h4 id="예제-5">예제</h4>
<p>강동원과 성별, 소속사가 같은 연예인의 이름, 성별, 소속사를 조회.</p>
</blockquote>
<pre><code class="language-sql">mysql&gt; select name, sex, agency from celeb 
    -&gt; where (sex, agency) in (select sex, agency from celeb where name=&#39;강동원&#39;);</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[<7주차_5일>SQL(5) Concat,  Alias,  Distinct, Limit]]></title>
            <link>https://velog.io/@nary_kim/sql-5-concat-alias-distict-limit</link>
            <guid>https://velog.io/@nary_kim/sql-5-concat-alias-distict-limit</guid>
            <pubDate>Tue, 20 Jun 2023 02:21:44 GMT</pubDate>
            <description><![CDATA[<ul>
<li>참고사항 : 데이터를 찾을 때, 양쪽 데이터에 중복되는 분류명이 없다면 그냥 분류명만을 써주면 되고 혹시 양쪽 데이터에 같은 분류명이 있다면 그땐 그 테이블명이나 그 테이블의 alias를 같이 명시해주어야 한다.<h3 id="concat">CONCAT</h3>
여러 문자열을 하나로 합치거나 연결<pre><code class="language-sql">select concat(&#39;이름:&#39;, name) from celeb;</code></pre>
</li>
</ul>
<h3 id="alias">ALIAS</h3>
<p>칼럼이나 테이블에 이름 별칭 생성</p>
<pre><code class="language-sql">select name as &#39;이름&#39; from celeb;
+-----------+
| 이름      |
+-----------+
| 아이유    |
| 이미주    |
| 송강      |
| 강동원    |
| 유재석    |
| 차승원    |
| 이수현    |
+-----------+

select name as &#39;이름&#39;,agency as &#39;소속사&#39; from celeb;
+-----------+--------------------------+
| 이름      | 소속사                   |
+-----------+--------------------------+
| 아이유    | EDAM엔터테이먼트         |
| 이미주    | 울림엔터테이먼트         |
| 송강      | 나무엑터스               |
| 강동원    | YG엔터테이먼트           |
| 유재석    | 안테나                   |
| 차승원    | YG엔터테이먼트           |
| 이수현    | YG엔터테이먼트           |
+-----------+--------------------------+</code></pre>
<h3 id="concat-과-alias">CONCAT 과 ALIAS</h3>
<ul>
<li>두 명령어를 동시에 사용하면 좀더 쉽게 데이터 찾기가 가능하다.
```sql<h1 id="1">1.</h1>
select concat(name,&#39;:&#39;,job_title) as profile from celeb;</li>
<li>----------------------------------+
| profile                          |</li>
<li>----------------------------------+
| 아이유:가수, 탤런트              |
| 이미주:가수                      |
| 송강:탤런트                      |
| 강동원:영화배우,탤런트           |
| 유재석:MC, 개그맨                |
| 차승원:영화배우, 모델            |
| 이수현:가수                      |</li>
<li>----------------------------------+
7 rows in set (0.00 sec)</li>
</ul>
<h1 id="2">2.</h1>
<p>select concat(season,&#39;-&#39;,episode,&#39;(&#39;,broadcast_date,&#39;)&#39;) 
as &#39;방송정보&#39;, 
concat(name,&#39;(&#39;,job_title,&#39;)&#39;) 
as &#39;출연자정보&#39; 
from celeb, snl_show 
where name=host;
+------------------+-----------------------------------+
| 방송정보         | 출연자정보                        |
+------------------+-----------------------------------+
| 8-7(2020-09-05)  | 강동원(영화배우,탤런트)           |
| 8-8(2020-09-12)  | 유재석(MC, 개그맨)                |
| 8-9(2020-09-19)  | 차승원(영화배우, 모델)            |
| 8-10(2020-09-26) | 이수현(가수)                      |
+------------------+-----------------------------------+</p>
<pre><code>
### DISTINCT
검색한 결과의 중복을 제거

```sql
select distinct agency from celeb;
+--------------------------+
| agency                   |
+--------------------------+
| EDAM엔터테이먼트         |
| 울림엔터테이먼트          |
| 나무엑터스               |
| YG엔터테이먼트           |
| 안테나                  |
+--------------------------+
5 rows in set (0.00 sec)
</code></pre><h3 id="limit">LIMIT</h3>
<p>검색결과를 정렬된 순으로 주어진 숫자만큼만 조회</p>
<pre><code class="language-sql">select * from celeb order by age limit 4;
+----+-----------+------------+------+------+-------------------+--------------------------+
| ID | NAME      | BIRTHDAY   | AGE  | SEX  | JOB_TITLE         | AGENCY                   |
+----+-----------+------------+------+------+-------------------+--------------------------+
|  7 | 이수현    | 1999-05-04 |   23 | F    | 가수              | YG엔터테이먼트           |
|  2 | 이미주    | 1994-09-23 |   28 | F    | 가수              | 울림엔터테이먼트         |
|  3 | 송강      | 1994-04-23 |   28 | M    | 탤런트            | 나무엑터스               |
|  1 | 아이유    | 1993-05-16 |   29 | F    | 가수, 탤런트      | EDAM엔터테이먼트         |
+----+-----------+------------+------+------+-------------------+--------------------------+
4 rows in set (0.00 sec)
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[<7주차_4일>SQL(4) UNION, JOIN]]></title>
            <link>https://velog.io/@nary_kim/SQL-4-UNION-JOIN</link>
            <guid>https://velog.io/@nary_kim/SQL-4-UNION-JOIN</guid>
            <pubDate>Tue, 20 Jun 2023 02:16:32 GMT</pubDate>
            <description><![CDATA[<h3 id="union">UNION </h3>
<ul>
<li>UNION : 중복된 값을 제거하여 알려준다.</li>
<li>UNION ALL : 중복된 값도 포함하여 모두 보여준다.</li>
</ul>
<pre><code>select * from test1
union
select * from test2</code></pre><h3 id="join">JOIN</h3>
<p>INNER JOIN
두 개의 테이블에서 공통되 ㄴ요소들을 통해 결합하는 조인방식(교집합)</p>
<pre><code class="language-sql">select celeb.id, celeb.name, snl_show.id, snl_show.host 
from celeb inner join snl_show 
on celeb.name = snl_show.host;
+----+-----------+----+-----------+
| id | name      | id | host      |
+----+-----------+----+-----------+
|  4 | 강동원    |  1 | 강동원    |
|  5 | 유재석    |  2 | 유재석    |
|  6 | 차승원    |  3 | 차승원    |
|  7 | 이수현    |  4 | 이수현    |
+----+-----------+----+-----------+</code></pre>
<p>LEFT JOIN
두 개의 테이블에서 공통영역을 포함해 왼쪽 테이블의 다른 데이터를 포함하는 조인 방식</p>
<ul>
<li>문제 : snl_show 에 호스트로 출연한 celeb을 기준으로 celeb테이블과 snl_show테이블을 left join 해주세요.</li>
</ul>
<pre><code class="language-sql">select celeb.id, celeb.name, snl_show.id, snl_show.host 
from celeb left join snl_show 
on celeb.name = snl_show.host;
+----+-----------+------+-----------+
| id | name      | id   | host      |
+----+-----------+------+-----------+
|  4 | 강동원    |    1 | 강동원    |
|  5 | 유재석    |    2 | 유재석    |
|  6 | 차승원    |    3 | 차승원    |
|  7 | 이수현    |    4 | 이수현    |
|  1 | 아이유    | NULL | NULL      |
|  2 | 이미주    | NULL | NULL      |
|  3 | 송강      | NULL | NULL      |
+----+-----------+------+-----------+</code></pre>
<p>RIFHT JOIN
두 개의 테이블에서 공통영역을 포함해 오른쪽 테이블의 다른 데이터를 포함하는 조인 방식</p>
<ul>
<li>문제 : snl_show 에 호스트로 출연한 celeb을 기준으로 celeb테이블과 snl_show테이블을 right join 해주세요.</li>
</ul>
<pre><code class="language-sql">select celeb.id, celeb.name, snl_show.id, snl_show.host 
from celeb right join snl_show 
on celeb.name = snl_show.host;
+------+-----------+----+-----------+
| id   | name      | id | host      |
+------+-----------+----+-----------+
|    4 | 강동원    |  1 | 강동원    |
|    5 | 유재석    |  2 | 유재석    |
|    6 | 차승원    |  3 | 차승원    |
|    7 | 이수현    |  4 | 이수현    |
| NULL | NULL      |  5 | 이병헌    |
| NULL | NULL      |  6 | 하지원    |
| NULL | NULL      |  7 | 제시      |
| NULL | NULL      |  8 | 조정석    |
| NULL | NULL      |  9 | 조여정    |
| NULL | NULL      | 10 | 옥주현    |
+------+-----------+----+-----------+</code></pre>
<p>FULL OUTER JOIN
두 개의 테이브에서 공통영역을 포함하여 양쪽 테이블의 다른 영역을 모두 포함하는 조인방식(합집합)</p>
<p>MySQL 에서는 FULL JOIN을 지원하고 있지 않기 때문에 LEFT JOIN과 RIGHT JOIN을 UNION하는 식으로 구현해야한다. </p>
<ul>
<li>문제 : snl_show 에 호스트로 출연한 celeb을 기준으로 celeb테이블과 snl_show테이블을 full outer join 해주세요.</li>
</ul>
<pre><code class="language-sql">select celeb.id, celeb.name, snl_show.id, snl_show.host 
from celeb left join snl_show 
on celeb.name = snl_show.host 
union 
select celeb.id, celeb.name, snl_show.id, snl_show.host 
from celeb right join snl_show 
on celeb.name = snl_show.host;
+------+-----------+------+-----------+
| id   | name      | id   | host      |
+------+-----------+------+-----------+
|    4 | 강동원    |    1 | 강동원    |
|    5 | 유재석    |    2 | 유재석    |
|    6 | 차승원    |    3 | 차승원    |
|    7 | 이수현    |    4 | 이수현    |
|    1 | 아이유    | NULL | NULL      |
|    2 | 이미주    | NULL | NULL      |
|    3 | 송강      | NULL | NULL      |
| NULL | NULL      |    5 | 이병헌    |
| NULL | NULL      |    6 | 하지원    |
| NULL | NULL      |    7 | 제시      |
| NULL | NULL      |    8 | 조정석    |
| NULL | NULL      |    9 | 조여정    |
| NULL | NULL      |   10 | 옥주현    |
+------+-----------+------+-----------+</code></pre>
<p>SELF JOIN</p>
<ul>
<li>컬럼명 앞에 테이블명을 명시</li>
<li>컬럼명만 명시해도 되나, 동일한 이름의 컬럼이 존재하면 그것에는 테리블명을 명시해야한다.</li>
</ul>
<ul>
<li>문제 : snl_show 에 호스트로 출연한 celeb을 기준으로 소속사가 안테나인 사람을 찾으세요.</li>
</ul>
<pre><code class="language-sql">select celeb.id, celeb.name, snl_show.id, snl_show.host 
from celeb, snl_show 
where celeb.name=snl_show.host and celeb.agency=&#39;안테나&#39;;
+----+-----------+----+-----------+
| id | name      | id | host      |
+----+-----------+----+-----------+
|  5 | 유재석    |  2 | 유재석    |
+----+-----------+----+-----------+</code></pre>
<p>self join에서 가장 중요한 것은 &quot;찾으려는 데이터의 조건이 무엇이냐&quot; 를 파악하는 것이다. 예제나 실습 모두 뭘 찾으라는 건지 잘못이해해서 헤맸다. 문해력이 중요한 시대이다. 책좀 읽어라!</p>
]]></description>
        </item>
    </channel>
</rss>