<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>jisukim.log</title>
        <link>https://velog.io/</link>
        <description>오늘 배운 것을 기록하며, 나만의 지식으로 만들어가는 성장 일지 💪🍀</description>
        <lastBuildDate>Fri, 25 Jul 2025 05:17:38 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>jisukim.log</title>
            <url>https://velog.velcdn.com/images/jisukim_28/profile/6bcd423c-59d6-4a6b-9b4b-887bb95d4e66/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. jisukim.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jisukim_28" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[이중차분법 - 마케팅 효과 추정 통계 기법]]></title>
            <link>https://velog.io/@jisukim_28/%EC%9D%B4%EC%A4%91%EC%B0%A8%EB%B6%84%EB%B2%95-%EB%A7%88%EC%BC%80%ED%8C%85-%ED%9A%A8%EA%B3%BC-%EC%B6%94%EC%A0%95-%ED%86%B5%EA%B3%84-%EA%B8%B0%EB%B2%95</link>
            <guid>https://velog.io/@jisukim_28/%EC%9D%B4%EC%A4%91%EC%B0%A8%EB%B6%84%EB%B2%95-%EB%A7%88%EC%BC%80%ED%8C%85-%ED%9A%A8%EA%B3%BC-%EC%B6%94%EC%A0%95-%ED%86%B5%EA%B3%84-%EA%B8%B0%EB%B2%95</guid>
            <pubDate>Fri, 25 Jul 2025 05:17:38 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>이중차분법</strong></p>
</blockquote>
<p>광고 캠페인, 가격 인하, 리브랜딩 등 특정 마케팅 개입이 실제로 매출이나 고객 행동에 어떤 영향을 미쳤는지 평가할 때 유용한 분석 기법</p>
<blockquote>
<p><strong>마케팅에서 이중차분법이 필요한 이유</strong></p>
</blockquote>
<ul>
<li>단순히 캠페인 전후의 매출 변화만 보면, 시장 트렌드나 계절 요인 등의 외부 요인까지 포함되어 있음.</li>
<li>이중차분법은 &#39;통제집단&#39;을 기준선으로 삼아, 외부요인을 제거하고 순수한 마케팅 효과만 추정할 수 있도록 도와줌.</li>
</ul>
<blockquote>
<p>*<em>지역별 광고 캠페인 효과 분석 *</em></p>
</blockquote>
<p>✅상황: 한 식음료 브랜드가 서울에서만 TV 광고 캠페인을 시작함. 캠페인을 하지 않은 부산과 캠페인을 한 서울의 광고 전후 매출 데이터를 비교해 광고 효과를 추정해보고 싶음. </p>
<p><img src="https://velog.velcdn.com/images/jisukim_28/post/0b1bf70a-4482-433b-a422-f59c06e48b8f/image.png" alt=""></p>
<p>✅분석과정</p>
<ol>
<li>처리집단의 변화: 서울은 광고 후 +500만원 증가</li>
<li>통제집단의 변화: 부산도 +200만원 증가 (광고를 하지 않았는데도)</li>
<li>이중차분법 추정치: (1500-1000) - (1100-900) = 500-200 = +300만원</li>
</ol>
<p>-&gt; 순수하게 광고 캠페인으로 생긴 매출 증가는 300만원으로 추정 
통제집단이 있으면, 마케팅 효과를 더 과학적으로 분석 가능 </p>
<blockquote>
<p><strong>통제집단 선정 기준</strong></p>
</blockquote>
<ul>
<li>통제집단은 가급적 유사한 특정을 가진 집단이어야 함</li>
<li>캠페인 전 트렌드가 유사해야 이중차분법이 유효함</li>
<li>데이터를 시각화해서 먼저 평행 추세 여부를 확인하는 것이 좋음 </li>
</ul>
<blockquote>
<p><strong>예시 코드</strong></p>
</blockquote>
<pre><code>import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# 3개월간 수집한 매출 데이터
np.random.seed(42)
campaign_before = np.random.normal(100, 8, 20)  # 서울 캠페인 전
campaign_after = np.random.normal(115, 8, 20)   # 서울 캠페인 후
control_before = np.random.normal(95, 8, 20)    # 부산 캠페인 전
control_after = np.random.normal(100, 8, 20)    # 부산 캠페인 후

data = pd.DataFrame({
    &#39;region&#39;:[&#39;Seoul&#39;]*40 + [&#39;Busan&#39;]*40,
    &#39;time&#39;: [&#39;before&#39;]*20 + [&#39;after&#39;]*20 + [&#39;before&#39;]*20 + [&#39;after&#39;]*20,
    &#39;sales&#39;: np.concatenate([campaign_before, campaign_after, control_before, control_after])
})

# 시각화 그래프
avg_data = data.groupby([&#39;region&#39;, &#39;time&#39;])[&#39;sales].mean().reset_index()

plt.figure(figsize=(10, 6))
sns.lineplot(data=avg_data, x=&#39;time&#39;, y=&#39;sales&#39;, hue=&#39;region&#39;, marker=&#39;o&#39;, linewidth=3, markersize=10)
plt.title(&#39;에코프레시 캠페인 전후 매출 변화&#39;)
plt.xlabel(&#39;시점&#39;)
plt.ylabel(&#39;매출 (만원)&#39;)
plt.legend(title=&#39;지역&#39;)
plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/jisukim_28/post/db95db71-8a56-4669-b60e-f1bb2fe78a06/image.png" alt=""></p>
<p>평행 추세 가정이 시각적으로는 대체로 만족되는 것으로 보임 </p>
<pre><code># CEO 앞에서 실시간 계산
means = data.groupby([&#39;region&#39;, &#39;time&#39;])[&#39;sales&#39;].mean()
print(&quot;그룹별 평균 매출:&quot;)
print(means)

# DID 계산 - 핵심 순간
campaign_before = means[&#39;Seoul&#39;, &#39;before&#39;]
campaign_after = means[&#39;Seoul&#39;, &#39;after&#39;]
control_before = means[&#39;Busan&#39;, &#39;before&#39;]
control_after = means[&#39;Busan&#39;, &#39;after&#39;]

diff_campaign = campaign_after - campaign_before
diff_control = control_after - control_before
did_effect = diff_campaign - diff_control

print(f&quot;\n서울 지역 변화: {diff_campaign:.2f}만원&quot;)
print(f&quot;부산 지역 변화: {diff_control:.2f}만원&quot;)
print(f&quot;DID 효과: {did_effect:.2f}만원&quot;)</code></pre><p><img src="https://velog.velcdn.com/images/jisukim_28/post/a9271257-597e-4274-bf24-8574447acb3a/image.png" alt=""></p>
<ul>
<li>서울 지역 변화량: 112.87−98.63=14.24만원</li>
<li>부산 지역 변화량: 99.75−94.79=4.96만원</li>
<li>이중차분 효과: (서울 변화)−(부산 변화)=14.24−4.96=9.28만원</li>
<li><blockquote>
<p>광고 캠페인 또는 마케팅 개입의 순수한 효과로 해석되는 부분이 9.28만원</p>
</blockquote>
</li>
</ul>
<p>*<em>즉, 외부 요인(계절, 전반적 시장 성장 등)을 통제한 순수한 마케팅 효과는 약 9.28만 원이라고 판단 *</em></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AB테스트 - SQL 실습 ]]></title>
            <link>https://velog.io/@jisukim_28/AB%ED%85%8C%EC%8A%A4%ED%8A%B8-SQL-%EC%8B%A4%EC%8A%B5</link>
            <guid>https://velog.io/@jisukim_28/AB%ED%85%8C%EC%8A%A4%ED%8A%B8-SQL-%EC%8B%A4%EC%8A%B5</guid>
            <pubDate>Mon, 14 Jul 2025 07:38:59 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>AB 테스트란?</strong></p>
</blockquote>
<ul>
<li><p>두 가지 버전(A와 B)을 비교하여 어떤 것이 더 효과적인지를 판단하는 실험 방법</p>
</li>
<li><p>예를 들어, 기존 버전에서는 &quot;지금 구매하세요!&quot;라는 광고 문구를 넣고 실험 버전에서는 &quot;오늘 한정 할인!&quot;이라는 광고 문구를 삽입한다. 두 가지 버전 중 어떤 문구에서 클릭률이 높을지 확인하는 것이 AB 테스트이다.</p>
</li>
</ul>
<blockquote>
<p>*<em>AB 테스트의 절차 *</em></p>
</blockquote>
<ol>
<li><p><strong>가설 수립</strong>: “오늘 한정 할인! 이라는 문구에서 클릭률이 높을 것이다.”</p>
</li>
<li><p><strong>테스트 설계</strong>: 사용자 집단을 무작위로 나누기</p>
</li>
<li><p><strong>실험 수행</strong>: 일정 기간 동안 데이터 수집</p>
</li>
<li><p><strong>분석</strong>: 통계적으로 유의미한 차이 있는지 확인</p>
</li>
<li><p><strong>결정</strong>: 승자 선택 → 적용</p>
</li>
</ol>
<blockquote>
<p><strong>A/B 테스트로 할 수 있는 분석</strong></p>
</blockquote>
<ol>
<li><strong>그룹 간 전환율 비교</strong></li>
</ol>
<ul>
<li>Control 그룹과 Treatment 그룹의 평균 전환율 차이를 비교한다.</li>
<li>B 그룹의 성과가 더 좋다면, 해당 변경을 정식 도입할 수 있다.</li>
</ul>
<ol start="2">
<li><strong>시간 흐름에 따른 변화 분석</strong></li>
</ol>
<ul>
<li>날짜별 전환율 추이나 적응 곡선을 확인한다.</li>
<li>A 그룹은 시간이 지나도 꾸준한 성과 유지 / 시간이 지나면서 B 그룹의 전환율이 점점 상승한다.</li>
</ul>
<ol start="3">
<li><strong>세그먼트 분석</strong></li>
</ol>
<ul>
<li>나이, 지역, 디바이스 종류 등 사용자 속성에 따른 실험 효과의 차이를 분석한다.</li>
<li>20대에겐 B가 더 효과적, 40대에겐 A가 더 나은 결과가 나온다.</li>
</ul>
<ol start="4">
<li><strong>이상치 및 데이터 정합성 확인</strong></li>
</ol>
<ul>
<li>데이터 오류나 이상치를 찾아낸다.</li>
<li>Control 그룹인데 신버전 페이지를 본 경우? / 특정 날짜에 전환율이 비정상적으로 급등한 경우?</li>
</ul>
<ol start="5">
<li><strong>통계적 유의성 검정</strong></li>
</ol>
<ul>
<li>실험 결과가 우연이 아닌지를 통계적으로 검증한다.</li>
<li>z-test: 전환율처럼 비율 비교에 사용</li>
<li>t-test: 체류 시간이나 구매액 등 평균값 비교에 사용</li>
</ul>
<blockquote>
<p><strong>A/B 테스트 설계 시 고려할 점</strong></p>
</blockquote>
<ol>
<li><p><strong>무작위 할당</strong></p>
<ul>
<li>실험군(Treatment)과 대조군(Control)에 랜덤하게 할당해야 한다.</li>
</ul>
</li>
<li><p><strong>통제 변수 설정</strong></p>
</li>
</ol>
<ul>
<li>실험 외적인 변수(시간대, 브라우저, 캠페인 등)가 결과에 영향을 주지 않도록 조건을 통일하거나 분석 시 통제 변수로 포함시킨다.</li>
</ul>
<ol start="3">
<li><strong>충분한 표본 크기 확보</strong></li>
</ol>
<ul>
<li>너무 적은 사용자로 실험하면 우연에 의한 결과일 가능성이 높다.</li>
</ul>
<ol start="4">
<li><strong>지표의 명확한 정의</strong></li>
</ol>
<ul>
<li>환율, 클릭률, 이탈률, 체류 시간 등 핵심 성과지표(KPI)를 실험 전에 명확히 정해둔다. </li>
</ul>
<ol start="5">
<li><strong>실험 기간 설정</strong></li>
</ol>
<ul>
<li>짧은 기간에는 특정 요일/시간대/이벤트의 영향을 받을 수 있어 대표성이 떨어질 수 있다. </li>
</ul>
<blockquote>
<p> <strong>A/B 테스트에서 통계적 유의미성을 도출하는 과정</strong></p>
</blockquote>
<ol>
<li><strong>귀무가설과 대립가설 수립</strong></li>
</ol>
<ul>
<li>귀무가설(H₀): A와 B 간에 차이가 없다.</li>
<li>대립가설(H₁): A와 B 간에 차이가 있다.</li>
</ul>
<ol start="2">
<li><strong>적절한 통계 검정 선택</strong></li>
</ol>
<ul>
<li>측정하려는 지표의 특성에 따라 적절한 검정을 선택한다.</li>
<li>전환율 비교: z-test / 평균값 비교: t-test</li>
</ul>
<ol start="3">
<li><strong>p-value 계산</strong></li>
</ol>
<ul>
<li>p-value는 “귀무가설이 맞다고 가정했을 때, 관측된 결과가 나타날 확률”을 의미한다. </li>
<li>일반적으로 p-value &lt; 0.05이면, 귀무가설을 기각하고 “차이가 있다”고 판단한다.</li>
</ul>
<ol start="4">
<li><strong>신뢰수준(Confidence Level) 설정</strong></li>
</ol>
<ul>
<li>보통 95% 신뢰수준을 사용한다. 오차 가능성이 5% 미만이라는 의미이다</li>
</ul>
<ol start="5">
<li><strong>효과 크기 (Effect Size)도 함께 고려</strong></li>
</ol>
<ul>
<li>효과크기는 두 그룹 간 차이의 크기를 나타내는 지표이다.</li>
<li>통계적으로 유의미한 차이(p &lt; 0.05)라도 실제로는 미미한 차이일 수 있다. (예: 샘플 수가 너무 많아서) 따라서, &quot;그 차이가 실제로 의미 있는 크기인가?&quot;도 함께 판단해야 한다.</li>
</ul>
<ol start="6">
<li><strong>파워 분석(Power Analysis)으로 검정력 확인 (사후 분석 시)</strong></li>
</ol>
<ul>
<li>실험에서 진짜 차이가 있을 때, 그걸 감지할 수 있는 확률</li>
<li>파워가 낮으면 → 실험 결과가 &quot;유의미하지 않다&quot;고 나왔어도 그건 “진짜 효과가 없어서”가 아니라 “검출할 능력이 부족해서” 일 수 있다. (예: 샘플 개수의 부족)</li>
<li>실험을 잘 설계하려면 얼마나 많은 샘플이 필요한지 미리 계산해야 한다. (사전 파워 분석)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[SQL 심화 - 마케팅 분석 ]]></title>
            <link>https://velog.io/@jisukim_28/SQL-%EC%8B%AC%ED%99%94-%EB%A7%88%EC%BC%80%ED%8C%85-%EB%B6%84%EC%84%9D</link>
            <guid>https://velog.io/@jisukim_28/SQL-%EC%8B%AC%ED%99%94-%EB%A7%88%EC%BC%80%ED%8C%85-%EB%B6%84%EC%84%9D</guid>
            <pubDate>Mon, 07 Jul 2025 11:57:20 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>PV, UV</strong></p>
</blockquote>
<ol>
<li>PV (Page View): 웹사이트의 특정 페이지가 사용자에게 열람된 횟수</li>
</ol>
<ul>
<li>페이지별 관심도 측정</li>
<li>사용자가 어떤 페이지에 머무는지 파악 가능</li>
</ul>
<ol start="2">
<li>UV (Unique Visitor): 웹사이트를 방문한 고유 사용자 수 </li>
</ol>
<ul>
<li>같은 사용자가 여러 번 방문해도 1명으로 카운트</li>
<li>실질적으로 몇 명의 고객이 내 사이트에 관심을 가졌는지 보여줌 </li>
</ul>
<ol start="3">
<li>UV/PV 증가 및 감소의 의미</li>
</ol>
<ul>
<li>UV, PV 모두 증가 (인기 상승)<ul>
<li>유지 + 강화 전략 필요 </li>
</ul>
</li>
<li>UV감소, PV 증가 (충성고객 중심)<ul>
<li>재유입 유도 + 핵심 사용자 강화</li>
</ul>
</li>
<li>UV증가, PV 감소 (대충보고 떠남)<ul>
<li>콘텐츠 품질/관심 유도 필요<ul>
<li>UV, PV 모두 감소 (관심 하락)</li>
</ul>
</li>
<li>전면적 점검 필요</li>
</ul>
</li>
</ul>
<blockquote>
<p><strong>ARPU와 ARPPU 구하기</strong></p>
</blockquote>
<ol>
<li>ARPU (Average Revenue Per User)</li>
</ol>
<ul>
<li>사용자당 평균 수익</li>
<li>전체 매출 / 전체 유저 수</li>
</ul>
<ol start="2">
<li>ARPPU (Average Revenue Per Paying User)</li>
</ol>
<ul>
<li>유료 결제 사용자당 평균 수익</li>
<li>전체 매출 / 유료 결제 사용자 수 </li>
</ul>
<pre><code>-- ARPU와 ARPPU 구하기
SELECT SUM(revenue) / SUM(user_id) AS ARPU,
SUM(revenue) / SUM(CASE WHEN revenue != 0 THEN user_id ELSE 0 END) AS ARPPU
FROM 테이블명 </code></pre><blockquote>
<p><strong>퍼널 분석</strong> </p>
</blockquote>
<ul>
<li>사용자 행동 흐름을 단계별로 추적해서 어디서 이탈하는지, 어디서 전환되는지 파악하는 방법
<img src="https://velog.velcdn.com/images/jisukim_28/post/5a8ea6ef-3e37-4db2-a557-7e6aef53d555/image.png" alt=""></li>
</ul>
<pre><code>WITH funnel_count AS(
  SELECT
    COUNT(DISTINCT CASE WHEN action=&#39;visit&#39; THEN user_id END) AS visit,
    COUNT(DISTINCT CASE WHEN action=&#39;signup&#39; THEN user_id END) AS signup,
    COUNT(DISTINCT CASE WHEN action=&#39;add_to_cart&#39; THEN user_id END) AS add_to_cart,
    COUNT(DISTINCT CASE WHEN action=&#39;purchase&#39; THEN user_id END) AS purchase
  FROM hardy-aleph-464902-v8.modulabs.funnel
)
SELECT visit,
       signup,
       add_to_cart,
       purchase,
       ROUND(signup/visit *100,2) AS SignupRate,
       ROUND(add_to_cart/visit *100,2) AS AddToCartRate,
       ROUND(purchase/visit *100,2) AS PurchaseRate
FROM funnel_count</code></pre><blockquote>
<p>*<em>리텐션 분석 *</em></p>
</blockquote>
<ul>
<li>내 서비스나 앱에 유입된 사용자가 일정 기간 후에도 얼마나 다시 돌아오는지를 측정</li>
<li>신규 유저 유입만 되고 바로 떠나면 성장 지속이 어려움 </li>
<li>유지율이 높아야 마케팅 비용이 효율적</li>
</ul>
<ol>
<li><p>Classic Retention</p>
<ul>
<li>특정 기준일에 다시 돌아오는 비율 </li>
<li>짧은 주기의 서비스(sns, 게임)에서 중요</li>
</ul>
</li>
<li><p>Rolling Retention</p>
<ul>
<li>마지막 방문 이후 한 번이라고 돌아오면 유지된 것으로 간주 </li>
<li>사용 빈도가 낮은 서비스 (쇼핑몰 등)</li>
</ul>
</li>
<li><p>Range Retention</p>
<ul>
<li>일정 기간 (설치 후 7~14일 사이) 안에 재방문한 비율 </li>
</ul>
</li>
</ol>
<blockquote>
<p> <strong>RFM 분석</strong></p>
</blockquote>
<ul>
<li><p>Recency: 고객이 마지막으로 구매한 시점</p>
</li>
<li><p>Frequency: 특정 기간 동안 몇 번 구매</p>
</li>
<li><p>Monetary: 총 구매 금액 </p>
</li>
<li><p>분석 절차</p>
</li>
</ul>
<p><strong>1. 데이터 준비</strong></p>
<p><strong>2. 각 지표 점수화</strong>
Recency: 최근일수록 점수가 높음 (5=최근 구매)
Frequency: 많이 구매할수록 점수가 높음
Monetary: 금액이 클수록 점수가 높음</p>
<p>*<em>3. RFM 점수를 조합해 고객을 여러 그룹으로 나눔 *</em>
R    F    M    세그먼트
5    5    5    VIP (가장 가치 높은 고객)
5    1    1    신규 고객
3    2    2    잠재 이탈 고객
1    1    1    이탈 고객</p>
<p><strong>4. 전략 수립</strong>
각 그룹에 맞는 액션 설계</p>
<p>VIP → 프리미엄 혜택, 우선 상담
잠재 이탈 고객 → 리마인드 이메일, 쿠폰 제공
신규 고객 → 온보딩 캠페인, 상품 추천
이탈 고객 → 재유입 유도 프로모션</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SQL 기초 문법 정리 (2)]]></title>
            <link>https://velog.io/@jisukim_28/SQL-%EA%B8%B0%EC%B4%88-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC-2</link>
            <guid>https://velog.io/@jisukim_28/SQL-%EA%B8%B0%EC%B4%88-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC-2</guid>
            <pubDate>Sun, 06 Jul 2025 06:47:47 GMT</pubDate>
            <description><![CDATA[<h4 id="예제문제">예제문제</h4>
<ul>
<li>&quot;ex4_member&quot;, &quot;ex4_review&quot; 라는 이름의 테이블에는 각각 회원에 대한 정보와, 회원이 남긴 리뷰에 대한 정보가 담겨있음</li>
<li>ex4_member 테이블과 ex4_review 테이블을 사용하여 리뷰를 가장 많이 남긴 회원의 리뷰를 조회</li>
<li>회원 이름, 리뷰 텍스트, 리뷰 작성일이 포함되어 있어야 하고 오름차순 정렬 </li>
</ul>
<h4 id="첫-번째-방식-with-구문-사용">첫 번째 방식 (WITH 구문 사용)</h4>
<pre><code># 각 멤버 별로 몇 번의 리뷰를 남겼는지 확인하기, 상위 1명만 출력 
WITH ReviewCounts AS (
    SELECT MEMBER_ID, COUNT(MEMBER_ID) AS membercount
    FROM hardy-aleph-464902-v8.modulabs.ex4_review
    GROUP BY MEMBER_ID
    ORDER BY membercount DESC
    LIMIT 1
)
# r 데이터와 m 데이터 JOIN
# 그 데이터를 ReviewCounts와 JOIN. 가장 많은 리뷰를 남긴 KEVIN만 남음
# 리뷰 작성일을 기준으로 오름차순 정렬 
SELECT MEMBER_NAME, REVIEW_TEXT, REVIEW_DATE
FROM hardy-aleph-464902-v8.modulabs.ex4_review AS r
JOIN hardy-aleph-464902-v8.modulabs.ex4_member AS m
ON r.MEMBER_ID = m.MEMBER_ID
JOIN ReviewCounts AS rc
ON r.MEMBER_ID = rc.MEMBER_ID
ORDER BY r.REVIEW_DATE</code></pre><h4 id="두-번째-방식-서브쿼리-방식">두 번째 방식 (서브쿼리 방식)</h4>
<pre><code>SELECT MEMBER_NAME,REVIEW_TEXT, REVIEW_DATE
FROM hardy-aleph-464902-v8.modulabs.ex4_review AS r
JOIN hardy-aleph-464902-v8.modulabs.ex4_member AS m
ON r.MEMBER_ID = m.MEMBER_ID
JOIN (
  SELECT MEMBER_ID, COUNT(MEMBER_ID) AS membercount
  FROM hardy-aleph-464902-v8.modulabs.ex4_member 
  GROUP BY MEMBER_ID
  ORDER BY membercount DESC
  LIMIT 1
) AS rc
ON r.MEMBER_ID = rc.MEMBER_ID
ORDER BY r.REVIEW_DATE</code></pre><blockquote>
<p>*<em>WITH 구문과 서브쿼리 방식의 차이 *</em></p>
</blockquote>
<ul>
<li>공통점: 임시 테이블의 역할</li>
<li>차이점</li>
</ul>
<ol>
<li><strong>WITH 구문</strong></li>
</ol>
<ul>
<li>쿼리 맨 앞에 WITH절 선언 </li>
<li>여러 번 재사용 가능 </li>
<li>중간 데이터를 여러 번 사용해야 할 때 사용 </li>
</ul>
<ol start="2">
<li>*<em>서브쿼리 방식 *</em></li>
</ol>
<ul>
<li>FROM / JOIN 안에 바로 SELECT문</li>
<li>1회성 </li>
<li>간단히 한번만 필요할 때 사용 </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[SQL 기초 문법 정리 (1)]]></title>
            <link>https://velog.io/@jisukim_28/SQL-%EA%B8%B0%EC%B4%88-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC-1</link>
            <guid>https://velog.io/@jisukim_28/SQL-%EA%B8%B0%EC%B4%88-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC-1</guid>
            <pubDate>Sun, 06 Jul 2025 06:25:19 GMT</pubDate>
            <description><![CDATA[<h4 id="고객-테이블-데이터-전체-조회">고객 테이블 데이터 전체 조회</h4>
<pre><code>SELECT *
FROM customers</code></pre><h4 id="고객번호-이름-가입일자-조회">고객번호, 이름, 가입일자 조회</h4>
<pre><code>SELECT customerId, customerName, signupDate
FROM customers</code></pre><h4 id="탈퇴하지-않고-2023년-이후-가입한-고객-정보-조회">탈퇴하지 않고 2023년 이후 가입한 고객 정보 조회</h4>
<pre><code>SELECT customerId, customerName, status
FROM customers
WHERE status != &#39;Withdrawn&#39;;
AND signupDate &gt;= &#39;2023-01-01&#39;;</code></pre><h4 id="가격-30000원-이하이거나-등록일이-2023년-3월-1일-이후인-상품-조회">가격 30,000원 이하이거나 등록일이 2023년 3월 1일 이후인 상품 조회</h4>
<pre><code>SELECT productId, productName, registrationDate, price
FROM products
WHERE price &lt;= 30000
OR registrationDate &gt;= &#39;2023-03-01&#39;</code></pre><h4 id="상태status가-판매중on-sale-품절out-of-stock인-상품-조회-in-사용">상태(status)가 판매중(On Sale), 품절(Out of Stock)인 상품 조회 (IN 사용)</h4>
<pre><code>SELECT productId, productName, status
FROM products
WHERE status IN (&#39;On Sale&#39;, &#39;Out of Stock&#39;)</code></pre><h4 id="상태status가-판매중-품절이-아닌-상품-조회-in-사용">상태(status)가 판매중, 품절이 아닌 상품 조회 (IN 사용)</h4>
<pre><code>SELECT productId, productName, status
FROM products
WHERE status NOT IN (&#39;On Sale&#39;, &#39;Out of Stock&#39;);</code></pre><h4 id="입사일자hiredate가-null이고-상태status가-재직중active인-직원-조회">입사일자(hireDate)가 NULL이고 상태(status)가 재직중(Active)인 직원 조회</h4>
<pre><code>SELECT employeeId, employeeName, status, department
FROM employees
WHERE hireDate IS NULL
AND status = &#39;Active&#39;</code></pre><h4 id="입사일자가-2022년-4월-1일--4월-20일인-직원의-급여salary를-2로-나눈-값-확인">입사일자가 2022년 4월 1일 ~ 4월 20일인 직원의 급여(salary)를 2로 나눈 값 확인</h4>
<pre><code>SELECT employeeId, salary, salary / 2 AS halfSalary
FROM employees
WHERE hireDate BETWEEN &#39;2022-04-01&#39; AND &#39;2022-04-20&#39;;</code></pre><h4 id="코멘트comments가-special로-시작하는-상품-코멘트에-limited-단어를-포함하는-상품-조회">코멘트(comments)가 &#39;Special&#39;로 시작하는 상품, 코멘트에 &#39;limited&#39; 단어를 포함하는 상품 조회</h4>
<pre><code>SELECT productId, comments
FROM products
WHERE comments LIKE &#39;Special%&#39;
AND comments LIKE &#39;%limited%&#39;</code></pre><h4 id="가격을-오름차순-정렬하고-별칭-부여">가격을 오름차순 정렬하고 별칭 부여</h4>
<pre><code>SELECT productId AS 상품번호, price AS 가격
FROM products
ORDER BY price ASC</code></pre><h4 id="상품-상태의-중복-제거">상품 상태의 중복 제거</h4>
<pre><code>SELECT DISTINCT status AS 상태
FROM products</code></pre><h4 id="60만원-기준으로-가격에-대한-조건문-iif-함수-사용">60만원 기준으로 가격에 대한 조건문 (IIF 함수 사용)</h4>
<pre><code>SELECT productId, price, IIF(price &gt;= 600000, &#39;High&#39;, &#39;Low&#39;) AS &quot;60만원 기준&quot;
FROM products</code></pre><h4 id="주문일자를-기준으로-연도를-분리하여-표시">주문일자를 기준으로 연도를 분리하여 표시</h4>
<pre><code>SELECT
    saleId,
    saleDate,
    CASE WHEN YEAR(saleDate) = 2022 THEN &#39;2022년&#39;
         WHEN YEAR(saleDate) = 2022 THEN &#39;2023년&#39;
         ELSE &#39;기타&#39;
    END AS 판매연도
FROM sales</code></pre><h4 id="국가별-판매건수-집계">국가별 판매건수 집계</h4>
<pre><code>SELECT c.country, COUNT(s.saleId) AS 판매건수
FROM sales s
JOIN clients c
ON s.clientId = c.clientId
GROUP BY c.country</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 - Feature Engineering / z-score]]></title>
            <link>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-Feature-Engineering-z-score</link>
            <guid>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-Feature-Engineering-z-score</guid>
            <pubDate>Mon, 23 Jun 2025 10:07:19 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>*<em>Z-Score(표준점수): (관측값 - 데이터의 평균) / 표준편차 *</em></p>
</blockquote>
<ul>
<li>통계적으로 관측값이 평균에서 얼마나 떨어져 있는지를 표준편차 기준으로 나타내는 지표</li>
<li>이를 통해 데이터의 상대적인 위치를 파악하고 이상값을 탐지할 수 있음 </li>
</ul>
<h3 id="데이터-탐색">데이터 탐색</h3>
<pre><code># 컬럼명과 자료형 확인 
cc_df.info()

# 출력:
&lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;
RangeIndex: 491134 entries, 0 to 491133
Data columns (total 22 columns):
 #   Column                 Non-Null Count   Dtype  
---  ------                 --------------   -----  
 0   trans_date_trans_time  491134 non-null  object 
 1   cc_num                 491134 non-null  int64  
 2   merchant               491134 non-null  object 
 3   category               491134 non-null  object 
 4   amt                    491134 non-null  float64
 5   first                  491134 non-null  object 
 6   last                   491134 non-null  object 
 7   gender                 491134 non-null  object 
 8   street                 491134 non-null  object 
 9   city                   491134 non-null  object 
 10  state                  491134 non-null  object 
 11  zip                    491134 non-null  int64  
 12  lat                    491134 non-null  float64
 13  long                   491134 non-null  float64
 14  city_pop               491134 non-null  int64  
 15  job                    491134 non-null  object 
 16  dob                    491134 non-null  object 
 17  trans_num              491134 non-null  object 
 18  unix_time              491134 non-null  int64  
 19  merch_lat              491134 non-null  float64
 20  merch_long             491134 non-null  float64
 21  is_fraud               491134 non-null  int64  </code></pre><pre><code># cc_num 컬럼의 값마다 amt의 평균, 표준편차를 계산하여 amt_info에 저장
# cc_num: account number
# amt: amount
amt_info = cc_df.groupby(&#39;cc_num)[&#39;amt&#39;].agg([&#39;mean&#39;,&#39;std&#39;]).reset_index()

# cc_num 컬럼을 기준으로 cc_df와 amt_info 데이터 merge
cc_df = cc_df.merge(amt_info, on=&#39;cc_num&#39;, how=&#39;left&#39;)

# z-score 계산
cc_df[&#39;amt_z&#39;] = (cc_df[&#39;amt&#39;] - cc_df[&#39;mean&#39;]) / cc_df[&#39;std&#39;]</code></pre><ul>
<li>사기 거래 컬럼 (is_fraud)를 살펴봤을 때 사기 거래 기록이 있는 컬럼에서 z-score이 크게 나온 것을 알 수 있었음</li>
<li>즉, 정상 거래들과는 다른 패턴을 보이며 이상치임을 알 수 있음</li>
</ul>
<pre><code># category와 cc_num 컬럼의 값마다가 mean, std 계산
cat_info = cc_df.groupby([&#39;cc_num&#39;, &#39;category&#39;])[&#39;amt&#39;].agg([&#39;mean&#39;,&#39;std&#39;]).reset_index()

# cc_df 데이터와 cat_info 데이터 합치기 
cc_df = cc_df.merge(cat_info, on=[&#39;cc_num&#39;,&#39;category&#39;],how=&#39;left&#39;)

# 결제금액의 z-score 계산하기
cc_df[&#39;cat_amt_z&#39;] = (cc_df[&#39;amt&#39;] - cc_df[&#39;mean&#39;]) / cc_df[&#39;std&#39;]</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[코드 모듈화 & 패키징을 통한 데이터 전처리 효율화]]></title>
            <link>https://velog.io/@jisukim_28/%EC%BD%94%EB%93%9C-%EB%AA%A8%EB%93%88%ED%99%94-%ED%8C%A8%ED%82%A4%EC%A7%95%EC%9D%84-%ED%86%B5%ED%95%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EC%B2%98%EB%A6%AC-%ED%9A%A8%EC%9C%A8%ED%99%94</link>
            <guid>https://velog.io/@jisukim_28/%EC%BD%94%EB%93%9C-%EB%AA%A8%EB%93%88%ED%99%94-%ED%8C%A8%ED%82%A4%EC%A7%95%EC%9D%84-%ED%86%B5%ED%95%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EC%B2%98%EB%A6%AC-%ED%9A%A8%EC%9C%A8%ED%99%94</guid>
            <pubDate>Fri, 20 Jun 2025 08:28:24 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>✅ 코드 모듈화 &amp; 패키징을 통한 데이터 전처리 효율화</strong></p>
</blockquote>
<h3 id="왜-필요할까"><strong>왜 필요할까?</strong></h3>
<p>반복되는 전처리 코드를 매번 복사/붙여넣기 하지 말고,
함수화하고 모듈화해서 필요할 때 불러오면 훨씬 효율적이고 깔끔함</p>
<p>이를 위해 총 3개의 파일이 필요:</p>
<ol>
<li>func.py – 전처리 함수를 정의한 파일</li>
<li>col_rename.py – func.py에서 만든 함수를 저장할 .py 스크립트 파일</li>
<li>test.py – 실제로 함수를 import해서 테스트하는 파일</li>
</ol>
<h3 id="funcpy---전처리-함수-정의">func.py - 전처리 함수 정의</h3>
<pre><code>def col_rename(dating_df):
    new_cols = []
    for i in dating_df.columns:
      if i.startswith(&#39;pref_o&#39;):
        i = i.replace(&#39;pref_o&#39;,&#39;o_important&#39;)
      elif i.endswith(&#39;_o&#39;):
        i = &#39;o_score_&#39; + i.replace(&#39;_o&#39;,&#39;&#39;)
      elif i.endswith (&#39;important&#39;):
        i = &#39;i_important_&#39; + i.replace(&#39;_important&#39;,&#39;&#39;)
      elif i.endswith(&#39;_partner&#39;):
        i = &#39;i_score_&#39; + i.replace(&#39;_partner&#39;,&#39;&#39;)
      new_cols.append(i)
     dating_df.columns = new_cols
     return dating_df

script = &quot;&quot;&quot;
def col_rename(x):
    new_cols = []
    for i in dating_df.columns:
      if i.startswith(&#39;pref_o&#39;):
        i = i.replace(&#39;pref_o&#39;,&#39;o_important&#39;)
      elif i.endswith(&#39;_o&#39;):
        i = &#39;o_score_&#39; + i.replace(&#39;_o&#39;,&#39;&#39;)
      elif i.endswith (&#39;important&#39;):
        i = &#39;i_important_&#39; + i.replace(&#39;_important&#39;,&#39;&#39;)
      elif i.endswith(&#39;_partner&#39;):
        i = &#39;i_score_&#39; + i.replace(&#39;_partner&#39;,&#39;&#39;)
      new_cols.append(i)
     dating_df.columns = new_cols
     return dating_df
&quot;&quot;&quot;

filename = &quot;./src/col_rename.py&quot;

with open(file, &#39;w&#39;) as file:
    file.write(script)

# 결과: ./src/col_rename.py 파일이 생성됨 </code></pre><h3 id="testpy---실제-적용-테스트">test.py - 실제 적용 테스트</h3>
<pre><code>import sys
import pandas as pd

# 모듈이 들어 있는 폴더를 경로에 추가
sys.path.append(&#39;./src&#39;)

# 데이터 로드
dating_df = pd.read_csv(&#39;new_dating.csv&#39;)

# 함수 불러와 적용
from col_rename import col_rename
dating_df = col_rename(dating_df)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[분류 알고리즘 - KNN / SVM / Decision Tree ]]></title>
            <link>https://velog.io/@jisukim_28/%EB%B6%84%EB%A5%98-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-KNN-SVM-Decision-Tree</link>
            <guid>https://velog.io/@jisukim_28/%EB%B6%84%EB%A5%98-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-KNN-SVM-Decision-Tree</guid>
            <pubDate>Thu, 19 Jun 2025 11:20:22 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>분류 알고리즘 (Classification)</strong></p>
</blockquote>
<p>설명변수를 바탕으로 목표 변수가 가질 수 있는 <strong>여러 범주 중 하나를 예측하는 지도학습</strong>의 대표적인 방법 </p>
<h3 id="--knn-k-nearest-neighbors">- KNN (K-Nearest Neighbors)</h3>
<p><strong>핵심 개념</strong>: 주변의 &#39;가까운&#39; 데이터를 기준으로 분류
<strong>방식</strong>:</p>
<ul>
<li>새로운 데이터 포인트가 들어왔을 때, 학습 데이터 중에서 가장 가까운 K개의 데이터를 찾음</li>
<li>이 K개 중 다수의 클래스가 새로운 데이터의 클래스가 됨 -&gt; 다수결 튜표 방식 </li>
</ul>
<p><strong>특징</strong></p>
<ul>
<li>장점: 구현이 간단, 이상치에 비교적 강함, 이상치가 있어도 그 값에 크게 영향을 받지 않음 </li>
<li>단점: 데이터가 많거나 차원이 높아지면 성능 저하 </li>
</ul>
<pre><code># 속성 변수 선택
X = ndf[[&#39;pclass&#39;,&#39;age&#39;,&#39;sibsp&#39;,&#39;parch&#39;,&#39;female&#39;,&#39;male&#39;,&#39;town_C&#39;,&#39;town_Q&#39;,&#39;town_S&#39;]] # 설명변수 X
y = ndf[[&#39;survived&#39;]] # 예측 변수 y

# 데이터 전처리 도구들을 모아둔 모듈 preprocessing을 불러옴
# StandardScaler: 표준화(standardization)를 수행하는 도구
# 왜 표준화를 할까? K-Means, SVM, KNN, PCA 같은 알고리즘은 거리 기반 계산을 하기 때문에, 특성들의 스케일이 다르면 성능이 나빠질 수 있음
# fit(X): X의 평균과 표준편차를 계산
# transform(X): 위 통계를 사용해서 실제로 데이터를 변환

from sklearn import preprocessing
X = preprocessing.StandardScaler().fit(X).transform(X)

# train data와 test data를 7:3으로 구분
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=10)

print(&#39;train data 개수:&#39;, X_train.shape)
print(&#39;test data 개수:&#39;, X_test.shape)

# sklearn 라이브러리에서 KNN 분류 모형 가져오기
from sklearn.neighbors import KNeighborsClassifier

# 모형 객체 생성 (k=5로 설정)
# 가장 가까운 이웃 5개를 사용하겠다. 보통 k는 홀수로 지정. 짝수로 지정할 경우 동점이 될 수 있음 
knn = KNeighborsClassifier(n_neighbors=5)

# train data를 가지고 모형 학습
knn.fit(X_train, y_train)

# test data를 가지고 y_hat 예측(분류)
y_hat = knn.predict(X_test) # y_hat: 예측된 값 

print(y_hat[0:10]) # 예측된 값 10개 
print(y_test.values[0:10]) # 실제 정답 10개 

# 모형 성능 평가 - Confusion Matrix 계산
from sklearn import metrics
knn_matrix = metrics.confusion_matrix(y_test, y_hat)
print(knn_matrix)

# Confusion Matrix 시각화
# annot=True: 각 셀에 숫자값(정수)을 표시
# fmt=&#39;d&#39;: 포맷 정수로 입력 
plt.figure(figsize=(8, 6))
sns.heatmap(knn_matrix, annot=True, fmt=&#39;d&#39;, cmap=&#39;Blues&#39;,
            xticklabels=[&#39;Negative&#39;, &#39;Positive&#39;],
            yticklabels=[&#39;Negative&#39;, &#39;Positive&#39;])
plt.title(&#39;Confusion Matrix&#39;)
plt.ylabel(&#39;Actual label&#39;)
plt.xlabel(&#39;Predicted label&#39;)
plt.show()

# 모형 성능 평가 - 평가지표 계산
knn_report = metrics.classification_report(y_test,y_hat)
print(knn_report)</code></pre><p><img src="https://velog.velcdn.com/images/jisukim_28/post/b4dd5e05-a466-49b6-bba9-dcab26bc8ed5/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/jisukim_28/post/cfd7580d-2939-475b-8b4b-9bded79698e1/image.png" alt=""></p>
<h3 id="--svm-support-vector-machine">- SVM (Support Vector Machine)</h3>
<p><strong>핵심 개념</strong>: 클래스 간 최대한 margin을 가능한 한 넓게 벌려서 데이터를 나누는 방법 -&gt; Test data가 그 경계선의 어느 쪽에 있는지 분류하는 알고리즘 
<strong>방식</strong></p>
<ul>
<li>데이터를 선형 또는 비선형적으로 분리할 수 있는 초평면 찾음</li>
<li>가장 가까운 데이터 포인트와의 거리를 최대화하도록 설계</li>
</ul>
<p><strong>특징</strong></p>
<ul>
<li>장점: 고차원 데이터에 강함 -&gt; 텍스트 분류 (뉴스, 이메일) 등에 강함 </li>
<li>단점: 대용량 데이터에 느림</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jisukim_28/post/1f223928-7a80-4793-8263-4d9f70a7a050/image.png" alt="">
<img src="https://velog.velcdn.com/images/jisukim_28/post/46e14c00-0282-46b2-a9f6-36c0916d7783/image.png" alt=""></p>
<h3 id="--decision-tree-의사결정나무">- Decision Tree (의사결정나무)</h3>
<p><strong>핵심 개념</strong>: 데이터 특징을 기준으로 질문을 반복하며 나무 구조로 분기
<strong>방식</strong></p>
<ul>
<li>각 노드에서 특정 feature을 기준으로 데이터 분할</li>
<li>잎 노드에 최종 클래스 값이 위치</li>
</ul>
<p><strong>특징</strong></p>
<ul>
<li>장점: 비정형 데이터에서 사용 가능, 전처리 적음</li>
<li>단점: 분할을 너무 세세하게 하기 때문에 과적합 우려 </li>
</ul>
<pre><code># 특성 중요도 계산
features = pd.DataFrame(tree_model.feature_importances_,
                        index=train_features,
                        columns=[&#39;Importance&#39;])
features = features.sort_values(by=&#39;Importance&#39;, ascending=False)
features</code></pre><p><img src="https://velog.velcdn.com/images/jisukim_28/post/07698661-c522-4a17-a800-163900d3ac63/image.png" alt=""></p>
<blockquote>
<p>*<em>Confusion Matrix와 모델 성능 평가 *</em></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/jisukim_28/post/a19438f9-e689-41f1-95ba-8f91fd265d1d/image.png" alt=""></p>
<p>False Positive (FP) = 24: 실제로는 Negative인데 Positive로 잘못 예측 -&gt;     잘못된 경고/오탐
False Negative (FN) = 26: 실제로는 Positive인데 Negative로 잘못 예측 -&gt; 놓친 탐지/누락</p>
<p><img src="https://velog.velcdn.com/images/jisukim_28/post/fcb1be41-2b12-4b98-8c4f-c92a9f0f7313/image.png" alt="">
📌 <strong>Precision (정밀도)</strong>
양성이라고 예측한 것 중 실제로 양성인 비율
클래스 0: 0.79 → 예측한 Negative 중 79%가 실제로 Negative
클래스 1: 0.70 → 예측한 Positive 중 70%가 실제로 Positive</p>
<p>📌 <strong>Recall (재현율)</strong>
실제 양성 중에서 모델이 양성으로 잘 맞춘 비율
클래스 0: 0.80 → 실제 Negative 중 80%를 정확히 Negative로 예측
클래스 1: 0.68 → 실제 Positive 중 68%만을 Positive로 예측 (False Negative 존재)</p>
<h4 id="따라서">따라서,</h4>
<p>FN 비용이 큰 문제라면 → Recall 향상 필요
FP 비용이 큰 문제라면 → Precision 향상 필요</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 - 선형회귀분석 ]]></title>
            <link>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%84%A0%ED%98%95%ED%9A%8C%EA%B7%80%EB%B6%84%EC%84%9D</link>
            <guid>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%84%A0%ED%98%95%ED%9A%8C%EA%B7%80%EB%B6%84%EC%84%9D</guid>
            <pubDate>Wed, 18 Jun 2025 08:13:50 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>선형회귀의 정의</strong></p>
</blockquote>
<ul>
<li><p>입력 변수(독립 변수)와 출력 변수(종속 변수) 사이의 선형적인 관계를 모델링하는 기법</p>
</li>
<li><p>즉, <strong>데이터를 가장 잘 설명하는 직선</strong>을 찾아내는 것</p>
</li>
<li><p>광고비, 계절성, 요일 등의 데이터를 바탕으로 매출을 예측 / 수업 출석률, 과제 점수, 시험 점수를 이용해 최종 학점을 예측 / 키, 나이, 식습관 정보를 바탕으로 예상 몸무게 예측 등의 상황에서 선형회귀분석이 사용될 수 있음 </p>
</li>
</ul>
<blockquote>
<p><strong>수학적 표현</strong></p>
</blockquote>
<p>y=wx+b</p>
<ul>
<li>y: 예측 값 (종속 변수)</li>
<li>x: 입력 값 (독립 변수)</li>
<li>w: 기울기 (slope)</li>
<li>b: 절편 (bias 또는 y절편)</li>
<li>여기서 w와 b는 학습을 통해 결정되는 파라미터</li>
</ul>
<blockquote>
<p><strong>훈련/검증 데이터 분할</strong></p>
</blockquote>
<pre><code># 속성(변수) 선택
X=ndf[[&#39;weight&#39;]] # 독립변수
Y=ndf[[&#39;mpg&#39;]] # 종속변수

# train data와 test data로 구분 (7:3 비율)
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X,Y,test_size=0.3,random_state=10)
print(&#39;train data 개수:&#39;, len(X_train))
print(&#39;train data 개수:&#39;, len(X_test))</code></pre><blockquote>
<p><strong>모델 학습 및 검증</strong></p>
</blockquote>
<pre><code># sklearn 라이브러리에서 선형회귀분석 모듈 가져오기
from sklearn.linear_model import LinearRegression

# 단순회귀번석 모델 객체 생성
lr = LinearRegression()

# train data를 가지고 모델 학습
lr.fit(X_train, Y_train) # 학습에 사용되는 입력 데이터, 출력 데이터 

# 학습을 마친 모델에 test data를 적용하여 결정계수 계산
r_square = lr.score(X_test, Y_test)
print(&#39;결정계수:&#39;, r_square)</code></pre><p>결정계수: 모델이 전체 데이터의 변동성을 얼마나 잘 설명하는가? 를 나타내는 수치
이때 R² = 0.85 라면, 85%의 연비 변화를 자동차 무게로 설명할 수 있다는 뜻</p>
<pre><code># 모델에 test data 데이터를 입력하여 예측한 값 y_hat을 실제 y와 비교
y_hat = lr.predict(X_test) # 학습된 모델 lr이 X_test를 보고 예측한 종속변수 

# 오차 계산
test_preds = pd.DataFrame(Y_test)
test_preds.columns = [&#39;Y_test&#39;]
test_preds[&#39;y_hat&#39;] = y_hat
# 실제값(Y_test)과 예측값(y_hat)을 비교
test_preds[&#39;squared_error&#39;] = (test_preds[&#39;y_hat&#39;] - test_preds[&#39;Y_test&#39;]) ** 2
test_preds</code></pre><pre><code># 오차 분석
fig, axes = plt.subplots(1,2, figsize=(10,5)) # 1행 2열 구조 
sns.regplot(x=&#39;Y_test&#39;, y=&#39;y_hat&#39;, data=test_preds, ax=axes[0]);
# 그래프가 왼쪽에 뾰족하게 치우쳐 있으면 → 예측이 전반적으로 정확하다는 뜻
# 커널 밀도 추정을 이용해 데이터 분포를 부드럽게 표현
sns.kdeplot(x=&#39;squared_error&#39;, data=test_preds, ax=axes[1]);</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 - 판다스 데이터 클리닝 / 이상치 탐색 및 처리 / 중복데이터 / 텍스트 처리 ]]></title>
            <link>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%ED%8C%90%EB%8B%A4%EC%8A%A4-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%81%B4%EB%A6%AC%EB%8B%9D-%EC%9D%B4%EC%83%81%EC%B9%98-%ED%83%90%EC%83%89-%EB%B0%8F-%EC%B2%98%EB%A6%AC-%EC%A4%91%EB%B3%B5%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%ED%8C%90%EB%8B%A4%EC%8A%A4-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%81%B4%EB%A6%AC%EB%8B%9D-%EC%9D%B4%EC%83%81%EC%B9%98-%ED%83%90%EC%83%89-%EB%B0%8F-%EC%B2%98%EB%A6%AC-%EC%A4%91%EB%B3%B5%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Tue, 17 Jun 2025 06:49:20 GMT</pubDate>
            <description><![CDATA[<h3 id="데이터-정보-확인하기">데이터 정보 확인하기</h3>
<pre><code># 앞의 10줄만 입력
data.head()
# 뒤의 10줄만 입력 
data.tail()

# 데이터 정보 확인
data.info()
# 데이터의 통계적 요약 (object 형태는 제외)
data.describe()

# series를 강제로 DataFrame으로 만들어야 할 때
pd.DataFrame(data[&#39;Name&#39;])</code></pre><h3 id="데이터-클리닝">데이터 클리닝</h3>
<pre><code># Name 컬럼을 제거
# inplace=True: 기존의 데이터 대체 
data.drop(&#39;Name&#39;, axis=1, inplace=True)

# 2 인덱스의 행 지우기
data.drop(2, axis=0)

# 두 개의 컬럼을 동시에 지우기
data.drop([&#39;Pcalss&#39;,&#39;Age&#39;]), axis=1)

# 특정 행 불러오기
data.loc[[4,5,6]]

# 결측치가 있는 열 확인
data.insa().sum()

# 특정 컬럼의 결측치 확인
data[&#39;Age&#39;].isna()

# 결측치 True에 해당하는 인덱스만 출력
age_na_index = data[data[&#39;Age&#39;].isna()].index

# 특정 컬럼의 결측치 제거
data.drop(subset = [&#39;Embarked&#39;])

# 평균값으로 Age의 결측치를 채움
data[&#39;Age&#39;].mean()
data[&#39;Age&#39;] = data[&#39;Age&#39;].fillna(data[&#39;Age&#39;].mean())</code></pre><h3 id="이상치-탐지-및-처리-outlier">이상치 탐지 및 처리 (Outlier)</h3>
<pre><code> # 나이 데이터 오름차순/내림차순 정리
 data[&#39;Age&#39;].sort_values()
 data[&#39;Age&#39;].sort_values(ascending=False)

 # 이상치: 나이 중 100보다 큰 값
 data = data[data[&#39;Age&#39;] &lt;= 100]

 # 80보다 큰 나이는 80으로 대체, 그렇지 않으면 원래값 (함수 사용)
 def age_func(x):
     if x &gt; 80:
        return 80
    else:
        return x
 age_func(77)
 # Age 컬럼에 age_func 함수 적용
 data[&#39;Age&#39;].apply(age_func)

 # lambda 함수 사용
 data[&#39;Age&#39;].apply(lambda x : 70 if x &gt; 70 else x)</code></pre><h3 id="중복-데이터-처리-및-데이터-형태-반환처리">중복 데이터 처리 및 데이터 형태 반환처리</h3>
<pre><code># 중복 데이터 추출
data[data.duplicated()]

# 중복 데이터 삭제 
data = data.drop_duplicates()

# Gendr 열 이름 변경
data.rename({&#39;Gendr&#39;:&#39;Gender&#39;}, axis=1)

# replace를 활용해 값 바꾸기
data[&#39;Embarked&#39;].replace({&#39;S&#39;:&#39;South&#39;, &#39;C&#39;:&#39;Chernourg&#39;, &#39;Q&#39;:&#39;Queenstown&#39;})

# map: replace와 동일한 기능을 수행하지만 series에만 적용 가능
data[&#39;Embarked&#39;].map({&#39;S&#39;:&#39;South&#39;,&#39;C&#39;:&#39;Chernourg&#39;,&#39;Q&#39;:&#39;Queenstown&#39;})</code></pre><h3 id="텍스트-처리">텍스트 처리</h3>
<pre><code># 인덱싱을 활용해 특정 문자열 추출
sample_txt[0]
# 0이상 3 미만
sample_txt[0:3]
sampe_txt[:3]
sample_txt[4:]
# 뒤에서부터 추출
sample_txt[-1]

# 대문자를 소문자로 변경 
sample_txt.lower()
# 소문자를 대문자로 변경 
sample_txt.lower().upper()

# 문자열 띄어쓰기 기준으로 쪼개기, 리스트 형태로 반환
sample_txt.split()
# / 기준으로 쪼개기
sample_txt.split(&#39;/&#39;)

# 앞에 띄어쓰기 들어간 예시
new_txt = &#39; 안녕 하세요 &#39;
# 앞의 띄어쓰기 없애기, 중간의 띄어쓰기는 그대로 유지 
new_txt.strip()
# Ticket 컬럼의 문자열에 대한 인덱싱 후 추출
data[&#39;Ticket&#39;].str[-5:]
# Ticket 컬럼의 문자열을 분할 후 그 결과를 여러 컬럼에 나눠줌
data[&#39;Ticket&#39;].str.split(expand=True)
# # Ticket 값들을 띄어쓰기 기준으로 분할 후 마지막 것들만 가져옴
data[&#39;New Ticket&#39;] = data[&#39;Ticket&#39;].str.split().apply(lambda x : x[-1])

# 열의 데이터가 숫자인지 문자인지 확인
# ~을 사용하면 True/False 반대로 확인
data[data[&#39;new_ticket&#39;].str.isdigit()]
# data 타입을 &#39;int&#39;로 바꿔줌
data[&#39;new_ticket&#39;].astype(&#39;int&#39;)
# to_numeric을 사용해 int로 변환
data[&#39;new_ticket&#39;] = pd.to_numerice(data[&#39;new_ticket&#39;])</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 - 결측치, 이상치 / 그룹화 / 피벗테이블 / 원핫인코딩 ]]></title>
            <link>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EA%B2%B0%EC%B8%A1%EC%B9%98-%EC%9D%B4%EC%83%81%EC%B9%98-%EA%B7%B8%EB%A3%B9%ED%99%94-%ED%94%BC%EB%B2%97%ED%85%8C%EC%9D%B4%EB%B8%94-%EC%9B%90%ED%95%AB%EC%9D%B8%EC%BD%94%EB%94%A9</link>
            <guid>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EA%B2%B0%EC%B8%A1%EC%B9%98-%EC%9D%B4%EC%83%81%EC%B9%98-%EA%B7%B8%EB%A3%B9%ED%99%94-%ED%94%BC%EB%B2%97%ED%85%8C%EC%9D%B4%EB%B8%94-%EC%9B%90%ED%95%AB%EC%9D%B8%EC%BD%94%EB%94%A9</guid>
            <pubDate>Mon, 16 Jun 2025 10:29:41 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>** 결측치, 이상치 처리 **</p>
</blockquote>
<pre><code># CPI 컬럼 object -&gt; float으로 바꾸기
salary_df[&#39;CPI&#39;] = pd.to_numberic(salary[&#39;CPI&#39;]

# 결측치 확인
salary_df.isna().sum()

# Age의 결측치 확인
salary_df[salary_df[&#39;Age&#39;].isna()]</code></pre><p>결측치가 있는 행을 출력할 수 있음 
<img src="https://velog.velcdn.com/images/jisukim_28/post/5a1a252e-69f1-44b0-ba5f-05eb2c9b2336/image.png" alt=""></p>
<pre><code># 결측치가 있는 행은 지우기 
salary_df[&#39;Age&#39;] = salary[&#39;Age&#39;].dropna()</code></pre><p>Years of Experience 컬럼에서 -1 이상치 발견 </p>
<pre><code># Years of Experience가 -1이 아닌 행들만 salary_df 에 넣어주기 
salary_df = salary_df[salary_df[&#39;Years of Experience&#39;] != -1]

# 오름차순 정렬
salary_df[&#39;Years of Experience&#39;].sort_values()

# 나이보다 경력이 많은 경우 제외
# ~: True와 False를 반대로 
salary_df = salary_df[~(salary_df[&#39;Years of Experience&#39;] &gt; salary_df[&#39;Age&#39;] - 18)]</code></pre><blockquote>
<p>*<em>groupby(): 그룹화하여 집계, 변환, 필터링 가능 *</em></p>
</blockquote>
<pre><code># 젠더 별 샐러리의 최대 
salary_df.groupby(&#39;Gender&#39;)[&#39;Salary&#39;].max()

# # Gender와 Country 별 Salary의 평균
salary_df.groupby([&#39;Gender&#39;,&#39;Country&#39;])[&#39;Salary&#39;].mean()

# agg 함수 사용해 sum과 mean 한번에 구하기
salary_df.groupby(&#39;Gender&#39;)[&#39;Salary&#39;].agg([&#39;sum&#39;,&#39;mean&#39;])

# 피벗테이블 만들기 
df = pd.DataFrame({
    &#39;Department&#39;: [&#39;Sales&#39;, &#39;Sales&#39;, &#39;HR&#39;, &#39;HR&#39;, &#39;IT&#39;],
    &#39;Gender&#39;: [&#39;M&#39;, &#39;F&#39;, &#39;M&#39;, &#39;F&#39;, &#39;M&#39;],
    &#39;Salary&#39;: [50000, 55000, 48000, 52000, 60000]
})
df.pivot_table(values=&#39;Salary&#39;, index=&#39;Department&#39;, aggfunc=&#39;mean&#39;)
# 출력
             Salary
Department         
HR           50000.0
IT           60000.0
Sales        52500.0

# 부서 &amp; 성별 기준으로 평균 급여
df.pivot_table(values=&#39;Salary&#39;, index=&#39;Department&#39;, columns=&#39;Gender&#39;, aggfunc=&#39;mean&#39;)
# 출력
Gender         F       M
Department              
HR        52000.0  48000.0
IT            NaN  60000.0
Sales     55000.0  50000.0

#여러 함수 한번에 사용
df.pivot_table(values=&#39;Salary&#39;, index=&#39;Department&#39;, aggfunc=[&#39;mean&#39;, &#39;max&#39;])
# 출력
            mean     max
Salary                    
Department              
HR         50000  52000
IT         60000  60000
Sales      52500  55000</code></pre><blockquote>
<p><strong>원-핫 인코딩</strong>: 범주형(categorical) 데이터를 수치형(numerical) 데이터로 변환하는 대표적인 방법</p>
</blockquote>
<ul>
<li>예를 들어, Red, Green, Blue의 컬러가 있다고 했을 때 해당 범주일 경우 1, 아니면 0을 부여하는 방식 </li>
<li>pandas의 경우에는 pd.get_dummies()를 사용 </li>
<li>하지만 범주가 많을수록 열이 많아진다는 문제점이 있음</li>
</ul>
<pre><code>import pandas as pd

df = pd.DataFrame({&#39;Color&#39;: [&#39;Red&#39;, &#39;Green&#39;, &#39;Blue&#39;, &#39;Green&#39;]})
encoded = pd.get_dummies(df, columns=[&#39;Color&#39;])
print(encoded)
# 출력
   Color_Blue  Color_Green  Color_Red
0           0            0          1
1           0            1          0
2           1            0          0
3           0            1          0

# 각각 컬럼의 고유값이 몇 개인지 확인하는 방법
df[[&#39;Color_Blue&#39;, &#39;Color_Green&#39;, &#39;Color_Red&#39;]].nunique()</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 - 데이터 병합 concat, merge, join]]></title>
            <link>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B3%91%ED%95%A9</link>
            <guid>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B3%91%ED%95%A9</guid>
            <pubDate>Mon, 16 Jun 2025 10:02:14 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong><em>데이터 병합: concat, merge, join</em></strong></p>
</blockquote>
<ul>
<li>concat(): 단순한 연결, 위아래로 합치기 (axis=0)<pre><code># concat 
import pandas as pd
</code></pre></li>
</ul>
<p>df1 = pd.DataFrame({&#39;A&#39; : [&#39;A0&#39;, &#39;A1&#39;], &#39;B&#39;: [&#39;B0&#39;, &#39;B1&#39;]})
df2 = pd.DataFrame({&#39;A&#39;: [&#39;A2&#39;, &#39;A3&#39;], &#39;B&#39;: [&#39;B2&#39;, &#39;B3&#39;]})</p>
<p>result = pd.concat([df1, df2])
print(result)</p>
<h1 id="출력">출력</h1>
<p>A   B
0   A0  B0
1   A1  B1
0   A2  B2
1   A3  B3</p>
<pre><code>- merge(): 공통된 컬럼이나 인덱스를 기준으로 테이블 병합</code></pre><h1 id="merge-inner-교집합">merge inner: 교집합</h1>
<p>df_a = pd.DataFrame({&#39;key&#39;: [&#39;K0&#39;, &#39;K1&#39;, &#39;K2&#39;], &#39;A&#39;: [&#39;A0&#39;, &#39;A1&#39;, &#39;A2&#39;]})
df_b = pd.DataFrame({&#39;key&#39;: [&#39;K0&#39;, &#39;K2&#39;, &#39;K3&#39;], &#39;B&#39;: [&#39;B0&#39;, &#39;B2&#39;, &#39;B3&#39;]})</p>
<p>result = df_a.merge(df_b, how=&#39;inner&#39;)
print(result)</p>
<h1 id="출력-1">출력</h1>
<p>  key   A   B
0  K0  A0  B0
1  K2  A2  B2</p>
<h1 id="merge-outer-합집합">merge outer: 합집합</h1>
<p>result = pd.merge(df_a, df_b, on=&#39;key&#39;, how=&#39;outer&#39;)
print(result)</p>
<h1 id="출력-2">출력</h1>
<p>  key    A    B
0  K0   A0   B0
1  K1   A1  NaN
2  K2   A2   B2
3  K3  NaN   B3</p>
<h1 id="merge-left-왼쪽-기준-병합">merge left: 왼쪽 기준 병합</h1>
<p>result = pd.merge(df_a, df_b, on=&#39;key&#39;, how=&#39;left&#39;)
print(result)</p>
<h1 id="출력-3">출력</h1>
<p>  key   A    B
0  K0  A0   B0
1  K1  A1  NaN
2  K2  A2   B2</p>
<h1 id="merge-right-오른쪽-기준-병합">merge right: 오른쪽 기준 병합</h1>
<p>result = pd.merge(df_a, df_b, on=&#39;key&#39;, how=&#39;right&#39;)
print(result)</p>
<h1 id="출력-4">출력</h1>
<p>  key    A   B
0  K0   A0  B0
1  K2   A2  B2
2  K3  NaN  B3</p>
<pre><code>- join(): 데이터프레임의 인덱스를 기준으로 병합 </code></pre><p>df3 = pd.DataFrame({&#39;A&#39; : [&#39;A0&#39;, &#39;A1&#39;], &#39;B&#39;: [&#39;B0&#39;, &#39;B1&#39;]})
df4 = pd.DataFrame({&#39;A&#39;: [&#39;A2&#39;, &#39;A3&#39;], &#39;B&#39;: [&#39;B2&#39;, &#39;B3&#39;]})</p>
<p>df_3.join(df_4, lsuffix=&#39;_3&#39;, rsuffix=&#39;_4&#39;)</p>
<h1 id="출력-5">출력</h1>
<p>   A_3 B_3 A_4 B_4
0  A0  B0  A2  B2
1  A1  B1  A3  B3</p>
<p>df_3 = df_3.set_index(&#39;key&#39;)
df_4 = df_4.set_index(&#39;key&#39;)</p>
<p>df_3.join(df_4, how=&#39;inner&#39;)</p>
<p>#출력
       A_3 B_3 A_4 B_4
key<br>K0     A0  B0  A2  B2</p>
<pre><code>
- 데이터 합칠 때 생길 수 있는 문제</code></pre><p>salary_df = pd.concat([salary_1, salary_2])
salary_df.loc[0]</p>
<pre><code>![](https://velog.velcdn.com/images/jisukim_28/post/fa7e4e6f-454c-47a0-8be5-f35cdb411550/image.png)
0번째 인덱스가 2개가 생겼음. 이처럼 모든 인덱스가 2개씩 존재하는 문제 발생
</code></pre><h1 id="해결방법">해결방법</h1>
<h1 id="인덱스-리셋">인덱스 리셋</h1>
<p>salary_df.reset_index(drop=True)</p>
<pre><code>![](https://velog.velcdn.com/images/jisukim_28/post/22fd2450-1d91-418f-aec1-5ec1efefad10/image.png)
</code></pre><h1 id="국가-이름-통일시키기">국가 이름 통일시키기</h1>
<p>cpi[&#39;Country&#39;] = cpi[&#39;Country&#39;].replace({&#39;United States&#39;:&#39;USA&#39;,&#39;United Kingdom&#39;:&#39;UK&#39;})</p>
<h1 id="기존의-데이터를-기준으로-새로운-cpi-데이터-merge">기존의 데이터를 기준으로 새로운 cpi 데이터 merge</h1>
<p>salary_df = salary_df.merge(cpi, on=&#39;Country&#39;, how=&#39;left&#39;)</p>
<h1 id="컬럼-지우기">컬럼 지우기</h1>
<h1 id="inplacetrue-원본이-수정됨">inplace=True: 원본이 수정됨</h1>
<p>salary_df.drop([&#39;Reference&#39;,&#39;Previous&#39;,&#39;Units&#39;,&#39;Frequency&#39;],axis=1, inplace=True)
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 Numpy - arange, linspace, 인덱싱, 데이터 합치기, 쪼개기, 기본 연산 함수]]></title>
            <link>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-Numpy-arange-linspace-%EC%9D%B8%EB%8D%B1%EC%8B%B1-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%95%A9%EC%B9%98%EA%B8%B0-%EC%AA%BC%EA%B0%9C%EA%B8%B0-%EA%B8%B0%EB%B3%B8-%EC%97%B0%EC%82%B0-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-Numpy-arange-linspace-%EC%9D%B8%EB%8D%B1%EC%8B%B1-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%95%A9%EC%B9%98%EA%B8%B0-%EC%AA%BC%EA%B0%9C%EA%B8%B0-%EA%B8%B0%EB%B3%B8-%EC%97%B0%EC%82%B0-%ED%95%A8%EC%88%98</guid>
            <pubDate>Wed, 11 Jun 2025 14:19:45 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>np.arange(): Numpy 라이브러리의 함수로 숫자 배열을 생성할 때 사용</strong></p>
</blockquote>
<pre><code># start부터 stop 미만의 값, step의 간격으로 출력 
np.arange(start, stop, step)

print(np.arange(10,30,5))
# 출력: [10, 15, 20, 25]

print(np.arange(0,2,0.3))
# 출력: [0.  0.3 0.6 0.9 1.2 1.5 1.8]</code></pre><blockquote>
<p><strong>np.linspace(): 시작과 끝값 사이를 지정된 개수만큼 균등하게 나눈 값을 만듬</strong></p>
</blockquote>
<pre><code>np.linspace(0,5,6)
# 출력: [0., 1., 2., 3., 4., 5.]

np.linspace(0,1,5)
#출력: [0.   0.25  0.5  0.75  1.] </code></pre><ul>
<li>np.arange(): 일정한 간격으로 나누고 싶을 때</li>
<li>np.linspace(): 정확히 몇 개의 값이 필요한 경우</li>
</ul>
<pre><code>np.arange(0, 1, 0.3)  
# → [0.  0.3  0.6  0.9] (소수 오차로 인해 1 포함 안 됨)

np.linspace(0, 1, 5)  
# → [0.   0.25  0.5  0.75  1.] (정확하게 나눠짐)</code></pre><blockquote>
<p><strong>기본 연산</strong></p>
</blockquote>
<pre><code>a = np.array([20,30,40,50])
b = np.arange(4)
print(a)
prnit(b)

# 출력: [20 30 40 50]
[0 1 2 3]

c=a-b
print(c)
# 출력: [20 29 38 47]

print(b**2)
# 출력: [0 1 4 9]

print(10*a)
# 출력: [200 300 400 500]

print(a &lt; 35)
# 출력: [ True  True False False]
</code></pre><ul>
<li>.sum(): 합계</li>
<li>.min(): 최소값</li>
<li>.max(): 최댓값</li>
<li>.argmax(): 모든 요소 중 최댓값 인덱스</li>
<li>.cumsum(): 모든 요소의 누적합</li>
</ul>
<pre><code>a = np.arange(8).reshape(2,4) **2 
print(a)
# 출력: [[ 0  1  4  9]
 [16 25 36 49]]

print(a.sum()) # 140
print(a.min()) # 0
print(a.max()) # 49
print(a.argmax()) # 7
print(a.cumsum()) # [  0   1   5  14  30  55  91 140]
</code></pre><ul>
<li>axis=1: 열</li>
<li>axis=0: 행</li>
</ul>
<pre><code>b = np.arange(12).reshape(3,4)
print(b)
# [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

 print(b.sum(axis=0))
 # [12 15 18 21]

 print(b.sum(axis=1))
 # [ 6 22 38]</code></pre><blockquote>
<p><strong>데이터 합치기, 쪼개기 - stack, split</strong></p>
</blockquote>
<ul>
<li>np.stack(): 배열 합치기</li>
<li>np.slpit(): 배열 쪼개기</li>
</ul>
<pre><code># 합치기 
a = np.array([1,2,3,4]).reshape(2,2)
print(a)
# [[1 2]
 [3 4]]

b = np.array([5,6,7,8]).reshape(2,2)
print(b)
# [[5 6]
 [7 8]]

print(np.vstack((a,b)))
# [[1 2]
 [3 4]
 [5 6]
 [7 8]]

print(np.hstack((a,b)))
# [[1 2 5 6]
 [3 4 7 8]] </code></pre><pre><code># 쪼개기
a = np.arange(12).reshape(2,6)
print(a)
# [[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]]

print(np.hsplit(a,3))
[array([[0, 1],
       [6, 7]]), array([[2, 3],
       [8, 9]]), array([[ 4,  5],
       [10, 11]])]

# a를 3번째 열 ~ 4번째 열 미만 기준으로 분할 
print(np.hsplit(a,(3,4)))
[array([[0, 1, 2],
       [6, 7, 8]]), array([[3],
       [9]]), array([[ 4,  5],
       [10, 11]])]
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 클래스 - 객체, 생성자, 속성, 메소드, 상속 ]]></title>
            <link>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%ED%81%B4%EB%9E%98%EC%8A%A4-%EA%B0%9D%EC%B2%B4-%EC%83%9D%EC%84%B1%EC%9E%90-%EC%86%8D%EC%84%B1-%EB%A9%94%EC%86%8C%EB%93%9C-%EC%83%81%EC%86%8D</link>
            <guid>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%ED%81%B4%EB%9E%98%EC%8A%A4-%EA%B0%9D%EC%B2%B4-%EC%83%9D%EC%84%B1%EC%9E%90-%EC%86%8D%EC%84%B1-%EB%A9%94%EC%86%8C%EB%93%9C-%EC%83%81%EC%86%8D</guid>
            <pubDate>Tue, 03 Jun 2025 06:22:59 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>*<em>클래스와 객체란? *</em></p>
</blockquote>
<ul>
<li>클래스: 설계도 </li>
<li>객체: 설계도를 바탕으로 만들어진 실체 </li>
<li>속성: 클래스 안의 변수</li>
<li>메소드: 클래스 안의 함수<pre><code># 클래스 Recipe 생성 
class Recipe:
  def cook(self):
      print(&quot;오리가 완성되었습니다!&quot;)
# 객체 생성
pasta = Recipe()
pasta.cook() #출력: 요리가 완성되었습니다!</code></pre></li>
</ul>
<blockquote>
<p><strong>생성자(<strong>Init</strong>)와 속성</strong></p>
</blockquote>
<ul>
<li>생성자: 객체가 생성될 때 자동으로 호출되는 메서드</li>
<li>속성: 객체가 가지는 변수들 </li>
</ul>
<pre><code>class Book:
    # 인스턴스 속성: title, author
    # 생성자: __init__()
    def __init__(self, title, author):
        self.title = title
        self.author = author

    def info(self):
        print(f&quot;책 제목: {self.title}, 저자: {self.author}&quot;)
book1 = Book(&quot;파이썬 입문&quot;, &quot;홍길동&quot;)
book.info() # 출력: 책 제목: 파이썬 입문, 저자: 홍길동</code></pre><blockquote>
<p>*<em>메소드와 생성자(<strong>init</strong>)의 차이 *</em></p>
</blockquote>
<ul>
<li>메소드: 객체의 기능/동작 수행, 객체 생성 이후 필요할 때 호출</li>
<li>생성자: 초기 속성값 설정, 객체가 생성될 때 자동 호출</li>
</ul>
<pre><code># 생성자의 예제
class Car:
    def __init__(self, brand, color):
        self.brand = brand
        self.color = color
    # 메소드의 예제
    def drive(self):
        print(f&quot;{self.color}색 {self.brand} 자동차가 달립니다&quot;)</code></pre><blockquote>
<p><strong>상속 (Inheritance)</strong></p>
</blockquote>
<ul>
<li>부모 클래스의 속성과 메소드를 자식 클래스가 물려받음</li>
<li>자식 클래스에서 부모의 생성자를 호출하려면 super() 사용</li>
</ul>
<pre><code>class Employee:
    def __init__(self, name):
        self.name = name

    def work(self):
        print(f&quot;{self.name}이 일을 합니다.&quot;)

class Manager(Employee):
    def __init__(self, name, department):
        super().__init__(name)
        self.department = department

    def manage(self):
        print(f&quot;{self.name}이 {self.department} 부서를 관리합니다.&quot;)

m = Manager (&quot;이영희&quot;, &quot;영업&quot;)
m. work()  # 출력: 이영희이 일을 합니다.
m. manage()  # 출력: 이영희이 영업 부서를 관리합니다.
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 기초 마스터 - 자료형/반복문/연산자/조건문/함수 ]]></title>
            <link>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EA%B8%B0%EC%B4%88-%EB%A7%88%EC%8A%A4%ED%84%B0-%EC%9E%90%EB%A3%8C%ED%98%95%EB%B0%98%EB%B3%B5%EB%AC%B8%EC%97%B0%EC%82%B0%EC%9E%90%EC%A1%B0%EA%B1%B4%EB%AC%B8%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EA%B8%B0%EC%B4%88-%EB%A7%88%EC%8A%A4%ED%84%B0-%EC%9E%90%EB%A3%8C%ED%98%95%EB%B0%98%EB%B3%B5%EB%AC%B8%EC%97%B0%EC%82%B0%EC%9E%90%EC%A1%B0%EA%B1%B4%EB%AC%B8%ED%95%A8%EC%88%98</guid>
            <pubDate>Sun, 01 Jun 2025 08:08:37 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>*<em>파이썬 자료형 *</em></p>
</blockquote>
<p><strong>1. 숫자형 (int, float)</strong></p>
<ul>
<li>int: 정수형 (예: 1, -5, 100)</li>
<li>float: 실수형 (예: 3.14, -0.5)</li>
</ul>
<p>*<em>2. 연산자: *</em></p>
<ul>
<li>// : 몫 (정수 나눗셈)</li>
<li>% : 나머지</li>
<li>** : 거듭제곱</li>
</ul>
<pre><code>a = 7
b = 3
print(a // b)  # 2
print(a % b)   # 1
print(a ** b)  # 343

#복합대입연산자 
x = 10
x += 5  # x = x + 5
print(x)  # 15</code></pre><p><strong>3.</strong> <strong>문자형 (String)</strong></p>
<ul>
<li><p>이스케이프 코드</p>
<p>\n : 줄바꿈
\t : 탭
\ : 역슬래시
&#39; 또는 &quot; : 따옴표 출력</p>
</li>
</ul>
<pre><code>print(&quot;Hello\nWorld&quot;)
print(&quot;나는 \&quot;파이썬\&quot;을 좋아해&quot;)

# 문자열 길이
s = &quot;Python&quot;
print(len(s)) #6</code></pre><p><strong>4. 자료형의 종류: type()</strong></p>
<pre><code>x = 10
print(type(x)) # &lt;class &#39;int&#39;&gt;</code></pre><p><strong>5. 문자열 슬라이싱</strong></p>
<pre><code># 끝은 포함되지 않음 
s = &quot;Python&quot;
print(s[0:2])     #Py
print(s[:3])    # &#39;Pyt&#39;
print(s[::2])   # &#39;Pto&#39;</code></pre><blockquote>
<p><strong>자료형들</strong> </p>
</blockquote>
<p><strong>1. List (리스트)</strong></p>
<ul>
<li>변경 가능</li>
<li>순서 O, 중복 O<pre><code>리스트명 = [1, 2, 3, 4, 5]
리스트명.append(6)
print(리스트명) #[1,2,3,4,5,6]</code></pre></li>
</ul>
<p><strong>2. Tuple (튜플)</strong></p>
<ul>
<li>변경 불가</li>
<li>순서 O, 중복 O</li>
<li>del 불가 <pre><code>튜플명 = (1, 2, 3)
print(튜플명)</code></pre></li>
</ul>
<p><strong>3. Set (집합)</strong></p>
<ul>
<li>중복 X, 순서X<pre><code>집합명 = {1, 2, 3, 3, 4}
print(집합명)  # {1, 2, 3, 4}</code></pre></li>
</ul>
<p><strong>4. Dictionary (딕셔너리)</strong></p>
<ul>
<li>Key와 Value 로 구성<pre><code>딕셔너리명 = {&quot;이름&quot;: &quot;홍길동&quot;, &quot;나이&quot;: 30}
print(딕셔너리명[&quot;이름&quot;])</code></pre></li>
</ul>
<p><strong>5. Bool (불린형)</strong></p>
<ul>
<li>참(True), 거짓(False)</li>
</ul>
<blockquote>
<p><strong>파이썬 기초문법</strong></p>
</blockquote>
<p><strong>1. 반복문</strong></p>
<pre><code># while + 조건문
i = 0
while i &lt; 5:
    print(i)
    i += 1

# continue와 break
i = 0
while i &lt; 5:
    i += 1
    if i == 3:
        continue # 3은 건너뜀
    if i == 5:
        break # 5에서 종료 
    print(i)

# for + range()
for i in range(1,6,1)
    print(i)</code></pre><p><strong>2. 연산자</strong> </p>
<ul>
<li><p>비교 연산자
= (대입)
== (같다)
!= (다르다)</p>
</li>
<li><p>논리 연산자
and (그리고)
or (또는)
not (부정)</p>
</li>
<li><p>기타 연산자
in, not in (포함 여부 확인)</p>
<pre><code>x = 5
print(x == 5)  # True
print(not x == 5)  # False
print(3 in [1, 2, 3, 4])  # True</code></pre></li>
</ul>
<p><strong>3. 조건문</strong></p>
<pre><code>score = 85
if score &gt;= 90:
    print(&quot;A&quot;)
elif score &gt;= 80:
    print(&quot;B&quot;)
else:
    print(&quot;C&quot;)</code></pre><p><strong>4. 함수 (def)</strong></p>
<pre><code>def add(a, b):
    return a + b

result = add(3, 4)
print(result)  # 7</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 - 람다, 전역변수 / 지역변수, 매개변수 / 인수]]></title>
            <link>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%9E%8C%EB%8B%A4-%EC%A0%84%EC%97%AD%EB%B3%80%EC%88%98-%EC%A7%80%EC%97%AD%EB%B3%80%EC%88%98-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-%EC%9D%B8%EC%88%98</link>
            <guid>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%9E%8C%EB%8B%A4-%EC%A0%84%EC%97%AD%EB%B3%80%EC%88%98-%EC%A7%80%EC%97%AD%EB%B3%80%EC%88%98-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-%EC%9D%B8%EC%88%98</guid>
            <pubDate>Sun, 01 Jun 2025 07:34:43 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>Lambda는 언제 쓸까?</strong></p>
</blockquote>
<ol>
<li><p>짧고 간단한 함수를 만들고 싶을 때</p>
<ul>
<li>함수를 매번 def로 정의하기 귀찮을 때</li>
<li>일회성으로 쓸 때 -&gt; 굳이 이름을 붙일 필요 없을 때</li>
</ul>
</li>
<li><p>고차 함수 (map, filter, reduce 등)과 함께 사용할 때</p>
</li>
</ol>
<blockquote>
<p><strong>Lambda 표현식 (익명함수)</strong></p>
</blockquote>
<ul>
<li><p>lambda 매개변수 : 표현식 </p>
</li>
<li><p>이름이 없는 간단한 함수를 만들 때 사용</p>
</li>
<li><p>Lambda 작성 규칙</p>
<ol>
<li>람다 내부에서는 새로운 변수를 만들 수 없음</li>
<li>람다 외부의 변수는 참조 가능 </li>
</ol>
</li>
</ul>
<pre><code>add = lambda x, y : x + y
print(add(2,3)) #출력: 5

# 람다 작성 규칙
# 외부에서 새로운 변수 만듬 
n = 10
# 람다 외부의 변수 n 참조 가능 
f = lambda x : x+n
print(f(5)) # 출력: 15
</code></pre><blockquote>
<p><strong>고차 함수와 Lambda 활용</strong></p>
</blockquote>
<p><strong>1. map()</strong>: 모든 요소에 함수 적용</p>
<pre><code>nums = [1,2,3,4]
doubled = list(map(lambda x : x * 2, nums))
print(doubled)  # 출력: [2, 4, 6, 8]</code></pre><p><strong>2. filter()</strong>: 조건에 맞는 요소만 추출</p>
<pre><code>nums = [1, 2, 3, 4, 5, 6]
even = list(filter(lambda x : x % 2 ==0, nums))
print(even)  # 출력: [2, 4, 6]</code></pre><p><strong>3. reduce()</strong>: 누적 결과 생성 (import 필요)</p>
<pre><code>from functools import reduce

nums = [1, 2, 3, 4]
total = reduce(lambda x,y : x + y, nums)
print(total) # 출력: 10</code></pre><blockquote>
<p><strong>변수 범위 (Variable Scope)</strong></p>
</blockquote>
<ul>
<li>전역 변수: 함수 바깥에서 선언된 변수</li>
<li>지역 변수: 함수 안에서 선언된 변수</li>
</ul>
<pre><code># 전역 변수
name = &#39;지수&#39;
def print_name():
    print(name)
print_name() # 출력: 지수

# 지역 변수
def hello():
    user = &#39;지수&#39;
    print(user)
hello() #출력: 지수</code></pre><blockquote>
<p>*<em>변수 범위 수정하기 global vs nonlocal *</em></p>
</blockquote>
<p><strong>1. global</strong>: 함수 안에서 전역 변수를 수정하고 싶을 때 </p>
<pre><code>count = 0 # 전역 변수
def increase():
    global count
    count += 1
increase()
print(count) #출력: 1</code></pre><p><strong>2. nonlocal</strong>: 중첩 함수에서 바깥 변수를 수정하고 싶을 때  </p>
<pre><code>def outer():
    x = 10 #바깥 함수의 지역 변수
    def inner():
        nonlocal x
        x += 5
    inner()
    print(x)
outer() # 출력: 15</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 모듈, 패키지, 라이브러리 ]]></title>
            <link>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%AA%A8%EB%93%88-%ED%8C%A8%ED%82%A4%EC%A7%80-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC</link>
            <guid>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%AA%A8%EB%93%88-%ED%8C%A8%ED%82%A4%EC%A7%80-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC</guid>
            <pubDate>Fri, 30 May 2025 13:11:03 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>모듈, 패키지, 라이브러리 비교</strong></p>
</blockquote>
<p><strong>모듈:</strong> 파이썬 코드가 들어가 있는 단일 파일 (.py파일)
<strong>패키지:</strong> 여러 모듈을 폴더로 묶은 것 
<strong>라이브러리:</strong> 모듈과 패키지를 포함한 전체적인 기능 집합</p>
<blockquote>
<p><strong>포준모듈: 파이썬 내장 모듈</strong></p>
</blockquote>
<p><strong>1. random 모듈</strong>: 난수 생성을 위한 함수 제공 </p>
<pre><code># random 모듈 불러오기
import random

# 모듈 r이라는 키워드로 지정도 가능 
#import random as r 

# randint(a,b): a 이상 b 이상의 정수 무작위로 변환 
num = random.randint(1,10)
print(num)

# random(): 0 이상 1 미만의 실수 반환
num = r.random(1,10)
print(num)

# seed(): 난수 생성의 초기값을 고정
random.seed(42)
print(random.randint(1,10)) # 항상 같은 값 출력</code></pre><p><strong>2. math 모듈</strong>: 수학적 함수 및 상수 제공 </p>
<pre><code>import math

# pi: 원주율
print(math.pi)

# e: 자연상수 제공 
print(math.e)

# pow(n,x): n의 x 제곱 반환, 항상 실수형 결과를 반환 
result = math.pow(2,3)
print(result) #8.0

# ceil(): 올림 함수, 수직선 상에서 우측의 값 반환
result = ceil(3.14)
print(result) # 4

# floor(): 내림 함수, 수직전 상에서 좌측의 값 반환
result = math.floor(3.14)
print(result) #3

# round(숫자, 소수점_자리수): 반올림 함수
result = round(3.14159, 2)
print(result) #3.14
</code></pre><ol start="3">
<li><strong>time 모듈</strong>: 시간과 관련된 기능 <pre><code>import time
</code></pre></li>
</ol>
<h1 id="timesleepsecs">time.sleep(secs)</h1>
<p>print(&quot;3초 대기 시작&quot;
time.sleep(3)
print(&quot;3초 대기 후 출력&quot;)</p>
<h1 id="timelocaltime-현지-시간-반환">time.localtime(): 현지 시간 반환</h1>
<p>now = time.localtime()
print(now) # ime.struct_time(tm_year=2025, tm_mon=5, tm_mday=30, tm_hour=14, tm_min=25, tm_sec=10, ...)</p>
<pre><code>
4. **keyword 모듈**: 예약어와 관련된 기능 제공 
</code></pre><p>import keyword</p>
<p>print(keyword.kwlist) # 현재 사용되는 모든 예약어 리스트 반환</p>
<p>print(keyword.iskeyword(&quot;for&quot;)) # for이 파이썬의 예약어인지 여부를 True/False로 반환</p>
<pre><code>
&gt; **import로 모듈 불러오기 **
</code></pre><h1 id="from-import로-모듈-일부분만-가져오기">from import로 모듈 일부분만 가져오기</h1>
<p>from math import pi
pi</p>
<h1 id="여러-개의-변수-함수를-가져올-때">여러 개의 변수, 함수를 가져올 때</h1>
<p>from math import e, pi, pow
pi, e, pow(2, 6)</p>
<h1 id="from-import-as-모듈-일부분만-가져오기--키워드">from import as: 모듈 일부분만 가져오기 + 키워드</h1>
<h1 id="case1">case1</h1>
<p>from 모듈 import 변수 as 이름
from 모듈 import 함수 as 이름
from 모듈 import 클래스 as 이름</p>
<h1 id="case2">case2</h1>
<p>from 모듈 import 변수 as 이름1, 함수 as 이름2, 클래스 as 이름3</p>
<p>#모두 import
from math import *
ceil (6.3)</p>
<p>#모듈만 import
import math
math.ceil(6.3)</p>
<pre><code>
&gt; 실습: 계산기 만들기
</code></pre><p>while True:
    try:
        # 두 개의 정수를 받을 때는 나눠서 입력해야됨. 
        num1 = int(input(&quot;첫 번째 정수를 입력하세요:&quot;))
        num2 = int(input(&quot;두 번째 정수를 입력하세요:&quot;))
        cal = input(&quot;연산자를 입력하세요:&quot;)</p>
<pre><code>except ValueError:
    print(&quot;잘못된 입력입니다. 정수를 입력해주세요.&quot;)
    num1 = int(input(&quot;첫 번째 정수를 입력하세요:&quot;))
    num2 = int(input(&quot;두 번째 정수를 입력하세요:&quot;))
    cal = input(&quot;+, -, *, /, ** 중 연산자를 한 개 입력하세요:&quot;)

#문자열과 리스트는 다르다 
    #if cal not in [&#39;+&#39;,&#39;-&#39;,&#39;*&#39;,&#39;/&#39;,&#39;**&#39;]:
    #print(&quot;지원하지 않는 연산자를 입력하여 오류가 발생했습니다.&quot;)

else:
    if cal == &#39;+&#39;:
        result1 = num1 + num2
        print (f&#39;계산된 값은:{result1}입니다.&#39;)
    elif cal == &#39;-&#39;:
        result2 = num1 - num2
        print (f&#39;계산된 값은:{result2}입니다.&#39;)
    elif cal == &#39;*&#39;:
        result3 = num1 * num2
        print (f&#39;계산된 값은:{result3}입니다.&#39;)
    elif cal == &#39;/&#39;:
        if num2 == 0:
            raise ZeroDivisionError(&#39;나눗셈 연산 시 두 번째 정수가 0이 될 수 없습니다.&#39;)
        else:
            result4 = num1 / num2
            print (f&#39;계산된 값은:{result4}입니다.&#39;)
    # 처음에 else 를 썼는데, else 뒤에는 조건문 쓸 수 없음 
    elif cal == &#39;**&#39;:
        from math import pow
        result5 = pow(num1,num2)
        print (f&#39;계산된 값은:{result5}입니다.&#39;)
    #오류 메시지는 항상 모든 정상 케이스를 처리한 맨 마지막 else문 안에 넣어야 한다.
    else:
        print(&quot;지원하지 않는 연산자를 입력하여 오류가 발생했습니다.&quot;)</code></pre><pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 예외처리 / try-except 구문 / 새롭게 알게 된 f-string, isdigit(), lstrip()]]></title>
            <link>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%98%88%EC%99%B8%EC%B2%98%EB%A6%AC-try-except-%EA%B5%AC%EB%AC%B8-%EC%83%88%EB%A1%AD%EA%B2%8C-%EC%95%8C%EA%B2%8C-%EB%90%9C-f-string-isdigit-lstrip</link>
            <guid>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%98%88%EC%99%B8%EC%B2%98%EB%A6%AC-try-except-%EA%B5%AC%EB%AC%B8-%EC%83%88%EB%A1%AD%EA%B2%8C-%EC%95%8C%EA%B2%8C-%EB%90%9C-f-string-isdigit-lstrip</guid>
            <pubDate>Fri, 30 May 2025 12:32:07 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>파이썬 오류 종류</strong></p>
</blockquote>
<p><strong>1. 구문 오류 (Syntax Error)</strong></p>
<ul>
<li>코드가 문법적으로 잘못됨. 따라서, 프로그램 실행 자체가 안 됨</li>
</ul>
<p><strong>2. 런타임 오류 (Runtime Error)</strong></p>
<ul>
<li>문법적으로 문제는 없지만 프로그램 실행 중 발생하는 오류</li>
</ul>
<blockquote>
<p><strong>예외처리 ((Exceptional Handling)</strong></p>
</blockquote>
<p>런타임 오류가 발생했을 때 프로그램이 중단되지 않고 정상적으로 이어서 동작하도록 만들어주기 위함
예외 처리 방법에는 크게 두 가지 방식이 있음</p>
<p><strong>1. 조건문 사용 (사전처리)</strong></p>
<ul>
<li>오류가 발생하기 이전에 미리 검사해서 오류 피하는 방식. 따라서, 모든 상황을 예측하고 모두 조건문으로 처리해야 함 </li>
</ul>
<p><strong>2. try-excpet (사후처리)</strong></p>
<ul>
<li>실제로 오류가 발생했을 때 이를 처리하는 방식. 조건문과 달리 모든 상황을 예측하지 못해도 예외를 처리할 수 있음</li>
</ul>
<blockquote>
<p><strong>try-except 구문을 구체적으로 알아보자</strong></p>
</blockquote>
<p><strong>1. try + except</strong></p>
<ul>
<li>가장 기본적인 예외 처리 <pre><code>#오류가 발생할 수 있는 코드
try:
  x = int(input(&quot;숫자를 입력하세요:&quot;))
  result = 10 / x
</code></pre></li>
</ul>
<h1 id="오류가-발생했을-때-처리할-코드">오류가 발생했을 때 처리할 코드</h1>
<p>except ZeroDivisionError:
    print(&quot;0으로 나눌 수 없습니다!&quot;)</p>
<h1 id="여러-개의-except로-다양한-예외를-처리-가능">여러 개의 except로 다양한 예외를 처리 가능</h1>
<p>except ValueError:
    print(&quot;숫자를 입력해야 합니다.&quot;)</p>
<pre><code>
**2. try + except + else**
- 오류가 발생하지 않았을 때만 실행할 코드 추가 </code></pre><p>try:
    x = int(input(&quot;숫자를 입력하세요:&quot;))
    result = 10 / x</p>
<p>except ZeroDivisionError:
    print(&quot;0으로 나눌 수 없습니다!&quot;)</p>
<p>except ValueError:
    print(&quot;숫자를 입력해야 합니다.&quot;)</p>
<h1 id="예외가-발생하지-않았을-때-실행됨">예외가 발생하지 않았을 때 실행됨</h1>
<p>else:
    print(&quot;계산 결과:&quot;, result)</p>
<pre><code>
**3. try + except + finally**
- 예외가 발생하든 말든 항상 실행되는 finally</code></pre><p>try:
    x = int(input(&quot;숫자를 입력하세요: &quot;))
    result = 10 / x</p>
<p>except ZeroDivisionError:
    print(&quot;0으로 나눌 수 없습니다!&quot;)</p>
<p>except ValueError:
    print(&quot;숫자를 입력해야 합니다.&quot;)</p>
<p>#예외 발생 여부와 상관없이 항상 실행<br>finally:
    print(&quot;프로그램이 종료됩니다.&quot;)</p>
<pre><code>
&gt; **오늘 새롭게 배운 개념 **

**1. f-string(formatted string literal)**
- 문자열 앞에 f 또는 F를 붙이고, 문자열 안에 중괄호 {}를 사용하여 변수를 직접 넣을 수 있는 기능 
</code></pre><p>name = &#39;지수&#39;
age = 25
print(f&#39;안녕하세요. 제 이름은 {name}이고, 나이는 {age}살입니다.&#39;)</p>
<pre><code>
**2. isdigit() 함수**
- 문자열이 정수인지 검사할 때 사용 
- 문자열이 전부 숫자이면 True, 아니면 False</code></pre><h1 id="간단한-사용">간단한 사용</h1>
<p>s = &quot;12345&quot;
print(s.isdigit()) #True</p>
<h1 id="입력값-검증">입력값 검증</h1>
<p>user_input = input(&quot;숫자를 입력하세요:&quot;)</p>
<p>if user_input.isdigit():
    num = int(user_input)
    print(&quot;입력한 숫자:&quot;, num)
else:
    print(&quot;숫자가 아닙니다.&quot;)</p>
<pre><code>
**3. lstrip()**
- 문자열의 왼쪽에서 특정한 문자들을 제거하는 함수</code></pre><p>s = &quot;abcabcHello&quot;
result = s.lstrip(&quot;abc&quot;)
print(result) # &quot;Hello&quot;
```<strong>텍스트</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬에서 꼭 알아야 할 리스트·딕셔너리 함수 정리‼️]]></title>
            <link>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%97%90%EC%84%9C-%EA%BC%AD-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-%EB%A6%AC%EC%8A%A4%ED%8A%B8%EB%94%95%EC%85%94%EB%84%88%EB%A6%AC-%ED%95%A8%EC%88%98-%EC%B4%9D%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@jisukim_28/%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%97%90%EC%84%9C-%EA%BC%AD-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-%EB%A6%AC%EC%8A%A4%ED%8A%B8%EB%94%95%EC%85%94%EB%84%88%EB%A6%AC-%ED%95%A8%EC%88%98-%EC%B4%9D%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Wed, 28 May 2025 12:10:50 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>리스트</strong></p>
</blockquote>
<p>✅ <strong>1차원 리스트</strong></p>
<ul>
<li>한 줄로 된 목록<pre><code># 1차원 리스트
a = [10, 20, 30, 40, 50]
</code></pre></li>
</ul>
<h1 id="1차원-리스트-인덱싱">1차원 리스트 인덱싱</h1>
<p>print (a[0]) #10
print (a[4]) #50</p>
<pre><code>
✅** 2차원 리스트**
- 리스트 안에 리스트가 포함된 형태
- 행과 열로 표 형태의 데이터 표현 가능</code></pre><h1 id="2차원-리스트">2차원 리스트</h1>
<p>b = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
    ]</p>
<h1 id="2차원-리스트의-len함수---행의-길이로-출력">2차원 리스트의 len함수 -&gt; 행의 길이로 출력</h1>
<p>len(b) #3</p>
<h1 id="2차원-리스트-인덱싱">2차원 리스트 인덱싱</h1>
<p>b[2][0] # [7]
b[0][2] # [3]
b[1] #[4, 5, 6]</p>
<pre><code>
✅ **3차원 리스트**
- 2차원 리스트가 리스트 안에 들어간 형태</code></pre><h1 id="3차원-리스트">3차원 리스트</h1>
<p>c = [
    [  # 첫 번째 블록
        [1, 2],
        [3, 4]
    ],
    [  # 두 번째 블록
        [5, 6],
        [7, 8]
    ]
]</p>
<h1 id="3차원-리스트-인덱싱">3차원 리스트 인덱싱</h1>
<p>print(c[0][0][1])  # 2 
print(c[1][1][0])  # 7
print(c[1][1][:])  # 7,8</p>
<h1 id="3차원-리스트의-길이">3차원 리스트의 길이</h1>
<p>len(c) #2 (depth)</p>
<pre><code>✅ **리스트 주요 함수**
- min(): 리스트 함수에서 가장 작은 요소 반환
-  max(): 리스트에서 가장 큰 요소 반환
- sum(): 리스트 안의 요소들을 모두 더해 반환
- enumerate(): 리스트를 반복할 때, 인덱스 번호와 값을 함께 가져옴
- zip(): 여러 리스트를 같은 인덱스끼리 묶어 반환
</code></pre><h1 id="min">min()</h1>
<p>numbers = [5, 8, 1, 9, 3]
print(min(numbers))  # 1</p>
<h1 id="max">max()</h1>
<p>numbers = [5, 8, 1, 9, 3]
print(max(numbers))  # 9</p>
<p>#sum()
scores = [70, 80, 90]
print(sum(scores))  # 240</p>
<p>#enumerate()
fruits = [&#39;apple&#39;, &#39;banana&#39;, &#39;cherry&#39;]
for i in enumerate(fruits):
    print(i)
#0 apple
1 banana
2 cherry</p>
<p>#zip()
fruits = [&#39;apple&#39;, &#39;banana&#39;, &#39;cherry&#39;]
colors = [&#39;red&#39;, &#39;yellow&#39;, &#39;pink&#39;] </p>
<p>for i in zip(fruits, colors):
    print(i)
#(&#39;apple&#39;, &#39;red&#39;)
 (&#39;banana,&#39; &#39;yellow&#39;)
 (&#39;cherry&#39;, &#39;pink&#39;)</p>
<pre><code>
&gt; **딕셔너리 **

✅ **딕셔너리 주요 함수**

1. setdefault()
키가 존재하지 않으면 새로 추가하고, 있으면 기존 값을 반환</code></pre><p>person = {&#39;name&#39;: &#39;지수&#39;}
person.setdefault(&#39;age&#39;, 25)     # age가 없으므로 추가됨
person.setdefault(&#39;name&#39;, &#39;지영&#39;)  # name은 이미 있으므로 무시됨</p>
<p>print(person)  # {&#39;name&#39;: &#39;지수&#39;, &#39;age&#39;: 25}</p>
<pre><code>2. update()
딕셔너리에 키-값 쌍을 추가하거나 수정</code></pre><p>person = {&#39;name&#39;: &#39;지수&#39;, &#39;age&#39;: 25}
person.update({&#39;age&#39;: 30, &#39;city&#39;: &#39;Seoul&#39;})  # age는 수정, city는 추가</p>
<p>print(person)  # {&#39;name&#39;: &#39;지수&#39;, &#39;age&#39;: 30, &#39;city&#39;: &#39;Seoul&#39;}</p>
<pre><code>
3. pop()
특정 키의 값을 꺼내고 삭제</code></pre><p>person = {&#39;name&#39;: &#39;지수&#39;, &#39;age&#39;: 25}
age = person.pop(&#39;age&#39;)</p>
<p>print(age)      # 25
print(person)   # {&#39;name&#39;: &#39;지수&#39;}</p>
<pre><code>
4. popitem()
딕셔너리에서 마지막 항목을 제거하고 (key, value) 튜플로 반환</code></pre><p>person = {&#39;name&#39;: &#39;지수&#39;, &#39;age&#39;: 25}
item = person.popitem()</p>
<p>print(item)     # (&#39;age&#39;, 25) 
print(person)   # {&#39;name&#39;: &#39;지수&#39;}</p>
<pre><code>
5. fromkeys()
리스트나 튜플을 넣으면 자동으로 딕셔너리를 만들어주는 함수</code></pre><p>keys = [&#39;name&#39;, &#39;age&#39;, &#39;city&#39;]
defaults = dict.fromkeys(keys, &#39;미정&#39;)</p>
<p>print(defaults)  </p>
<h1 id="name-미정-age-미정-city-미정">{&#39;name&#39;: &#39;미정&#39;, &#39;age&#39;: &#39;미정&#39;, &#39;city&#39;: &#39;미정&#39;}</h1>
<pre><code>
6. in/not in
딕셔너리에 특정 키가 있는지 확인
value가 있는지 확인하고 싶으면 values()를 붙이기 </code></pre><p>person = {&#39;name&#39;: &#39;지수&#39;, &#39;age&#39;: 25}</p>
<p>print(&#39;name&#39; in person)     # True
print(&#39;city&#39; not in person) # True</p>
<p>#value 확인할 때
print(&#39;25&#39; in person.values())  # True</p>
<pre><code>
&gt; **컴프리헨션**

✅ **컴프리헨션이란?**

파이썬의 대표적인 문법 중 하나
대괄호 [ ] 안에 if문, for문, in의 조건과 반복문을 활용
</code></pre><h1 id="for-반복문">for 반복문</h1>
<p>squares = []
for x in range(1, 6):
    squares.append(x**2)</p>
<p>print(squares)  # [1, 4, 9, 16, 25]</p>
<p>#리스트 컴프리헨션
squares = [x**2 for x in range(1, 6)]
print(squares)  # [1, 4, 9, 16, 25]</p>
<pre><code></code></pre><p>#for 조건문
evens = []
for x in range(10):
    if x % 2 == 0:
        evens.append(x)</p>
<p>print(evens)  # [0, 2, 4, 6, 8]</p>
<p>#반복문 조건문 컨프리헨션
evens = [x for x in range(10) if x % 2 == 0]
print(evens)  # [0, 2, 4, 6, 8]</p>
<p>#이중 if문 컨프리헨션
nums = [x for x in range(1, 21) if x % 2 == 0 if x % 3 == 0]
print(nums)</p>
<pre><code>
&gt; **예제문제 풀이 **
</code></pre><h1 id="국-영-수-사-과-점수-입력-후-최저-점수-최고-점수-평균-점수-출력">국, 영, 수, 사, 과 점수 입력 후 최저 점수, 최고 점수, 평균 점수 출력</h1>
<p>score = input(&quot;성적을 입력하세요. (국어 영어 수학 사회 과학):&quot;)
score_list = list(map(int, score.split()))</p>
<p>average = sum(score_list) / len(score_list)</p>
<p>print(&quot;최저 점수:&quot;, min(score_list), 
      &quot;최고 점수:&quot;, max(score_list),
      &quot;평균 점수:&quot;, average)</p>
<pre><code>
✅ score.split()</code></pre><h1 id="score은-문자열">score은 문자열</h1>
<h1 id="split을-하면-공백을-기준으로-문자열을-나눠-리스트로-만듬">split()을 하면 공백을 기준으로 문자열을 나눠 리스트로 만듬</h1>
<p>score = &quot;80 90 100 70&quot;
score.split()  # 👉 [&#39;80&#39;, &#39;90&#39;, &#39;100&#39;, &#39;70&#39;] → 문자열 리스트</p>
<pre><code>
✅ map(int, ...)</code></pre><h1 id="리스트의-각-요소에-int-함수를-적용해서-정수로-바꿈">리스트의 각 요소에 int() 함수를 적용해서 정수로 바꿈</h1>
<p>map(int, [&#39;80&#39;, &#39;90&#39;, &#39;100&#39;, &#39;70&#39;])  </p>
<h1 id="👉-80-90-100-70-map-객체">👉 [80, 90, 100, 70] (map 객체)</h1>
<pre><code>
✅ list(...)</code></pre><p>score_list = [80, 90, 100, 70]  # 문자열 → 정수 리스트</p>
<p>```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[초급자들을 위한 Github 사용방법 - add, commit, pull, push, clone ]]></title>
            <link>https://velog.io/@jisukim_28/%EC%B4%88%EA%B8%89%EC%9E%90%EB%93%A4%EC%9D%84-%EC%9C%84%ED%95%9C-Github-%EC%82%AC%EC%9A%A9%EB%B0%A9%EB%B2%95-add-commit-pull-push-%EB%93%B1</link>
            <guid>https://velog.io/@jisukim_28/%EC%B4%88%EA%B8%89%EC%9E%90%EB%93%A4%EC%9D%84-%EC%9C%84%ED%95%9C-Github-%EC%82%AC%EC%9A%A9%EB%B0%A9%EB%B2%95-add-commit-pull-push-%EB%93%B1</guid>
            <pubDate>Mon, 26 May 2025 10:39:27 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>Github를 사용하는 목적은?</strong> </p>
</blockquote>
<ul>
<li><strong>협업</strong>
여러 사람이 같은 프로젝트를 동시에 작업할 때, 서로의 작업 내용을 공유하기에 용이</li>
<li><strong>버전 관리</strong>
프로젝트의 내용을 업데이트 하기 쉬움 
파일의 변경 히스토리를 확인하고, 이전 버전으로 되돌릴 수 있음</li>
<li><strong>백업</strong>
로컬 컴퓨터 외에 클라우드 상에 저장하여 안전하게 보관
노트북이 고장나도 Github에 업로드된 파일은 그대로 유지</li>
</ul>
<blockquote>
<p>*<em>Github 계정 등록, 로컬 저장소 만들기, add/commit/push *</em></p>
</blockquote>
<p><strong><em>✅ 여기서 잠깐! Git과 Github의 차이점은?</em></strong></p>
<ul>
<li><strong>Git</strong>: 로컬에서 버전 관리하는 도구</li>
<li><strong>Github</strong>: Git에서 사용하는 프로젝트를 클라우드에서 협업하고 관리하는 플랫폼</li>
</ul>
<p>쉽게 말하면,
Git은 그림을 그릴 때마다 어떤 변화가 있었는지 기억해주고 저장해주는 똑똑한 공책, Github는 그림을 올려 친구들과 함께 그릴 수 있는 웹사이트</p>
<h4 id="✅-아래의-코드를-따라-기본적인-github세팅을-시작해보자">✅ <em>아래의 코드를 따라 기본적인 Github세팅을 시작해보자!</em></h4>
<pre><code># 로컬 Git에 Github 계정 정보 등록하기
# Github 가입 시 사용한 email과 username 입력 
$ git config --global user.email &quot;my-email@gmail.com&quot;
$ git config --global user.name &quot;my-username&quot;

# 내 컴퓨터에 &#39;workplace&#39;라는 로컬 저장소 만들기
# mkdir는 make directory라는 뜻
$ mkdir workplace

# &#39;이 폴더 안의 파일들을 Git으로 관리할거야!&#39; 라는 명령
$ git init

# workplace 내에 README.md 파일 생성하기,
# #first-repository라는 문구를 README.md 파일 내에 추가
$ echo &quot;#first-repository&quot; &gt;&gt; README.md

# Git에 변경사항 저장하기 (add, commit)
$ git add README.md
$ git commit -m &quot;커밋에 대한 설명메시지&quot;</code></pre><p><em><strong>✅ Add와 Commit의 차이점은?</strong></em></p>
<p>파일을 Github에 업로드하기 위해서는 <strong>Add-&gt;Commit-&gt;Push</strong> 의 과정이 필요</p>
<ul>
<li><p><strong>Add</strong>: 로컬에서 수정한 파일을 스테이징 영역으로 올리는 명령어. Add를 해야만 &quot;이 파일을 다음 commit에 포함시켜 주세요&quot; 라고 알릴 수 있음</p>
</li>
<li><p><strong>Commit</strong>: 스테이징 영역에 있는 파일들을 로컬 저장소에 버전 기록으로 저장, 변경 히스토리도 함께 저장  </p>
</li>
<li><p>git add 👉 &quot;이 파일들 저장할 거야!&quot; 라고 표시해두는 단계</p>
</li>
<li><p>git commit 👉 &quot;좋아, 이제 진짜 저장할게!&quot; 라고 Git에게 확정시키는 단계</p>
</li>
</ul>
<pre><code># 로컬 저장소와 원격 저장소 연결하기
# xxx에는 자신의 username, first-repository 에는 자신의 레파지토리 이름
$ git remote add origin https://github.com/xxx/first-repository.git

# 로컬 저장소의 기록 원격 저장소로 전송하기
$ git config credential.helper store
$ git push origin main
</code></pre><blockquote>
<p><strong>원격 저장소를 로컬로 가져오기 - clone</strong></p>
</blockquote>
<pre><code>#새로운 디렉토리 project 생성
$ mkdir project

# 깃허브의 레파지토리 project라는 파일 안에 복제
# xxx에는 자신의 username, first-repository 에는 자신의 레파지토리 이름
$ git clone https://github.com/xxx/first-repository.git

# 로컬로 가져온 레파지토리의 내용 수정
$ echo &quot;새로운 내용을 추가합니다&quot; &gt;&gt; README.md

# 수정된 내용을 원격 저장소에 다시 add, commit, push
$ git add README.md
$ git commit -m &quot;커밋에 대한 설명메시지&quot;
$ git push origin main

# 원격 저장소로부터 내용을 불러와 workplace 저장소에도 수정 내용 업데이트 (pull)
$ git pull origin main</code></pre><blockquote>
<p><strong>그 이외에 도움이 되는 기본 명령어들</strong> </p>
</blockquote>
<pre><code>1. cd: change directory
# project 디렉토리로 변경해주라는 의미
$ cd project

2. pwd: print working directory
# 현재 작업 중인 디렉토리의 전체 경로 출력
$ pwd

3. ls: list
# 현재 디렉토리에 있는 파일과 폴더 목록을 보여줌
$ ls

4. cat README.md
# README.md 파일의 내용을 출력함 
$ cat README.md

5. git status
# 현재 git 저장소의 상태를 보여줌
$ git status</code></pre>]]></description>
        </item>
    </channel>
</rss>