<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>s__youn9.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Mon, 25 May 2026 23:49:49 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>s__youn9.log</title>
            <url>https://velog.velcdn.com/images/s__youn9/profile/472f182d-9e1b-431c-9f28-2624982423b4/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. s__youn9.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/s__youn9" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[# WeeklyPaper 09]]></title>
            <link>https://velog.io/@s__youn9/WeeklyPaper-09</link>
            <guid>https://velog.io/@s__youn9/WeeklyPaper-09</guid>
            <pubDate>Mon, 25 May 2026 23:49:49 GMT</pubDate>
            <description><![CDATA[<h1 id="📚-지도-학습과-비지도-학습의-차이">📚 지도 학습과 비지도 학습의 차이</h1>
<h2 id="✔️-지도-학습">✔️ 지도 학습</h2>
<p>인공지능에게 문제와 정답을 함께 주고 학습시키는 방식
새로운 데이터가 들어왔을 때 학습한 규칙을 바탕으로 <strong>정확한 정답</strong>을 예측하는 것
예. 선형 회귀, 랜덤 포레스트...</p>
<h3 id="종류">종류</h3>
<ol>
<li><p>분류
데이터가 어떤 <strong>범주</strong>에 속하는지 맞히는 것</p>
</li>
<li><p>회귀
연속적인 수치 예측</p>
</li>
</ol>
<h2 id="✔️-비지도-학습">✔️ 비지도 학습</h2>
<p>정답은 주지 않고 데이터만 주며, 
데이터 자체의 구조나 특징을 인공지능이 알아서 파악하고 의미 있는 정보로 분류
예. K-평균 군집화, 주성분 분석...</p>
<h3 id="종류-1">종류</h3>
<ol>
<li><p>군집화
비슷한 특징을 가진 데이터끼리 그룹으로 묶음</p>
</li>
<li><p>차원 축소
데이터의 변수가 너무 많을 때,
중요한 정보만 남기고 데이터를 압축해서 시각화 및 분석을 쉽게 함</p>
</li>
</ol>
<hr>
<h1 id="📚-손실-함수loss-function란">📚 손실 함수(loss function)란?</h1>
<p>인공지능이 모델이 예측한 값과 실제 정답이 얼마나 차이가 나는지를 계산
정답을 맞혔다면 손실 함수 값은 0
정답에서 크게 벗어날수록 값이 커지게 된다
&#39;얼마나 틀리고 있는가&#39;를 명확한 숫자로 알려 주는 지표</p>
<h2 id="사용-목적">사용 목적</h2>
<p>인공지능이 학습할 방향을 제시하기 위함
모델이 처음 데이터를 분석할 경우 무지한 상태라, 예측이 들어맞지 않는 경우가 많기 때문에
손실 함수가 정확한 수치를 이용해 알려 주면
해당 오차를 줄이는 방향으로 내부의 수학적 가중치를 수정하게 된다</p>
<p>손실 함수의 결괏값이 최소화되는 지점을 향해 모델을 지속적으로 업데이터해 나가는 과정이라고 할 수 있으며, 이를 <strong>최적화</strong>라고 칭한다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[# Weekly Paper 08]]></title>
            <link>https://velog.io/@s__youn9/Weekly-Paper-8</link>
            <guid>https://velog.io/@s__youn9/Weekly-Paper-8</guid>
            <pubDate>Sun, 19 Apr 2026 13:13:49 GMT</pubDate>
            <description><![CDATA[<h1 id="📚-ab-테스트">📚 A/B 테스트</h1>
<p>두 가지 이상의 사안을 대조하여 어떤 것이 더 효과적인지 판단하는 실험 기법이다.
동일 기간에 놓여 있는 두 집단을 비교하는 것이며,
데이터를 기반으로 지표를 확인해 나가면서 실험 결과에 따라 배포하지 않을 수 있다.</p>
<hr>
<h2 id="💡-장점">💡 장점</h2>
<ul>
<li>객관적인 의사결정이 가능하다. 실제 사용자 데이터를 바탕으로 결론을 내릴 수 있기 때문이다.</li>
<li>전체 사용자에게 변경 사항 적용 전, 소수인 표본에 먼저 테스트해 리스크를 방지한다.</li>
<li>특정 변경(A =&gt; B) 결과에 미친 인과관계를 비교적 명확히 확인이 가능하다.</li>
</ul>
<h2 id="💡-단점">💡 단점</h2>
<ul>
<li>유의미한 표본을 모으는 데에 시간이 오래 걸릴 수 있다.</li>
<li>단지 새롭기 때문에 클릭율이 오르는 상황을 착각할 수 있다.</li>
<li>샘플 편향으로 특정 집단에만 유리한 실험이 될 수 있다.</li>
</ul>
<blockquote>
<h3 id="📈-해결-방안">📈 해결 방안</h3>
</blockquote>
<h4 id="✔️-mabmulti-armed-bandit">✔️ MAB(Multi-Armed Bandit)</h4>
<p>탐색과 활용 사이의 균형점을 찾는 것이다. 이를 통해 성과가 좋은 안으로 트래픽을 실시간으로 몰아 기회비용을 줄인다.</p>
<ul>
<li>탐색: 각 버전의 <strong>실제 성과를 알아보기 위해 충분히 시도</strong>하는 것</li>
<li>활용: 지금까지 <strong>가장 좋은 성과를 보인 버전</strong>을 더 많이 사용
=&gt; 이 사이의 균형점을 찾는 것이 중요한 것이다.<br/>
#### ✔️ 경험 증가
비교적 많은 사용자가 경험해 본 이후의 데이터가 수집될 수 있도록 실험 기간을 1-2주 이상 유지해 데이터가 안정화되었을 때 수집된 데이터를 활용하도록 한다.
<br/>
#### ✔️ 무작위 할당 점검
실험-대조군을 나눌 때 무작위 할당이 제대로 되었는지, 너무 특정 범주 안에서 무작위로 표본을 추출한 것은 아닌지 점검해 볼 필요성이 있다.

</li>
</ul>
<hr>
<h2 id="💡-통계적-유의미">💡 통계적 유의미</h2>
<p>p-value, 즉 통계적으로 유의미함을 나타내는 지표가 전체 실험 중 가능한 오차 범위인 5%(0.05)보다 높을 경우 통계적 유의미가 상실되었다고 한다. </p>
<p>이것은 A와 B 사이의 차이가 없다는 <strong>귀무가설에 더 힘이 실린 것</strong>이므로 추가적인 실험 및 또 다른 가설의 수립이 필요하다. </p>
<p>혹은 검정력이 부족하여 실제로는 차이가 있으나 샘플 사이즈가 너무 작아 차이를 감지하지 못하였을 가능성도 배제해서는 안 된다.</p>
<hr>
<h3 id="✔️-다음-단계">✔️ 다음 단계</h3>
<h4 id="1️⃣-세그먼트-분석">1️⃣ 세그먼트 분석</h4>
<p>전체적인 데이터가 아닌 특정 집단의 데이터를 수집하여 재실험해 볼 수 있다. 특정 집단 내에서라도 효과가 있을 가능성을 배제하지 않는 것이다</p>
<h4 id="2️⃣-가설-재설정">2️⃣ 가설 재설정</h4>
<p>전체적인 가설을 재설정한다. 사용자를 이용한 실험이므로 변경 사항이 사용자의 눈에 크게 띄지 않아 변동성이 적을 만큼 미미한 결과를 보였는지 검토한 후 과감한 변화를 시도해 본다.</p>
<h4 id="3️⃣-정성적-조사-진행">3️⃣ 정성적 조사 진행</h4>
<p>정량적인 조사를 진행하여 나온 결과이므로 사용자의 의견을 직접 들어 보는 정성적인 조사를 한 번 시도해 볼 수 있다.</p>
<hr>
<h1 id="📚-이벤트-데이터-로그-설계event-taxonomy의-주요-구성-요소">📚 이벤트 데이터 로그 설계(Event Taxonomy)의 주요 구성 요소</h1>
<p>서비스 내 유저의 행동을 체계적으로 분류한 데이터 지도라고 할 수 있다.</p>
<ul>
<li><strong>Event Name</strong> 사용자가 수행한 행동 그 자체를 정의한다.</li>
<li>** Event Properties** 행동이 발생한 상황 그 자체의 정보를 담는다.</li>
<li>** User Properties** 행동을 한 유저의 특성을 의미한다. 이는 시간이 지나도 유지되는 속성이다.</li>
<li>** Common/Global Properties** 모든 이벤트에 공통으로 붙는 시스템 정보다.</li>
</ul>
<blockquote>
<p>시스템 설계 시, <strong>네이밍 규칙</strong>을 정해 이름을 혼동하지 않게끔 하고,
서비스가 커져도 구조가 깨지지 않도록 <strong>유연한 설계를 진행</strong>하며,
어떤 <strong>문제의 해결을 위해 해당 데이터가 필요한 것인지를 먼저 정의</strong>해 보아야 한다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[# WeeklyPaper 07]]></title>
            <link>https://velog.io/@s__youn9/Weekly-Paper-07</link>
            <guid>https://velog.io/@s__youn9/Weekly-Paper-07</guid>
            <pubDate>Sat, 11 Apr 2026 16:02:52 GMT</pubDate>
            <description><![CDATA[<h1 id="📚-aarrr-프레임워크와-리텐션--funnel">📚 AARRR 프레임워크와 리텐션 + Funnel</h1>
<h2 id="1️⃣-사용자-획득-acquisition">1️⃣ 사용자 획득 Acquisition</h2>
<p>사용자를 유입시키는 과정</p>
<p>잠재고객이 프로덕트 신규 사용자로 유입되는 획득 단계</p>
<p>프로덕트 고객이 될 수 있는 사용자를 많이, 효율적으로 획득</p>
<h3 id="규모-지표">규모 지표</h3>
<ul>
<li>신규 사용자 수: 웹사이트 및 서비스에 첫 방문한 사람</li>
<li>회원가입 수: 얼마나 많은 신규 회원을 획득했는지</li>
<li>앱 다운로드 수: 특정 기간 공안 어플리케이션이 획득한 사용자 규모</li>
<li>리드(잠재고객 수): 많을수록 실제 고객 확보 가능성이 높아짐</li>
</ul>
<h3 id="효율-지표">효율 지표</h3>
<ul>
<li>CAC 고객 획득 비용: 신규 고객 한 명을 유지하기 위해 필요한 비용, 낮은 투자 비용으로 많은 고객을 확보할 수 있는 매체를 사용함</li>
</ul>
<p>⇒ (투입 금액) / (획득 고객 수) </p>
<p>⇒ 고객 품질에 따라 크게 영향 받을 수 있기 떄문에 CAC가 저렴하다고 해서 무조건 좋은 것만은 X, 중간 CAC로 고품질의 고객을 얻는 것이 더 좋을 수 있음</p>
<h3 id="광고-지표">광고 지표</h3>
<p>광고 진행 후 결과를 확인할 때 사용, 높을수록 광고 성과가 좋은 것</p>
<h4 id="광고-성과-지표">광고 성과 지표</h4>
<ul>
<li><strong>광고 클릭률(CTR)</strong>: 광고에 노출되었을 때 광고를 클릭한 비율</li>
</ul>
<p>⇒ (광고 클릭 수) / (광고 노출 수) * 100</p>
<ul>
<li><strong>광고 조회율(VTR)</strong>: 동영상 등의 광고, 광고 끝까지 혹은 기준 이상으로 시청하는 비율</li>
</ul>
<p>⇒ (광고 영상 조회 수) / (영상 광고 노출 수) * 100</p>
<ul>
<li><strong>광고 전환율(CVR)</strong>: 광고를 클릭해 유입된 사용자 중 주요 전환 활동(결제, 구독 등)을 한 사용자의 비율</li>
</ul>
<p>⇒ (전환 수) / (광고 클릭 수) * 100</p>
<h4 id="광고-비용-지표cost-per--">광고 비용 지표(Cost-Per- )</h4>
<ul>
<li>CPM: 광고 1,000번 노출당 비용(저렴할수록 노출 측면 효율이 좋음)</li>
<li>CPC: 광고 클릭당 비용</li>
<li>CPV: 영상 광고 조회당 비용</li>
<li>CPA: 특정 액션(회원가입, 상품 구매 등) 당 비용</li>
<li>CPI: 앱 설치당 비용</li>
</ul>
<p>⇒ 매체별, 광고 종류별 비용적인 효율 비교가 가능함</p>
<hr>
<table>
<thead>
<tr>
<th>광고 매체</th>
<th>지출 광고비</th>
<th>CPC</th>
<th>획득 고객 수</th>
<th>CAC</th>
</tr>
</thead>
<tbody><tr>
<td>틱톡</td>
<td>1,000만</td>
<td>60</td>
<td>10,000</td>
<td>1,000</td>
</tr>
<tr>
<td>인스타그램</td>
<td>1,000만</td>
<td>200</td>
<td>20,000</td>
<td>500</td>
</tr>
<tr>
<td>유튜브</td>
<td>1,000만</td>
<td>650</td>
<td>1,000</td>
<td>10,000</td>
</tr>
</tbody></table>
<p>⇒ CPC는 틱톡이 저렴하나, 고객 획득 측면에선느 인스타그램이 비용 효율적일 수 있음</p>
<hr>
<h2 id="2️⃣-사용자-활성화-activation">2️⃣ 사용자 활성화 Activation</h2>
<p>유입된 사용자 활동</p>
<p>사용자가 프로덕트의 핵심 자치를 경험하며 활성화되는 단계</p>
<h3 id="사용-경험-지표">사용 경험 지표</h3>
<ul>
<li>체류 시간(Duration time): 웹사이트, 웹서비스에 머문 시간 ⇒ 길수록 긍정적</li>
</ul>
<p>⇒ (사용자가 방문해 머무른 시간 총합) / (특정 기간 방문한 사용자 수)</p>
<ul>
<li>평균 페이지 체류 시간: 특정 페이지의 매력도, 유용성 판단 가능</li>
</ul>
<p>⇒ (특정 페이지에서 보낸 총 체류 시간) / (해당 페이지 방문자 수)</p>
<ul>
<li>평균 세션 시간: 사용자가 페이지와 상호작용하며 체류한 시간</li>
</ul>
<p>⇒ (세선 종료 - 세션 시작) / 2 </p>
<ul>
<li>페이지 뷰(PV): 일정 기간 동안 사용자가 웹 사이트가 앱을 방문하며 열람한 페이지 개수</li>
</ul>
<p>⇒ 순 방문자 수(UV): 중복된 사용자 배제한 순 방문자 수, 실질적인 방문자 수)</p>
<p>⇒ UV 당 평균 PV가 높을수록 방문한 사용자가 이탈하지 않고 페이지를 많이 방문하는 것</p>
<ul>
<li>페이지 이탈률: 첫 페이지만 조회한 후 추가적인 행동 없이 이탈한 것</li>
</ul>
<p>⇒ (반송 수) / (방문 수) * 100</p>
<h3 id="활성화-지표">활성화 지표</h3>
<p>⇒ 사용자가 Aha-moment 경험, 확실한 전환 행동을 했을 경우 충성 고객으로 전환 가능성 높음</p>
<ul>
<li>Aha-moment: 프로덕트의 핵심 가치를 처음 경험한 고객</li>
<li>Funnel Conversion: 세부적인 퍼널 안에서 단계별 전환율 확인하는 것</li>
</ul>
<p>⇒ 단계별 전환율을 높이고 이탈 사용자를 줄여 최대한 많은 사용자를 남기는 것이 중요함</p>
<p>⇒ 고객 관계 CRM 채널 관리, UX/UI 개선, 프로덕트 이용 경로 단순화 등</p>
<hr>
<h2 id="3️⃣-사용자-유지-retention">3️⃣ 사용자 유지 Retention</h2>
<p>이탈하지 않고 계속해서 프로덕트를 사용하게끔 만듦</p>
<p>사용자 유지가 잘 이루어지고 있는지 파악</p>
<ul>
<li>유지율(Retention Rate): 사용자가 유지되는 비율, 처음 사용한 이후 일정 시점이 지난 이후에도 사용하고 있는 사용자의 비율</li>
<li>이탈률(Churn Rate): 이탈 사용자 ⇒ (전체) - (유지율)</li>
</ul>
<h3 id="유지율-파악-기준">유지율 파악 기준</h3>
<ul>
<li>유지 기준 행동 설정(비즈니스 모델에 영향)</li>
<li>유지율 측정할 단위 기간 선택(프로덕트 사용 주기 고려)</li>
<li>유지율 계산 방식 설정</li>
</ul>
<h3 id="유지율-계산-방식">유지율 계산 방식</h3>
<ul>
<li>클래식 리텐션(Classic Retention): 행동 첫날을 기준으로 N일 후 다시 행동하는 사용자의 비율 계산(N-day)</li>
</ul>
<p>⇒ (N일 후 행동 사용자) / (첫날 행동 사용자)</p>
<ul>
<li>범위 리텐션(Range Retention): 기간 기준 유지율, 기간 범위 내에서 한 번이라도 활동한 경우 해당 기간 동안 유지되었다고 함
행동이 최초 발생한 Range0 기준으로 N번째 RangeN 범위에 다시 행동하는 사용자를 구하면 됨</li>
</ul>
<p>⇒ (N 기간 동안 한 번이라도 행동한 사용자) / (첫날 행동 사용자)</p>
<ul>
<li>롤링 리텐션(Rolling Retention): 마지막 행동을 한 날을 기준으로 그 이전의 모든 날을 행동한 것으로 간주하고 계산, 사용자가 이탈하지 않고 남아 있는지에 초점</li>
</ul>
<p>⇒ 유지율 과대 추정, 시점에 따른 유지율 변화 가능성</p>
<h3 id="고착도-지표">고착도 지표</h3>
<p>사용자들이 지속적으로 서비스에 참여하여 상호작용하는 비율</p>
<p>자주 방문할수록 고착도 100%에 가까워짐</p>
<p>서비스 특성에 따라 매우 다른 수치로 나타나는 것이 일반적임</p>
<h4 id="활성-사용자-수">활성 사용자 수</h4>
<p>특정 서비스와 상호작용하며 활성화된 사용자 수</p>
<p>기간 내 중복 제거</p>
<p>많을수록 더 많은 사람이 프로덕트를 이용하고 있는 것</p>
<p>기간 조건을 더하면 기간별 활성 사용자 지표</p>
<aside>

<ul>
<li>HAU: 시간당 활성 사용자 수</li>
<li>DAU: 일간 활성 사용자 수</li>
<li>WAU: 주간 활성 사용자 수</li>
<li>MAU: 월간 활성 사용자 수</aside>

</li>
</ul>
<p>⇒ (DAU / MAU) * 100 / (DAU / WAU) * 100</p>
<hr>
<h2 id="4️⃣-수익화-revenue">4️⃣ 수익화 Revenue</h2>
<p>수익화와 관련된 전반적인 영역을 검토하는 단계</p>
<p>사용자의 활동이 매출로 이어지는지 확인</p>
<h3 id="수익성-지표">수익성 지표</h3>
<ul>
<li>매출(Revenue): 비즈니스가 고객에게 상품 혹은 서비스를 판매해 창출하는 총 금액, 비스니스 운영과 관련한 비용 공제하기 전의 금액</li>
<li>순이익(Net Profit): 비즈니스가 사용한 모든 비용을 차감하고 남은 금액</li>
<li>월간 반복 매출(MRR): 비즈니스가 매월 반복적으로 발생시키는 매출</li>
</ul>
<p>⇒ (기존 고객의 월간 매출) - (이탈 고객의 월간 기여 매출) + (신규/부활 고객 월간 매출) + (플랜 업/다운그레이드로 인한 월간 매출 차액)</p>
<p>⇒ (이전 달 유지된 고객의 반복 매출) + (이번 달 새 고객이 발생시킨 반복 매출)</p>
<p>⇒ 이벤트성 매출(1회성 매출)은 포함하지 않음</p>
<ul>
<li>연간 반복 매출(ARR): 연간 반복적으로 발생시키는 매출</li>
<li>ROI: 투자 대비 수익률, 투자 비용(비즈니스에 사용한 모든 비용)에 비해 얼마나 많은 순이익을 얻었는지</li>
</ul>
<p>⇒ (순이익 / 전체 투자 비용) * 100</p>
<ul>
<li>ROAS: 광고 투자 대비 수익률, 투자한 광고비에 대비한 매출</li>
</ul>
<p>⇒ (광고 매출 / 투입 광고 비용) * 100</p>
<p>⇒ 광고 매체별로 계산해 관리 (특정 관고 매체 매출 / 총 광고 비용) * 100</p>
<h3 id="고객-가치-지표">고객 가치 지표</h3>
<h4 id="객단가-지표">객단가 지표</h4>
<p>한 명의 사용자가 평균적으로 발생시키는 매출, 1인당 평균 구매 금액</p>
<ul>
<li>ARPU: 무료 사용자와 유료 결제 사용자를 포함한 전체 사용자 1명당 평균 매출 (전체 매출 / 전체 사용자 수)</li>
<li>ARPPU: 유료 사용자 한 명당 평균 매출 (전체 매출 / 유료 결제 사용자 수)</li>
<li>ARPDAU: 일간 활성 사용자 한 명이 평균적으로 발생시키는 하루 동안의 매출(일 매출 / 일일 활성 사용자 수)</li>
</ul>
<h4 id="고객-생애-매출ltr">고객 생애 매출(LTR)</h4>
<p>한 명의 고객이 제품 및 서비스를 이용하는 전체 생애 동안 비즈니스에서 발생할 것으로 예상되는 기대 매출</p>
<p>(생애 누적해 발생한 총 매출 합 / 고객 수)</p>
<h4 id="고객-생애-가치ltv">고객 생애 가치(LTV)</h4>
<p>한 명의 고객이 제품 및 서비스 이용하는 전체 <strong>생애 동안 가져다줄 것으로 예상되는 기대 가치</strong>(기대 순이익) 비즈니스가 얻는 매출, 비용을 모두 고려(고객 획득 비용 + 투자 비용 함께 고려)</p>
<p>평균 구매 금액 * 마진율 * 구매 빈도 * 고객 수명 - (고객 획득 비용 + 객 유지 비용)</p>
<p>마진율 ⇒ (매출액 - 매출원가 / 매출) * 100 : 순수한 수익 비율</p>
<p>CAC 가 LTV 보다 작을 때 수익이 유의미</p>
<p>마케팅 예산을 적절히 분배해 사용하기 위한 지표</p>
<hr>
<table>
<thead>
<tr>
<th>평균 구매 금액</th>
<th>100,000</th>
</tr>
</thead>
<tbody><tr>
<td>마진율</td>
<td>50%</td>
</tr>
<tr>
<td>구미 빈도(횟수)</td>
<td>(1년) 6회</td>
</tr>
<tr>
<td>고객 수명</td>
<td>3년</td>
</tr>
<tr>
<td>평균 고객 획득 비용</td>
<td>30,000</td>
</tr>
<tr>
<td>평균 고객 유지 비용</td>
<td>(1년) 10,000</td>
</tr>
<tr>
<td>(3년) 30,000</td>
<td></td>
</tr>
</tbody></table>
<p>(100,000 * 50%) * (6 * 3) - (30,000 + 30,000)= 840,000 </p>
<hr>
<h2 id="5️⃣-새-사용자-추천-referral">5️⃣ 새 사용자 추천 Referral</h2>
<p>기존 사용자의 추천을 통해 새 사용자가 유입되는지 확인</p>
<p>선순환구조를 만드는 것이 목적</p>
<h3 id="바이럴-지표">바이럴 지표</h3>
<ul>
<li>바이럴 주기 시간: 친구 초대하고 친구가 신규 사용자로 유입되기까지의 시간</li>
<li>바이럴 계수: 기존 사용자 한 명당 만들어내는 신규 사용자 수, 총 1 이상이 될 때 유의미(확산의 패턴이 확연히 달라지기 때문)</li>
</ul>
<p>⇒ 주기 시간을 단축, 바이럴 계수를 증가시켜야 신규 사용자 확보 유리</p>
<p>⇒ (기존 사용자 1명당 평균 친구 초대 수 * 친구의 초대 수락 비율)</p>
<h3 id="추천-가능성-지표">추천 가능성 지표</h3>
<ul>
<li>순 추천 지수 NPS: 기존 사용자가 특정 제품 및 서비스, 브랜드를 추천할 가능성으로 <strong>고객 충성도를 측정하는 표준 척도</strong></li>
</ul>
<p>⇒ (추천 그룹 비율) - (비추천 그룹의 비율) : 설문조사를 이용해 판단</p>
<ul>
<li>너무 순서에 얽매일 필요 X, 지금 당장 필요한 단계에 집중해 관련 자료 개선할 필요 있음</li>
<li>지표 계산식은 고정된 것이 아님. 상황에 따라 유동적으로 변경 가능</li>
</ul>
<hr>
<h1 id="📚-코호트와-세그먼트">📚 코호트와 세그먼트</h1>
<h3 id="⭐️-코호트cohort">⭐️ 코호트(Cohort)</h3>
<p>특정 시기 공통적인 특성이나 행동 양식을 공유하는 사용자 그룹</p>
<p>Retention Plateau : 사용자가 이탈하지 않고 유지되면서 지속적으로 프로덕트를 사용하고 있는 구간 &gt;&gt; 어느 정도의 프로덕트 성공</p>
<h3 id="⭐️-세그먼트segment">⭐️ 세그먼트(Segment)</h3>
<p>몇 가지 기준을 정해 자사의 서비스를 이용하는 고객들로부터 각 기준에 따라 나타나는 특징에 따라 분류하고 군집하는 작업</p>
<blockquote>
<p>** 코호트<strong>는 **특정 기간</strong>에,
** 세그먼트<strong>는 **시간의 흐름</strong>에 따라 분류하는 차이 존재.</p>
</blockquote>
<hr>
<h1 id="📚-rfm-분석">📚 RFM 분석</h1>
<p>고객의 가치를 데이터에 기반해 평가하고,
이를 통해 고객을 여러 그룹으로 나누어 전략을 세울 때 사용.</p>
<h2 id="요소">요소</h2>
<h3 id="최근성-recency">최근성 Recency</h3>
<p>고객이 가장 최근에 서비스를 이용하거나 구매한 시점이 언제인지.
최근에 방문한 고객이 다시 방문할 가능성이 높기 때문.</p>
<h3 id="빈도-frequency">빈도 Frequency</h3>
<p>고객이 정해진 기간 동안 얼마나 자주 이용했는지.
고객의 숙련도나 로열티. 자주 올수록 서비스의 찐팬일 확률이 높아진다.</p>
<h3 id="수익성-monetary">수익성 Monetary</h3>
<p>고객이 지출한 금액.
비즈니스의 직접적인 매출 기여도를 보여 준다.</p>
<h2 id="고객-세분화segmentation">고객 세분화(Segmentation)</h2>
<table>
<thead>
<tr>
<th>고객 그룹</th>
<th>특징</th>
<th>마케팅 전략</th>
</tr>
</thead>
<tbody><tr>
<td>VIP</td>
<td>R, F, M 점수 모두 높음</td>
<td>전담 관리, 프리미엄 혜택</td>
</tr>
<tr>
<td>유망주</td>
<td>R은 높으나 F, M 은 낮음</td>
<td>환영 메세지, 재방문 유도 쿠폰 발부</td>
</tr>
<tr>
<td>충성 고객</td>
<td>F, M은 높으나 R 이 떨어짐</td>
<td>새상품 추천, 로열티 프로그램</td>
</tr>
<tr>
<td>이탈 위기</td>
<td>F, M은 높으나 R 이 <strong>매우</strong> 낮음</td>
<td>강력한 할인 혜택</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[#WeeklyPaper 06]]></title>
            <link>https://velog.io/@s__youn9/WeeklyPaper-6</link>
            <guid>https://velog.io/@s__youn9/WeeklyPaper-6</guid>
            <pubDate>Sat, 04 Apr 2026 18:43:03 GMT</pubDate>
            <description><![CDATA[<h1 id="📚-beautifulsoup과-selenium">📚 BeautifulSoup과 Selenium</h1>
<h2 id="📍-beautifulsoup">📍 BeautifulSoup</h2>
<p><span style= 'background-color: #FCC6BB'> <strong>정적 웹브라우저</strong>를 파싱 </span> 해 특정 요소를 탐색 및 수정 가능한 도구이다.</p>
<blockquote>
<h4 id="💡-정적-웹페이지-크롤링-순서">💡 정적 웹페이지 크롤링 순서</h4>
</blockquote>
<ol>
<li>원하는 웹 페이지의 HTML 문서를 긁어 오고</li>
<li>긁어 온 HTML 문서를 파싱,</li>
<li>파싱한 HTML 문서에 원하는 태그를 가져와 사용한다.<br/>
</li>
</ol>
<hr>
<p><span style='color:#A9A9A9'> <strong>파싱(Parsing)</strong> - 데이터나 문서를 AI 및 컴퓨터가 이해 가능하도록 문법적 구조를 분석해 정규화하고 필요한 정보만 구조화해 추출하는 과정. 
<strong>비정형 데이터</strong>인 HTML, PDF, LOG 등을 JSON, CSV 등의 <strong>구조화된 포맷으로 변환</strong>해 활용성을 높이는 역할을 한다.  </span></p>
<pre><code class="language-python">soup = BeautifulSoup(data,&#39;html.parser&#39;) # html 문서를 parsing</code></pre>
<br/>

<h3 id="1️⃣-라이브러리-import">1️⃣ 라이브러리 import</h3>
<pre><code class="language-python">import requests                    # HTML 문서를 불러올 때 사용하는 모듈
from bs4 import BeautifulSoup    # 긴 HTML 문서를 정리되고 다루기 쉬운 형태로 만들어 주는 모듈</code></pre>
<br/>

<h3 id="2️⃣-문서-불러오기-및-파싱">2️⃣ 문서 불러오기 및 파싱</h3>
<pre><code class="language-python">url = &#39;https://example.com&#39;
response = requests.get(url) # url의 HTML 문서를 불러오고
html = response.text         # HTML 문서를 text 형식으로 변환,

soup = BeautifulSoup(html, &#39;html.parser&#39;) # 컴퓨터가 알아보기 쉬운 형태로 parsing</code></pre>
<p><br/><br/><br/></p>
<hr>
<h2 id="📍-selenium">📍 Selenium</h2>
<p><span style= 'background-color: #FCC6BB'><strong>동적 웹 브라우저</strong>의 동작을 자동화</span> 하는 오픈 소스 프레임워크다.
chromedriver을 제어하거나 원하는 정보를 얻기 위해 사용된다.</p>
<h3 id="1️⃣-라이브러리-import-1">1️⃣ 라이브러리 import</h3>
<pre><code class="language-python">from selenium import webdriver                     # selenium의 webdriver을 사용하기 위한 모듈
from selenium.webdriver.common.keys import Keys # key 조작을 위한 모듈
import time                                     # 페이지 로딩을 기다리는 모듈
</code></pre>
<h3 id="2️⃣-chrome-driver-실행">2️⃣ chrome driver 실행</h3>
<pre><code class="language-python">driver = webdriver.Chrome()            # Chrome 실행
driver.get(&#39;https://example.com&#39;)    # get 안의 url 불러오기
time.sleep(3)                        # 페이지 완전히 로딩되도록 기다리는 시간
</code></pre>
<blockquote>
<p>💡 <code>time.sleep()</code>의 경우, 동적 웹페이지에서 HTML 코드가 새로고침되거나 특정 버튼을 클릭할 때 잠시 코드가 꺼지거나 변경되는 경우가 있는데, 그동안은 <strong>HTML 코드 인식 불가로 인한 오류 발생 가능성</strong>이 있으므로 이를 방지하기 위해 <strong>웹이 로딩되기까지의 시간</strong>을 주는 것이다. 그래야 원하는 HTML 코드를 이용한 파싱 및 자동화가 가능하다.</p>
</blockquote>
<p><br/><br/></p>
<hr>
<h1 id="📚--robotstxt-파일이란">📚  robots.txt 파일이란</h1>
<p>검색 엔진 크롤러 bot에게 웹사이트의 어떤 부분을 수집 허용하고, 어떤 부분을 제한할지 <strong>안내</strong>하는 국제 표준 텍스트 파일이다. 주로 사이트의 <strong>크롤러 트래픽을 관리하고 중요하지 않은 페이지 또는 비슷한 페이지의 크롤링을 방지하는 역할</strong>을 한다. IETF에서 2022년 9월 표준화 문서를 발행했다.</p>
<p>해당 파일은 항상 사이트의 루트 디렉토리 ( <a href="https://example.com/robots.txt">https://example.com/robots.txt</a> ), 로봇 배제 표준을 따르는 일반 텍스트 파일로 작성되어야 한다.</p>
<p>수집 조건에 대한 협약 존재 시, 광고주 정보 취득, 링크 미리보기 등의 수익성 크롤링은 robots.txt 내 규칙을 참조하지 않았거나 완벽히 준수되지 않았을 수 있다. </p>
<p>웹 페이지 크롤링 시 해당 문서를 참조하여 크롤링이 가능한 웹 페이지인지 사전에 확인이 필요하다. 그렇지 않으면 법적인 문제가 야기될 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/s__youn9/post/7cf79ce9-4e21-47ef-973b-072e4b812749/image.png" alt=""></p>
<p>위는 구글에서 사용하는 robotst.txt다.
정확한 형식 및 표준 사용 방법은 <a href="https://www.rfc-editor.org/rfc/rfc9309">공식 문서</a> 및 <a href="https://searchadvisor.naver.com/guide/seo-basic-robots">네이버 문서</a> 를 참고하길 바란다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 업그레이드 할 수 없는 아이템 구하기]]></title>
            <link>https://velog.io/@s__youn9/SQL-%EC%97%85%EA%B7%B8%EB%A0%88%EC%9D%B4%EB%93%9C-%ED%95%A0-%EC%88%98-%EC%97%86%EB%8A%94-%EC%95%84%EC%9D%B4%ED%85%9C-%EA%B5%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@s__youn9/SQL-%EC%97%85%EA%B7%B8%EB%A0%88%EC%9D%B4%EB%93%9C-%ED%95%A0-%EC%88%98-%EC%97%86%EB%8A%94-%EC%95%84%EC%9D%B4%ED%85%9C-%EA%B5%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 31 Mar 2026 00:24:09 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="📍-문제">📍 문제</h3>
<p>어느 한 게임에서 사용되는 아이템들은 업그레이드가 가능합니다.<br/>
ITEM_A -&gt; ITEM_B 업그레이드 가능할 때,
ITEM_A를 ITEM_B의 <code>PARENT</code> 아이템,
PARENT 아이템이 없는 아이템을 <code>ROOT</code> 아이템이라고 합니다.
예를 들어 ITEM_A -&gt; ITEM_B -&gt; ITEM_C 와 같이 업그레이드가 가능한 아이템이 있다면<br/>
ITEM_C의 <code>PARENT</code> 아이템은 ITEM_B
ITEM_B의 <code>PARENT</code> 아이템은 ITEM_A
<code>ROOT</code> 아이템은 ITEM_A가 됩니다.<br/>
다음은 해당 게임에서 사용되는 아이템 정보를 담은 <code>ITEM_INFO</code> 테이블과 아이템 관계를 나타낸 <code>ITEM_TREE</code> 테이블입니다.<br/>
<ITEM_INFO>
<strong>ITEM_ID</strong> - 아이템 ID
<strong>ITEM_NAME</strong> - 아이템 명
<strong>RARITY</strong> - 아이템의 희귀도
<strong>PRICE</strong> - 아이템의 가격<br/>
<ITEM_TREE>
<strong>ITEM_ID</strong> - 아이템 ID
<strong>PARENT_ITEM_ID</strong> - PARENT 아이템의 ID 
<br/>단, 각 아이템들은 오직 하나의 PARENT 아이템 ID 를 가지며, ROOT 아이템의 PARENT 아이템 ID 는 NULL 입니다. ROOT 아이템이 없는 경우는 존재하지 않습니다.
<br/>
더 이상 <strong>업그레이드할 수 없는 아이템</strong>의 아이템 ID(ITEM_ID), 아이템 명(ITEM_NAME), 아이템의 희귀도(RARITY)를 출력하는 SQL 문을 작성해 주세요. 이때 결과는 <strong>아이템 ID를 기준</strong>으로 내림차순 정렬해 주세요.</p>
</blockquote>
<hr>
<p>시작 ITEM = <code>PARENT_ID</code>가 존재하지 않는다.
최종 ITEM = <code>PARENT_ID</code>가 된 적이 없다.</p>
<p>고로 <code>PARENT_ID</code>에 속한 적 없는 <code>ITEM_ID</code>를 구하면 된다.</p>
<pre><code class="language-sql">SELECT
    ITEM_ID,
    ITEM_NAME,
    RARITY
FROM ITEM_INFO
WHERE ITEM_ID NOT IN (
    SELECT PARENT_ITEM_ID
    FROM ITEM_TREE
    WHERE PARENT_ITEM_ID IS NOT NULL
)
ORDER BY ITEM_ID DESC;</code></pre>
<p><code>WHERE</code>을  내부에 서브 쿼리를 작성,
NULL이 아닌 <code>PARENT_ID</code> (NULL이 되면 비교할 대상이 없어질뿐더러 <code>PARENT_ID</code>가 NULL 이면 시작 쿼리를 구하는 것과 다름없음)에 <strong>속한 적 없는</strong> <code>ITEM_ID</code>를 구한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[#WeeklyPaper 05]]></title>
            <link>https://velog.io/@s__youn9/WeeklyPaper-05</link>
            <guid>https://velog.io/@s__youn9/WeeklyPaper-05</guid>
            <pubDate>Mon, 30 Mar 2026 00:39:32 GMT</pubDate>
            <description><![CDATA[<h1 id="📚-정규화">📚 정규화</h1>
<p>결정자에 의해 함수적 종속을 가진 일반 속성을 <strong>의존자로 입력, 수정, 삭제하여 이상 현상을 제거</strong>하는 것이다.</p>
<p>쉽게 말해, 데이터를 <strong>잘게 나누어서 쓸데없이 중복되어 생기는 오류를 없애</strong>는 작업.</p>
<hr>
<h2 id="📍-형태">📍 형태</h2>
<h3 id="⭐️-제-1-정규형-1nf">⭐️ 제 1 정규형 (1NF)</h3>
<p>하나의 칼럼에는 하나의 원자값만 포함되어야 한다는 것.
테이블의 중복 데이터를 분리해 유사한 속성이 반복되지 않도록 테이블을 분리하는 작업이다.
<img src="https://velog.velcdn.com/images/s__youn9/post/11694047-8e3a-44b7-b3be-e13e5ded8c54/image.png" alt=""></p>
<hr>
<h3 id="⭐️-제-2-정규형-2nf">⭐️ 제 2 정규형 (2NF)</h3>
<p>제 1 정규형을 만족하고, 기본키가 <strong>복합키</strong>일 때 테이블을 기본키(복합키) 하나씩을 기준으로 분리하여
기본키 전체에 모든 속성이 의존되도록 한다.
하지 않을 경우 데이터 조회, 수정, 추가 등에 어려움을 겪을 수 있다.
복잡하게 관련 없는 기본키까지 기억하여 쿼리를 작성해야 하기 때문이다.<img src="https://velog.velcdn.com/images/s__youn9/post/1a2f20b2-2324-4705-8b25-f888d4ada37e/image.png" alt=""></p>
<hr>
<h3 id="⭐️-제-3-정규형-3nf">⭐️ 제 3 정규형 (3NF)</h3>
<p>속성이 모든 주식별자에만 종속되고, 비주요속성 간 의존하지 않게끔 분리하는 역할을 한다.
만약 의존하고 있는 비주요속성이 존재할 경우,
해당 속성을 주요 식별자로 취급한 후 종속되는 속성을 모두 한 테이블에 묶는다.
<img src="https://velog.velcdn.com/images/s__youn9/post/ca098a0b-71d9-4394-856e-6a4449b4ae57/image.png" alt=""></p>
<hr>
<h3 id="💡-장점">💡 장점</h3>
<ul>
<li>데이터의 중복과 수정, 삽입, 삭제 이상을 막아 준다.</li>
<li>정규화로 인한 간결해진 구조 덕분에 <strong>유지보수</strong>가 편하다.</li>
</ul>
<h3 id="💡-단점">💡 단점</h3>
<ul>
<li>중복을 없애는 과정이기 때문에 <strong>테이블 분리로 인한 개수가 많아질</strong> 수있다.</li>
<li>또한 테이블을 분리할수록 <strong>JOIN을 이용해 쿼리를 작성해야 할 경우가 잦아져 성능 저하</strong>가 우려된다.
=&gt; 이를 대비하기 위해, 
무조건적인 정규화가 아닌 테이블을 합치거나 원 상태로 두는 <strong>반정규화</strong>를 선택하기도 한다.</li>
</ul>
<hr>
<h1 id="📚-논리적-모델링">📚 논리적 모델링</h1>
<p>데이터를 어떻게 구조화할지 개념적으로 설계하는 단계다.
해당 과정에서 정규화를 진행한다.</p>
<hr>
<h2 id="📍-엔터티-entity">📍 엔터티 Entity</h2>
<p>업무에 필요한 정보를 저장 및 관리하기 위한 실체/객체이다.
집합에 속하는 개체 특정을 설명하는 속성을 필수적으로 소유한다.
다른 데이터에 의존하지 않고 독립적으로 존재해야 한다.</p>
<p>식별자에 의해 식별이 가능해야 한다.
또한 타 엔터티와 한 개 이상의 관계를 가지고 있어야 한다.</p>
<hr>
<h2 id="📍-속성-attribute">📍 속성 Attribute</h2>
<p>업무에 필요로하는 최소한의 데이터 단위이며, 더는 분리할 수 없다.
엔터티를 설명하며 인스턴스의 구성요소라고 할 수 있다.</p>
<p>주식별자에 함수적인 종속성을 가져야 한다.
즉 PK를 알고 있다면 자연스럽게 종속된 속성을 알 수 있어야 한다.
<strong>꼭 한 개의 값만을 가져야(제 1 정규형을 만족해야)</strong> 한다.</p>
<blockquote>
<h4 id="💡-분류">💡 분류</h4>
<p>** PK ** : 엔터티를 식별할 수 있다.
** FK ** : 타 엔터티와의 관계를 나타낸다.
** 일반 ** : PK/FK에 포함되지 않는 엔터티의 일반 속성이다.</p>
</blockquote>
<hr>
<h2 id="📍-관계-relationship">📍 관계 Relationship</h2>
<p>엔터티 간 상호연관성이 있는 상태이다.
엔터티의 인스턴스 간 연관성을 가지는 존재이며, 
서로에게 연관성이 부여된 것을 말한다.</p>
<h3 id="카디널리티관계차수">카디널리티(관계차수)</h3>
<p>두 엔터티 간 관계에서 몇 개까지 종속될 수 있는지를 나타낸다.</p>
<p>ex) 1 : 1 / 1 : N / M : N ...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[전화번호에 하이픈 추가하기]]></title>
            <link>https://velog.io/@s__youn9/%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8%EC%97%90-%ED%95%98%EC%9D%B4%ED%94%88-%EC%B6%94%EA%B0%80%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@s__youn9/%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8%EC%97%90-%ED%95%98%EC%9D%B4%ED%94%88-%EC%B6%94%EA%B0%80%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 27 Mar 2026 07:51:13 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-sql">CONCAT(
    SUBSTRING(TEL, 1, 3), &#39;-&#39;,
    SUBSTRING(TEL, 4, 4), &#39;-&#39;,
    SUBSTRING(TEL, 8, 4)
)
-- 010-1234-1234 형태로 출력됨!</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 자동차 대여 기록에서 대여중 / 대여 가능 여부 구분하기]]></title>
            <link>https://velog.io/@s__youn9/SQL</link>
            <guid>https://velog.io/@s__youn9/SQL</guid>
            <pubDate>Fri, 27 Mar 2026 05:55:37 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="📍-문제">📍 문제</h3>
<p>다음은 어느 자동차 대여 회사의 자동차 대여 기록 정보를 담은 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블입니다. <br/>
<strong>HISTORY_ID</strong> - 자동차 대여 기록 ID
<strong>CAR_ID</strong> - 자동차 ID
<strong>START_DATE</strong> - 대여 시작일
<strong>END_DATE</strong> - 대여 종료일 
<br/>
CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 
<strong>2022년 10월 16일에 대여 중인 자동차인 경우 &#39;대여중&#39;</strong> 이라고 표시하고, <strong>대여 중이지 않은 자동차인 경우 &#39;대여 가능&#39;</strong>을 표시하는 컬럼(컬럼명: AVAILABILITY)을 추가하여 자동차 ID와 AVAILABILITY 리스트를 출력하는 SQL문을 작성해주세요. 
이때 <strong>반납 날짜가 2022년 10월 16일인 경우에도 &#39;대여중&#39;으로 표시</strong>해주시고 결과는 <strong>자동차 ID를 기준으로 내림차순</strong> 정렬해주세요.</p>
</blockquote>
<p>분명 CASE문 작성하는 것까지는 알고 있었는데 내가 생각한 대로 작성하니 틀렸다기에...</p>
<pre><code class="language-sql">SELECT
    CAR_ID,
    (CASE 
        WHEN END_DATE &lt; &#39;2022-10-16&#39; THEN &#39;대여 가능&#39;
        ELSE &#39;대여중&#39;
    END) AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
ORDER BY CAR_ID DESC;</code></pre>
<p>뭐 대충 이렇게 작성했었다.
이렇게 되면 답은 도출되는데, </p>
<p><strong>🚨 첫 번째 문제점 = GROUP BY</strong>
하나의 CAR_ID에 대여 기록이 여러 개라 어떤 기록을 기준점으로 보아야 하는지 모르게 된다.</p>
<p><strong>🚨 두 번째 문제점 = <code>START_DATE</code> 지정하지 않음</strong>
그러게 되면 <code>END_DATE</code>가 2022-10-16보다 큰 값이라 &#39;대여중&#39;이라고 구분되었는데, 만약 해당 데이터의 <code>START_DATE</code>가 2022-11-10 처럼 2022-10-16이 포함되지 않은 날짜라 &#39;대여 가능&#39;으로 표기되어야 한다면? 표기 오류가 드러난다.</p>
<p>그래서 SubQuery를 이용해 2022-10-16가 <code>START_DATE</code>와 <code>END_DATE</code> 사이에 존재하는 <code>CAR_ID</code>를 먼저 선택하고,
해당 날짜에 이미 빌리고 있는 사람이 있다는 거니까 <strong>&#39;대여중&#39;</strong>을 표기한다.</p>
<p>만약 해당 날짜 사이 존재하지 않는다면 이미 대여를 끝내고 대여되길 기다리고 있는 거니까 <strong>&#39;대여 가능&#39;</strong>으로 표기해 주어야 한다.</p>
<pre><code class="language-sql">SELECT
    CAR_ID,
    (CASE 
        WHEN CAR_ID IN (
            SELECT CAR_ID
            FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
            WHERE &#39;2022-10-16&#39; BETWEEN START_DATE AND END_DATE) THEN &#39;대여중&#39;
        ELSE &#39;대여 가능&#39;
    END) AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
ORDER BY CAR_ID DESC;</code></pre>
<p>서브쿼리 니 딱대. 내가 너때문에 이골이 난 지 벌써 삼십년째다...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 업그레이드 된 아이템 구하기]]></title>
            <link>https://velog.io/@s__youn9/SQL-%EC%97%85%EA%B7%B8%EB%A0%88%EC%9D%B4%EB%93%9C-%EB%90%9C-%EC%95%84%EC%9D%B4%ED%85%9C-%EA%B5%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@s__youn9/SQL-%EC%97%85%EA%B7%B8%EB%A0%88%EC%9D%B4%EB%93%9C-%EB%90%9C-%EC%95%84%EC%9D%B4%ED%85%9C-%EA%B5%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 25 Mar 2026 01:33:13 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="📍-문제">📍 문제</h3>
<p>어느 한 게임에서 사용되는 아이템들은 업그레이드가 가능합니다.<br/>
ITEM_A ➡️ ITEM_B와 같이 업그레이드가 가능할 때
ITEM_A를 ITEM_B 의 <code>PARENT</code>,
<code>PARENT</code> 아이템이 없는 아이템을 <code>ROOT</code>라고 합니다.<br/>
예를 들어 ITEM_A ➡️ ITEM_B ➡️ ITEM_C 와 같이 업그레이드가 가능한 아이템이 있다면<br/>
<strong>ITEM_C</strong>의 <code>PARENT</code> 아이템은 <strong>ITEM_B</strong>
<strong>ITEM_B</strong>의 <code>PARENT</code> 아이템은 <strong>ITEM_A</strong>
<code>ROOT</code> 아이템은 <strong>ITEM_A</strong>가 됩니다.<br/>
다음은 해당 게임에서 사용되는 아이템 정보를 담은 <code>ITEM_INFO</code> 테이블과 아이템 관계를 나타낸 <code>ITEM_TREE</code> 테이블입니다. <br/>
<ITEM_INFO> 
<strong>ITEM_ID</strong> - 아이템 ID
<strong>ITEM_NAME</strong> - 아이템 명
<strong>RARITY</strong> - 아이템의 희귀도
<strong>PRICE</strong> - 아이템의 가격<br/>
<ITEM_TREE> 
<strong>ITEM_ID</strong> - 아이템 ID
<strong>PARENT_ITEM_ID</strong> - PARENT 아이템의 ID<br/>
각 아이템들은 오직 하나의 <code>PARENT_ITEM_ID</code>를 가지며, 
<code>ROOT</code> 아이템의 <code>PARENT_ITEM_ID</code>는 <code>NULL</code> 입니다.
ROOT 아이템이 없는 경우는 존재하지 않습니다.<br/>
아이템의 <strong>희귀도가 &#39;RARE&#39;</strong>인 아이템들의 <strong>모든 다음 업그레이드 아이템</strong>의 
<strong>아이템 ID(ITEM_ID), 아이템 명(ITEM_NAME), 아이템의 희귀도(RARITY)</strong>를 출력하는 SQL 문을 작성해 주세요. 
이때 결과는 <strong>아이템 ID를 기준으로 내림차순</strong> 정렬해 주세요.</p>
</blockquote>
<p>처음에는 subquery 사용하지 않고
일단 <code>ROOT</code>는 아니어야 된다는 거니까 IS NOT NULL 사용했다.</p>
<pre><code class="language-sql">SELECT
    INFO.ITEM_ID,
    INFO.ITEM_NAME,
    INFO.RARITY
FROM ITEM_INFO INFO
JOIN ITEM_TREE TREE
    ON INFO.ITEM_ID = TREE.ITEM_ID
WHERE INFO.RARITY = &#39;RARE&#39;
    AND TREE.PARENT_ITEM_ID IS NOT NULL</code></pre>
<p>이렇게 풀었는데
결과를 보니 아니라는 것이다!
OMG</p>
<p>생각해 보니 <strong>다음 업그레이드 아이템</strong>이 되려면, <code>ITEM_ID</code>가 타 아이템의 <code>PARENT_ITEM_ID</code>와 같아야 한다.
예를 들면, A아이템의<code>PARENT_ITEM_ID</code> 값이 B아이템의 <code>ITEM_ID</code>와 같다면 B아이템이 A아이템의 PARENT가 되는 것이니까, 
A아이템의 다음 업그레이드 아이템은 B아이템이 되는 것이다. </p>
<p>이를 구하려면 subquery를 사용해서,
<code>RARITY</code>가 RARE인 <code>ITEM_ID</code>를 이용해
<code>PARENT_ITEM_ID</code>를 찾아야 한다.
그래야 <code>RARITY</code>가 RARE인 아이템의 업그레이드 아이템 ID를 알 수 있으니까</p>
<pre><code class="language-sql">SELECT
    INFO.ITEM_ID,
    INFO.ITEM_NAME,
    INFO.RARITY
FROM ITEM_INFO INFO
JOIN ITEM_TREE TREE
    ON INFO.ITEM_ID = TREE.ITEM_ID
WHERE TREE.PARENT_ITEM_ID IN (
    SELECT ITEM_ID
    FROM ITEM_INFO
    WHERE RARITY = &#39;RARE&#39;
)
ORDER BY INFO.ITEM_ID DESC;</code></pre>
<p>너무 문제를 헷갈리게 내 놓았네...
 ㄴ 님의 문해력이 문제라는 생각은?</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 가격이 제일 비싼 식품의 정보 출력하기]]></title>
            <link>https://velog.io/@s__youn9/SQL-%EA%B0%80%EA%B2%A9%EC%9D%B4-%EC%A0%9C%EC%9D%BC-%EB%B9%84%EC%8B%BC-%EC%8B%9D%ED%92%88%EC%9D%98-%EC%A0%95%EB%B3%B4-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@s__youn9/SQL-%EA%B0%80%EA%B2%A9%EC%9D%B4-%EC%A0%9C%EC%9D%BC-%EB%B9%84%EC%8B%BC-%EC%8B%9D%ED%92%88%EC%9D%98-%EC%A0%95%EB%B3%B4-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0</guid>
            <pubDate>Mon, 23 Mar 2026 00:46:22 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="📍-문제">📍 문제</h3>
<p>다음은 식품의 정보를 담은 FOOD_PRODUCT 테이블입니다. <br/>
<strong>PRODUCT_ID</strong> - 식품 ID
<strong>PRODUCT_NAME</strong> - 식품 이름
<strong>PRODUCT_CD</strong> - 식품 코드
<strong>CATEGORY</strong> - 식품분류
<strong>PRICE</strong> - 식품 가격 <br/>
FOOD_PRODUCT 테이블에서 <strong>가격이 제일 비싼 식품의 식품 ID, 식품 이름, 식품 코드, 식품분류, 식품 가격을 조회하는 SQL문을 작성</strong>해주세요.</p>
</blockquote>
<hr>
<p>처음에</p>
<pre><code class="language-sql">SELECT 
    PRODUCT_ID,
    PRODUCT_NAME,
    PRODUCT_CD,
    CATEGORY,
    MAX(PRICE) AS PRICE
FROM FOOD_PRODUCT</code></pre>
<p>이따구로 풀고
아~ ㅋ 쉽네? 해놓고
채점해 보니까 틀렸다는 청천벽력같은 말이 팝업창에 뜨길래 찾아보니까,</p>
<p>그냥 생으로 <code>SELECT</code>문에 <code>PRICE</code>에만 <code>MAX</code>를 사용하면, <strong><code>PRICE</code>만 최댓값으로 나오고 나머지 행들은 모두 그냥 첫 번째 행에 있는 값으로만 출력</strong>되게 된다고 한다. 그래서 최댓값을 구하려면 <strong>서브 쿼리를 이용해, 전체적으로 최댓값인 행을 구하라고 적용</strong>해 주어야 내가 원하는 최댓값을 출력하는 쿼리를 작성한 게 된다.</p>
<hr>
<pre><code class="language-sql">SELECT
    PRODUCT_ID,
    PRODUCT_NAME,
    PRODUCT_CD,
    CATEGORY,
    PRICE
FROM FOOD_PRODUCT
WHERE PRICE = (SELECT MAX(PRICE) FROM FOOD_PRODUCT)</code></pre>
<p>서브 쿼리 작성하는 게 아직 미숙한데 많이 활용해 보아야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[# WeeklyPaper 04]]></title>
            <link>https://velog.io/@s__youn9/07-SQL-%EC%8B%A4%ED%96%89-%EC%88%9C%EC%84%9C</link>
            <guid>https://velog.io/@s__youn9/07-SQL-%EC%8B%A4%ED%96%89-%EC%88%9C%EC%84%9C</guid>
            <pubDate>Sat, 21 Mar 2026 17:24:10 GMT</pubDate>
            <description><![CDATA[<h1 id="📚-sql-실행-순서">📚 SQL 실행 순서</h1>
<blockquote>
<h4 id="group-by와-having의-차이">GROUP BY와 HAVING의 차이</h4>
</blockquote>
<blockquote>
<p>SQL 쿼리를 작성할 때, 작성되는 구문 순서와 달리 DB 엔진이 해당 구문을 처리하는 순서에는 차이가 있다.</p>
</blockquote>
<hr>
<h2 id="📍-구문">📍 구문</h2>
<h3 id="종류-작성-순서에-따라">종류 (작성 순서에 따라)</h3>
<h4 id="select">SELECT</h4>
<p>DB에 저장된 데이터들을 조회하는 데 사용된다.</p>
<h4 id="from">FROM</h4>
<p>어떤 테이블에서 어떤 테이터를 가져올지 지정하는 데 사용된다.</p>
<h4 id="where">WHERE</h4>
<p>불러올 데이터에 조건을 추가해 필터링한다.</p>
<h4 id="group-by">GROUP BY</h4>
<p>특정 기준이 되는 칼럼을 기준으로 그룹화하는 역할이다.</p>
<h4 id="having">HAVING</h4>
<p>그룹화된 결과들 중 
HAVING에 작성된 조건에 맞는 데이터만 출력한다.</p>
<h4 id="order-by">ORDER BY</h4>
<p>작성되는 칼럼명을 기준으로 데이터를 정렬한다.
<code>ASC</code>는 오름차순, <code>DESC</code>는 내림차순으로 정렬된다.</p>
<hr>
<h2 id="📍-구문-실행-순서">📍 구문 실행 순서</h2>
<ol>
<li><strong>FROM</strong>으로 
어떤 테이블에서 데이터를 가져오면 좋을지 지정한다.</li>
<li><strong>WHERE</strong>로 
전체 데이터 중 개별 행을 조건에 맞춰 필터링한다.
어떤 테이블인지 지정해야만(FROM) 필터링이 가능하다.</li>
<li><strong>GROUP BY</strong>로 
필터링된 데이터를 특정 열을 기준으로 묶어 준다.
한 번 걸러낸 이후 그룹화를 하는 것이 복잡한 계산을 한 번 줄여 주는 중요한 역할을 한다.</li>
<li><strong>HAVING</strong>으로 
그룹화된 데이터 중 
조건에 맞는 데이터만 남기도록 한 번 더 필터링한다.</li>
<li><strong>SELECT</strong>로 
최종적으로 보여 줄 칼럼을 꼽는다. 
모든 필터링이 끝난 이후 사용자에게 테이블에 얹어 보여 줄 칼럼을 꼽아 준다.</li>
<li><strong>ORDER BY</strong>를 
이용해 마지막으로 데이터를 정렬한다.
모든 데이터를 출력할 준비가 끝난 후 정렬해야 정확한 정렬 결과가 나온다.</li>
</ol>
<p>여기에서, WHERE과 HAVING은 모두 <strong>조건을 지정하는 열</strong>이나, 
<span style='color:#B02121'> <strong>GROUP BY</strong> </span> 여부에 따라 사용될 수 있는 쿼리가 달라진다.
WHERE은 GROUP BY가 없어도 사용될 수 있지만 HAVING은 GROUP BY가 없다면 사용될 수 없다.</p>
<hr>
<blockquote>
<h3 id="✔️-group-by-having-where">✔️ GROUP BY, HAVING, WHERE</h3>
</blockquote>
<h4 id="💡-group-by">💡 GROUP BY</h4>
<p>데이터를 그룹으로 묶는다.
행의 개수가 그룹에 포함된 만큼 줄어들며, 집계 함수 사용을 위한 기준을 제공하는 역할을 한다.</p>
<h4 id="💡-having">💡 HAVING</h4>
<p>그룹화 이후 실행된다.
조건에 부합되지 않는 그룹 자체가 사라진다.
그룹화 이후 실행되므로 집계 함수를 자유로이 사용할 수 있으며, 그를 조건으로 사용한다.<br/>
➡️ GROUP BY는 단독 사용이 가능하나 HAVING은 GROUP BY가 있어야만 존재할 수 있다.</p>
<h4 id="💡-where">💡 WHERE</h4>
<p>그룹화 이전에 실행된다. 
GROUP BY가 없어도 사용될 수 있는 기본 쿼리다.
아직 그룹화를 하기 이전이므로 집계 함수를 사용할 수 없다.</p>
<hr>
<h1 id="📚-sql의-null">📚 SQL의 NULL</h1>
<h2 id="📍-null">📍 NULL</h2>
<p>말 그대로 존재하지 않는 값이다.
0, &#39;&#39; 와 같은 것이 아닌, <span style='color:#B02121'> NULL 값 그 자체</span>를 일컫는다.
NULL은 문자열도, 정수도 어떤 데이터 타입에도 포함되지 않으므로 어떠한 연산을 실행하더라도 NULL 값을 뱉어낸다.</p>
<hr>
<h2 id="📍-null-처리-함수">📍 NULL 처리 함수</h2>
<h3 id="✔️-null-확인">✔️ NULL 확인</h3>
<h4 id="is-null">IS NULL</h4>
<p>해당 칼럼의 값이 비어 있는(NULL) 행만 골라냄</p>
<h4 id="is-not-null">IS NOT NULL</h4>
<p>값이 채워져 있는 행만 골라냄</p>
<h3 id="✔️-null-대체">✔️ NULL 대체</h3>
<h4 id="if-null칼럼-명-대체값">IF NULL(칼럼 명, 대체값)</h4>
<p>해당하는 칼럼 값이 NULL일 때 다른 값으로 대체해 출력할 수 있게 해 준다.</p>
<pre><code class="language-sql">WHERE IFNULL(phone, &#39;연락처 없음&#39;) 
-- 핸드폰 번호가 없으면 &#39;연락처 없음&#39;을 출력한다.</code></pre>
<h4 id="coalesce값1-값2-">COALESCE(값1, 값2, ...)</h4>
<p>IF NULL의 확장. 
인자들을 순서대로 훑다 처음으로 NULL이 아닌 값을 만나면 해당 값을 반환</p>
<pre><code class="language-sql">WHERE COALESCE(mobile, home, office, &#39;연락처 없음&#39;)
-- mobile이 없으면 home,
-- home이 없으면 office,
-- office가 없으면 &#39;연락처 없음&#39;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 특정 형질을 가지는 대장균 찾기]]></title>
            <link>https://velog.io/@s__youn9/mySQL-%ED%8A%B9%EC%A0%95-%ED%98%95%EC%A7%88%EC%9D%84-%EA%B0%80%EC%A7%80%EB%8A%94-%EB%8C%80%EC%9E%A5%EA%B7%A0-%EC%B0%BE%EA%B8%B0</link>
            <guid>https://velog.io/@s__youn9/mySQL-%ED%8A%B9%EC%A0%95-%ED%98%95%EC%A7%88%EC%9D%84-%EA%B0%80%EC%A7%80%EB%8A%94-%EB%8C%80%EC%9E%A5%EA%B7%A0-%EC%B0%BE%EA%B8%B0</guid>
            <pubDate>Fri, 20 Mar 2026 04:48:29 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="📍-문제">📍 문제</h3>
<p>대장균들은 일정 주기로 분화하며, 분화를 시작한 개체를 부모 개체, 분화가 되어 나온 개체를 자식 개체라고 합니다.<br/><br/>
다음은 실험실에서 배양한 대장균들의 정보를 담은 <strong>ECOLI_DATA</strong> 테이블입니다.<br/><br/>
<strong>ID</strong> - 대장균 개체의 ID
<strong>PARENT_ID</strong> - 부모 개체의 ID
<strong>SIZE_OF_COLONY</strong> - 개체의 크기
<strong>DIFFERENTIATION_DATE</strong> - 분화되어 나온 날짜
<strong>GENOTYPE</strong> - 개체의 형질 <br/><br/>
<u> <strong>2번 형질을 보유하지 않으면서 1번이나 3번 형질을 보유하고 있는</strong> 대장균 개체의 수(COUNT)를 출력하는 SQL 문을 작성</u>해주세요. 1번과 3번 형질을 모두 보유하고 있는 경우도 1번이나 3번 형질을 보유하고 있는 경우에 포함합니다.</p>
</blockquote>
<pre><code class="language-sql">SELECT COUNT(*) AS COUNT
FROM ECOLI_DATA
WHERE (GENOTYPE &amp; 2 = 0 )
    AND (GENOTYPE &amp; 5 != 0)
</code></pre>
<hr>
<p>갑자기 이진수 문제가 나와서 어려웠다...
이건 이진수 비교 문제다. 일반 숫자를 대입해 풀면 안 된다. 복수전공 할 때 잠시 배웠던 게 도움이 됐다.</p>
<p><code>TYPE 1</code> = 0001
<code>TYPE 2</code> = 0010 
<code>TYPE 3</code> = 0100 
<code>TYPE 4</code> = 1000 </p>
<p>이렇게 타입별로 이진수로 이루어져 있으므로
GENOTYPE도 이진수로 분해해서 생각해야 하는 것이다.</p>
<hr>
<h1 id="💡">💡</h1>
<p>일단 <span style='color: #BF3119'> <strong>2번 형질을 보유하지 않아야 된다</strong> </span>고 했다.
그렇다는 건, <code>TYPE 2</code> 형태를 가진 대장균을 <strong>제외</strong>해야 한다는 것.
즉 <strong>_ _1_ 의 형질</strong>을 가진다면 조회 대상에서 제외해야 한다.</p>
<p>이진수의 자리마다 형태를 비교하는 <span style='color: #BF3119'> <em>&amp; 연산자 </span>를 사용</em> 한다.</p>
<p>0010과 GENOTYPE <strong>둘 다 1일 때만 1을 반환</strong>하는 연산이다. 나머지(둘 다 0 / 둘 중의 하나가 0) 연산은 모두 <strong>0이 반환</strong>된다.
해당 문제에선 <code>TYPE 2</code> 즉 0010을 제외해야 한다고 했으므로, <span style='color: #BF3119'> <strong>GRNOTYPE &amp; 2(0010) 연산의 결과가 0이 되는 대상</strong>들만 출력</span>해야 한다. </p>
<p>그래야만 <em>0010 &amp; _ _1_ = 1</em>, 
즉 0010의 1과 연산되어 GENOTYPE에 2번 형질이 포함되는 것을 막는다.</p>
<pre><code class="language-sql">WHERE GENOTYPE &amp; 2 = 0</code></pre>
<hr>
<h1 id="💡-1">💡</h1>
<p><span style='color: #BF3119'> <strong>1번이나 3번 형질을 포함하거나 
1번과 3번 모두 포함</strong> </span> 해야 한다고 했다.</p>
<p><code>1 TYPE</code> = 0001
<code>3 TYPE</code> = 0100</p>
<p>위의 <code>TYPE 2</code> 포함시키지 않았던 것과 비슷하게 식을 도출한다.</p>
<p><code>1 TYPE</code> 와 <code>3 TYPE</code> 를 더해 함께 계산.
<strong>0001 + 0100 = 0101, 즉 5</strong>와 비교해야 한다.</p>
<p>0101 &amp; _ 1 _ 1 결과값이 0이 아니어야 한다. 1과 만나 이진수값이 출력되어야만이 </p>
<p><strong><code>1 TYPE</code> 
혹은 
<code>3 TYPE</code> 
혹은<br><code>1 TYPE</code>과 <code>3 TYPE</code>
이 포함</strong>되는 것이므로.</p>
<pre><code class="language-sql">WHERE (GENOTYPE &amp; 2 = 0)
    AND (GENOTYPE &amp; 5 != 0)</code></pre>
<blockquote>
<p>✔️ 
1, 3번 형질이 포함되는 걸 AND 연산자로 붙이는 등 따로 계산하지 않는 이유는, <strong>둘 중 하나가 포함되거나 둘 다 포함되는 경우</strong>가 조건이기 때문이다.<br/>
만약,</p>
</blockquote>
<pre><code class="language-sql">WHERE (0001 &amp; 1) AND (0100 &amp; 4) </code></pre>
<p>로 붙이면 두 형질 모두 가진 것들만 출력될 것이고,</p>
<pre><code class="language-sql">WHERE (0001 &amp; 1) OR (0100 &amp; 4)</code></pre>
<p>로 붙이면 둘 중에 하나만 포함되는 것들만 출력될 것.
<br/>
둘 다 포함 or 둘 중 하나만 포함 을 함께 계산해야 하므로, <strong>1번과 3번을 더해 &amp; 연산자로 0101과 GENOTYPE를 비교하는 형식</strong>으로 계산해야 옳은 결과가 도출된다.</p>
<p>아이구. 복잡혀라.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[03 통계 분석의 기초]]></title>
            <link>https://velog.io/@s__youn9/03-%ED%86%B5%EA%B3%84-%EB%B6%84%EC%84%9D%EC%9D%98-%EA%B8%B0%EC%B4%88</link>
            <guid>https://velog.io/@s__youn9/03-%ED%86%B5%EA%B3%84-%EB%B6%84%EC%84%9D%EC%9D%98-%EA%B8%B0%EC%B4%88</guid>
            <pubDate>Thu, 12 Mar 2026 06:24:37 GMT</pubDate>
            <description><![CDATA[<h2 id="📍-데이터-유형">📍 데이터 유형</h2>
<h3 id="✔️-변수">✔️ 변수</h3>
<p>공통의 측정 방법으로 얻은 같은 성질의 값이다.
즉, <strong>똑같은 기준과 도구를 사용해 조사</strong>하여 측정 <strong>대상마다 결과값이 다르게 나오는 것</strong>을 의미한다.
한 번에 몇 개의 변수를 보느냐에 따라 n변수라고 표현한다.</p>
<h4 id="--차원">- 차원</h4>
<p>데이터를 좌표 공간으로 생각하면 변수를 차원이라 칭할 수 있다.
1차원은 직선, 2차원은 평면, 3차원은 공간으로 표현할 수 있으나,
3차원 초과로 넘어간 차원은 표현하기 어려워지기 때문에 조심해야 한다.</p>
<h4 id="--차원의-저주">- 차원의 저주</h4>
<p>차원이 많아질수록 데이터 공간이 커져 패턴을 찾기가 어려워지는 것을 말한다.
상술하였듯 3차원이 넘어가면 표현 및 패턴 찾기가 어려워지므로 그 이상으로 차원을 늘리지 않을 수 있도록 변수 조정에 신경 써야 한다.</p>
<hr>
<h2 id="📍-데이터-분포">📍 데이터 분포</h2>
<p>대략적인 데이터의 경향을 파악할 수 있게 해 주는 값이다.</p>
<h3 id="✔️-이산형-양적-변수">✔️ 이산형 양적 변수</h3>
<p>가로축은 숫자, 세로축은 데이터의 개수(빈도 등)을 표기하는 변수이다.
ex) 주사위 던진 횟수 등</p>
<h3 id="✔️-연속형-양적-변수">✔️ 연속형 양적 변수</h3>
<p>구간폭(범위)에 따라 표현이 달라지므로 적절한 범위를 가로축에 포함하여 사용해야 한다.
ex) 키 분포</p>
<h3 id="✔️-범주형-변수">✔️ 범주형 변수</h3>
<p>가로축에는 각 범주, 세로축에는 범주에 속하는 개수를 표기한다.
ex) 좋아하는 메뉴</p>
<hr>
<h2 id="📍-통계량">📍 통계량</h2>
<p>수집한 데이터로 계산을 수행하여 얻은 값을 말한다.</p>
<h3 id="✔️-기술통계량">✔️ 기술통계량</h3>
<p>데이터 그 자체의 성질을 기술 및 요약하는 통계량을 말한다.
대푯값으로 평균/중앙값/최빈값을 가지며,
데이터 퍼짐 정도를 나타내는 것은 분산/표준편차가 있다.</p>
<h4 id="--평균값">- 평균값</h4>
<p>모든 값을 더한 뒤 값의 개수로 나눈 값이다.</p>
<h4 id="--중앙값">- 중앙값</h4>
<p>크기 순으로 값을 정렬했을 때 한가운데 위치하는 값이다.
데이터 개수가 홀수라면 정중앙,
짝수라면 정중앙의 두 개의 숫자의 평균이 중앙값이 된다.</p>
<h4 id="--최빈값">- 최빈값</h4>
<p>데이터 중 가장 자주 나타나는 값이다.</p>
<h4 id="--분산">- 분산</h4>
<p>표본의 각 값과 평균이 어느 정도 떨어져 있는지 평가하는 것이다.
데이터의 퍼짐 상태를 정량화하는 역할을 한다.</p>
<h4 id="--표준편차">- 표준편차</h4>
<p>분산에 제곱근을 취한 값이다.
극단적인 성질 파악 없이 원래 단위와 일치해 정량화된 지표로 알기 쉽게 표현된다.
가진 특징이 분산과 비슷한 경향을 보인다.</p>
<blockquote>
<h4 id="💡-분산-표준편차-특징">💡 분산, 표준편차 특징</h4>
<p>(측정값) - (평균) / (데이터 개수) 이므로 항상 0보다 큰 값을 가지며,
모든 값이 같다면 분포가 없는 것과 같으므로 분포가 0이 된다.
또한 데이터 퍼짐 정도가 크다면 분포값이 커진다.</p>
</blockquote>
<h3 id="✔️-이상값">✔️ 이상값</h3>
<p>드물게 극단적으로 나타나는 큰 값이나 작은 값이다.
평균값 및 표준편차와 2-3배 차이 나는 형태를 보인다.
평균값은 모든 값을 고려하기 때문에 이상치의 영향을 많이 받으므로, 
상대적인 크기인 중앙값이나 빈도가 낮은 최빈값을 사용하는 것이 좋다.</p>
<hr>
<h2 id="📍-분포-시각화-방법">📍 분포 시각화 방법</h2>
<h3 id="✔️-상자-수염-그림">✔️ 상자 수염 그림</h3>
<p><img src="https://velog.velcdn.com/images/s__youn9/post/9b634212-d2d0-4833-b45b-04ce98f2dea0/image.png" alt=""></p>
<p><strong>상자와 수염</strong>으로 구성돼 있으며 각각 <strong>데이터 분포를 특정 짓는 통계량</strong>을 나타낸다.
<strong>Q1인 1사분위 수</strong>는 <em>큰 쪽</em> 부터 세었을 때 1/4 위치에 있는 값이며,
<strong>Q3인 3사분위 수</strong>는 <em>작은 쪽</em> 부터 세었을 때 1/4 위치에 있는 값을 말한다.
상위 절반과 하위 절반을 나눈 위치의 제 <strong>2사분위 수는 중앙값</strong>을 지칭한다.
상하위로 길게 늘어진 <strong>수염은 상자 길이(Q1 - Q3)의 1.5배를 늘인 범위 안에서의 최대/최소값</strong>을 나타낸다.
최대/최소값 내에 포함되지 않는 부분을 <strong>이상치</strong>라고 하며 동그란 점으로 퍼지게 표현된다.</p>
<h3 id="✔️-막대-그래프-오차-막대">✔️ 막대 그래프 오차 막대</h3>
<p><img src="https://velog.velcdn.com/images/s__youn9/post/e44c188a-c82a-4354-8e47-9dade39a238f/image.png" alt="">
막대 그래프 높이로 나타내고 표준편차를 평균값에서 아래위로 늘려 표기한다.</p>
<h3 id="✔️-바이올린-플롯">✔️ 바이올린 플롯</h3>
<p><img src="https://velog.velcdn.com/images/s__youn9/post/5760b202-05d0-4af9-aaf0-640f3877dd1c/image.jpeg" alt="">
히스토그램을 부드럽게 표현한 것이며,
어디쯤에 데이터가 존재하기 쉬운지 추정할 수 있다.</p>
<h3 id="✔️-스웜-플롯">✔️ 스웜 플롯</h3>
<p><img src="https://velog.velcdn.com/images/s__youn9/post/10f3e6a0-71cc-4b10-a626-7f52bd9865de/image.png" alt="">
값이 겹치지 않도록 점을 찍어 각 데이터가 어디에 있는지 자세하게 나타낸다.
평균값/중앙값은 알 수 없으나 분포 형태나 자세한 위치 정보를 확인할 수 있다.</p>
<h3 id="✔️-스웜-플롯--상자-수염-그림">✔️ 스웜 플롯 + 상자 수염 그림</h3>
<p><img src="https://velog.velcdn.com/images/s__youn9/post/0b3ca136-c530-4890-8960-1dc3d9466a63/image.png" alt="">
평균값/중앙값이 없는 스웜 플롯의 단점을 보완,
통계량 나타내는 박스플롯과 함께 표기해
데이터가 어디에 위치해 있는지 자세하게 나타냄과 동시에 통계량도 확인이 가능하다.</p>
<hr>
<h2 id="📍-확률">📍 확률</h2>
<p>발생 여부가 불확실한 사건의 발생 가능성을 숫자로 표현한 것이다.</p>
<h3 id="✔️-확률변수">✔️ 확률변수</h3>
<p>X와 같이 확률이 달라지는 변수다.</p>
<h3 id="✔️-실현값">✔️ 실현값</h3>
<p>확률변수가 실제로 취하는 값이다.</p>
<h3 id="✔️-확률분포">✔️ 확률분포</h3>
<p>가로축에 확률변수, 세로축에 발생 가능성을 표기한 분포이다.
이산형일 경우 세로축이 확률 그 자체이며,
연속형일 때는 값에 범위를 두고 구한다.
범주형일 경우 가로축 순서에 의미가 없다.</p>
<h4 id="--확률밀도함수">- 확률밀도함수</h4>
<p><img src="https://velog.velcdn.com/images/s__youn9/post/75a55d7b-c0f0-481b-a788-ea2707635126/image.jpg" alt=""></p>
<p>상대적인 발생 가능성을 말하며, 연속형일 때 사용한다.
범위에 속할 확률을 구하고 싶다면 적분 후 넓이를 구하는 것이 방법이다.</p>
<blockquote>
<h4 id="💡-확률분포의-중요성">💡 확률분포의 중요성</h4>
<p>추론통계는 표본에서 모집단의 성질을 추정하기 때문에 관측과 이해에 어려움이 있다.
현실의 모집단을 수학의 확률분포로 / 표본을 실현값으로 가정해 분석하여
다루기 어려운 대상을 쉬운 대상으로 치환해 추정함으로써 모집단 이해를 쉽게 할 수 있다.</p>
</blockquote>
<h3 id="✔️-기댓값">✔️ 기댓값</h3>
<p>변수가 확률적으로 얼마나 발생하기 쉬운지 평균적인 값으로 나타낸 것이다.
확률이 가중치 역할을 하는 평균을 구하는 것이라 할 수 있다.
이산형일 경우 각 실현값과 실현값이 발생할 확률을 곱하여 더하여 계산하고,
연속형일 경우 실현값 x 와 그에 대응하는 확률밀도를 곱한 후 적분하여 계산한다.</p>
<h4 id="--분산-1">- 분산</h4>
<p>확률분포가 기댓값 주변에 얼마나 퍼져 있는지 나타내는 값이다.
기댓값과 차이를 제곱한 숫자로 판단하며,
이산형일 경우 실현값에서 기댓값을 빼어 제곱한 값과 각 실현값의 확률을 곱하여 계산하고,
연속형일 경우 실현값에서 기댓값을 빼어 제곱한 값과 그에 대응하는 확률밀도를 곱해 적분하여 계산한다.</p>
<h4 id="--표준편차-1">- 표준편차</h4>
<p>단순히 분산에 제곱근을 취한 값이다.</p>
<blockquote>
<h4 id="💡-분산-표준편차-특징-1">💡 분산 표준편차 특징</h4>
<p>각 값이 0 이상이어야 하며,
모두 같은 값이 나타나는 경우 퍼짐이 없다는 뜻이므로 0이다.
기댓값에서 떨어진 값이 많을수록 값이 커진다.</p>
</blockquote>
<blockquote>
<h4 id="💡-왜도와-첨도br">💡 왜도와 첨도<br/></h4>
</blockquote>
<ul>
<li>왜도
<img src="https://velog.velcdn.com/images/s__youn9/post/1c777ec2-26de-44c8-a079-f929b806165b/image.png" alt="">
분포가 좌우대칭에서 얼마큼 벗어나 있는지를 나타낸다.<br/><br/></li>
<li>첨도
<img src="https://velog.velcdn.com/images/s__youn9/post/eea2f7e2-11ea-4896-9709-5f0fd5090ef1/image.png" alt="">
분포가 얼마나 뾰족한지, 그래프 꼬리가 차지하는 비율의 크기를 나타낸다.</li>
</ul>
<h3 id="✔️-동시확률분포">✔️ 동시확률분포</h3>
<p>확률변수 2개를 동시에 생각할 때의 확률분포
한쪽이 어떤 값을 취하든 다른 한쪽의 확률은 변하지 않는 독립 관계다.</p>
<blockquote>
<p>P(X,Y) = P(X) x P(Y)</p>
</blockquote>
<p>두 변수가 동시에 값을 가지는 확률 구조이며, 두 변수 간의 관계 설명이 필요할 때 사용한다.</p>
<h3 id="✔️-조건부-확률">✔️ 조건부 확률</h3>
<p>한쪽 확률변수 Y의 정보가 주어졌을 때 다른 한쪽 확률변수 X의 확률을 말한다.
P(X|Y) = Y는 조건, X는 확률변수, 즉
Y의 정보를 얻으면 X를 알 수 있는 형태다.
독립할 경우에는 P(X|Y) = P(X) 의 관계가 성립한다.</p>
<hr>
<h2 id="📍-정규분포">📍 정규분포</h2>
<p><img src="https://velog.velcdn.com/images/s__youn9/post/d6e6bc62-eca3-4f38-b82e-96f21770bff2/image.webp" alt=""></p>
<p>평균 중심으로 좌우가 대칭이 종 모양의 확률분포다.
파라미터 즉 확률분포 및 모델 형태를 결정하는 고정값이 평균과 표준편차로 구성돼 있으며,
두 개의 파라미터로 인해 정규 분포 모양이 달라진다.</p>
<p><img src="blob:https://velog.io/2d069f22-9141-4ebe-a740-ac9bb0e52efd" alt="업로드중.."></p>
<p>데이터 밀집 구조가 평균에서 멀어질수록 극단적인 값일 확률이 낮아진다.</p>
<h3 id="✔️-표준화">✔️ 표준화</h3>
<p>(측정값) - (평균) / (표준편차) 를 이용해 평균을 0, 표준편차를 1로 만드는 것이다.
데이터를 평균을 기준으로 다시 표현하는 방법이며,
본래의 평균 및 표준편차와 상관없이 분포 안에서 어디쯤 위치하는지 알 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[02 모집단과 표본]]></title>
            <link>https://velog.io/@s__youn9/2.-%EB%AA%A8%EC%A7%91%EB%8B%A8%EA%B3%BC-%ED%91%9C%EB%B3%B8</link>
            <guid>https://velog.io/@s__youn9/2.-%EB%AA%A8%EC%A7%91%EB%8B%A8%EA%B3%BC-%ED%91%9C%EB%B3%B8</guid>
            <pubDate>Sat, 07 Mar 2026 17:27:45 GMT</pubDate>
            <description><![CDATA[<hr>
<blockquote>
<p>✔️ 데이터 분석 시, 해당 데이터로 얻고자 하는 구체적인 목표와 알고자 하는 대상을 명확히 하는 것이 제일 중요하다. 그렇기에 모집단에서 표본으로 수집 단위를 좁혀 특정 집단의 성질을 예측하는 것이다.</p>
</blockquote>
<hr>
<h3 id="📍-모집단">📍 모집단</h3>
<p>통계학에서 알고자 하는 대상 전체를 말한다.
상술한 데이터 분석 목적과 알고자 하는 대상에 기초하여 직접 설정해야 한다.
얻을 가능성이 희박한 데이터는 수집에 적합하지 않으며, 
&#39;알고자 하는 대상은 무엇인지&#39; / &#39;무엇을 모집단으로 설정할 것인지&#39;의 문제에는 항상 주의를 기울여야 한다.
<br/></p>
<h4 id="모집단-크기">모집단 크기</h4>
<ul>
<li><p>유한 모집단: 모집단 중 한정된 요소(특정 범주)만 포함하는 것이다. 원칙적으로 세어 볼 수 있으나 시간과 비용이 많이 들어 현실적이지 않다.</p>
</li>
<li><p>무한 모집단: 모집단 중 포함된 요소가 무한한 것을 말한다. 이는 유한 모집단과 유사하게 해당 전체 요소를 전부 조사 및 파악하는 것은 불가능하다.</p>
<br/>

</li>
</ul>
<h4 id="성질-파악-방법">성질 파악 방법</h4>
<p>모집단 크기 및 성질을 파악하기 위해 행해 볼 수 있는 조사 방법이다.</p>
<ul>
<li><p><strong>전수조사</strong>
모집단에 포함된 모든 요소를 조사하는 것이다. 
모집단에 포함된 요소의 개수가 한정된, 유한 모집단일 때 선택이 가능하다.
해당 모집단을 모두 파악 및 기술하기만 해도 특성 파악이 되는 건 사실이나 비용과 시간 면에서 부담이 막대해 잘 사용하지 않는다.</p>
</li>
<li><p><strong>표본조사</strong></p>
</li>
<li><p><em>모집단*</em>의 일부인 표본을 분석해 모집단 전체의 성질을 추정하는 조사 방법이다.</p>
</li>
<li><p><em>표본*</em>은 모집단의 일부를 말하며,</p>
</li>
<li><p><em>표본추출*</em>은 모집단의 일부를 뽑아 내는 과정을 말한다.</p>
</li>
<li><p><em>표본크기**는 표본 내에 포함된 요소의 개수를 말하는데, 보통 n으로 나타낸다. 
이는 *성질 추정의 확실성 및 가설검정 결과</em> 에 막대한 영향을 끼치므로 분석의 중요 요소 중 하나라고 할 수 있다.
표본개수는 샘플 수와 같은 표현이며, 표본 종류의 개수를 말한다.<br/>
예를 들어,
A 집단의 [표본크기는 30개] / B 집단의 [표본크기는 20개]이며
뽑힌 표본은 총 2개이므로 표본개수 및 샘플 수는 2개라고 할 수 있는 것이다.
크기와 개수는 완전히 다른 표현이니 헷갈리지 않도록 조심하자.<br/>
또한 표본은 어디까지나 예측에 불과하며 모집단의 성질을 100% 알아맞힐 수는 없기 때문에, 불확실성을 염두에 두고 파악하여야 한다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[01 통계학이란]]></title>
            <link>https://velog.io/@s__youn9/1.-%ED%86%B5%EA%B3%84%ED%95%99%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@s__youn9/1.-%ED%86%B5%EA%B3%84%ED%95%99%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Sat, 07 Mar 2026 16:04:48 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="📍-데이터-분석의-목적">📍 데이터 분석의 목적</h2>
<h3 id="데이터-요약">데이터 요약</h3>
<p>아무런 처리도 되지 않은 원자료는 수치의 나열일 뿐이므로 경향 파악이 불가하다. 그렇기에 평균, 중앙값, 분산 등의 요약 및 정리를 통해 수치의 경향성을 대략적으로 파악해야 한다.</p>
<h3 id="대상-설명">대상 설명</h3>
<p>대상이 가진 성질 및 관계성을 밝히고 이를 이해하는 것이다. 
데이터 분석을 통해 객관적인 증거 도출이 가능하다.</p>
<blockquote>
<h4 id="💡-증거-도출">💡 증거 도출</h4>
</blockquote>
<ul>
<li><strong>실험군</strong>: 가설 검증을 위해 독립 변인 조작해 처치하는 집단</li>
<li><strong>대조군</strong>: 실험군과 결과를 비교하기 위해 아무런 조작을 가하지 않는 집단</br>
=&gt; 검증을 하되, 실험 이외의 원인으로 인해 도출된 결과일 수 있는 가능성을 배제하지 않아야 한다. </li>
</ul>
<blockquote>
<h4 id="💡-변수-관계">💡 변수 관계</h4>
</blockquote>
<ul>
<li><strong>상관관계</strong>: 두 변수가 함께 움직이는 걸 파악할 수 있으나, 원인과 결과가 존재하는지, 그렇다면 어떤 변수인지 확인할 수 없다. 얕은 이해가 가능하다.</li>
<li><strong>인과관계</strong>: 둘 중 하나의 원인이 변화할 경우 다른 하나도 함께 변화하는 원인과 결과 관계가 존재한다. 매커니즘 이해에 용이하며 깊은 이해가 가능하다.</li>
</ul>
<h3 id="미지의-데이터-예측">미지의 데이터 예측</h3>
<p>특정 데이터를 기반으로 새롭게 얻은 데이터를 예측하는 것이다.
가능한 한 오차가 적은, 즉 예측이 들어맞기 쉬운 관계성을 발견할 수 있다.</p>
<hr>
<h2 id="📍-통계학의-역할">📍 통계학의 역할</h2>
<p>퍼짐(산포)이 있는 데이터에 대해 설명 및 예측하는 역할을 한다.
=&gt; 퍼짐이 있는 데이터는 대상이 가진 성질이나 관계성의 본질을 감추므로, 이의 본질을 어느 정도 정확히 예측하기 위해 통계학이라는 도구를 사용하는 것.</p>
<hr>
<h2 id="📍-통계학-전체-모습">📍 통계학 전체 모습</h2>
<h4 id="기술-통계">기술 통계</h4>
<p>수집한 데이터를 정리하고 요약하는 방법이다. 확보한 데이터에만 집중하여, 데이터 그 자체의 특성이나 경향, 성질을 이해하는 데 용이하다.</p>
<h4 id="추론-통계">추론 통계</h4>
<p>수집한 데이터로부터 데이터의 발생원을 추정하는 방법이다. 대상을 이해하거나 데이터를 예측하는 데에 사용된다.</p>
<blockquote>
<h4 id="💡-추론-통계-종류">💡 추론 통계 종류</h4>
</blockquote>
<ul>
<li><strong>통계적 추론</strong>
데이터에서 가정한 확률 모형의 성질을 추정하는 방법</li>
<li><strong>가설검정</strong>
세운 가설과 얻은 데이터가 얼마나 들어맞는지 평가해 가설을 채택할 것인지 판단하는 방법</li>
</ul>
<h4 id="확률-모형">확률 모형</h4>
<p>데이터 성질 추정 시 비교적 단순한 확률에서 생성된 것이라고 생각하는 것이다. 그 자체로 추상적이고 이해하기 어려운 성질을 단순한 확률로 단정지어 비교적 예측을 용이하게 한다.
ex) 주사위가 n이 나올 확률 =&gt; 1/6(단순 확률 모형으로 성질 예측)</p>
<hr>
<blockquote>
<p>✔️ <strong>통계 분석에 다양한 방법이 존재하는 이유</strong>는, 데이터 유형 및 변수 개수, 가정하는 확률 모형 등에 따라 데이터를 이용하는 방법이 다르기 때문이다. 
또한, 데이터 분석 목적에 따라 다른 통계 방법을 사용해야 할지도 모른다. 
그렇기에 <strong>다양한 분석 방법</strong>을 배워야만이 적재적소에 통계를 사용해 유의미한 결론을 내놓을 가능성이 높아진다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[#WeeklyPaper 03]]></title>
            <link>https://velog.io/@s__youn9/06-Tableau-%EB%8C%80%EC%8B%9C%EB%B3%B4%EB%93%9C</link>
            <guid>https://velog.io/@s__youn9/06-Tableau-%EB%8C%80%EC%8B%9C%EB%B3%B4%EB%93%9C</guid>
            <pubDate>Mon, 02 Mar 2026 09:47:09 GMT</pubDate>
            <description><![CDATA[<h1 id="📚-join-방법">📚 Join 방법</h1>
<ol>
<li><span style= 'background-color: #FCC6BB'> <strong>Inner Join</strong></span>: 두 데이터에 모두 존재하는 값들을 위주로 합친다.</li>
<li><span style= 'background-color: #FCC6BB'> <strong>Left Outer Join</strong></span>: 왼쪽 데이터에 존재하는 값을 위주로 데이터를 합친다.
왼쪽 데이터는 모두, 오른쪽 데이터는 왼쪽에 존재하는 값들만 합쳐진다.</li>
<li><strong>Right Outer Join</strong>: 오른쪽 데이터에 있는 값을 위주로 데이터를 합친다.
오른쪽 데이터는 모두, 왼쪽 데이터는 오른쪽에 존재하는 값들만 합쳐진다.</li>
<li><strong>Full Outer Join</strong>: 두 데이터의 모든 값을 가져와 하나로 합친다. <br/>
<span style= 'background-color: #FCC6BB'>   </span> <span style='color: #A9A9A9'/> : 자주 사용되는 함수 종류 </span></li>
</ol>
<hr>
<h2 id="📍-concat">📍 concat()</h2>
<p>: 데이터 속성이 동일한 데이터셋끼리 합칠 때 사용할 수 있는 함수
key가 되는 공통된 열이나 인덱스 지정 없이 열/행 방향으로 합칠 수 있다.
DataFrame, Series에 모두 사용이 가능하다.</p>
<blockquote>
<p>💡 기본 정의
<code>objs</code>: 합칠 Series, DataFrame, Panel Object 변수를 삽입한다.
<code>axis=0/1</code>: 데이터를 위+아래로 합친다 / 데이터를 오른쪽+왼쪽으로 합친다.
<code>join=outer/inner</code>: 합집합(모든 데이터를 합친다) / 교집합(모든 데이터셋에 존재하는 값끼리 합친다)
<code>ignore_index=False/True</code>: 기존 인덱스 유지 / 기존 인덱스를 무시하고 합친다.
<code>keys=[]</code>: 계층적인 index 를 사용하려면 keys 튜플을 입력한다. 
각 데이터 프레임마다 대표적인 키값을 부여하는 역할을 한다.</p>
</blockquote>
<pre><code class="language-python">import pandas as pd

english_df1 = pd.DataFrame({
    &#39;name&#39;: [&#39;dongwook&#39;, &#39;taego&#39;, &#39;jimin&#39;],
    &#39;english_score&#39;: [50, 91, 72]
})

english_df2 = pd.DataFrame({
    &#39;name&#39;: [&#39;yoonsoo&#39;, &#39;sowon&#39;, &#39;haeun&#39;],
    &#39;english_score&#39;: [88, 91, 72]
})</code></pre>
<pre><code class="language-python">pd.concat([english_df1, english_df2])</code></pre>
<p><img src='https://velog.velcdn.com/images/s__youn9/post/959521bd-894a-40f6-b1c7-1bdf6c725d9a/image.png' width='200'/></img></p>
<p><br/><br/></p>
<hr>
<h2 id="📍-merge">📍 merge()</h2>
<p>: 두 데이터프레임을 각 데이터에 존재하는 고유값, 즉 열값을 기준으로 병합할 때 사용된다.
기본적으로 Inner Join을 사용한다.</p>
<blockquote>
<p>💡 기본 정의
<code>on=&#39;&#39;</code>: 병합에 기준이 될 키값을 지정한다.
<code>how=left/right</code>: lefr outer join/right outer join을 사용한다.
<code>suffixes=()</code>: 각 데이터에 똑같은 이름을 가진 key 역할을 하는 열 이름은 자동으로 _x, _y 구분자가 작성되는데,해당 구분자를 변경하는 역할을 한다.
<code>right/left_on=&#39;&#39;</code>: key 역할을 하는 열의 이름이 같지 않을 때 값이 같은 열 이름을 입력해 결합한다.
<code>left/right_index</code>: 오른쪽/왼쪽 데이터의 키값을 인덱스로 지정한다.</p>
</blockquote>
<pre><code class="language-python">pd.merge(employee_df, survey_df, on=&#39;id) # id열을 기준으로 데이터 병합</code></pre>
<img src='https://velog.velcdn.com/images/s__youn9/post/947755f4-b66c-4cd9-bf6e-5341b38df4ef/image.png'/>

<p><span style='color:#A9A9A9'> id가 똑같은 <strong>열들끼리 병합</strong>, 같은 이름을 가진 열들엔 department&quot;_x&quot;, department&quot;_y&quot; 처럼 <strong>열 이름 뒤에 구분자</strong>가 주어진다.</span></p>
<pre><code class="language-python">pd.merge(employee_df, survey_df, on=&#39;id&#39;, how=&#39;left&#39;)</code></pre>
<img src='https://velog.velcdn.com/images/s__youn9/post/77b9b528-c54c-4c38-8588-4192184f8792/image.png'/>

<p><span style='color:#A9A9A9'> how=left를 통해 left outer join, 즉 <strong>왼쪽의 값을 위주로 오른쪽 값을 병합</strong>하였다. 왼쪽에는 있으나 오른쪽에 없는 값은 <strong>결측값</strong>으로 결합되었다.</span>
<br/><br/></p>
<hr>
<h2 id="📍-join">📍 join()</h2>
<p>: 공통으로 들어 있는 값을 하나로 합치는 함수이다.
merge() 함수를 기반으로 만들어져 작동 방식이 유사하나, 행 인덱스를 기준으로 결합한다는 점에서 차이가 있다. 
<code>[데이터].join</code>에서, 입력한 데이터를 기준으로 데이터를 병합한다.</p>
<blockquote>
<p>💡 기본 정의
<code>l/rsuffix=&#39;&#39;</code>: 똑같은 이름을 가진 key 역할을 하는 열의 이름을 각각 설정한다.
<code>how=&#39;inner&#39;</code>: inner join으로 교집합인 값들만 가져와 결합한다.</p>
</blockquote>
<pre><code class="language-python">employee_df.join(survey_df, lsuffix=&#39;_x&#39;, rsuffix=&#39;_y&#39;)</code></pre>
<img src='https://velog.velcdn.com/images/s__youn9/post/45aa80e8-677b-4070-bf87-c01f56178d05/image.png'/>

<p><span style='color:#A9A9A9'> <strong>employee_df 데이터를 기준</strong>으로 survey_df와 결합하였다. <strong>lsuffix, rsuffix를 통해 동일한 이름을 가진 열 department 뒤에 구분 문자를 지정</strong>해 주었다.
</span>
<br/><br/></p>
<hr>
<blockquote>
<h3 id="💡-merge와-join">💡 merge()와 join()</h3>
<p>** ✔️ merge()** </p>
</blockquote>
<ul>
<li>특정 <strong>열이나 인덱스</strong>를 기준으로 데이터프레임을 결합하는 방식이다. </li>
<li>기준이 되는 <strong>열의 이름이 서로 다를</strong> 때,</li>
<li>인덱스가 아닌 <strong>일반 데이터 열</strong>을 기준으로 데이터를 합치고 싶을 때,</li>
<li>복잡한 <strong>join조건을 명확히 지정해야 할 때(how=&#39;&#39;)</strong> 사용하면 좋다.<br/><br/></li>
<li><ul>
<li>✔️ join()** </li>
</ul>
</li>
<li><strong>인덱스를 기준</strong>으로 빠르게 결합하는 방식이다</li>
<li><strong>여러 개의 데이터프레임을 한 번에 결합</strong>할 때 유용하다. </li>
<li>두 개의 데이터프레임의 <strong>인덱스가 맞추어져 있을</strong> 때,</li>
<li><strong>여러 개(3개 이상)의 데이터프레임을 동시에 행을 기준으로 결합</strong>하고 싶을 때,</li>
<li>인덱스를 기준으로 <strong>왼쪽 데이터에 정보를 추가</strong>하고 싶을 때 사용하면 좋다.<br/><br/>
➡️ 가장 범용적으로 자주 쓰이는 것은 <strong>세부적인 내용 조정이 가능한 merge()</strong>이지만, 인덱스를 기준으로 하는 <strong>간결한 작업이라면 join()</strong>을 사용하는 것이 효율적이다.</li>
</ul>
<hr>
<h1 id="📚-tableau-살펴보기">📚 Tableau 살펴보기</h1>
<h2 id="📍-end-of-year-overview">📍 End Of Year Overview</h2>
<p>- Adil Ahmad</p>
<p><a href="https://public.tableau.com/views/EndOfYearOverview/EndofYearOverview?:language=ko-KR&amp;:sid=&amp;:redirect=auth&amp;:display_count=n&amp;:origin=viz_share_link">https://public.tableau.com/views/EndOfYearOverview/EndofYearOverview?:language=ko-KR&amp;:sid=&amp;:redirect=auth&amp;:display_count=n&amp;:origin=viz_share_link</a></p>
<p>해당 대시보드는 <strong>한 해의 핵심 비즈니스 지표와, 작년(PY) 대비 증감률</strong>을 직관적으로 보여 준다. 불필요한 요소들은 모두 배제한 후 핵심 데이터가 한눈에 들어오도록 그래프를 깔끔하게 배치한 점이 돋보인다. 특히 Sales, Profit, Orders, Returns 등 주요 측정값을 선택하여 추이를 동적으로 확인할 수 있어, 이상적인 대시보드라고 생각하여 선정하였다.</p>
<hr>
<h3 id="1-전체-구성">1. 전체 구성</h3>
<p><img src="https://velog.velcdn.com/images/s__youn9/post/b54832bd-0d45-4d04-8ed9-f850801d759e/image.png" alt=""></p>
<ul>
<li>2022년부터 연도별로 데이터를 확인할 수 있도록 <strong>연도 매개변수</strong>를 활용하여 사용자가 원하는 시점의 데이터를 뷰에 반영할 수 있게 구성하였다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/s__youn9/post/2cde8ec8-5c0a-4a48-8f95-33e79c4277d4/image.png" alt=""></p>
<ul>
<li>Metrics의 각 카테고리를 클릭하면 해당 지표과 작년 지표를 비교하는 그래프로 전체 화면이 전환되도록, <strong>매개변수 동작</strong>기능을 적극적으로 활용한 점이 돋보인다.</li>
</ul>
<hr>
<h3 id="2-그래프-요소">2. 그래프 요소</h3>
<p><img src="https://velog.velcdn.com/images/s__youn9/post/d9c38d14-5c4d-48ed-8d58-c85a37b7bff0/image.png" alt=""></p>
<ul>
<li>Sales, Profit, Orders 등의 가장 최근 실적을 직관적으로 보여주기 위해 <strong>텍스트 마크</strong>를 활용하였다. 연도, 타이틀, 비즈니스 지표, 작년 대비 증감률을 조합해 하나의 텍스트 박스처럼 깔끔하게 삽입한 점이 인상적이다.</li>
<li><strong>꺾은선 그래프(Line Chart)</strong>를 통해 작년 지표 대비 올해 지표의 월별 지표 추이를 나타내었다. </li>
<li>작년 대비 실적이 저조한 달은 빨간색 원으로 강조했으며, 마우스 오버 시 도구 설명을 통해 정확한 증감률을 확인할 수 있다.</li>
<li>전체 추이를 가리지 않도록, 마크 레이블 설정에서 최대값을 기록한 달에만 레이블이 표시되도록 자동화하였다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/s__youn9/post/50810750-ef1e-4db3-bc79-6b73d1fb9f3b/image.png" alt=""></p>
<ul>
<li>Segment(고객 세그먼트), Sub-Category(하위 범주), Ship Mode(배송 방법) 별로 지표를 나누어 막대 그래프로 세부 추이를 보여 주었다. </li>
<li>특히, 올해 측정값 막대 위에 작년 측정값을 투명하게 겹쳐 배치하는 <strong>바 인 바(Bar-in-Bar) 차트</strong> 형태를 띠고 있다. 이는 이중 축 기능을 활용해 두 막대를 겹치고, 크기와 투명도를 조절해 작년 대비 증감을 매우 직관적으로 비교 가능하게 한 시각화 방법이다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/s__youn9/post/ffcae9f1-d91b-409a-b612-e920dcfb4c71/image.png" alt=""></p>
<ul>
<li>지리적 역할을 부여한 맵 차트를 이용해 어느 지역에서 실적이 발생했는지 한눈에 파악할 수 있게 했다. 전체 지도를 하나로 합치지 않고 Central, South, West, East 지역별로 패널을 분할하여 가독성을 높였다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/s__youn9/post/fbe686b4-83c2-48a5-9ece-4da7e4383c8d/image.png" alt=""></p>
<ul>
<li>파이차트 두 개를이중 축으로 겹쳐서 구현한 <strong>도넛 차트</strong>를 사용해 Sub-Category 별 작년 대비 증감률을 표기하였다.</li>
<li>마우스 오버 시 제품명, 현재 가격, 증감률을 도구 설정으로 알려 주며, 타 제품과의 비중 및 대비를 더욱 명확하게 확인할 수 있다.</li>
</ul>
<hr>
<p>그래프끼리 겹쳐 또 다른 그래프를 만들 수도 있구나... 정말정말 새롭고, 대시보드가 예쁘고 직관적이게, 깔끔히 한눈에 들어오도록 배치된 게 많아서, 노트를 예쁘게 정리하고 A4에 요약할 때도 마음에 들지 않으면 안 되는 병이 있는 나에게는 앞으로 더 많은 데이터 전처리 및 대시보드 제작에 대한 인풋과 아웃풋을 늘리고 강사님이 말씀하셨던 공모전에 나가 보는 것도 정말 좋은 경험이 될 것 같다는 생각이 들었다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[기초] 조건 문자열]]></title>
            <link>https://velog.io/@s__youn9/%EA%B8%B0%EC%B4%88-%EC%A1%B0%EA%B1%B4-%EB%AC%B8%EC%9E%90%EC%97%B4</link>
            <guid>https://velog.io/@s__youn9/%EA%B8%B0%EC%B4%88-%EC%A1%B0%EA%B1%B4-%EB%AC%B8%EC%9E%90%EC%97%B4</guid>
            <pubDate>Wed, 25 Feb 2026 08:16:18 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="📍-문제">📍 문제</h3>
<p>문자열에 따라 다음과 같이 두 수의 크기를 비교하려고 합니다.
두 수가 n과 m이라면<br/></p>
</blockquote>
<ul>
<li>&quot;&gt;&quot;, &quot;=&quot; : n &gt;= m</li>
<li>&quot;&lt;&quot;, &quot;=&quot; : n &lt;= m</li>
<li>&quot;&gt;&quot;, &quot;!&quot; : n &gt; m</li>
<li>&quot;&lt;&quot;, &quot;!&quot; : n &lt; m<br/>
두 문자열 ineq와 eq가 주어집니다. 
ineq는 <strong>&quot;&lt;&quot;와 &quot;&gt;&quot;중 하나</strong>고, eq는 <strong>&quot;=&quot;와 &quot;!&quot;중 하나</strong>입니다. 
그리고 두 정수 n과 m이 주어질 때,
n과 m이 <strong>ineq와 eq의 조건에 맞으면 1을 아니면 0을 return</strong>하도록 solution 함수를 완성해주세요.</li>
</ul>
<blockquote>
<h3 id="⚠️-제한사항">⚠️ 제한사항</h3>
</blockquote>
<ul>
<li>1 ≤ n, m ≤ 100</li>
</ul>
<pre><code class="language-python">def solution(ineq, eq, n, m):
    if ineq == &quot;&gt;&quot;: # ineq에 &gt; 이 들었고,
        if eq == &quot;=&quot;: # eq에 =이 들어서 
            return 1 if n &gt;= m else 0 # n &gt;= m 이라면 1, 아니라면 0 출력
        else: # ineq에 &gt; 이 들었고, eq에는 !(같지 않다)가 들어서,
            return 1 if n &gt; m else 0 # n &gt; m 이라면 1, 아니라면 0 출력 
    else: # ineq에 &lt; 이 들었고,
        if eq == &quot;=&quot;: # eq 에 = 이 들어서
            return 1 if n &lt;= m else 0 # n &lt;= m 이면 1, 아니라면 0 출력
        else: # ineq 에 &lt; 이 들었고, eq에 !(같지 않다)가 들어서,
            return 1 if n &lt; m else 0 # n &lt; m 이 되면 1, 아니라면 0 출력</code></pre>
<p>어리브라......</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[기초] 문자열 곱하기]]></title>
            <link>https://velog.io/@s__youn9/%EA%B8%B0%EC%B4%88-%EB%AC%B8%EC%9E%90%EC%97%B4-%EA%B3%B1%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@s__youn9/%EA%B8%B0%EC%B4%88-%EB%AC%B8%EC%9E%90%EC%97%B4-%EA%B3%B1%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 25 Feb 2026 07:46:15 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="📍문제">📍문제</h3>
<p>문자열 my_string과 정수 k가 주어질 때, 
my_string을 k번 반복한 문자열을 return 하는 solution 함수를 작성해 주세요.</p>
</blockquote>
<blockquote>
<h3 id="⚠️-제한사항">⚠️ 제한사항</h3>
</blockquote>
<ul>
<li>1 ≤ my_string의 길이 ≤ 100</li>
<li>my_string은 영소문자로만 이루어져 있습니다.</li>
<li>1 ≤ k ≤ 100</li>
</ul>
<pre><code class="language-python"># 내가 작성한 코드
def solution(my_string, k):
    answer = my_string * k
    return answer</code></pre>
<p>이것밖에 생각이 안 났다. 
혹시 너무 간단한 건 아닌지, 더 알고리즘 문제에 맞게 풀어 볼 수 있는 방법은 없는지 알아보았다.</p>
<h4 id="1-for-loop">1. for loop</h4>
<pre><code class="language-python">def solution(my_string, k):
    answer = &#39;&#39;
    for _ in range(k):
        answer += my_string
    return answer</code></pre>
<p>왠지 모범답안 같았다. 문제에도 <code>answer= &#39;&#39;</code> 이 주어져 있어서 딱 이런 로직을 바라고 문제 낸 느낌.
k만큼 for 루프를 돈다. 진행하는 동안 빈 answer 변수에 my_string 내부 문자열을 k만큼 반복해 출력한다. 시각적으로 이해하기 쉬운 코드라고 생각된다.</p>
<h4 id="2-join">2. join()</h4>
<pre><code class="language-python">def solution(my_string, k):
    return &#39;&#39;.join([my_string for _ in range(k)])</code></pre>
<p>join() 함수를 통해 문자열을 <strong>공백을 기준으로 병합</strong>하는 것이다.(문자열을 합할 때 join() 함수를 많이 얘기하는 것 같다. 한눈에 보기 어렵지만 작성하기에 편리해서 그런 것 같기도 하다. 기억해 두자.) 리스트를 만들어서, 그 안에 my_string 문자열을 k만큼 리스트에 넣는다.</p>
<h4 id="3-recursion">3. Recursion</h4>
<pre><code class="language-python">def solution(my_string, k):
    if k == 0: # 만약 k가 0이라면 공백 출력,
        return &quot;&quot;
    return my_string + solution(my_string, k - 1)</code></pre>
<ol>
<li>solution 함수로 들어가서, 먼저 k가 0인지 아닌지 확인한다. 만약 0이 아니라면,</li>
<li>마지막 return 문으로 가서 <strong>my_string을 출력</strong>한다.</li>
<li>그 후 <strong>solution 함수를 다시 호출</strong>하여, 그 안에 my_string과</li>
<li>이미 한 번 my_string을 출력하였으니 k - 1을 넘겨 준다.</li>
<li>k가 0이 될 때까지 my_string을 옆에 덧붙이기를 반복하고, </li>
<li>0이 되면 공백을 출력하며 재귀를 종료한다.</li>
</ol>
<p>재귀함수는 k가 너무 크면 stack overflow가 날 수 있어, 반복을 많이 해야 한다면 추천하지 않는다. 되려 for문을 사용하는 것이 더 효과적이다.</p>
<p>재작년에 알고리즘 공부할 때 로직 짜기 어려워서 애먹었는데 다시 마주하다니...
solution을 계속 재귀해서 호출하는 걸 이해하여아만 내가 직접 로직을 짜는 데에 어려움이 없을 것 같다. 알고리즘 공부하려면 제대로 꿰고 싶은데... 더 공부해 봐야지.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[기초] 문자열 겹쳐쓰기]]></title>
            <link>https://velog.io/@s__youn9/%EA%B8%B0%EC%B4%88-%EB%AC%B8%EC%9E%90%EC%97%B4-%EA%B2%B9%EC%B3%90%EC%93%B0%EA%B8%B0</link>
            <guid>https://velog.io/@s__youn9/%EA%B8%B0%EC%B4%88-%EB%AC%B8%EC%9E%90%EC%97%B4-%EA%B2%B9%EC%B3%90%EC%93%B0%EA%B8%B0</guid>
            <pubDate>Tue, 24 Feb 2026 07:46:23 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="📍-문제">📍 문제</h3>
<p>문자열 <strong>my_string, overwrite_string과 정수 s</strong>가 주어집니다.<br/>
문자열 my_string의 인덱스 s부터 overwrite_string의 길이만큼을 문자열 overwrite_string으로 바꾼 문자열을 return 하는 solution 함수를 작성해 주세요.</p>
</blockquote>
<blockquote>
<h3 id="⚠️-제한사항">⚠️ 제한사항</h3>
</blockquote>
<ul>
<li>my_string와 overwrite_string은 <strong>숫자와 알파벳</strong>으로 이루어져 있습니다.</li>
<li>1 ≤ overwrite_string의 길이 ≤ my_string의 길이 ≤ 1,000</li>
<li>0 ≤ s ≤ my_string의 길이 - overwrite_string의 길이</li>
</ul>
<pre><code class="language-python">
def solution(my_string, overwrite_string, s):

    front = my_string[: s] # 먼저, 기본 문자열의 s까지만 출력
    middle = overwrite_string # 중간에 겹쳐쓸 문자열 출력
    back = my_string[s + len(overwrite_string) : ] # 마지막으로 앞서 작성한 문자열의 길이만큼 제외한 나머지 my_string 문자 출력

    answer = front + middle + back

    return answer 
</code></pre>
<p><strong>문자열 인덱싱</strong>은 아무리 많이 연습해 보아도 어려운 것 같다.😕
처음에는 콜론을 이용해 인덱싱 할 생각을 못하고 대괄호만 이용해 값 하나만 가져오는 인덱싱을 이용해버려서 제대로 출력되지 않았다.</p>
<pre><code class="language-python">def solution(my_string, overwrite_string, s):
    answer = &#39;&#39;
    str_len = len(my_string)
    over_len = len(overwrite_string)

    anser = ...
</code></pre>
<p>이렇게 먼저 풀었던 것 같은데...
아마 len 을 이용해 각 값의 길이를 구하고, 처음에는 overwrite_string 에서 my_string의 길이를 빼어 my_string에 해당 값을 인덱싱한 후 overwrite_string을 합쳐 보려고 했던 것 같다.
s라는 인덱싱 값이 분명히 존재함에도 불구하고...
문제가 조금만 길어지고, 변수가 조금만 많아져도 머릿속이 새하얘져서 복잡하게 생각하는 듯하다. 테스트를 더 많이 풀어보고 손에 익숙해지게끔 해 보아야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[기초] 대소문자 바꿔서 출력하기]]></title>
            <link>https://velog.io/@s__youn9/%EA%B8%B0%EC%B4%88-%EB%8C%80%EC%86%8C%EB%AC%B8%EC%9E%90-%EB%B0%94%EA%BF%94%EC%84%9C-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@s__youn9/%EA%B8%B0%EC%B4%88-%EB%8C%80%EC%86%8C%EB%AC%B8%EC%9E%90-%EB%B0%94%EA%BF%94%EC%84%9C-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 24 Feb 2026 07:03:25 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="📍-문제">📍 문제</h3>
<p>영어 알파벳으로 이루어진 <strong>문자열 str</strong>이 주어집니다. 각 알파벳을 <u><strong>대문자는 소문자로 소문자는 대문자로 변환</strong></u> 해서 출력하는 코드를 작성해 보세요.</p>
</blockquote>
<blockquote>
<h3 id="⚠️-제한사항">⚠️ 제한사항</h3>
</blockquote>
<ul>
<li>1 ≤ str의 길이 ≤ 20</li>
<li>str은 알파벳으로 이루어진 문자열입니다.</li>
</ul>
<hr>
<pre><code class="language-python">str = input()

for i in str:
    if i.isupper() == True:
        print(i.lower(), end = &quot;&quot;)
    else:
        print(i.upper(), end = &quot;&quot;)</code></pre>
<hr>
<p><code>.isupper()</code>, <code>.islower()</code> 메서드는
입력값의 대소문자를 판단해 boolean 값으로 반환한다.
이 메서드를 몰라서 몇 분 끙끙댔다.</p>
]]></description>
        </item>
    </channel>
</rss>