<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>데이터과학 삼학년</title>
    <link>https://dodonam.tistory.com/</link>
    <description>Data scientist 의 소소한 개발(계발) 일기</description>
    <language>ko</language>
    <pubDate>Fri, 12 Jun 2026 00:12:50 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Dan-k</managingEditor>
    <image>
      <title>데이터과학 삼학년</title>
      <url>https://tistory1.daumcdn.net/tistory/3527959/attach/18a02de043334e2e8912b2229eece05a</url>
      <link>https://dodonam.tistory.com</link>
    </image>
    <item>
      <title>아파치 피닉스(Apache Phoenix): HBase에서 SQL을 이용한다?!</title>
      <link>https://dodonam.tistory.com/511</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;HBase&lt;/b&gt;는 대규모 데이터를 처리하는 &lt;b&gt;NoSQL&lt;/b&gt; 데이터베이스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 HBase는 &lt;b&gt;SQL을 지원하지 않음&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;아파치 피닉스(Apache Phoenix)&lt;/b&gt;는 HBase 위에서 &lt;b&gt;SQL&lt;/b&gt;을 사용할 수 있도록 해주는 도구&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;258&quot; data-start=&quot;242&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;1. 아파치 피닉스란?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- HBase&lt;/b&gt;의 SQL 계층을 제공하는 &lt;b&gt;쿼리 엔진&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQL 쿼리로 HBase 데이터를 &lt;b&gt;관리하고 조회&lt;/b&gt;할 수 있도록 도와줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- JDBC&lt;/b&gt; 연결을 통해 기존 SQL 기반 애플리케이션에서 HBase를 &lt;b&gt;쉽게 활용&lt;/b&gt; 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- HBase&lt;/b&gt;의 분산 처리 성능을 그대로 유지하며 &lt;b&gt;SQL&lt;/b&gt;로 데이터를 다룰 수 있음&lt;/p&gt;
&lt;p data-end=&quot;478&quot; data-start=&quot;457&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;478&quot; data-start=&quot;457&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;2. 아파치 피닉스의 주요 특징&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- SQL 지원&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SQL을 통해 HBase 데이터를 &lt;b&gt;직관적으로 쿼리&lt;/b&gt;하고 &lt;b&gt;관리&lt;/b&gt; 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- HBase 통합&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;HBase 위에서 실행되어, &lt;b&gt;분산 아키텍처&lt;/b&gt;를 그대로 활용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- JDBC 지원&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SQL 기반 애플리케이션에서 &lt;b&gt;HBase와 쉽게 연결&lt;/b&gt; 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 고성능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;쿼리 최적화를 통해 &lt;b&gt;대규모 데이터 처리 성능&lt;/b&gt; 최적화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 쿼리 최적화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;복잡한 SQL 쿼리를 &lt;b&gt;자동으로 최적화&lt;/b&gt;해 빠른 성능 제공&lt;/p&gt;
&lt;p data-end=&quot;775&quot; data-start=&quot;755&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1119&quot; data-start=&quot;1100&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;3. 아파치 피닉스 사용 예시&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;SQL 쿼리&lt;/b&gt;로 HBase 테이블 생성, 데이터 삽입, 조회 가능&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1742127000708&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE TABLE my_table (id INTEGER PRIMARY KEY, name VARCHAR);
UPSERT INTO my_table VALUES (1, 'John Doe');
SELECT * FROM my_table;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1330&quot; data-start=&quot;1313&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1330&quot; data-start=&quot;1313&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SQL을 사용하여 &lt;b&gt;HBase 데이터 모델링&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;테이블 생성, 인덱스 추가, 데이터 수정 등을 SQL로 처리&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1742127028363&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE TABLE employees (
    id INTEGER PRIMARY KEY,
    name VARCHAR,
    department VARCHAR
);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1534&quot; data-start=&quot;1513&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;4. 아파치 피닉스 사용의 장점&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- SQL 쿼리&lt;/b&gt; 지원으로 SQL에 익숙한 개발자가 쉽게 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;b&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;HBase의 성능&lt;/b&gt;과 &lt;b&gt;SQL의 편리함&lt;/b&gt;을 동시에 활용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;b&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;JDBC 지원&lt;/b&gt;으로 기존 SQL 기반 애플리케이션에서 HBase를 &lt;b&gt;손쉽게 연결&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;b&gt;-&lt;span&gt; &lt;/span&gt;&lt;/b&gt;자동 쿼리 최적화&lt;/b&gt;로 빠른 데이터 처리 속도 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;mttContainer&quot; class=&quot;notranslate&quot; style=&quot;transform: translate(855px, 1068px);&quot; aria-expanded=&quot;true&quot;&gt;
&lt;div id=&quot;tippy-1&quot; style=&quot;z-index: 100000200; visibility: visible; position: absolute; inset: auto auto 0px 0px; margin: 0px; transform: translate(387px, -20px);&quot; data-tippy-root=&quot;&quot;&gt;
&lt;div class=&quot;tippy-box&quot; style=&quot;max-width: 350px; transition-duration: 300ms;&quot; tabindex=&quot;-1&quot; role=&quot;mtttooltip&quot; data-state=&quot;visible&quot; data-theme=&quot;custom&quot; data-animation=&quot;fade&quot; data-placement=&quot;top&quot;&gt;
&lt;div class=&quot;tippy-content&quot; style=&quot;transition-duration: 300ms;&quot; data-state=&quot;visible&quot;&gt;&lt;span&gt;테이블 직원 만들기 ( ID 정수 기본 키, 이름 바르 차르, 부서 Varchar );&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;tippy-arrow&quot; style=&quot;position: absolute; left: 0px; transform: translate(104px, 0px);&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>Data Visualization &amp;amp; DataBase</category>
      <author>Dan-k</author>
      <guid isPermaLink="true">https://dodonam.tistory.com/511</guid>
      <comments>https://dodonam.tistory.com/511#entry511comment</comments>
      <pubDate>Tue, 18 Mar 2025 22:12:16 +0900</pubDate>
    </item>
    <item>
      <title>큰 수의 법칙, 중심극한의 정리</title>
      <link>https://dodonam.tistory.com/510</link>
      <description>&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;1. 큰 수의 법칙(Law of Large Numbers, LLN)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;큰 수의 법칙은 표본 크기가 커질수록 표본의 평균이 모집단의 평균에 가까워진다는 정리입니다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;br /&gt;✔️ 개념&lt;br /&gt;&amp;bull; 표본 크기 n 이 커질수록 표본 평균 $&amp;nbsp;\bar{X}&amp;nbsp;$은 모집단 평균 $ \mu $&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;에 수렴&lt;br /&gt;&amp;bull; 개별 표본 값이 변동성이 크더라도, 많은 데이터를 모으면 전체적인 경향이 모집단을 반영&lt;br /&gt;&lt;br /&gt;✔️ 수식&lt;br /&gt;&lt;br /&gt;표본 평균 $&amp;nbsp;\bar{X}n $&amp;nbsp;은 모집단 평균 $ \mu $ &amp;nbsp;에 확률적으로 수렴&lt;br /&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size18&quot;&gt;\[&lt;br /&gt;\lim_{n&amp;nbsp;\to&amp;nbsp;\infty}&amp;nbsp;\bar{X}_n&amp;nbsp;=&amp;nbsp;\mu&lt;br /&gt;\]&lt;br /&gt;&lt;br /&gt;✔️ 예제&lt;br /&gt;&lt;br /&gt;예를 들어, 동전을 던질 때 앞면이 나올 확률은 0.5입니다.&lt;br /&gt;하지만 동전을 10번 던지면 앞면이 정확히 5번 나올 확률은 낮습니다.&lt;br /&gt;그러나 1000번, 10000번 던질수록 앞면이 나오는 비율은 0.5에 가까워짐.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;2. 중심극한정리(Central Limit Theorem, CLT)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;중심극한정리는 표본의 크기가 충분히 크면, 모집단의 분포와 관계없이 표본평균의 분포가 정규분포를 따른다는 정리입니다.&lt;br /&gt;&lt;br /&gt;✔️ 개념&lt;br /&gt;&amp;bull; 모집단이 어떤 분포든지 상관없이, 충분히 큰 표본을 반복적으로 추출하면 표본 평균의 분포는 정규분포에 가까워짐&lt;br /&gt;&amp;bull; 표본 크기가 커질수록 표본 평균의 분포가 평균 $ \mu $ ,&amp;nbsp;분산 $&amp;nbsp;\sigma^2/n $&amp;nbsp;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 인 정규분포 $&amp;nbsp;N(\mu, \sigma^2/n) $&amp;nbsp;&amp;nbsp;에 수렴&lt;br /&gt;&lt;br /&gt;✔️ 수식&lt;br /&gt;&lt;br /&gt;표본 평균 $&amp;nbsp;\bar{X} $&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 의 분포는&lt;br /&gt;$$&amp;nbsp;\bar{X}&amp;nbsp;\sim&amp;nbsp;N\left(&amp;nbsp;\mu,&amp;nbsp;\frac{\sigma^2}{n}&amp;nbsp;\right)&amp;nbsp;$$단, n이 클 때&lt;br /&gt;&lt;br /&gt;✔️ 예제&lt;br /&gt;&lt;br /&gt;예를 들어, 주사위를 던지는 경우&lt;br /&gt;&amp;bull; 주사위 하나의 숫자는 균등분포(Uniform Distribution)를 따름&lt;br /&gt;&amp;bull; 하지만 주사위를 30번 던지고 평균을 구하면, 그 값들의 분포는 점점 정규분포에 가까워짐&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;3. 큰 수의 법칙 vs 중심극한정리 차이점&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100.93%; height: 90px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 19.4961%; height: 18px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 40.9133%; height: 18px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: left;&quot;&gt;큰 수의 법칙 (LLN)&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.5187%; height: 18px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;중심극한정리 (CLT)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 19.4961%; height: 18px;&quot;&gt;&lt;b&gt;핵심 내용&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.9133%; height: 18px;&quot;&gt;표본 평균이 모집단 평균에 수렴&lt;/td&gt;
&lt;td style=&quot;width: 40.5187%; height: 18px;&quot;&gt;표본 평균의 분포가 정규분포에 가까워짐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 19.4961%; height: 18px;&quot;&gt;&lt;b&gt;목적&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.9133%; height: 18px;&quot;&gt;표본 크기가 커질수록 평균이 모집단의 평균과 같아짐을 보장&lt;/td&gt;
&lt;td style=&quot;width: 40.5187%; height: 18px;&quot;&gt;표본의 크기가 커질수록 분포 형태가 정규분포에 가까워짐을 보장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 19.4961%; height: 18px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;필요한 표본&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.9133%; height: 18px;&quot;&gt;크기 크면 클수록 좋음&lt;/td&gt;
&lt;td style=&quot;width: 40.5187%; height: 18px;&quot;&gt;대략 30개 이상이면 정규분포 근사 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 19.4961%; height: 18px;&quot;&gt;&lt;b&gt;적용 예시&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.9133%; height: 18px;&quot;&gt;동전을 1000번 던지면 앞면 비율이 0.5에 가까워짐&lt;/td&gt;
&lt;td style=&quot;width: 40.5187%; height: 18px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;주사위를 30번씩 여러 번 던지면 평균값들이 정규분포를 따름&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;즉,&lt;br /&gt;&lt;b&gt;&amp;bull; 큰 수의 법칙은 &amp;ldquo;많이 하면 평균이 모집단과 같아진다&amp;rdquo;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;bull; 중심극한정리는 &amp;ldquo;표본평균의 분포가 정규분포에 가까워진다&amp;rdquo;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Statistical Learning</category>
      <author>Dan-k</author>
      <guid isPermaLink="true">https://dodonam.tistory.com/510</guid>
      <comments>https://dodonam.tistory.com/510#entry510comment</comments>
      <pubDate>Sun, 16 Mar 2025 18:13:23 +0900</pubDate>
    </item>
    <item>
      <title>불균형 데이터 오버샘플링 기법: SMOTE, ADASYN, SMOTE-Tomek Link</title>
      <link>https://dodonam.tistory.com/509</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. SMOTE (Synthetic Minority Over-sampling Technique)&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개념&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SMOTE는 소수 클래스(minority class)의 데이터를 합성하여 새로운 데이터를 생성하는 방식의 오버샘플링 기법입니다. 단순히 데이터를 복제하는 것이 아니라, K-최근접 이웃(K-NN) 기반으로 새로운 데이터를 생성하여 데이터의 다양성을 증가시킵니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;알고리즘&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;소수 클래스의 데이터 샘플을 선택합니다.&lt;/li&gt;
&lt;li&gt;선택된 샘플의 K-최근접 이웃을 찾습니다.&lt;/li&gt;
&lt;li&gt;이웃 중 하나를 랜덤하게 선택하여 기존 데이터와의 차이를 계산합니다.&lt;/li&gt;
&lt;li&gt;이 차이에 랜덤한 값을 곱하고 기존 데이터에 더하여 새로운 데이터를 생성합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 데이터를 단순 복제하는 것이 아니라, 새로운 데이터를 생성하여 모델의 일반화 성능을 향상시킴.&lt;/li&gt;
&lt;li&gt;다양한 데이터 분포를 유지하면서 소수 클래스의 샘플 수를 증가시킴.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생성된 샘플이 실제 데이터가 아니므로, 원본 데이터의 분포를 왜곡할 가능성이 있음.&lt;/li&gt;
&lt;li&gt;노이즈가 있는 데이터의 경우, 노이즈까지 증폭될 위험이 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2560&quot; data-origin-height=&quot;898&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2ZbLm/btsMslxrRVG/8gnd8FSfPuYIGJurbPSMx0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2ZbLm/btsMslxrRVG/8gnd8FSfPuYIGJurbPSMx0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2ZbLm/btsMslxrRVG/8gnd8FSfPuYIGJurbPSMx0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2ZbLm%2FbtsMslxrRVG%2F8gnd8FSfPuYIGJurbPSMx0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2560&quot; height=&quot;898&quot; data-origin-width=&quot;2560&quot; data-origin-height=&quot;898&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. ADASYN (Adaptive Synthetic Sampling)&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개념&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ADASYN은 SMOTE와 유사한 방식으로 새로운 데이터를 생성하지만, 데이터 밀도가 낮은 영역에 더 많은 샘플을 생성하는 방식으로 적응적(adaptive) 오버샘플링을 수행합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;알고리즘&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;각 소수 클래스 샘플의 K-최근접 이웃을 찾고, 다수 클래스 샘플과의 비율을 계산하여 샘플링 가중치를 부여합니다.&lt;/li&gt;
&lt;li&gt;샘플링 가중치가 높은(즉, 데이터 밀도가 낮은) 샘플 주변에서 더 많은 데이터를 생성합니다.&lt;/li&gt;
&lt;li&gt;새로운 데이터를 생성하는 과정은 SMOTE와 유사하지만, 밀도가 낮은 영역일수록 더 많은 샘플이 추가됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;소수 클래스의 데이터 분포를 더욱 자연스럽게 확장할 수 있음.&lt;/li&gt;
&lt;li&gt;밀도가 낮은 영역을 보완하여 모델의 성능을 향상시킬 가능성이 높음.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;노이즈가 많은 데이터셋에서는 성능이 저하될 수 있음.&lt;/li&gt;
&lt;li&gt;계산량이 증가할 가능성이 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2560&quot; data-origin-height=&quot;898&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dbfzwQ/btsMsmbY3r4/0ja4X9dpqVasjOEd3oyRO1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dbfzwQ/btsMsmbY3r4/0ja4X9dpqVasjOEd3oyRO1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dbfzwQ/btsMsmbY3r4/0ja4X9dpqVasjOEd3oyRO1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdbfzwQ%2FbtsMsmbY3r4%2F0ja4X9dpqVasjOEd3oyRO1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2560&quot; height=&quot;898&quot; data-origin-width=&quot;2560&quot; data-origin-height=&quot;898&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. SMOTE-Tomek Link&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개념&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tomek Link는 데이터 정제(cleaning) 기법으로, 클래스 간 경계에 위치한 샘플을 제거하여 더 명확한 분류 경계를 만들도록 돕습니다. SMOTE와 결합하여 오버샘플링과 언더샘플링을 함께 수행하면, 데이터의 균형을 맞추면서도 더 정제된 데이터셋을 만들 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;알고리즘&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;SMOTE를 적용하여 소수 클래스 데이터를 합성합니다.&lt;/li&gt;
&lt;li&gt;Tomek Link를 찾아 제거합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Tomek Link: 두 개의 샘플 (A, B)이 서로의 최근접 이웃이며, A는 다수 클래스, B는 소수 클래스인 경우, B를 제거합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SMOTE의 단점을 보완하여 경계에 위치한 애매한 샘플을 정리함으로써 모델의 성능 향상 가능.&lt;/li&gt;
&lt;li&gt;불필요한 데이터 포인트를 줄여 과적합(overfitting) 가능성을 낮춤.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Tomek Link 제거 과정에서 일부 중요한 경계 데이터까지 손실될 가능성이 있음.&lt;/li&gt;
&lt;li&gt;데이터 양이 줄어들기 때문에, 성능 향상이 보장되지 않을 수도 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 비교&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기법 장점 단점&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;SMOTE&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;데이터 다양성 증가, 과적합 방지&lt;/td&gt;
&lt;td&gt;데이터 왜곡 가능성, 노이즈 증폭 위험&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;ADASYN&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;밀도가 낮은 영역을 보완, 자연스러운 데이터 생성&lt;/td&gt;
&lt;td&gt;노이즈가 많은 데이터에서는 성능 저하 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;SMOTE-Tomek Link&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;경계 정리로 모델 성능 향상, 과적합 방지&lt;/td&gt;
&lt;td&gt;중요한 샘플 손실 가능성, 데이터 감소&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순한 오버샘플링이 필요한 경우에는 SMOTE를, 데이터 밀도가 낮은 영역을 보완하고 싶다면 ADASYN을, 데이터 정제까지 함께 고려하고 싶다면 SMOTE-Tomek Link를 고려&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2052&quot; data-origin-height=&quot;867&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/u3A55/btsMurW8YnR/9kLgnbzopcH7KBYohKlg50/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/u3A55/btsMurW8YnR/9kLgnbzopcH7KBYohKlg50/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/u3A55/btsMurW8YnR/9kLgnbzopcH7KBYohKlg50/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fu3A55%2FbtsMurW8YnR%2F9kLgnbzopcH7KBYohKlg50%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2052&quot; height=&quot;867&quot; data-origin-width=&quot;2052&quot; data-origin-height=&quot;867&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://towardsdatascience.com/smote-synthetic-data-augmentation-for-tabular-data-1ce28090debc/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://towardsdatascience.com/smote-synthetic-data-augmentation-for-tabular-data-1ce28090debc/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1740310512286&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;SMOTE: Synthetic Data Augmentation for Tabular Data | Towards Data Science&quot; data-og-description=&quot;An exploration of SMOTE and some variants like Borderline-SMOTE and ADASYN&quot; data-og-host=&quot;towardsdatascience.com&quot; data-og-source-url=&quot;https://towardsdatascience.com/smote-synthetic-data-augmentation-for-tabular-data-1ce28090debc/&quot; data-og-url=&quot;https://towardsdatascience.com/smote-synthetic-data-augmentation-for-tabular-data-1ce28090debc/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/gpYKd/hyYjFihNNf/vgLXhYcKIFB2j4cpRNwkVk/img.jpg?width=2052&amp;amp;height=867&amp;amp;face=0_0_2052_867,https://scrap.kakaocdn.net/dn/cJgb7E/hyYjAnJXuk/SBhdUT3ecLrUbxpCzofD6K/img.jpg?width=2560&amp;amp;height=898&amp;amp;face=0_0_2560_898,https://scrap.kakaocdn.net/dn/byk6Yl/hyYjHAnXOt/rEwvkFZUAsL4c1KaG7hnCK/img.jpg?width=2560&amp;amp;height=898&amp;amp;face=0_0_2560_898&quot;&gt;&lt;a href=&quot;https://towardsdatascience.com/smote-synthetic-data-augmentation-for-tabular-data-1ce28090debc/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://towardsdatascience.com/smote-synthetic-data-augmentation-for-tabular-data-1ce28090debc/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/gpYKd/hyYjFihNNf/vgLXhYcKIFB2j4cpRNwkVk/img.jpg?width=2052&amp;amp;height=867&amp;amp;face=0_0_2052_867,https://scrap.kakaocdn.net/dn/cJgb7E/hyYjAnJXuk/SBhdUT3ecLrUbxpCzofD6K/img.jpg?width=2560&amp;amp;height=898&amp;amp;face=0_0_2560_898,https://scrap.kakaocdn.net/dn/byk6Yl/hyYjHAnXOt/rEwvkFZUAsL4c1KaG7hnCK/img.jpg?width=2560&amp;amp;height=898&amp;amp;face=0_0_2560_898');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;SMOTE: Synthetic Data Augmentation for Tabular Data | Towards Data Science&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;An exploration of SMOTE and some variants like Borderline-SMOTE and ADASYN&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;towardsdatascience.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Statistical Learning</category>
      <author>Dan-k</author>
      <guid isPermaLink="true">https://dodonam.tistory.com/509</guid>
      <comments>https://dodonam.tistory.com/509#entry509comment</comments>
      <pubDate>Sun, 23 Feb 2025 20:30:41 +0900</pubDate>
    </item>
    <item>
      <title>LLM을 활용한 추천 시스템</title>
      <link>https://dodonam.tistory.com/507</link>
      <description>&lt;h1 data-pm-slice=&quot;1 3 []&quot;&gt;&lt;span&gt;LLM을 활용한 추천 시스템: 넷플릭스 데이터셋 사례&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;추천 시스템은 방대한 콘텐츠 속에서 사용자들이 적합한 항목을 찾을 수 있도록 돕는 중요한 역할을 하고 있습니다. 여러분이 이 글을 발견한 것도 추천 시스템 덕분일 가능성이 높습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;기존의 추천 시스템은 주로 협업 필터링과 콘텐츠 기반 필터링에 의존해 왔습니다. 하지만 최근 등장한 **대규모 언어 모델(LLMs)**은 이 분야에 새로운 가능성을 열어주고 있습니다. 이번 글에서는 넷플릭스 데이터셋을 활용하여 LLM 기반 추천 시스템을 구축하는 과정을 소개하고, 이 기술이 추천 시스템을 어떻게 혁신하는지 알아보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;LLM이 추천 시스템에서 게임 체인저가 되는 이유&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;LLM은 기존 추천 시스템과 비교해 여러 가지 독특한 강점을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;1. 풍부한 세계 지식&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;LLM은 방대한 데이터 학습을 통해 축적된 세계 지식을 내포하고 있어, 보다 세부적이고 문맥적으로 적합한 추천이 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;2. 제로샷 및 퓨샷 학습 능력&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사전 학습된 모델로도 새로운 추천 시나리오에 빠르게 적응할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;3. 고품질 텍스트 표현 생성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;텍스트를 이해하고 표현하는 데 강점을 가져, 더 정교한 콘텐츠 기반 추천이 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;시스템 개념과 설계&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 시스템의 핵심은 &lt;/span&gt;&lt;span&gt;&lt;b&gt;LLM을 활용해 영화 설명을 임베딩(embedding)으로 변환&lt;/b&gt;&lt;/span&gt;&lt;span&gt;하는 것입니다. 이 임베딩은 영화의 의미적 정보를 내포하며, 이를 기반으로 유사한 영화를 빠르게 찾을 수 있습니다. 유사성 검색은 &lt;/span&gt;&lt;span&gt;&lt;b&gt;FAISS(Facebook AI Similarity Search)&lt;/b&gt;&lt;/span&gt;&lt;span&gt; 라이브러리를 활용해 효율적으로 수행됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;구현 과정&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;1. 데이터 준비&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;먼저 넷플릭스 데이터셋을 불러와 각 영화의 다양한 정보를 텍스트로 결합합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;import pandas as pd

df = pd.read_csv(&quot;netflix_titles.csv&quot;)

def create_textual_representation(row):
    return f&quot;&quot;&quot;Type: {row['type']}, Title: {row['title']}, Director: {row['director']}, Cast: {row['cast']}, Released: {row['release_year']}, Genres: {row['listed_in']}, Description: {row['description']}&quot;&quot;&quot;

df['textual_representation'] = df.apply(create_textual_representation, axis=1)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 과정은 영화의 타입, 제목, 감독, 배우, 장르, 설명 등의 정보를 하나의 텍스트로 결합합니다. 이렇게 생성된 텍스트는 LLM의 입력값으로 사용됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;2. 임베딩 생성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;LLM(LLaMA 2)을 활용하여 각 텍스트의 임베딩을 생성합니다. 아래는 로컬 API를 사용하여 임베딩을 생성하는 예제입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;import requests

def get_embedding(text):
    res = requests.post('http://localhost:11434/api/embeddings', json={'model': 'llama2', 'prompt': text})
    return res.json()['embedding']&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;최적화 팁&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;임베딩 캐싱&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 반복 작업을 줄이기 위해 생성된 임베딩은 로컬 파일에 저장합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;병렬 처리&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 데이터가 클 경우, &lt;/span&gt;&lt;span&gt;ThreadPoolExecutor&lt;/span&gt;&lt;span&gt;를 사용해 병렬로 임베딩을 생성하여 처리 속도를 높입니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;3. FAISS 인덱스 생성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;FAISS를 사용해 임베딩 기반 유사성 검색을 위한 인덱스를 생성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;sas&quot;&gt;&lt;code&gt;import faiss

index = faiss.IndexFlatL2(4096)  # 임베딩 차원 크기
index.add(X)  # X는 생성된 임베딩 배열&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;FAISS는 대규모 데이터셋에서도 빠른 유사성 검색이 가능하며, 확장성 있는 구조를 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;4. 추천 생성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;특정 영화와 유사한 영화를 추천하려면 해당 영화의 임베딩을 기준으로 인덱스에서 가장 가까운 임베딩을 찾습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;def get_recommendations(movie_index, num_recommendations=5):
    movie_embedding = X[movie_index].reshape(1, -1)
    D, I = index.search(movie_embedding, num_recommendations + 1)
    return df.iloc[I[0][1:]]  # 입력 영화는 제외&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어, &lt;/span&gt;&lt;span&gt;favorite_movie_index = 1358&lt;/span&gt;&lt;span&gt;로 설정하면, 해당 영화와 유사한 영화 목록을 출력할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;이 접근법의 장점&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;1. 의미적 이해&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;LLM을 통해 설명, 장르, 캐스트 등 다양한 정보를 학습하여 영화 간의 미묘한 관계를 이해할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;2. 유연성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;새로운 특성(feature)을 쉽게 추가하거나, 텍스트 외 다른 콘텐츠로도 확장 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;3. 확장성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;FAISS를 통해 수백만 개 이상의 항목을 효율적으로 처리할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;4. 콜드 스타트 문제 해결&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사용자 기록이 없는 경우에도 콘텐츠 기반 추천이 가능해 초기 사용자 경험을 개선할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;한계점 및 개선 방향&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;1. 텍스트 품질 의존성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;영화 설명이나 메타데이터가 부실할 경우, 추천 품질이 낮아질 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;2. 개인화 부족&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사용자 선호도와 시청 기록을 반영하지 않아 개인화된 추천이 어렵습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;3. 모델 성능 의존성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사용하는 LLM과 임베딩 품질에 따라 시스템 성능이 크게 좌우됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;4. 실시간 응답성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;대규모 데이터에서 실시간으로 작동하려면 추가적인 최적화가 필요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;결론&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;LLM을 활용한 추천 시스템은 기존 방식과는 다른 차원의 추천 경험을 제공합니다. 텍스트 데이터를 보다 깊이 이해하고 활용할 수 있어 더 정교한 추천이 가능하며, 특히 콘텐츠 기반 추천에 강점을 보입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 글에서 소개한 구현은 비교적 간단한 예제지만, LLM과 FAISS의 결합을 통해 고도화된 추천 시스템 구축의 가능성을 보여줍니다. 앞으로 LLM 기술이 더욱 발전하면서 추천 시스템의 새로운 패러다임이 열릴 것으로 기대됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;참고 자료&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;Netflix Titles Dataset: &lt;/span&gt;&lt;span&gt;&lt;a&gt;Kaggle&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;FAISS Documentation: &lt;/span&gt;&lt;a href=&quot;https://github.com/facebookresearch/faiss&quot;&gt;&lt;span&gt;FAISS GitHub&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Recommendation System</category>
      <author>Dan-k</author>
      <guid isPermaLink="true">https://dodonam.tistory.com/507</guid>
      <comments>https://dodonam.tistory.com/507#entry507comment</comments>
      <pubDate>Mon, 27 Jan 2025 10:05:24 +0900</pubDate>
    </item>
    <item>
      <title>MAB(Multi-Armed Bandit), 톰슨 샘플링</title>
      <link>https://dodonam.tistory.com/508</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. MAB란 무엇인가?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Multi-Armed Bandit(MAB) 문제는 여러 개의 슬롯 머신(팔을 당기는 밴딧) 중에서 어느 것을 선택해야 가장 높은 보상을 얻을 수 있는지 결정하는 문제입니다. 이 문제는 탐색(Exploration)과 활용(Exploitation) 사이의 균형을 잡는 것이 핵심입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;702&quot; data-origin-height=&quot;472&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9Ica1/btsLYqefk9z/Xn0T1UV4wAkK41zJg0jOGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9Ica1/btsLYqefk9z/Xn0T1UV4wAkK41zJg0jOGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9Ica1/btsLYqefk9z/Xn0T1UV4wAkK41zJg0jOGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9Ica1%2FbtsLYqefk9z%2FXn0T1UV4wAkK41zJg0jOGK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;702&quot; height=&quot;472&quot; data-origin-width=&quot;702&quot; data-origin-height=&quot;472&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주요 구성 요소&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;팔(Arm)&lt;/b&gt;: 선택 가능한 슬롯 머신 또는 행동.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;보상(Reward)&lt;/b&gt;: 선택한 팔에서 얻는 결과(예: 클릭, 구매 등).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;목표&lt;/b&gt;: 보상의 합계를 최대화.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MAB 문제는 A/B 테스트, 광고 배치, 콘텐츠 추천 등 다양한 실생활 문제에 응용됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 탐색과 활용의 트레이드오프&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MAB의 가장 큰 도전 과제는 탐색과 활용 사이의 트레이드오프를 해결하는 것입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;탐색(Exploration)&lt;/b&gt;: 더 나은 팔을 찾기 위해 새로운 선택을 시도.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;활용(Exploitation)&lt;/b&gt;: 현재 가장 성과가 좋은 팔을 선택하여 보상을 극대화.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;예시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 3개의 팔을 가진 슬롯 머신이 있다고 가정해봅시다. 각각의 팔은 서로 다른 확률로 보상을 제공합니다. 이 확률을 미리 알 수 없기 때문에 탐색과 활용을 통해 최적의 팔을 찾아야 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 톰슨 샘플링(Thompson Sampling)&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;톰슨 샘플링은 확률론적 방법을 이용해 탐색과 활용을 균형 있게 수행하는 알고리즘입니다. 각 팔의 보상 분포를 추정하기 위해 베타 분포를 사용합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;동작 원리&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;각 팔에 대해 베타 분포를 초기화합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;베타 분포의 초기값은 (모두 동일한 사전 정보).&lt;/li&gt;
&lt;li&gt;알파가 커질수록 오른쪽으로 봉우리가 이동!!!! -&amp;gt; 즉, 선택(성공)될 수록 선택될 확률이 높아지는 것!!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;각 팔에서 샘플을 한 번씩 추출합니다.&lt;/li&gt;
&lt;li&gt;가장 높은 샘플 값을 가진 팔을 선택합니다.&lt;/li&gt;
&lt;li&gt;선택한 팔의 결과에 따라 베타 분포를 업데이트합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;성공(보상 획득):&lt;/li&gt;
&lt;li&gt;실패(보상 미획득):&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;위 과정을 반복합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-1842157661141847&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 예제 코드&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 톰슨 샘플링을 구현한 Python 코드입니다:&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import numpy as np
from scipy.stats import beta
import matplotlib.pyplot as plt

# 팔의 실제 보상 확률
true_conversion_rates = [0.1, 0.3, 0.5]
num_arms = len(true_conversion_rates)

# 각 팔의 베타 분포 파라미터 초기화
alpha = np.ones(num_arms)
beta_params = np.ones(num_arms)

# 시뮬레이션 설정
num_trials = 1000
rewards = np.zeros(num_trials)

for trial in range(num_trials):
    # 1. 각 팔의 샘플링
    sampled_theta = [np.random.beta(alpha[i], beta_params[i]) for i in range(num_arms)]

    # 2. 가장 높은 샘플 값을 가진 팔 선택
    chosen_arm = np.argmax(sampled_theta)

    # 3. 선택된 팔에서 보상 관찰
    reward = np.random.rand() &amp;lt; true_conversion_rates[chosen_arm]

    # 4. 보상에 따라 베타 분포 업데이트
    if reward:
        alpha[chosen_arm] += 1
    else:
        beta_params[chosen_arm] += 1

    # 보상 기록
    rewards[trial] = reward

    # 5. 주기적으로 베타 분포 시각화
    if trial % 200 == 0 or trial == num_trials - 1:
        x = np.linspace(0, 1, 1000)
        plt.figure(figsize=(12, 6))
        for i in range(num_arms):
            plt.plot(x, beta.pdf(x, alpha[i], beta_params[i]), label=f&quot;Arm {i+1}: Beta({alpha[i]}, {beta_params[i]})&quot;)
        plt.title(f&quot;Trial {trial+1}&quot;)
        plt.legend()
        plt.show()

print(f&quot;총 보상: {rewards.sum()}&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 결과 분석&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 다음을 보여줍니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;초기에는 각 팔에 대해 고르게 탐색합니다.&lt;/li&gt;
&lt;li&gt;시간이 지남에 따라 가장 보상이 높은 팔을 점점 더 자주 선택하게 됩니다.&lt;/li&gt;
&lt;li&gt;각 팔의 베타 분포는 트라이얼이 진행됨에 따라 업데이트됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;시각화&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;각 팔의 베타 분포를 시각화하면 탐색 및 활용 과정에서 팔들의 우선순위가 어떻게 변화하는지 확인할 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;처음에는 각 arm의 확률 분포를 기준으로 랜덤하게 선택했을때 선택되는 arm이 다를 수 있지만,&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;시도(exploration)가 반복됨에 따라 각 arm의 확률분포가 극단적으로 수렴하여 랜덤하게 선택되어도, 가장 우측에 봉우리가 만들어진 arm이 계속 선택될 것(exploitation)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;713&quot; data-origin-height=&quot;373&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnDq1H/btsLZghOLJk/VR2mWoDKvmG7IbRSSQt71k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnDq1H/btsLZghOLJk/VR2mWoDKvmG7IbRSSQt71k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnDq1H/btsLZghOLJk/VR2mWoDKvmG7IbRSSQt71k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnDq1H%2FbtsLZghOLJk%2FVR2mWoDKvmG7IbRSSQt71k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;713&quot; height=&quot;373&quot; data-origin-width=&quot;713&quot; data-origin-height=&quot;373&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;373&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GkSjA/btsLW1fpSYP/SObj4VJ2kI0KAUqYJeJk7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GkSjA/btsLW1fpSYP/SObj4VJ2kI0KAUqYJeJk7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GkSjA/btsLW1fpSYP/SObj4VJ2kI0KAUqYJeJk7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGkSjA%2FbtsLW1fpSYP%2FSObj4VJ2kI0KAUqYJeJk7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;697&quot; height=&quot;373&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;373&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;713&quot; data-origin-height=&quot;373&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q2zdd/btsLWZhDWCX/o5lEk88elfCoKHJw1eHfV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q2zdd/btsLWZhDWCX/o5lEk88elfCoKHJw1eHfV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q2zdd/btsLWZhDWCX/o5lEk88elfCoKHJw1eHfV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq2zdd%2FbtsLWZhDWCX%2Fo5lEk88elfCoKHJw1eHfV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;713&quot; height=&quot;373&quot; data-origin-width=&quot;713&quot; data-origin-height=&quot;373&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;373&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDpbkY/btsLYSal0Bq/BtCTAK6gy7CbXVaRSfgI8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDpbkY/btsLYSal0Bq/BtCTAK6gy7CbXVaRSfgI8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDpbkY/btsLYSal0Bq/BtCTAK6gy7CbXVaRSfgI8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDpbkY%2FbtsLYSal0Bq%2FBtCTAK6gy7CbXVaRSfgI8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;703&quot; height=&quot;373&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;373&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;373&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BHYCE/btsLXRDouk8/8I10fYK61GhKK3LNFJrVx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BHYCE/btsLXRDouk8/8I10fYK61GhKK3LNFJrVx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BHYCE/btsLXRDouk8/8I10fYK61GhKK3LNFJrVx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBHYCE%2FbtsLXRDouk8%2F8I10fYK61GhKK3LNFJrVx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;703&quot; height=&quot;373&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;373&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;톰슨 샘플링은 간단하면서도 강력한 MAB 알고리즘입니다. 베타 분포를 활용해 확률론적으로 최적의 선택을 수행하며, 실생활의 다양한 문제에 적용 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MAB 알고리즘은 온라인 광고, 콘텐츠 추천, 의료 실험 등 다양한 분야에서 큰 가치를 제공합니다. 특히, 탐색과 활용의 균형을 자동으로 맞춘다는 점에서 실용성이 매우 높습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737639200520&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import numpy as np

class ThompsonSampling:
    def __init__(self, num_arms):
        self.num_arms = num_arms
        self.successes = np.ones(num_arms)  # 각 팔의 성공 횟수 초기화
        self.failures = np.ones(num_arms)  # 각 팔의 실패 횟수 초기화

    def select_arm(self):
        # 각 팔에 대한 베타 분포에서 샘플링
        samples = np.random.beta(self.successes, self.failures)
        # 가장 높은 확률 값을 가진 팔 선택
        return np.argmax(samples)

    def update(self, chosen_arm, reward):
        if reward:
            self.successes[chosen_arm] += 1
        else:
            self.failures[chosen_arm] += 1
            

def run_experiment(num_arms, trials, data):
    ts = ThompsonSampling(num_arms)
    total_reward = 0
    for _ in range(trials):
        selected_arm = ts.select_arm()
        reward = get_reward(selected_arm, data)
        total_reward += reward
        ts.update(selected_arm, reward)
    return total_reward


# 예시 데이터
data = {0: 0.3, 1: 0.7, 2: 0.2}  # 각 팔의 실제 보상 확률
num_arms = len(data)
trials = 1000

total_reward = run_experiment(num_arms, trials, data)
print(&quot;Total reward:&quot;, total_reward)&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;참고자료&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://multithreaded.stitchfix.com/blog/2020/08/05/bandits/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://multithreaded.stitchfix.com/blog/2020/08/05/bandits/\&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737638089737&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Multi-Armed Bandits and the Stitch Fix Experimentation Platform | Stitch Fix Technology &amp;ndash; Multithreaded&quot; data-og-description=&quot;We understand that there is a lot going on in the world right now. We&amp;rsquo;re continuing to publish blog posts in the hope they provide some intellectual stimulation and a sense of connection during these times. See the following for actions that we&amp;rsquo;re taki&quot; data-og-host=&quot;multithreaded.stitchfix.com&quot; data-og-source-url=&quot;https://multithreaded.stitchfix.com/blog/2020/08/05/bandits/&quot; data-og-url=&quot;https://multithreaded.stitchfix.com/blog/2020/08/05/bandits/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/CL9pq/hyX7U0jo1S/5VJSUkElY8MkJAEbGK6Zh0/img.png?width=1025&amp;amp;height=654&amp;amp;face=0_0_1025_654,https://scrap.kakaocdn.net/dn/PwyJ7/hyX4x6N8ZU/9mAsEUDTGyHpgiGBcayRq1/img.png?width=1025&amp;amp;height=654&amp;amp;face=0_0_1025_654,https://scrap.kakaocdn.net/dn/NxkyK/hyX4kfiIq2/F7KO24okVuIpnRZeLaXg70/img.png?width=1025&amp;amp;height=654&amp;amp;face=0_0_1025_654&quot;&gt;&lt;a href=&quot;https://multithreaded.stitchfix.com/blog/2020/08/05/bandits/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://multithreaded.stitchfix.com/blog/2020/08/05/bandits/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/CL9pq/hyX7U0jo1S/5VJSUkElY8MkJAEbGK6Zh0/img.png?width=1025&amp;amp;height=654&amp;amp;face=0_0_1025_654,https://scrap.kakaocdn.net/dn/PwyJ7/hyX4x6N8ZU/9mAsEUDTGyHpgiGBcayRq1/img.png?width=1025&amp;amp;height=654&amp;amp;face=0_0_1025_654,https://scrap.kakaocdn.net/dn/NxkyK/hyX4kfiIq2/F7KO24okVuIpnRZeLaXg70/img.png?width=1025&amp;amp;height=654&amp;amp;face=0_0_1025_654');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Multi-Armed Bandits and the Stitch Fix Experimentation Platform | Stitch Fix Technology &amp;ndash; Multithreaded&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;We understand that there is a lot going on in the world right now. We&amp;rsquo;re continuing to publish blog posts in the hope they provide some intellectual stimulation and a sense of connection during these times. See the following for actions that we&amp;rsquo;re taki&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;multithreaded.stitchfix.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Recommendation System</category>
      <author>Dan-k</author>
      <guid isPermaLink="true">https://dodonam.tistory.com/508</guid>
      <comments>https://dodonam.tistory.com/508#entry508comment</comments>
      <pubDate>Fri, 24 Jan 2025 10:00:25 +0900</pubDate>
    </item>
    <item>
      <title>[Spark] 스파크 사용 최적화 / 유의사항!!!</title>
      <link>https://dodonam.tistory.com/506</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;스파크 사용 시 흔히 저지르는 실수와 최적화 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스파크는 빅데이터 처리를 위한 프레임워크로, 빠른 처리 속도로 유명합니다. 이전 글에서는 스파크의 기본 개념과 빠른 이유에 대해 다루었습니다. 이번 글에서는 스파크 애플리케이션의 성능과 메모리 활용을 개선하기 위해 알아야 할 흔한 실수와 최적화 방법에 대해 다루겠습니다. 여기에는 클러스터 최적화, 설정 값 조정, 코드 수준의 최적화 등이 포함됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실수 1: 지연 평가(Lazy Evaluation)를 이해하지 못함&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스파크는 전통적인 스크립트처럼 코드 라인별로 실행되지 않습니다.&lt;/p&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;data&amp;nbsp;=&amp;nbsp;spark.read.csv(&quot;large_file.csv&quot;)

data.filter(data[&quot;age&quot;]&amp;nbsp;&amp;gt;&amp;nbsp;30)

print(&quot;Filtering&amp;nbsp;done.&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드에서&amp;nbsp;print&amp;nbsp;문은 실행되지만, 스파크는 아직 필터링을 처리하지 않았습니다. 스파크는 지연 평가를 사용하여, 변환 작업은 액션(예:&amp;nbsp;.collect()&amp;nbsp;또는&amp;nbsp;.saveAsTextFile())이 트리거될 때만 실행됩니다. 즉각적인 실행을 기대하면 혼란스러울 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변환 작업(지연된 연산)과 액션(실행을 트리거하는 연산)의 차이를 이해해야 합니다.&lt;/p&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;data&amp;nbsp;=&amp;nbsp;spark.read.csv(&quot;large_file.csv&quot;)

filtered_data&amp;nbsp;=&amp;nbsp;data.filter(data[&quot;age&quot;]&amp;nbsp;&amp;gt;&amp;nbsp;30)

filtered_data.show()&amp;nbsp;&amp;nbsp;#&amp;nbsp;이&amp;nbsp;액션이&amp;nbsp;실행을&amp;nbsp;트리거합니다.

###
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실수 2: 데이터 분포를 고려하지 않고 기본 파티션 사용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘못된 데이터 파티셔닝은 작업 부하 분배의 불균형을 초래하여 작업이 느려지거나 충돌할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;파티셔닝 무시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 파티셔닝은 성능에 매우 중요합니다. 특히 데이터셋을 조인할 때 그렇습니다. 적절한 파티셔닝 없이 스파크는 데이터를 반복적으로 셔플링하여 불필요한 성능 저하를 초래할 수 있습니다. 병렬 처리는 스파크 작업 튜닝에서 매우 중요한 역할을 합니다. 각 파티션 ~ 작업은 처리에 단일 코어를 필요로 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;너무 많은 또는 너무 적은 파티션 사용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;너무 많은 파티션은 불필요한 오버헤드를 추가할 수 있고, 너무 적은 파티션은 클러스터 자원을 충분히 활용하지 못할 수 있습니다. 일반적인 가이드라인은 코어 수의 2~3배 정도의 파티션을 가지는 것입니다. 큰 데이터셋에 대해 파티션을 조정하지 않으면 불균형한 처리가 발생할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;clean&quot;&gt;&lt;code&gt;large_data&amp;nbsp;=&amp;nbsp;spark.read.csv(&quot;large_file.csv&quot;)

print(large_data.rdd.getNumPartitions())&amp;nbsp;&amp;nbsp;#&amp;nbsp;기본&amp;nbsp;파티션&amp;nbsp;수가&amp;nbsp;높거나&amp;nbsp;낮을&amp;nbsp;수&amp;nbsp;있습니다.

###
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.repartition()&amp;nbsp;또는&amp;nbsp;.coalesce()&amp;nbsp;사용하여 파티셔닝 조정&lt;/p&gt;
&lt;pre class=&quot;gauss&quot;&gt;&lt;code&gt;partitioned_data&amp;nbsp;=&amp;nbsp;large_data.repartition(10)

print(partitioned_data.rdd.getNumPartitions())&amp;nbsp;&amp;nbsp;#&amp;nbsp;이제&amp;nbsp;10개의&amp;nbsp;파티션으로&amp;nbsp;설정되었습니다.
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.repartition(numPartitions): 파티션 수를 증가 또는 감소시키는 데 사용됩니다. 클러스터의 노드 간에 데이터를 셔플링하므로 비용이 많이 듭니다. 더 많은 파티션이 필요하거나 조인 작업 후 데이터를 고르게 분배할 때 유용합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.coalesce(numPartitions): 주로 파티션 수를 줄이는 데 사용됩니다. 동일한 노드 내에서 파티션을 병합하여 셔플링을 피하므로&amp;nbsp;.repartition()보다 저렴합니다. 특히 처리 후 출력 준비를 위해 파티션을 통합할 때 유용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실수 3: 캐시/퍼시스트를 적절히 사용하지 않음&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 여러 번 사용할 때 캐시하지 않으면 스파크는 각 변환을 다시 계산합니다. 이는 변환이 복잡할 경우 비용이 많이 들 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;#&amp;nbsp;캐시&amp;nbsp;없이&amp;nbsp;데이터를&amp;nbsp;여러&amp;nbsp;번&amp;nbsp;사용

filtered_data&amp;nbsp;=&amp;nbsp;data.filter(data[&quot;age&quot;]&amp;nbsp;&amp;gt;&amp;nbsp;30)

filtered_data.count()

filtered_data.show()
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 액션은 필터링 단계를 다시 트리거합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;.cache()&amp;nbsp;또는&amp;nbsp;.persist()&amp;nbsp;사용&lt;/h3&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;#&amp;nbsp;데이터를&amp;nbsp;재사용할&amp;nbsp;의도가&amp;nbsp;있다면&amp;nbsp;캐시합니다.

filtered_data&amp;nbsp;=&amp;nbsp;data.filter(data[&quot;age&quot;]&amp;nbsp;&amp;gt;&amp;nbsp;30).cache()

filtered_data.count()

filtered_data.show()&amp;nbsp;&amp;nbsp;#&amp;nbsp;이제&amp;nbsp;더&amp;nbsp;빠르게&amp;nbsp;실행됩니다.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;캐시 및 퍼시스트의 부적절한 사용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 사람들이 캐시(예:&amp;nbsp;cache()&amp;nbsp;또는&amp;nbsp;persist())를 간과하여 반복 알고리즘이나 반복 액세스에서 재계산을 피할 수 있습니다. 그러나 모든 것을 캐시하면 메모리 문제가 발생할 수 있습니다. 필요할 때만 캐시하고 데이터가 더 이상 필요하지 않을 때는&amp;nbsp;unpersist를 사용하여 캐시를 해제하세요.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;너무 많은 변환 체인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중간 액션이나 캐시 없이 긴 변환 체인은 계보를 너무 복잡하게 만들어 실행 시간을 증가시킬 수 있습니다. 때로는 복잡한 체인을 분할하고 액션을 도입하거나 데이터를 캐시하는 것이 좋습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실수 4: 셔플 작업의 잘못된 구성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;셔플 작업(예:&amp;nbsp;join,&amp;nbsp;groupBy)은 네트워크와 메모리에 무거운 작업입니다. 잘못된 구성은 이러한 작업이 실패하게 만들 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;joined_data&amp;nbsp;=&amp;nbsp;large_data1.join(large_data2,&amp;nbsp;&quot;id&quot;)

joined_data.show()
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 크기에 따라 셔플 관련 구성을 조정하고 가능한 셔플을 줄이세요.&lt;/p&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;spark.conf.set(&quot;spark.sql.shuffle.partitions&quot;,&amp;nbsp;&quot;100&quot;)&amp;nbsp;&amp;nbsp;#&amp;nbsp;데이터&amp;nbsp;크기에&amp;nbsp;따라&amp;nbsp;조정

joined_data&amp;nbsp;=&amp;nbsp;large_data1.join(large_data2,&amp;nbsp;&quot;id&quot;)

joined_data.show()
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실수 5: 큰 데이터셋을 드라이버로 수집&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큰 데이터셋을&amp;nbsp;.collect()&amp;nbsp;또는&amp;nbsp;.take()로 드라이버로 가져오는 것은 메모리 오류를 일으킬 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;haskell&quot;&gt;&lt;code&gt;all_data&amp;nbsp;=&amp;nbsp;data.collect()&amp;nbsp;&amp;nbsp;#&amp;nbsp;전체&amp;nbsp;데이터셋을&amp;nbsp;드라이버로&amp;nbsp;수집
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터셋이 너무 크면 드라이버가 충돌할 수 있습니다. 작은 데이터 하위 집합에 대해&amp;nbsp;take&amp;nbsp;또는&amp;nbsp;takeSample과 같은 액션을 사용하는 것이 좋으며, 데이터셋 크기가 관리 가능한 경우를 제외하고&amp;nbsp;collect를 피하세요.&lt;/p&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;sample_data&amp;nbsp;=&amp;nbsp;data.limit(1000).collect()&amp;nbsp;&amp;nbsp;#&amp;nbsp;관리&amp;nbsp;가능한&amp;nbsp;양만&amp;nbsp;수집

#&amp;nbsp;또는&amp;nbsp;데이터를&amp;nbsp;직접&amp;nbsp;저장소에&amp;nbsp;씁니다.

data.write.parquet(&quot;output_path&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실수 6: 최적화 기술을 생략&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스파크에는 성능을 향상시키기 위한 최적화가 있지만, 이를 언제 사용해야 하는지 이해해야 합니다.&lt;/p&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;large_data.join(small_data,&amp;nbsp;&quot;id&quot;).show()&amp;nbsp;&amp;nbsp;#&amp;nbsp;큰&amp;nbsp;테이블과&amp;nbsp;작은&amp;nbsp;테이블의&amp;nbsp;느린&amp;nbsp;조
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작은 테이블에 대해 브로드캐스트 조인을 사용하고, 스파크의 Catalyst 옵티마이저에 의해 최적화된 DataFrame API를 활용하세요.&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;#&amp;nbsp;작은&amp;nbsp;테이블에&amp;nbsp;대해&amp;nbsp;브로드캐스트&amp;nbsp;조인을&amp;nbsp;사용

from&amp;nbsp;pyspark.sql.functions&amp;nbsp;import&amp;nbsp;broadcast

large_data.join(broadcast(small_data),&amp;nbsp;&quot;id&quot;).show()&amp;nbsp;&amp;nbsp;#&amp;nbsp;브로드캐스트가&amp;nbsp;조인을&amp;nbsp;최적화합니다.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실수 7: 비효율적인 집계&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;집계 작업을 실행할 때 성능에 미치는 영향을 이해하지 못함.&lt;/p&gt;
&lt;pre class=&quot;livecodeserver&quot;&gt;&lt;code&gt;#&amp;nbsp;큰&amp;nbsp;데이터를&amp;nbsp;직접&amp;nbsp;그룹화하는&amp;nbsp;대신

data.groupBy(&quot;category&quot;).sum(&quot;amount&quot;).show()

#&amp;nbsp;가능한&amp;nbsp;경우&amp;nbsp;맵&amp;nbsp;사이드&amp;nbsp;집계를&amp;nbsp;사용

data&amp;nbsp;=&amp;nbsp;data.map(lambda&amp;nbsp;x:&amp;nbsp;(x['category'],&amp;nbsp;x['amount']))&amp;nbsp;\\

.reduceByKey(lambda&amp;nbsp;a,&amp;nbsp;b:&amp;nbsp;a&amp;nbsp;+&amp;nbsp;b)
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;groupByKey&amp;nbsp;대신&amp;nbsp;reduceByKey&amp;nbsp;사용:&amp;nbsp;groupByKey는 동일한 키를 가진 모든 값을 단일 실행기로 보내 잠재적으로 메모리 문제를 일으킬 수 있습니다. 반면&amp;nbsp;reduceByKey는 각 파티션에서 로컬 축소를 수행한 후 데이터를 노드 간에 전송하여 일반적으로 더 효율적입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://medium.com/@vinciabhinav7/apache-spark-common-mistakes-14407bebe259&quot;&gt;https://medium.com/@vinciabhinav7/apache-spark-common-mistakes-14407bebe259&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1735118763656&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Apache Spark &amp;mdash; Common mistakes&amp;hellip;&quot; data-og-description=&quot;Spark is a framework for processing big data. In Part 1 we focused on the Basics of spark and Why its so fast&quot; data-og-host=&quot;medium.com&quot; data-og-source-url=&quot;https://medium.com/@vinciabhinav7/apache-spark-common-mistakes-14407bebe259&quot; data-og-url=&quot;https://medium.com/@vinciabhinav7/apache-spark-common-mistakes-14407bebe259&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bHaLds/hyXObjbZmI/9UC4onuboZfC94B38Ob3bK/img.png?width=1200&amp;amp;height=903&amp;amp;face=0_0_1200_903,https://scrap.kakaocdn.net/dn/KtZVJ/hyXOphqlPa/wykAqAGmA9a5mkGcqcZ5K1/img.png?width=1358&amp;amp;height=862&amp;amp;face=0_0_1358_862&quot;&gt;&lt;a href=&quot;https://medium.com/@vinciabhinav7/apache-spark-common-mistakes-14407bebe259&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://medium.com/@vinciabhinav7/apache-spark-common-mistakes-14407bebe259&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bHaLds/hyXObjbZmI/9UC4onuboZfC94B38Ob3bK/img.png?width=1200&amp;amp;height=903&amp;amp;face=0_0_1200_903,https://scrap.kakaocdn.net/dn/KtZVJ/hyXOphqlPa/wykAqAGmA9a5mkGcqcZ5K1/img.png?width=1358&amp;amp;height=862&amp;amp;face=0_0_1358_862');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Apache Spark &amp;mdash; Common mistakes&amp;hellip;&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Spark is a framework for processing big data. In Part 1 we focused on the Basics of spark and Why its so fast&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;medium.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Hadoop</category>
      <author>Dan-k</author>
      <guid isPermaLink="true">https://dodonam.tistory.com/506</guid>
      <comments>https://dodonam.tistory.com/506#entry506comment</comments>
      <pubDate>Wed, 25 Dec 2024 18:26:31 +0900</pubDate>
    </item>
    <item>
      <title>네거티브 샘플링</title>
      <link>https://dodonam.tistory.com/505</link>
      <description>&lt;h4 data-pm-slice=&quot;1 3 []&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;1. 네거티브 샘플링의 개념&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;대규모 데이터 학습에서 연산량을 줄이고 효율성을 높이는 기법.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;모든 데이터를 사용하지 않고 일부만 선택해 학습.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;주요 활용 분야: 자연어 처리(NLP), 딥러닝.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;대표 사례: &lt;/span&gt;&lt;span&gt;&lt;b&gt;Word2Vec&lt;/b&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5SL51/btsL2dd6whK/MFvPQbx0JFhbBkhC6pCVIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5SL51/btsL2dd6whK/MFvPQbx0JFhbBkhC6pCVIk/img.png&quot; data-alt=&quot;https://wikidocs.net/69141&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5SL51/btsL2dd6whK/MFvPQbx0JFhbBkhC6pCVIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5SL51%2FbtsL2dd6whK%2FMFvPQbx0JFhbBkhC6pCVIk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;656&quot; height=&quot;231&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;231&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://wikidocs.net/69141&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;2. 네거티브 샘플링의 작동 원리&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;Skip-gram 모델&lt;/b&gt;&lt;/span&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;중심 단어(center word)에서 주변 단어(context word)를 예측.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;예: &quot;고양이가 책상 위에 있다&quot; 문장에서 중심 단어 &quot;고양이&quot;를 기준으로 &quot;책상&quot;, &quot;위에&quot; 등을 예측.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;290&quot; data-origin-height=&quot;92&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FMKQ4/btsL1WDVpi2/2FvOryfSzBHNjsktyMGAw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FMKQ4/btsL1WDVpi2/2FvOryfSzBHNjsktyMGAw0/img.png&quot; data-alt=&quot;https://wikidocs.net/69141&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FMKQ4/btsL1WDVpi2/2FvOryfSzBHNjsktyMGAw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFMKQ4%2FbtsL1WDVpi2%2F2FvOryfSzBHNjsktyMGAw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;290&quot; height=&quot;92&quot; data-origin-width=&quot;290&quot; data-origin-height=&quot;92&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://wikidocs.net/69141&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;문제점&lt;/b&gt;&lt;/span&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;어휘 크기가 10만 개라면, 중심 단어마다 10만 개의 확률 분포를 계산해야 함.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;엄청난 연산량을 요구.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;해결: 네거티브 샘플링 도입&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;긍정 샘플(positive sample): 중심 단어와 실제 관련 있는 단어.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;네거티브 샘플(negative sample): 나머지 단어 중 일부를 무작위 선택.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;모델은 긍정 샘플과 네거티브 샘플을 구분하도록 학습.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;3. 네거티브 샘플링의 수학적 접근&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;손실 함수(Loss Function):&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;$v_c$: 중심 단어 벡터.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;$v_o$: 긍정 샘플 벡터.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;$v_i$: 네거티브 샘플 벡터.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;$P_n(w)$: 네거티브 샘플링 분포.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;$k$: 네거티브 샘플 개수.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;역할:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;중심 단어와 긍정 샘플 간 관계 강화.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;중심 단어와 네거티브 샘플 간 관계 약화.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;4. 네거티브 샘플링의 장점&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;연산 효율성 증가&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 일부 데이터만 사용해 연산량 감소.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;대규모 데이터셋 처리 가능&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 방대한 데이터도 빠르게 학습.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;간단한 구현&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 기존 모델에 쉽게 통합 가능.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;5. 네거티브 샘플링의 한계&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;샘플 품질 의존성&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 무작위 선택된 네거티브 샘플이 부적절할 가능성.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;균형 문제&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 샘플 수가 너무 적거나 많으면 학습 성능 저하.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;도메인 특화 데이터&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 적절한 샘플 분포 정의 어려움.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;6. 네거티브 샘플링 활용 사례&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;Word2Vec&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;구글 개발.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Skip-gram + 네거티브 샘플링 결합.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;효율적 단어 임베딩 생성.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;GloVe&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;Stanford NLP 연구.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;대규모 텍스트 데이터 처리.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;추천 시스템&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;사용자-아이템 상호작용 데이터 학습.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;실제 상호작용하지 않은 아이템을 네거티브 샘플로 사용.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;7. 결론&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;핵심 장점&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;연산량 감소.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;빠른 학습.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;대규모 데이터 효율적 처리.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;중요성&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;자연어 처리, 추천 시스템 등에서 널리 활용.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;적절한 네거티브 샘플 선택과 균형 유지 필요.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;참고 자료&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1301.3781&quot;&gt;&lt;span&gt;Word2Vec 논문&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nlp.stanford.edu/projects/glove/&quot;&gt;&lt;span&gt;GloVe 논문&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://example.com/recommendation-system&quot;&gt;&lt;span&gt;추천 시스템과 딥러닝&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Statistical Learning</category>
      <author>Dan-k</author>
      <guid isPermaLink="true">https://dodonam.tistory.com/505</guid>
      <comments>https://dodonam.tistory.com/505#entry505comment</comments>
      <pubDate>Fri, 20 Dec 2024 14:56:42 +0900</pubDate>
    </item>
    <item>
      <title>범주형 변수 상관관계?! -&amp;gt; cross tab with chi square</title>
      <link>https://dodonam.tistory.com/504</link>
      <description>&lt;h1&gt;&lt;b&gt;교차표와 카이제곱 검정: 독립성 테스트&lt;/b&gt;&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 교차표란?&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;교차표(Cross Tabulation)&lt;/b&gt;: 두 변수 간의 관계를 2차원 행렬로 나타내는 방법
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;두 변수의 각 범주에 대한 빈도를 표시&lt;/li&gt;
&lt;li&gt;Excel의 피벗 테이블과 유사하게 데이터를 시각화&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주요 장점&lt;/b&gt;: 데이터 분포를 쉽게 이해 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 카이제곱 검정이란?&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;카이제곱 검정(&amp;chi;&amp;sup2; Test)&lt;/b&gt;: 두 변수 간의 관계가 통계적으로 유의미한지 평가하는 방법
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;목적&lt;/b&gt;: 관찰된 데이터가 우연인지, 아니면 두 변수 간에 실제로 의미 있는 관계가 있는지를 판단&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 예시&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;질문&lt;/b&gt;: &quot;마지막 접촉 채널과 디바이스 유형 간에 관계가 있는가?&quot;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;방법&lt;/b&gt;: 교차표를 통해 두 변수의 분포 확인 후 카이제곱 검정 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 카이제곱 검정 수행 절차&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;관찰 데이터(Observed Data) 준비&lt;/b&gt;: 두 변수의 실제 데이터를 교차표 형태로 정리&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기대값(Expected Values) 계산&lt;/b&gt;: 각 셀의 기대값 계산
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 행, 열의 총합을 이용하여 기대값 도출&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;카이제곱 통계량 계산&lt;/b&gt;: 각 셀에 대해 관찰값과 기대값 차이를 제곱 후 기대값으로 나누어 카이제곱 통계량 계산&lt;/li&gt;
&lt;li&gt;&lt;b&gt;카이제곱 값 합산&lt;/b&gt;: 모든 셀의 카이제곱 값을 합산하여 최종 카이제곱 값 도출&lt;/li&gt;
&lt;li&gt;&lt;b&gt;유의미성 평가&lt;/b&gt;: 최종 카이제곱 값을 임계값과 비교하여 귀무가설 기각 여부 결정&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 예시 계산: 데스크탑 사용자와 유기적 검색&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;기대값 계산 방식&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;행 총합(데스크탑) / 전체 총합&lt;/li&gt;
&lt;li&gt;열 총합(유기적 검색) / 전체 총합&lt;/li&gt;
&lt;li&gt;위 두 값 곱한 후 전체 총합으로 곱산&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;수식 예시&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1731425999598&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;sessionsexpected = (r1 / T) * (c1 / T) * T = (100 / 300) * (80 / 300) * 300 = 26.67 &amp;asymp; 27&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 셀에 대해 기대값을 계산한 후 관찰값과 비교하여 카이제곱 통계량 계산&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. Python을 사용한 카이제곱 검정 예시&lt;/h2&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import pandas as pd
from scipy.stats import chi2_contingency

# 데이터 프레임 생성
data = {'device_category': ['Phone', 'Tablet', 'Desktop'],
        'Organic_Search': [35, 20, 25],
        'Paid_Search': [15, 30, 20],
        'Email': [10, 25, 35],
        'Display': [40, 25, 20]}
df = pd.DataFrame(data)

# 교차표 생성
cross_tab = df.set_index('device_category')

# 카이제곱 검정 수행
chi2, p, dof, expected = chi2_contingency(cross_tab)

print(f&quot;Chi2: {chi2}&quot;)
print(f&quot;P-value: {p}&quot;)
print(f&quot;Degrees of Freedom: {dof}&quot;)
print(&quot;Expected Frequencies:&quot;)
print(expected)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;출력 결과&lt;/b&gt;: 카이제곱 값, p-값, 자유도 및 기대값이 포함됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. 결과 해석&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;유의미성 평가&lt;/b&gt;: 자유도와 유의수준을 사용해 임계값 결정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예: 자유도 6, 유의수준 0.1일 때, 임계 카이제곱 값 = 10.64&lt;/li&gt;
&lt;li&gt;&lt;b&gt;결론&lt;/b&gt;: 관찰된 카이제곱 값이 임계값 초과 시 귀무가설 기각 &amp;rarr; 두 변수 간 유의미한 관계 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. 결론&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;카이제곱 검정&lt;/b&gt;: 두 변수 간 관계 평가에 유용한 도구
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 분석 시 &lt;b&gt;단순 우연이 아닌 유의미한 관계&lt;/b&gt; 여부를 판단하는 데 활용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;교차표와 카이제곱 검정&lt;/b&gt;을 통해 데이터에서 유용한 통찰 도출 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.dartistics.com/cross-tab-w-chi-square.html&quot;&gt;https://www.dartistics.com/cross-tab-w-chi-square.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1731425824524&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Cross Tab with Chi-Square&quot; data-og-description=&quot;Let&amp;rsquo;s get a little wordy and a little Greek. The full title of this topic (phonetically) is &amp;ldquo;Cross Tabulations with a Chi-Square Test of Independence.&amp;rdquo; To really write it in a way that will make a statistician happy, it&amp;rsquo;s, &amp;ldquo;Cross Tabulations with&quot; data-og-host=&quot;www.dartistics.com&quot; data-og-source-url=&quot;https://www.dartistics.com/cross-tab-w-chi-square.html&quot; data-og-url=&quot;https://www.dartistics.com/cross-tab-w-chi-square.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fQjUd/hyXwqG0MRZ/g4svw29gNAKiahfdRxaQmk/img.png?width=1536&amp;amp;height=576&amp;amp;face=0_0_1536_576,https://scrap.kakaocdn.net/dn/eDJ5U/hyXwh4l70K/8oKPvgHuM36ExTPdiVsFJk/img.png?width=1536&amp;amp;height=576&amp;amp;face=0_0_1536_576,https://scrap.kakaocdn.net/dn/RpvgN/hyXwq74r57/3HJqjBxikDd0FgtAtdXKVK/img.png?width=1536&amp;amp;height=576&amp;amp;face=0_0_1536_576&quot;&gt;&lt;a href=&quot;https://www.dartistics.com/cross-tab-w-chi-square.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.dartistics.com/cross-tab-w-chi-square.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fQjUd/hyXwqG0MRZ/g4svw29gNAKiahfdRxaQmk/img.png?width=1536&amp;amp;height=576&amp;amp;face=0_0_1536_576,https://scrap.kakaocdn.net/dn/eDJ5U/hyXwh4l70K/8oKPvgHuM36ExTPdiVsFJk/img.png?width=1536&amp;amp;height=576&amp;amp;face=0_0_1536_576,https://scrap.kakaocdn.net/dn/RpvgN/hyXwq74r57/3HJqjBxikDd0FgtAtdXKVK/img.png?width=1536&amp;amp;height=576&amp;amp;face=0_0_1536_576');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Cross Tab with Chi-Square&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Let&amp;rsquo;s get a little wordy and a little Greek. The full title of this topic (phonetically) is &amp;ldquo;Cross Tabulations with a Chi-Square Test of Independence.&amp;rdquo; To really write it in a way that will make a statistician happy, it&amp;rsquo;s, &amp;ldquo;Cross Tabulations with&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.dartistics.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Statistical Learning</category>
      <author>Dan-k</author>
      <guid isPermaLink="true">https://dodonam.tistory.com/504</guid>
      <comments>https://dodonam.tistory.com/504#entry504comment</comments>
      <pubDate>Wed, 13 Nov 2024 10:40:25 +0900</pubDate>
    </item>
    <item>
      <title>[SQL : impala] Join 최적화 (Broadcast Vs Partitioned)</title>
      <link>https://dodonam.tistory.com/503</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. JOIN 방식의 개요&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;임팔라의 JOIN 방식&lt;/b&gt;: 두 가지 방식 제공
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;BROADCAST JOIN&lt;/b&gt;: 작은 테이블을 모든 노드에 전송하여 메모리상에서 JOIN 수행&lt;/li&gt;
&lt;li&gt;&lt;b&gt;PARTITIONED JOIN&lt;/b&gt;: 큰 테이블 간 결합 시 파티셔닝을 통한 분산 처리 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;BROADCAST JOIN&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정의&lt;/b&gt;: JOIN 대상 중 작은 테이블을 쿼리 참여 노드에 모두 전송하여 JOIN 연산 수행&lt;/li&gt;
&lt;li&gt;&lt;b&gt;적합한 사용 시기&lt;/b&gt;: 작은 테이블과 큰 테이블의 JOIN 연산 시 유리&lt;/li&gt;
&lt;li&gt;&lt;b&gt;특징&lt;/b&gt;: 작은 테이블이 전체 노드에 복제되므로 빠른 처리 가능. 큰 테이블 broadcast 시 메모리 과부하 발생 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;PARTITIONED JOIN&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정의&lt;/b&gt;: JOIN 연산에 참여하는 두 테이블을 키(key) 기준으로 파티셔닝 후 각 파티션에서 JOIN 수행&lt;/li&gt;
&lt;li&gt;&lt;b&gt;적합한 사용 시기&lt;/b&gt;: 큰 테이블 간 결합에 주로 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;특징&lt;/b&gt;: 데이터를 분산 처리하여 메모리 사용 최적화 및 대규모 데이터 JOIN에서 성능 향상 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. BROADCAST JOIN과 PARTITIONED JOIN 비교&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비교 항목 BROADCAST JOIN PARTITIONED JOIN&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;사용 상황&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;작은 테이블과 큰 테이블의 JOIN&lt;/td&gt;
&lt;td&gt;큰 테이블 간의 JOIN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;처리 방식&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;작은 테이블을 모든 노드로 전송&lt;/td&gt;
&lt;td&gt;테이블을 키 기준으로 파티셔닝&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;간단한 구성으로 빠른 JOIN 가능&lt;/td&gt;
&lt;td&gt;메모리 사용 최적화, 대규모 데이터 효율적 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;큰 테이블 broadcast 시 메모리 과다 사용 위험&lt;/td&gt;
&lt;td&gt;초기 파티셔닝 작업으로 오버헤드 발생&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;메모리 사용&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;테이블 크기에 따라 메모리 사용 급증&lt;/td&gt;
&lt;td&gt;파티셔닝을 통한 메모리 사용 절감&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. JOIN 힌트를 통한 최적화 방법&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;JOIN 힌트&lt;/b&gt;: 특정 JOIN 방식을 강제하여 쿼리 최적화 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;힌트 종류&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;BROADCAST&lt;/b&gt;: BROADCAST JOIN 강제&lt;/li&gt;
&lt;li&gt;&lt;b&gt;SHUFFLE&lt;/b&gt;: PARTITIONED JOIN 강제&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;JOIN 힌트 사용 예시&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;BROADCAST 힌트&lt;/b&gt;: 작은 테이블을 모든 노드로 전송
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;small_table을 broadcast하여 JOIN 수행&lt;/li&gt;
&lt;li&gt;large_table이 큰 경우 적합&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1730985761752&quot; class=&quot;n1ql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;SELECT *
FROM large_table AS t1
	JOIN /* +BROADCAST */ small_table AS t2 ON t1.id = t2.id;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SELECT /*+ BROADCAST(t1) */ * FROM large_table AS t1 JOIN small_table AS t2 ON t1.id = t2.id;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;SHUFFLE 힌트&lt;/b&gt;: 테이블을 파티셔닝하여 PARTITIONED JOIN 수행
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;large_table1과 large_table2 간 PARTITIONED JOIN 수행 강제&lt;/li&gt;
&lt;li&gt;대규모 데이터 집합 간 JOIN 시 유리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1730985774820&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT *
FROM large_table1 AS t1
	JOIN /* +SHUFFLE */ large_table2 AS t2 ON t1.id = t2.id;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 결론: 데이터 특성에 맞는 JOIN 방식 선택하기&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;BROADCAST JOIN&lt;/b&gt;: 작은 테이블 JOIN에서 성능이 뛰어남, 큰 테이블 broadcast 시 메모리 부담&lt;/li&gt;
&lt;li&gt;&lt;b&gt;PARTITIONED JOIN&lt;/b&gt;: 큰 테이블 간 JOIN에 적합, 파티셔닝을 통한 메모리 최적화 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;JOIN 힌트 활용&lt;/b&gt;: 데이터 특성 및 쿼리 목적에 맞는 JOIN 방식 강제 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1730985893300&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
	straight_join t1.name, t2.id, t3.price
FROM t1 join /* +shuffle */ t2 join /* +broadcast */ t3 on t1.id = t2.id and t2.id = t3.id;​&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;750&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bU4VIB/btsKAHnYsPr/iHrtb0gMbDI1aOwoJmlpF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bU4VIB/btsKAHnYsPr/iHrtb0gMbDI1aOwoJmlpF0/img.png&quot; data-alt=&quot;source: https://docs.aws.amazon.com/prescriptive-guidance/latest/tuning-aws-glue-for-apache-spark/optimize-shuffles.html&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bU4VIB/btsKAHnYsPr/iHrtb0gMbDI1aOwoJmlpF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbU4VIB%2FbtsKAHnYsPr%2FiHrtb0gMbDI1aOwoJmlpF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;750&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;750&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;source: https://docs.aws.amazon.com/prescriptive-guidance/latest/tuning-aws-glue-for-apache-spark/optimize-shuffles.html&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/prescriptive-guidance/latest/tuning-aws-glue-for-apache-spark/optimize-shuffles.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.aws.amazon.com/prescriptive-guidance/latest/tuning-aws-glue-for-apache-spark/optimize-shuffles.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1730986069919&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Optimize shuffles -&quot; data-og-description=&quot;Optimize shuffles Certain operations, such as join() and groupByKey(), require Spark to perform a shuffle. The shuffle is Spark's mechanism for redistributing data so that it's grouped differently across RDD partitions. Shuffling can help remediate perform&quot; data-og-host=&quot;docs.aws.amazon.com&quot; data-og-source-url=&quot;https://docs.aws.amazon.com/prescriptive-guidance/latest/tuning-aws-glue-for-apache-spark/optimize-shuffles.html&quot; data-og-url=&quot;https://docs.aws.amazon.com/prescriptive-guidance/latest/tuning-aws-glue-for-apache-spark/optimize-shuffles.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ThnEp/hyXsQTEXEH/Qm9gPHvVKpiOjEx0a2R3Zk/img.png?width=1472&amp;amp;height=863&amp;amp;face=0_0_1472_863,https://scrap.kakaocdn.net/dn/bfWPHV/hyXwjs4Pjj/iBLyyVELL2wKQlSKynsLS1/img.png?width=1227&amp;amp;height=492&amp;amp;face=0_0_1227_492,https://scrap.kakaocdn.net/dn/9VYFd/hyXwp07Bhy/F2NmwOP2EjdRwbMPeDmDU0/img.png?width=1463&amp;amp;height=237&amp;amp;face=0_0_1463_237&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/prescriptive-guidance/latest/tuning-aws-glue-for-apache-spark/optimize-shuffles.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.aws.amazon.com/prescriptive-guidance/latest/tuning-aws-glue-for-apache-spark/optimize-shuffles.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ThnEp/hyXsQTEXEH/Qm9gPHvVKpiOjEx0a2R3Zk/img.png?width=1472&amp;amp;height=863&amp;amp;face=0_0_1472_863,https://scrap.kakaocdn.net/dn/bfWPHV/hyXwjs4Pjj/iBLyyVELL2wKQlSKynsLS1/img.png?width=1227&amp;amp;height=492&amp;amp;face=0_0_1227_492,https://scrap.kakaocdn.net/dn/9VYFd/hyXwp07Bhy/F2NmwOP2EjdRwbMPeDmDU0/img.png?width=1463&amp;amp;height=237&amp;amp;face=0_0_1463_237');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Optimize shuffles -&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Optimize shuffles Certain operations, such as join() and groupByKey(), require Spark to perform a shuffle. The shuffle is Spark's mechanism for redistributing data so that it's grouped differently across RDD partitions. Shuffling can help remediate perform&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://impala.apache.org/docs/build/html/topics/impala_hints.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://impala.apache.org/docs/build/html/topics/impala_hints.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1730986080648&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Optimizer Hints&quot; data-og-description=&quot;The Impala SQL supports query hints, for fine-tuning the inner workings of queries. Specify hints as a temporary workaround for expensive queries, where missing statistics or other factors cause inefficient performance. Hints are most often used for the re&quot; data-og-host=&quot;impala.apache.org&quot; data-og-source-url=&quot;https://impala.apache.org/docs/build/html/topics/impala_hints.html&quot; data-og-url=&quot;https://impala.apache.org/docs/build/html/topics/impala_hints.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://impala.apache.org/docs/build/html/topics/impala_hints.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://impala.apache.org/docs/build/html/topics/impala_hints.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Optimizer Hints&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The Impala SQL supports query hints, for fine-tuning the inner workings of queries. Specify hints as a temporary workaround for expensive queries, where missing statistics or other factors cause inefficient performance. Hints are most often used for the re&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;impala.apache.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Data Visualization &amp;amp; DataBase</category>
      <author>Dan-k</author>
      <guid isPermaLink="true">https://dodonam.tistory.com/503</guid>
      <comments>https://dodonam.tistory.com/503#entry503comment</comments>
      <pubDate>Thu, 7 Nov 2024 22:23:28 +0900</pubDate>
    </item>
    <item>
      <title>[앱개발] React Native</title>
      <link>https://dodonam.tistory.com/502</link>
      <description>&lt;h1&gt;&lt;b&gt;React Native로 모바일 앱 개발하기&lt;/b&gt;&lt;/h1&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 크로스 플랫폼 개발의 필요성&lt;/h2&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;모바일 애플리케이션 시장의 확대로 다양한 플랫폼(iOS, Android)에서 실행 가능한 앱이 요구됨.&lt;/li&gt;&lt;li&gt;기존에는 각각의 플랫폼에 맞는 네이티브 코드를 작성해야 했으나, &lt;b&gt;크로스 플랫폼 개발&lt;/b&gt; 프레임워크가 이를 해결.&lt;/li&gt;&lt;li&gt;&lt;b&gt;React Native&lt;/b&gt;는 Facebook이 개발한 오픈소스 크로스 플랫폼 프레임워크로, 단일 코드베이스로 iOS와 Android 앱을 만들 수 있음.&lt;/li&gt;&lt;/ul&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1238&quot; data-origin-height=&quot;646&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTmULS/btsKmp1nbxB/BE4LzvUX24D0wCMkuCSpqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTmULS/btsKmp1nbxB/BE4LzvUX24D0wCMkuCSpqK/img.png&quot; data-alt=&quot;source: https://pronteff.com/integrating-native-modules-into-react-native-android/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTmULS/btsKmp1nbxB/BE4LzvUX24D0wCMkuCSpqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTmULS%2FbtsKmp1nbxB%2FBE4LzvUX24D0wCMkuCSpqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1238&quot; height=&quot;646&quot; data-origin-width=&quot;1238&quot; data-origin-height=&quot;646&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;source: https://pronteff.com/integrating-native-modules-into-react-native-android/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. React Native란?&lt;/h2&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;&lt;b&gt;React Native&lt;/b&gt;는 &lt;b&gt;JavaScript와 React&lt;/b&gt;를 사용해 모바일 애플리케이션을 개발할 수 있는 프레임워크.&lt;/li&gt;&lt;li&gt;네이티브 앱 성능을 제공하면서도, 단일 코드베이스로 여러 플랫폼을 지원.&lt;/li&gt;&lt;li&gt;&lt;b&gt;React의 컴포넌트 기반 아키텍처&lt;/b&gt;를 적용해 UI와 로직을 재사용 가능하게 함.&lt;/li&gt;&lt;/ul&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. React Native의 주요 특징&lt;/h2&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;&lt;b&gt;크로스 플랫폼 개발&lt;/b&gt;: iOS와 Android용 애플리케이션을 하나의 코드로 개발.&lt;/li&gt;&lt;li&gt;&lt;b&gt;핫 리로딩(Hot Reloading)&lt;/b&gt;: 코드 변경 시 애플리케이션이 자동으로 업데이트되어 빠른 개발 사이클 가능.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Native Module 지원&lt;/b&gt;: 카메라, GPS, 스토리지 등 네이티브 모듈에 접근 가능.&lt;/li&gt;&lt;li&gt;&lt;b&gt;다양한 라이브러리 및 커뮤니티 지원&lt;/b&gt;: 다양한 플러그인과 커뮤니티 패키지 사용 가능.&lt;/li&gt;&lt;/ul&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. React Native 기본 설치 및 설정&lt;/h2&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;&lt;b&gt;환경 설정&lt;/b&gt;: Node.js, npm/yarn 설치 후 react-native-cli 설치.&lt;/li&gt;&lt;li&gt;bash 코드 복사 npm install -g react-native-cli&lt;/li&gt;&lt;li&gt;&lt;b&gt;새 프로젝트 생성&lt;/b&gt;:&lt;/li&gt;&lt;li&gt;bash 코드 복사 npx react-native init MyNewApp&lt;/li&gt;&lt;li&gt;&lt;b&gt;앱 실행&lt;/b&gt;: 에뮬레이터 혹은 실제 기기에서 앱 실행&lt;/li&gt;&lt;li&gt;bash 코드 복사 npx react-native run-android # Android npx react-native run-ios # iOS&lt;/li&gt;&lt;/ul&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. React Native의 UI 컴포넌트&lt;/h2&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;&lt;b&gt;뷰(View)&lt;/b&gt;: 레이아웃을 구성하는 컨테이너 역할.&lt;/li&gt;&lt;li&gt;&lt;b&gt;텍스트(Text)&lt;/b&gt;: 텍스트를 표시하는 컴포넌트.&lt;/li&gt;&lt;li&gt;&lt;b&gt;버튼(Button)&lt;/b&gt;: 기본 버튼 컴포넌트, 다양한 동작을 트리거하는 데 사용.&lt;/li&gt;&lt;li&gt;&lt;b&gt;스크롤뷰(ScrollView)&lt;/b&gt;: 스크롤 가능한 화면을 구현.&lt;/li&gt;&lt;li&gt;&lt;b&gt;이미지(Image)&lt;/b&gt;: 네트워크, 로컬 등 다양한 이미지 표시 지원.&lt;/li&gt;&lt;/ul&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;UI 구성 예시&lt;/h3&gt;&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;javascript
코드 복사
import React from 'react';
import { View, Text, Button } from 'react-native';

const App = () =&amp;gt; {
  return (
    &amp;lt;View style={{ padding: 20 }}&amp;gt;
      &amp;lt;Text&amp;gt;Welcome to React Native!&amp;lt;/Text&amp;gt;
      &amp;lt;Button title=&quot;Click me!&quot; onPress={() =&amp;gt; alert('Button clicked!')} /&amp;gt;
    &amp;lt;/View&amp;gt;
  );
};

export default App;

&lt;/code&gt;&lt;/pre&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 네이티브 모듈과의 통합&lt;/h2&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;카메라, 위치 정보, 파일 시스템 등 &lt;b&gt;네이티브 기능을 활용할 수 있는 모듈&lt;/b&gt;을 지원.&lt;/li&gt;&lt;li&gt;React Native 라이브러리 혹은 네이티브 코드(Java, Swift)로 구현 가능.&lt;/li&gt;&lt;/ul&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. React Native의 장점과 단점&lt;/h2&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt; 
 &lt;li&gt;&lt;b&gt;장점&lt;/b&gt; 
  &lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt; 
   &lt;li&gt;&lt;b&gt;생산성&lt;/b&gt;: 크로스 플랫폼 코드 재사용을 통해 개발 속도 향상.&lt;/li&gt; 
   &lt;li&gt;&lt;b&gt;다양한 라이브러리&lt;/b&gt;: 오픈소스 커뮤니티 지원이 많아 라이브러리 활용이 용이.&lt;/li&gt; 
   &lt;li&gt;&lt;b&gt;네이티브 성능&lt;/b&gt;: 네이티브 모듈을 통해 iOS와 Android 모두 최적화된 성능 제공.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;&lt;b&gt;단점&lt;/b&gt; 
  &lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt; 
   &lt;li&gt;&lt;b&gt;복잡한 UI 구현의 한계&lt;/b&gt;: 네이티브 앱에 비해 고도로 복잡한 UI 구현에 제약.&lt;/li&gt; 
   &lt;li&gt;&lt;b&gt;네이티브 코드 필요성&lt;/b&gt;: 네이티브 모듈이 필요한 경우 Java나 Swift 등의 네이티브 언어 지식이 필요.&lt;/li&gt; 
   &lt;li&gt;&lt;b&gt;성능&lt;/b&gt;: 크로스 플랫폼이기에 네이티브 앱 대비 성능이 약간 낮을 수 있음.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. React Native로 빠르게 모바일 앱 개발하기&lt;/h2&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;React Native는 &lt;b&gt;크로스 플랫폼 개발&lt;/b&gt;의 효율성과 생산성을 크게 높일 수 있음.&lt;/li&gt;&lt;li&gt;네이티브 성능과 UI 컴포넌트 사용이 가능하므로, 중소형 프로젝트는 물론 대형 프로젝트에도 사용하기 적합.&lt;/li&gt;&lt;li&gt;iOS와 Android 앱을 한 번에 개발하고자 하는 팀에 강력한 선택지가 될 수 있음.&lt;/li&gt;&lt;/ul&gt;</description>
      <category>Frontend</category>
      <author>Dan-k</author>
      <guid isPermaLink="true">https://dodonam.tistory.com/502</guid>
      <comments>https://dodonam.tistory.com/502#entry502comment</comments>
      <pubDate>Sun, 27 Oct 2024 22:59:48 +0900</pubDate>
    </item>
  </channel>
</rss>