<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>jongyoon_insight.log</title>
        <link>https://velog.io/</link>
        <description>효율적인 걸 좋아해요</description>
        <lastBuildDate>Sat, 09 Mar 2024 03:36:37 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>jongyoon_insight.log</title>
            <url>https://velog.velcdn.com/images/jongyoon_insight/profile/2baec606-203d-4691-b2f7-5ea5671dfd4f/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. jongyoon_insight.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jongyoon_insight" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Big query] 사용 함수]]></title>
            <link>https://velog.io/@jongyoon_insight/Big-query-%EC%82%AC%EC%9A%A9-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@jongyoon_insight/Big-query-%EC%82%AC%EC%9A%A9-%ED%95%A8%EC%88%98</guid>
            <pubDate>Sat, 09 Mar 2024 03:36:37 GMT</pubDate>
            <description><![CDATA[<p>EXTRACT
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/ce7cb9cd-21fc-4291-b25a-dae7893a8ebf/image.png" alt=""></p>
<p>DATE
DATETIME
TIMESTAMP</p>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/ee7deee0-0bb9-4b6d-9ddd-06ff8a3783c3/image.png" alt=""></p>
<p>SELECT * EXCEPT(column_name)
FROM <code>olist.olist_order</code></p>
<p>SELECT * REPLACE(column_name * 10000 AS column_name)
FROM <code>olist.olist_order</code></p>
<p>CAST(value AS data_type)
SAFE_CAST(value AS data_type)</p>
<blockquote>
<p>에러 있을 경우 에러를 발생시키지 않고 null 로 반환함</p>
</blockquote>
<p>SAFE_ADD(x,y) = x + y
SAFE_SUBTRACT(x,y) = x - y
SAFE_MULTIPLY(x,y) = x * y
<strong><em>SAFE_DIVIDE(x,y) = x / y</em></strong>
0으로 나눌 때 NaN 방지</p>
<pre><code>SELECT
 SAFE_DIVIDE(5, 0);
 IFNULL(SAFE_DIVIDE(5, 0) , 0)
&gt; null
&gt; 0</code></pre><h2 id="순위-행-매기는-방법">순위 행 매기는 방법</h2>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/a328e10c-4fdc-4f5e-a544-844602be6f70/image.png" alt=""></p>
<pre><code>
## order_id가 order_items 별로 price가 나눠져 있기 때문에 이를 합치기 위해 sum(order_items.price) 자료 준비

WITH tb as(
  SELECT
    item.order_id,
    sum(item.price) as ord_amt,
  from `olist.olist_order_items` as item
  group by item.order_id
)

## 도시, 주 별로 주문, 고객수, 매출을 agg 진행

, base as(
  SELECT
    cus.customer_city,
    cus.customer_state,
    count(distinct ord.order_id) as cnt_order,
    count(cus.customer_unique_id) as cnt_cus,
    sum(tb.ord_amt) as sum_sales

  FROM `olist.olist_orders` as ord
  INNER JOIN `tb`
    ON ord.order_id = tb.order_id
  LEFT JOIN `olist.olist_customers` as cus
    ON ord.customer_id = cus.customer_id
  WHERE 1=1
    AND EXTRACT(YEAR from order_approved_at) = 2017
    AND ord.order_status = &#39;delivered&#39;
    AND customer_state= &#39;SP&#39;
  GROUP BY 1,2
  ORDER by cnt_cus desc
)

## 위의 자료를 포함하여 랭킹까지 추가해줌

select *,
  row_number() over (partition by customer_state order by cnt_cus desc) as cust_rownum

from base
order by cust_rownum</code></pre><h2 id="월평균-구매금액-part-05-sql-chapter2-40">월평균 구매금액 part 05. SQL chapter2 40)</h2>
<pre><code>/* 우리 고객들은 월 평균 얼마를 사용하고 있는가
월 주문건
월 주문금액
*/

WITH tb AS(

SELECT 
  order_id, 
  sum(price) as sales
FROM `olist.olist_order_items` as item
GROUP BY order_id
)
, base AS(

SELECT 
  DATE_TRUNC(DATE(ord.order_approved_at),MONTH) as part_month,
  count(distinct ord.order_id) as cnt_ord,
  count(distinct cus.customer_unique_id) as cnt_cus,
  round(sum(tb.sales),0) as sales,
  round(safe_divide(round(sum(tb.sales),0), count(distinct cus.customer_unique_id)), 1) as avg_sales
FROM `olist.olist_orders` as ord
INNER JOIN `tb`
  ON ord.order_id = tb.order_id
LEFT JOIN `olist.olist_customers` as cus
  ON ord.customer_id = cus.customer_id
GROUP BY 1
ORDER BY 1
)

select * from base
WHERE 1=1
  and part_month is not null
</code></pre><h2 id="조건에-따라-값을-나누는-case">조건에 따라 값을 나누는 CASE</h2>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/aa000762-5ea6-4762-b48d-4daf44adf34d/image.png" alt=""></p>
<pre><code>/* 고객들의 등급 변화가 어떻게 일어나고 있는가?
월 주문금액
고객
*/

WITH tb AS(

SELECT 
  order_id, 
  sum(price) as sales
FROM `olist.olist_order_items` as item
GROUP BY order_id
)
, base AS(

SELECT 
  DATE_TRUNC(DATE(ord.order_approved_at),MONTH) as ord_month,
  cus.customer_unique_id,
  sum(tb.sales) as sales,
  CASE WHEN sum(tb.sales) &gt;= 300 THEN &#39;A&#39;
    WHEN sum(tb.sales) &gt;= 150 THEN &#39;B&#39;
    ELSE &#39;C&#39; END as level
FROM `olist.olist_orders` as ord
INNER JOIN `tb`
  ON ord.order_id = tb.order_id
LEFT JOIN `olist.olist_customers` as cus
  ON ord.customer_id = cus.customer_id
WHERE ord.order_status in (&#39;delivered&#39;, &#39;shipped&#39;)
GROUP BY 1,2
ORDER BY level,3 desc
)

select * from base
WHERE 1=1
  and ord_month is not null</code></pre><h2 id="과제-2번">과제 2번</h2>
<pre><code>/* 상품 카테고리별 매출 데이터
2017년 월별 대카테고리별(영문명) 매출

1. 집계 조건 : 날짜 기준 : 승인일시(order_approved_at), null 제외, delivered 한정
2. 정렬 : 날짜(연도/월) 오름차순, 매출 내림차순
3. join 조건 : 주문 테이블과 주문 상품 정보 테이블에 모두 있는 주문건만 사용
              from 절로 주문상품 정보 테이블 사용(order_items)
              카테고리 정보가 없어도 매출이 집계되도록 함.
*/
SELECT 
  trans.catg_1 as cat,
  DATE_TRUNC(DATE(ord.order_approved_at), MONTH) as month,
  round(sum(item.price),2) as sum_price
FROM `olist.olist_order_items` as item -- 3-2
INNER JOIN `olist.olist_orders` as ord -- 3-1
  ON item.order_id = ord.order_id  -- USING(oder_id) 이렇게 써도됨
LEFT JOIN `olist.olist_products` as pro
  ON item.product_id = pro.product_id
LEFT JOIN `olist.product_category_name_translation` as trans
  ON pro.product_category_name = trans.product_category_name
WHERE 1=1
  AND EXTRACT(YEAR from DATE(ord.order_approved_at)) = 2017
  AND ord.order_approved_at is not null
  AND ord.order_status = &#39;delivered&#39;
  -- AND pro.product_id = &#39;5eb564652db742ff8f28759cd8d2652a&#39;
GROUP BY 1,2
ORDER BY 2, sum_price desc</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] 실무 필수 문법]]></title>
            <link>https://velog.io/@jongyoon_insight/Python-%EC%8B%A4%EB%AC%B4-%ED%95%84%EC%88%98-%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@jongyoon_insight/Python-%EC%8B%A4%EB%AC%B4-%ED%95%84%EC%88%98-%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Thu, 29 Feb 2024 15:02:29 GMT</pubDate>
            <description><![CDATA[<h1 id="transform--map--apply-차이점">transform / map / apply 차이점</h1>
<p>transform(): 그룹 기반 함수 적용, 새로운 열 생성
map(): 벡터화된 함수 적용, 원본 열 변경
apply(): 축 기반 함수 적용, 다양한 결과 형식 가능
6. 선택 가이드:</p>
<p>그룹별 집계 또는 변환: transform()
벡터화된 함수 적용: map()
행 또는 열 기반 함수 적용: apply()</p>
<h1 id="data-handling">data handling</h1>
<p>df.shape()
df.isnull().sum()</p>
<p>len(df[&#39;col&#39;].unique())</p>
<p>df.replace(-200,np.NaN) ## 특정값 치환
df.fillna(method=&#39;ffill&#39;) ## frontfill 
np.where(df[&#39;col&#39;] &lt;= 5, 1, 0) ## 특정 조건 값 변경하기</p>
<p>df[df[&#39;col&#39;].astype(str).str.contains(&#39;text&#39;)]</p>
<p>pd.pivot_table(df_job, index=&#39;index&#39;, columns=&#39;col&#39;, values=&#39;value&#39;)</p>
<p>df.replace([np.inf, -np.inf], np.nan) ## 무한대 null 처리</p>
<p>##lag 데이터 생성 +n : 순방향 , -n 역방향
df[&#39;col&#39;].shift(1) </p>
<p>##문자열 데이터 앞 공백제거
df[&#39;col&#39;].str.lstrip() </p>
<p>##날짜 데이터 형식 변경
import datetime
df[&quot;Date&quot;].dt.strftime(&quot;%Y-%m&quot;)</p>
<p>##list 중복 없애기
all_list = list(df[&#39;start&#39;]) + list(df[&#39;end&#39;])
unique_list = set(all_list)</p>
<h1 id="data-visualization">data Visualization</h1>
<h3 id="연속형-변수-분포-확인">연속형 변수 분포 확인</h3>
<p>sns.displot(df[&#39;col&#39;])  # displot 활용 분포 그리기
print(&quot;col :&quot;, df[&#39;col&#39;].mean()) #분포의 기술 통계도 같이 출력</p>
<h3 id="plot-size-조절">Plot size 조절</h3>
<p>plt.gcf().set_size_inches(20,5)</p>
<h3 id="산점도-그리기">산점도 그리기</h3>
<p>import seaborn as sns
sns.scatterplot(x=df[&#39;x&#39;], y=df[&#39;y&#39;], hue=df[&#39;hue&#39;], data=df)</p>
<h3 id="line-plot-그리기">line plot 그리기</h3>
<p>import matplotlib.pyplot as plt
plt.plot(df[&#39;x&#39;], df[&#39;y&#39;], label=&#39;label&#39;)</p>
<h3 id="다중-distplot-출력">다중 distplot 출력</h3>
<p>for i in range(1,13):
    plt.subplot(3,4,i)
    plt.grid(False)
    sns.displot(df.iloc[:,i])
plt.tight_layout()
plt.show()</p>
<h3 id="pairplot-상관관계-분석">pairplot 상관관계 분석</h3>
<p>df_pair = df[[&#39;col1&#39; <del>~</del> ]] ## 변수 추리기
sns.pairplot(df_pair)</p>
<h3 id="heat-map-상관관계분석">Heat map 상관관계분석</h3>
<p>sns.heatmap(df_pair.corr(), vmin=-1, vmax=+1, annot = Ture, cmap=&#39;coolwarm&#39;)</p>
<h3 id="수직-수평선-추가-길이-조절">수직 수평선 추가 길이 조절</h3>
<p>plt.vlines(2, ymin=-2, ymax=2, color=&#39;r&#39;, linewidth=2)
plt.hlines</p>
<h3 id="catplot-카테고리-분류-분석">catplot 카테고리 분류 분석</h3>
<p>sns.catplot(x=&#39;x&#39;, hue=&#39;y&#39;, kind=&#39;count&#39;, palette=&#39;pastel&#39;, data=df)</p>
<h3 id="그래프-특정-값에-색상-입히기">그래프 특정 값에 색상 입히기</h3>
<p>df[&#39;vol_color&#39;] =np.where(df[&#39;Volume_issue&#39;]==1, &#39;red&#39;, &#39;gray&#39;)
colors= list(df[&#39;vol_color&#39;])</p>
<p>plt.bar(df[&#39;Date&#39;], df[&#39;Volume&#39;], label=&#39;volume&#39;, color=colors)</p>
<h4 id="이상분석할-때-자주-쓰임">이상분석할 때 자주 쓰임</h4>
<h1 id="data-analysis--modeling">data analysis &amp; modeling</h1>
<h2 id="이진-분류-randomforestclassifier">이진 분류 RandomForestClassifier</h2>
<h3 id="모델-학습-및-예측">모델 학습 및 예측</h3>
<ol>
<li><p>빈껍데기 만들기
rfc = RandomForestClassifier(random_state=123456)</p>
</li>
<li><p>모델 학습시키기
rfc.fit(x_train, y_train)</p>
</li>
<li><p>예측, 학습에 사용된 Data와 test data 모두 예측하고 평가(<strong><em>★★과적합 여부 판별</em></strong>)
y_pred_train = rfc(위에서 학습시킨).predict(x_train)
y_pred_test = rfc.predict(x_test)</p>
</li>
<li><p>이진 분류 모델 성능 확인
from sklearn.metrics import classification_report
classification_report(y_train, y_pred_train))
classification_report(y_test, y_pred_test))</p>
</li>
<li><p>하이퍼파라미터 튜닝</p>
<pre><code>from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
</code></pre></li>
</ol>
<p>params = { &#39;n_estimators&#39; : [400, 500],
           &#39;max_depth&#39; : [6, 8, 10, 12]
            }</p>
<h1 id="randomforestclassifier-객체-생성-후-gridsearchcv-수행">RandomForestClassifier 객체 생성 후 GridSearchCV 수행</h1>
<p>rf_clf = RandomForestClassifier(random_state = 123456, n_jobs = -1)
grid_cv = GridSearchCV(rf_clf, param_grid = params, cv = 3, n_jobs = -1, scoring=&#39;recall&#39;)
grid_cv.fit(x_train, y_train)</p>
<p>print(&#39;최적 하이퍼 파라미터: &#39;, grid_cv.best_params_)
print(&#39;최고 예측 정확도: {:.4f}&#39;.format(grid_cv.best_score_))</p>
<pre><code>
6. 중요변수 파악(Feature Importance)</code></pre><p>import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
plt.style.use([&#39;dark_background&#39;])</p>
<h1 id="rfc-→-생성한-model에-name-기재">rfc → 생성한 Model에 name 기재</h1>
<p>ftr_importances_values = rfc.feature_importances_
ftr_importances = pd.Series(ftr_importances_values, index = x_train.columns)
ftr_top20 = ftr_importances.sort_values(ascending=False)[:20]</p>
<p>plt.figure(figsize=(8,6))
plt.title(&#39;Feature Importances&#39;)
sns.barplot(x=ftr_top20, y=ftr_top20.index)
plt.show()</p>
<pre><code>
7. 모델 save &amp; read</code></pre><p>import pickle</p>
<h1 id="모델-저장">모델 저장</h1>
<p>saved_model = pickle.dumps(model)</p>
<h1 id="모델-read">모델 Read</h1>
<p>model_from_pickle = pickle.loads(saved_model)</p>
<pre><code>
8. 상관계수 값 출력</code></pre><p>import scipy.stats as stats
stats.pearsonr(x=df[&#39;x&#39;], y=df[&#39;y&#39;])</p>
<pre><code>

## Regressor(회귀) 모델 학습 및 평가
앞에는 비슷하다.</code></pre><h1 id="모델링을-학습하기-위한-fearuex와-y데이터를-구분하는-단계">모델링을 학습하기 위한 Fearue(X)와 Y데이터를 구분하는 단계</h1>
<p>from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn import metrics</p>
<p>X=df.drop([&#39;y&#39;], axis=1)
Y=df[&#39;y&#39;]</p>
<p>x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.3)</p>
<p>print(x_train.shape)
print(y_train.shape)</p>
<p>print(x_test.shape)
print(y_test.shape)</p>
<h1 id="randomforestregressor-모델-학습">RandomForestRegressor 모델 학습</h1>
<p>rfr = RandomForestRegressor()
rfr.fit(x_train, y_train)</p>
<h1 id="예측">예측</h1>
<h1 id="예측은-학습에-사용된-data와-test-data-모두-예측하고-평가함-과적합-여부-판별">예측은 학습에 사용된 Data와 Test Data 모두 예측하고 평가함(※ 과적합 여부 판별)</h1>
<p>import numpy as np
from sklearn.metrics import mean_absolute_error, r2_score
y_pred_train = rfr.predict(x_train)
y_pred_test = rfr.predict(x_test)</p>
<p>mse_train = mean_absolute_error(y_train, y_pred_train)
print(&#39;mse_train(mse): &#39;, mse_train)
rmse_train = (np.sqrt(mse_train))
print(&#39;rmse_train(rmse): &#39;, rmse_train)
r2_train = r2_score(y_train, y_pred_train)
print(&#39;rmse_train(r2): &#39;, r2_train)
print(&#39;&#39;)
mse_test = mean_absolute_error(y_test, y_pred_test)
print(&#39;mse_test(mse): &#39;, mse_test)
rmse_test = (np.sqrt(mse_test))
print(&#39;rmse_test(rmse): &#39;, rmse_test)
r2_test = r2_score(y_test, y_pred_test)
print(&#39;rmse_test(r2): &#39;, r2_test)</p>
<p>```</p>
<p>이후는,, 나중에 복습하자</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] Visualization]]></title>
            <link>https://velog.io/@jongyoon_insight/Python-Visualization</link>
            <guid>https://velog.io/@jongyoon_insight/Python-Visualization</guid>
            <pubDate>Sun, 25 Feb 2024 06:25:46 GMT</pubDate>
            <description><![CDATA[<h2 id="자주쓰는-matplotlib--seaborn">자주쓰는 matplotlib / seaborn</h2>
<pre><code>import matplotlib.pyplot as plt
import seaborn as sns


# print the graphs in the notebook
%matplotlib inline

# set seaborn style to white
sns.set_style(&quot;white&quot;)</code></pre><h2 id="boxplot행-열-색상-데이터">boxplot(행, 열, 색상, 데이터)</h2>
<pre><code>sns.boxplot(x = &quot;day&quot;, y = &quot;total_bill&quot;, hue = &quot;time&quot;, data = df);</code></pre><h3 id="df에서--연산자-사용법">df에서 &amp; 연산자 사용법</h3>
<pre><code>df[(df[&#39;day&#39;]==&#39;Thur&#39;) &amp; (df[&#39;time&#39;] == &#39;Dinner&#39;)]
#괄호 꼭 써라</code></pre><h2 id="histogram--facetgrid">histogram / FacetGrid</h2>
<pre><code>ttbill = sns.histplot(df.total_bill);

# set lables and titles
ttbill.set(xlabel = &#39;Value&#39;, ylabel = &#39;Frequency&#39;, title = &quot;Total Bill&quot;);
# 여기선 x,y 아니고 xlabel ylabel임. histogram 지정하고 set 지정(단순이름 valuesssss로 바꿔봄)</code></pre><p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/a227d0ed-fb9e-41ec-b797-30dd2b54b222/image.png" alt=""></p>
<pre><code># better seaborn style
sns.set(style = &quot;ticks&quot;)
plt.grid(True)
# creates FacetGrid
g = sns.FacetGrid(df, col = &quot;time&quot;) #두개로 나눌 기준 col
g.map(plt.hist, &quot;tip&quot;);  # tip 에 대해서 map</code></pre><pre><code>import numpy as np
# sort the values from the top to the least value and slice the first 5 items
df2 = df.Fare.sort_values(ascending = False)
# df3 = df.Fare

# create bins interval using numpy
binsVal = np.arange(0,600,10)
binsVal

# create the plot
plt.hist(df3, bins = binsVal)

# Set the title and labels
plt.xlabel(&#39;Fare&#39;)
plt.ylabel(&#39;Frequency&#39;)
plt.title(&#39;Fare Payed Histrogram&#39;)

# show the plot
plt.show()</code></pre><h2 id="scatter">scatter</h2>
<pre><code>g = sns.FacetGrid(df, col = &quot;sex&quot;, hue = &quot;smoker&quot;)
g.map(plt.scatter, &quot;total_bill&quot;, &quot;tip&quot;, alpha =.7) # alpha는 투명도

g.add_legend(); # 범례</code></pre><h2 id="pie-chart">pie chart</h2>
<pre><code># sum the instances of males and females
males = (df[&#39;Sex&#39;] == &#39;male&#39;).sum()
females = (df[&#39;Sex&#39;] == &#39;female&#39;).sum()

# put them into a list called proportions
proportions = [males, females]

# Create a pie chart
plt.pie(
    # using proportions
    proportions,

    # with the labels being officer names
    labels = [&#39;Males&#39;, &#39;Females&#39;],

    # with no shadows
    shadow = False,

    # with colors
    colors = [&#39;blue&#39;,&#39;yellow&#39;],

    # with one slide exploded out
    explode = (0.15 , 0),           #벌어진 크기

    # with the start angle at 90%
    startangle = 90,                #시작 각도

    # with the percent listed as a fraction
    autopct = &#39;%1.2f%%&#39;
    )

# View the plot drop above
plt.axis(&#39;equal&#39;)

# Set labels
plt.title(&quot;Sex Proportion&quot;)

# View the plot
plt.tight_layout()
plt.show()</code></pre><blockquote>
<p>&#39;%1.2f%%&#39;는 문자열 포매팅을 의미합니다.
% : 문자열 포매팅을 시작하겠다는 표시입니다.
1.2f : 소수점 아래 두 자리까지 표시하겠다는 의미입니다.
%% : 실제 &#39;%&#39; 문자를 출력합니다. &#39;%&#39;를 출력하기 위해서는 &#39;%%&#39;와 같이 두 번 입력해야 합니다</p>
</blockquote>
<h2 id="lmplot">lmplot</h2>
<pre><code># creates the plot using
lm = sns.lmplot(x = &#39;Age&#39;, y = &#39;Fare&#39;, data = df, hue = &#39;Sex&#39;, fit_reg=False)

# set title
lm.set(title = &#39;Fare x Age&#39;)

# get the axes object and tweak it
axes = lm.axes
axes[0,0].set_ylim(-5,)           # y축 길이
axes[0,0].set_xlim(-5,85)         # x축 길이</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] pivot, concat, merge]]></title>
            <link>https://velog.io/@jongyoon_insight/Python-pivot-concat-merge</link>
            <guid>https://velog.io/@jongyoon_insight/Python-pivot-concat-merge</guid>
            <pubDate>Fri, 23 Feb 2024 08:11:47 GMT</pubDate>
            <description><![CDATA[<h2 id="전처리">전처리</h2>
<pre><code>df.drop(&#39;Indicator&#39;,axis=1,inplace=True)
#indicator , 열, 원본에 대입 삭제

df[&#39;First Tooltip&#39;] = df[&#39;First Tooltip&#39;].map(lambda x: float(x.split(&quot;[&quot;)[0]))
#x.split을 [ 기준으로 나눠 첫번째 것만 실수로 선택하는 매핑</code></pre><h2 id="pivot--pivot_table-차이점">pivot / pivot_table 차이점</h2>
<p>pivot과 pivot_table은 두 함수 모두 데이터프레임을 재구성하여 새로운 데이터프레임을 생성하는데 사용되지만, 그들 사이에는 몇 가지 중요한 차이점이 있습니다.</p>
<ol>
<li>기능 차이: pivot 함수는 단순히 데이터프레임을 재구성하는 기능만 제공합니다. 
반면, pivot_table 함수는 추가로 그룹별로 데이터를 집계(agg)하는 기능도 제공합니다. <strong>pivot_table 함수에 aggfunc 매개변수를 통해 평균, 합계 등의 집계 함수를 지정할 수 있습니다.</strong></li>
<li>다중 인덱스 처리: pivot_table은 pivot에 비해 다중 인덱스(multi-index)를 더 잘 처리합니다. pivot은 하나의 인덱스를 기준으로 피벗하는 반면, pivot_table은 여러 개의 인덱스를 동시에 처리할 수 있습니다.</li>
<li>중복 데이터 처리: pivot 함수는 중복 데이터에 대해 에러를 발생시킵니다. 즉, 같은 인덱스와 열에 해당하는 값이 두 개 이상 존재하면 pivot 함수를 사용할 수 없습니다. 반면, pivot_table 함수는 중복 데이터를 집계 함수(aggfunc)를 사용하여 하나의 값으로 변환하여 처리합니다.
따라서, 단순히 데이터프레임의 모양을 바꾸는 경우에는 pivot을, 그룹별로 데이터를 집계하거나 중복 데이터를 처리해야 하는 경우에는 pivot_table을 사용하면 됩니다.</li>
</ol>
<h2 id="pivot">pivot</h2>
<p>Ans = target.pivot(index=&#39;Location&#39;,columns=&#39;Period&#39;,values=&#39;First Tooltip&#39;)</p>
<h2 id="pivot_table">pivot_table</h2>
<p>Ans = df.pivot_table(index=&#39;Dim1&#39;,columns=&#39;Period&#39;,values=&#39;First Tooltip&#39;,aggfunc=&#39;mean&#39;)
kr.pivot_table(index=&#39;Year&#39;, columns=&#39;Medal&#39;, aggfunc=&#39;size&#39;).fillna(0)</p>
<h1 id="concat-vs-merge">concat vs merge</h1>
<blockquote>
<p>concat 은 데이터를 좌우, 위아래로 합칠 때
merge 는 join 개념</p>
</blockquote>
<h4 id="chat-gpt-said">chat gpt said</h4>
<p>merge와 concat은 모두 pandas에서 두 개 이상의 데이터프레임을 결합하는데 사용되는 함수입니다.</p>
<p><strong><em>merge 함수는 SQL의 JOIN과 유사</em></strong>하며, 특정 공통 열이나 인덱스를 기준으로 두 데이터프레임을 결합합니다. merge 함수는 기본적으로 내부 결합(inner join)을 수행하지만, how 인자를 통해 외부 결합(outer join), 왼쪽 결합(left join), 오른쪽 결합(right join) 등도 수행할 수 있습니다.</p>
<p><strong><em>concat 함수는 주로 데이터프레임을 수직으로(위/아래) 결합</em></strong>하는 데 사용됩니다. 하지만 axis 인자를 통해 수평으로(왼쪽/오른쪽) 결합하는 것도 가능합니다. concat 함수는 join 인자를 통해 결합 방식을 지정할 수 있으며, 기본적으로 외부 결합(outer join)을 수행합니다.</p>
<p>join 함수
join 함수는 merge 함수를 기반으로 하며, 두 데이터프레임의 인덱스를 기준으로 결합합니다. 특히, join 함수는 기본적으로 왼쪽 결합(left join)을 수행하며, how 인자를 통해 다른 종류의 결합도 수행할 수 있습니다.</p>
<p>join 함수와 merge 함수 중 어느 것이 더 많이 사용되는지는 상황에 따라 다릅니다. 만약 두 데이터프레임을 공통 열을 기준으로 결합하려면 merge 함수를, 인덱스를 기준으로 결합하려면 join 함수를 사용하면 됩니다. 이때, join 함수는 merge 함수에 비해 문법이 더 간결하여 인덱스를 기준으로 결합하는 경우에는 join 함수를 더 선호하는 경향이 있습니다.</p>
<h2 id="concat">concat</h2>
<pre><code>pd.concat([df5,df6], axis=0)
#axis 행기준

pd.concat([df3,df4].join=&#39;inner&#39;)
#join을 쓸 수 있으나 merge에서 더 자주 쓰임</code></pre><h2 id="merge">merge</h2>
<pre><code>pd.merge(df5,df6, on=&#39;Algeria&#39;, how=&#39;inner&#39;).fillna()
pd.merge(df5,df6, on=&#39;Algeria&#39;, how=&#39;outer&#39;).fillna()
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[통계] 회귀분석 (2)]]></title>
            <link>https://velog.io/@jongyoon_insight/%ED%86%B5%EA%B3%84-%ED%9A%8C%EA%B7%80%EB%B6%84%EC%84%9D-2</link>
            <guid>https://velog.io/@jongyoon_insight/%ED%86%B5%EA%B3%84-%ED%9A%8C%EA%B7%80%EB%B6%84%EC%84%9D-2</guid>
            <pubDate>Fri, 23 Feb 2024 06:05:44 GMT</pubDate>
            <description><![CDATA[<h1 id="회귀분석의-표준화계수">회귀분석의 표준화계수</h1>
<h2 id="표준화계수란">표준화계수란?</h2>
<p> 종속변수에 대한 독립변수들의 단위(scaling)을 통일시긴 계수
 모든 독립변수를 같은 단위로 상정하고 비교 가능</p>
<h3 id="특징">특징</h3>
<p> 원점(0,0)을 지나가 절편이 &quot;0&quot;임
 해석이 어렵다</p>
<h3 id="장점">장점</h3>
<p> 여러 독립변수의 상대적 중요도를 비교 가능</p>
<h3 id="주의사항">주의사항</h3>
<p> 표준화 계수의 크기는 별도의 테스트를 해서 크다/작다를 말할 수 있음</p>
<h1 id="2-더미변수">2. 더미변수</h1>
<h2 id="더미변수란-">더미변수란 ?</h2>
<p>값이 오직 0 과 1로만 이루어진 변수
수리적 의미 없음, 기본적으로 이산형/범주형 변수인데 이를 연속형 변수처럼 사용</p>
<h2 id="왜-더미변수를-사용할까">왜 더미변수를 사용할까?</h2>
<p>범주형 변수의 경우 그 범주의 개수가 3개 이상일 경우
코딩을 1, 2, 3 이런식으로 하면 연속형 변수가 되어 회귀분석에서 사용 못함</p>
<h2 id="더미변수-만들기-예제">더미변수 만들기 예제</h2>
<p>변수의 범주 : 4개의 범주
필요한 변수의 개수 : 범주의 개수 - 1 = 3  </p>
<h2 id="더미변수-해석">더미변수 해석</h2>
<p>빠진 범주가 비교의 기준(reference group)이 됨
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/2c16a4a5-09de-4bb3-a3c8-2ede7cc33a18/image.png" alt=""></p>
<ol>
<li>credit 과 bank 의 차이는 무의미하다.</li>
<li>electroci check 가 bank transfer 보다 988만큼 덜 지불 하더라</li>
<li>mailed check 가 bank transfer 보다 2024만큼 덜 지불 하더라</li>
</ol>
<p>그런데, 만약 Electronic check과 mailed check을 비교하고 싶다면?
현재의 결과표로는 해석 불가.
비교하고 싶은 범주중 한개를 reference group로 하는 더미변수 3개를 다시 만들어야함</p>
<h2 id="결론">결론</h2>
<p>더미변수는 값이 오직 0, 1
수리적의미 없음</p>
<p>해석할 때는 해당 범주와 기준 그룹 간에 유의한 차이가 있다/없다로 해석
기준 그룹이 아닌 범주와는 해석 불가</p>
<h1 id="다중공선성">다중공선성</h1>
<h2 id="결론-1">결론</h2>
<p>유사한 독립변수들이 동시에 모델에 들어감으로써 발생하는 문제
완벽한 다중공선성이 있으면 최소제곱법 계산이 되지 않음
다중공선성이 높을 경우 회귀계수의 표준오차가 비정상적으로 커짐</p>
<ul>
<li>유의해야할 변수가 유의하지 않아질 수 있음
일반적으로 VIF 10을 기준으로 하나 더미변수는 3으로 보아야함</li>
</ul>
<h3 id="해결책">해결책</h3>
<p>높은 다중공선성에도 불구하고 유의하다면 그대로 좋음
유의해야할 변수가 유의하지 않다면 변수 중 뭔가를 빼야 함
다른 여러 방법이 있으나 일반적으로 완벽하지 않음
강제로 분산을 제거하는 방법이 더 큰 문제를 만들 수 있음</p>
<h1 id="이분산성heteroskedasticity">이분산성(Heteroskedasticity)</h1>
<h2 id="결론-2">결론</h2>
<p>회귀계수의 표준오차가 동일하지 않고 변화하는 경우
회귀계수의 표준오차가 독립변수의 함수로 나타남</p>
<p>확인 방법</p>
<ul>
<li>산포도</li>
<li>잔차도</li>
<li>White test</li>
</ul>
<p>해결 방법</p>
<ul>
<li>robust standard error</li>
<li>WLS regression(이론적으로는 쉬우나 현실적으로 어려움)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] time series]]></title>
            <link>https://velog.io/@jongyoon_insight/Python-time-series</link>
            <guid>https://velog.io/@jongyoon_insight/Python-time-series</guid>
            <pubDate>Thu, 22 Feb 2024 17:11:08 GMT</pubDate>
            <description><![CDATA[<h2 id="파이썬에서-이해하는-datetime으로-변경">파이썬에서 이해하는 datetime으로 변경</h2>
<p>df.Yr_Mo_Dy = pd.to_datetime(df.Yr_Mo_Dy)
Ans = df.Yr_Mo_Dy</p>
<h3 id="q66-yr_mo_dy에-존재하는-년도의-유일값을-모두-출력하라">Q66. Yr_Mo_Dy에 존재하는 년도의 유일값을 모두 출력하라</h3>
<p>Ans = df.Yr_Mo_Dy.dt.year.unique()</p>
<h3 id="q67-yr_mo_dy에-년도가-2061년-이상의-경우에는-모두-잘못된-데이터이다-해당경우의-값은-100을-빼서-새롭게-날짜를-yr_mo_dy-컬럼에-정의하라">Q67. Yr_Mo_Dy에 년도가 2061년 이상의 경우에는 모두 잘못된 데이터이다. 해당경우의 값은 100을 빼서 새롭게 날짜를 Yr_Mo_Dy 컬럼에 정의하라</h3>
<pre><code>def fix_century(x):
    import datetime

    year = x.year - 100 if x.year &gt;= 2061 else x.year
    return pd.to_datetime(datetime.date(year, x.month, x.day))
    # x.year만 변경되고 나머지 month day는 기존 값을 리턴해준다)

df[&#39;Yr_Mo_Dy&#39;] = df[&#39;Yr_Mo_Dy&#39;].apply(fix_century)</code></pre><h3 id="datetimedate에-대하여">datetime.date에 대하여</h3>
<p>datetime.date(year, x.month, x.day)는 Python의 내장 모듈인 datetime을 사용해서 특정 날짜를 나타내는 객체를 생성하는 코드입니다. datetime.date() 함수는 입력된 년, 월, 일 정보를 바탕으로 날짜를 나타내는 date 객체를 반환하는데, 이 객체는 연, 월, 일 등 날짜 관련 정보를 속성으로 가집니다.
그런 다음 pd.to_datetime() 함수는 이 date 객체를 pandas의 Timestamp 객체로 변환합니다. Timestamp 객체는 시간 관련 다양한 연산을 수행할 수 있게 해주는 pandas의 자료형입니다. 이를 통해 시계열 데이터를 다루기가 더 용이해집니다.</p>
<p>그러니까, 파이썬에서 해당 &#39;문자&#39;를 &#39;날짜&#39;데이터라고 인식할 수 있도록 datetime.date를 쓰고
pandas에서 timestamp로 연산 사용할 수 있도록 to_datetime()을 쓴다는거지</p>
<h3 id="dfyr_mo_dydtyearunique">df.Yr_Mo_Dy.dt.year.unique()</h3>
<p>dt는 pandas의 Series 객체에서 날짜와 시간에 관련된 속성들을 접근하거나 함수를 사용할 수 있게 해주는 접근자(Accessor)입니다.
따라서 df.Yr_Mo_Dy.dt.year는 Yr_Mo_Dy 열에 있는 각각의 날짜 값에서 년도 부분을 추출해내는 코드입니다.</p>
<h3 id="q69-weekday컬럼을-만들고-요일별로-매핑하라--월요일-0--일요일-6">Q69. weekday컬럼을 만들고 요일별로 매핑하라 ( 월요일: 0 ~ 일요일 :6)</h3>
<pre><code>df[&#39;weekday&#39;] = df.Yr_Mo_Dy.dt.weekday # 월~일 0~6으로 만들어줌

Ans = df[&#39;weekday&#39;].head(3).to_frame()</code></pre><h3 id="q70-weekday컬럼을-기준으로-주말이면-1-평일이면-0의-값을-가지는-weekcheck-컬럼을-만들어라">Q70. weekday컬럼을 기준으로 주말이면 1 평일이면 0의 값을 가지는 WeekCheck 컬럼을 만들어라</h3>
<p>df[&#39;weekcheck&#39;] = df[&#39;weekday&#39;].map(lambda x : 1 if x in [5,6] else 0)</p>
<h3 id="q71-년도-일자-상관없이-모든-컬럼의-각-달의-평균을-구하여라">Q71. 년도, 일자 상관없이 모든 컬럼의 각 달의 평균을 구하여라</h3>
<p>ans = df.groupby(df.Yr_Mo_Dy.dt.month).mean(numeric_only=True)</p>
<h3 id="q72-모든-결측치는-컬럼기준-직전의-값으로-대체하고-첫번째-행에-결측치가-있을경우-뒤에있는-값으로-대체하라">Q72. 모든 결측치는 컬럼기준 직전의 값으로 대체하고 첫번째 행에 결측치가 있을경우 뒤에있는 값으로 대체하라</h3>
<pre><code>df = df.fillna(method=&#39;ffill&#39;).fillna(method=&#39;bfill&#39;)
df.isnull().sum()</code></pre><p>두개 함수를 혼합해서도 사용가능. 맨 첫번째 행은 ffill이 불가하기 때문 bfill 함수를 붙여줌</p>
<h3 id="q73-년도---월을-기준으로-모든-컬럼의-평균값을-구하여라">Q73. 년도 - 월을 기준으로 모든 컬럼의 평균값을 구하여라</h3>
<pre><code>Ans = df.groupby(df.Yr_Mo_Dy.dt.to_period(&#39;M&#39;)).mean(numeric_only=True)</code></pre><p>dt.month 를 쓰면 위처럼 년도가 고려되지 않는 월만 나오기 때문에
to_period(&#39;M&#39;)을 사용</p>
<h3 id="q75-rpt와-val의-컬럼을-일주일-간격으로-각각-이동평균한값을-구하여라">Q75. RPT와 VAL의 컬럼을 일주일 간격으로 각각 이동평균한값을 구하여라</h3>
<pre><code>Ans= df[[&#39;RPT&#39;,&#39;VAL&#39;]].rolling(7).mean()</code></pre><h3 id="q76-년-월-일시-컬럼을-pandas에서-인식할-수-있는-datetime-형태로-변경하라-서울시의-제공데이터의-경우-0시가-24시로-표현된다">Q76. 년-월-일:시 컬럼을 pandas에서 인식할 수 있는 datetime 형태로 변경하라. 서울시의 제공데이터의 경우 0시가 24시로 표현된다</h3>
<pre><code>def change_date(x):
    import datetime
    hour = x.split(&#39;:&#39;)[1] # 예시 데이터 &gt; 2021-05-15:15
    date = x.split(&quot;:&quot;)[0] # :앞쪽

    if hour ==&#39;24&#39;:  # 24시면 다음날이어야 하기 때문에 이걸 함
        hour =&#39;00:00:00&#39;

        FinalDate = pd.to_datetime(date +&quot; &quot;+hour) + datetime.timedelta(days=1)
                           #pandas의 date stamp + 하루 더하기 timedelta(days=1) 

    else:
        hour = hour +&#39;:00:00&#39;
        FinalDate = pd.to_datetime(date +&quot; &quot;+hour)

    return FinalDate

df[&#39;(년-월-일:시)&#39;] = df[&#39;(년-월-일:시)&#39;].apply(change_date)</code></pre><pre><code>df[&#39;dayName&#39;]  =df[&#39;(년-월-일:시)&#39;].dt.day_name()</code></pre><p>weekday()는 숫자 day_name()은 영어</p>
<h3 id="q78-요일별-각-pm10등급의-빈도수를-파악하라">Q78. 요일별 각 PM10등급의 빈도수를 파악하라</h3>
<pre><code>Ans1 = df.groupby([&#39;dayName&#39;,&#39;PM10등급&#39;],as_index=False).size()
Ans2 = Ans1.pivot(index=&#39;dayName&#39;,columns=&#39;PM10등급&#39;,values=&#39;size&#39;).fillna(0)</code></pre><p>피벗 참 중요하다
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/2b16f595-5ab8-4668-a4bb-7ca83e28693b/image.png" alt="">
이렇게 생긴걸
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/2092e380-63de-48aa-babf-6d13e088cbf9/image.png" alt="">
이렇게 바꾼다.</p>
<h2 id="중요-pivotindex--행--columns--열-values--값">중요! <strong><em>pivot(index = 행 , columns = 열, values = 값)</em></strong></h2>
<h3 id="q79-시간이-연속적으로-존재하며-결측치가-없는지-확인하라">Q79. 시간이 연속적으로 존재하며 결측치가 없는지 확인하라</h3>
<pre><code>check = len(df[&#39;(년-월-일:시)&#39;].diff().unique())
if check ==2:
    Ans =True
else:
    Ans = False

df[&#39;(년-월-일:시)&#39;].diff().unique() #diff는 앞의 값과 뺀 결과 
array([         &#39;NaT&#39;, -3600000000000], dtype=&#39;timedelta64[ns]&#39;) #첫값은 뺄수가 없어서 NaT, 이후는 한시간씩 차이가 나니까 값이 2개만 존재해야함.=시간이 연속적으로 존재</code></pre><h3 id="q81-날짜-컬럼을-index로-만들어라">Q81. 날짜 컬럼을 index로 만들어라</h3>
<p>inplace true는 변경한 값을 실제 값에 변경 적용해라</p>
<pre><code>df.set_index(&#39;(년-월-일:시)&#39;,inplace=True)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] apply, map]]></title>
            <link>https://velog.io/@jongyoon_insight/Python-apply-map</link>
            <guid>https://velog.io/@jongyoon_insight/Python-apply-map</guid>
            <pubDate>Thu, 22 Feb 2024 16:09:14 GMT</pubDate>
            <description><![CDATA[<h2 id="maplambda-x--dicx">map(lambda x : dic[x])</h2>
<p>선택된 income_category 값을 x로하여 매핑하라</p>
<pre><code>df[&#39;newIncome&#39;] = df.Income_Category.map(lambda x: dic[x])</code></pre><h2 id="나이대-구하기">나이대 구하기</h2>
<pre><code>df[&#39;AgeState&#39;] = df.Customer_Age.map(lambda x: x//10 *10)
Ans = df[&#39;AgeState&#39;].value_counts().sort_index()</code></pre><p>values_counts 개수세기
sort_index 인덱스로 내림차순 정렬</p>
<h2 id="if문-축약형">if문 축약형</h2>
<p>df[&#39;newEduLevel&#39;] = df.Education_Level.map(lambda x : <strong>* if &#39;Graduate&#39; in x else 0)*</strong></p>
<p>np로도 가능하다. <strong><em>np.where(조건, true, false)</em></strong>
df[&#39;newEduLevel&#39;] = np.where( df.Education_Level.str.contains(&#39;Graduate&#39;), 1, 0)</p>
<h2 id="두-조건을-만족하는-행을-세어라">두 조건을 만족하는 행을 세어라</h2>
<pre><code>def check(x):
    if x.Marital_Status ==&#39;Married&#39; and x.Card_Category ==&#39;Platinum&#39;:
        return 1
    else:
        return 0


df[&#39;newState&#39;] = df.apply(check,axis=1)
Ans  = df[&#39;newState&#39;].value_counts() </code></pre><p>df.칼럼.apply를 보통 쓰는데, 2개의 칼럼에 대한 조건문을 넣어야하여
전체 df를 사용하게 표현함. df.apply(check, axis=1) axis는 행/열 기준 정해줌</p>
<pre><code>def changeGender(x):
    if x ==&#39;M&#39;:
        return &#39;male&#39;
    else:
        return &#39;female&#39;
df[&#39;Gender&#39;] = df.Gender.apply(changeGender)
Ans = df[&#39;Gender&#39;].value_counts()</code></pre><p>여기서는 Gender 칼럼 한개에 대한 식이다보니, df.Gender.apply(changeGender)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] Grouping]]></title>
            <link>https://velog.io/@jongyoon_insight/Python-Grouping</link>
            <guid>https://velog.io/@jongyoon_insight/Python-Grouping</guid>
            <pubDate>Thu, 22 Feb 2024 15:46:07 GMT</pubDate>
            <description><![CDATA[<p>df.groupby(&#39;host_name&#39;).size()
df.host_name.value_counts().sort_index()</p>
<p>두가지 방법이 있다. 
groupby size 는 null 값도 세고
value counts 는 null 값 제외</p>
<h3 id="host_name의-빈도수를-구하고-빈도수로-정렬하여-상위-5개를-출력하라">host_name의 빈도수를 구하고 빈도수로 정렬하여 상위 5개를 출력하라</h3>
<ol>
<li><p>df.host_name.value_counts().to_frame().head()</p>
</li>
<li><p>Ans = df.groupby(&#39;host_name&#39;).size().\</p>
<pre><code>         to_frame().rename(columns={0:&#39;counts&#39;}).\
         sort_values(&#39;counts&#39;,ascending=False)</code></pre><p>Ans.head(5)</p>
</li>
</ol>
<h3 id="neighbourhood_groupneighbourhood로-그룹정렬하고-neighbourhood_group그룹에서-최대값들을-출력하라">&#39;neighbourhood_group&#39;,&#39;neighbourhood&#39;로 그룹정렬하고 &#39;neighbourhood_group&#39;그룹에서 최대값들을 출력하라</h3>
<p>Ans= df.groupby([&#39;neighbourhood_group&#39;,&#39;neighbourhood&#39;], as_index=False).size()<br>.groupby([&#39;neighbourhood_group&#39;], as_index=False).max()</p>
<h3 id="neighbourhood_group그룹핑하여-price열의-최대최소평균분산-구하라">&#39;neighbourhood_group&#39;그룹핑하여 price열의 최대최소평균분산 구하라</h3>
<p>Ans = df.groupby(&#39;neighbourhood_group&#39;)[&#39;price&#39;].agg([&#39;mean&#39;,&#39;var&#39;,&#39;max&#39;,&#39;min&#39;])</p>
<blockquote>
<p>as_index=False 를 하면 시리즈 type 에서 DF type 으로 변경됨</p>
</blockquote>
<blockquote>
<p>fillna(-999) 빈값이 있으면 괄호값으로 채워넣는다.</p>
</blockquote>
<blockquote>
<p>unstack() 계층적 인덱싱을 파괴
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/9eb54341-abf8-49e8-8b6e-7c136fc323cf/image.png" alt=""></p>
</blockquote>
<h2 id="q55-데이터중-neighbourhood_group-값에-따른-room_type-컬럼의-숫자를-구하고-neighbourhood_group-값을-기준으로-각-값의-비율을-구하여라">Q55. 데이터중 neighbourhood_group 값에 따른 room_type 컬럼의 숫자를 구하고 neighbourhood_group 값을 기준으로 각 값의 비율을 구하여라</h2>
<p>Ans = df[[&#39;neighbourhood_group&#39;,&#39;room_type&#39;]].groupby([&#39;neighbourhood_group&#39;,&#39;room_type&#39;]).size().unstack()</p>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/09dadf91-01fd-4084-a2f4-0cbed8acbdc6/image.png" alt=""></p>
<p>Ans.loc[:,:] = (Ans.values /Ans.sum(axis=1).values.reshape(-1,1))</p>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/09ec6807-4a73-4e3e-a1f6-475434ac00d9/image.png" alt="">
axis=1은 행을 다 더해라, axis=0은 열을 다 더해라
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/822e7ce2-0a74-49a6-971e-a7cca2d5e7a9/image.png" alt="">
values는 array 형태로 변경
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/0514fe6a-e2a1-4c6b-a21a-c98ebf39d344/image.png" alt="">
행렬 연산을 위해 1차원 형태의 행렬로 만듬 reshape(-1,1) 기억하자</p>
<p>loc[:,:] = 전체 df의 값에 뒤의 식을 적용할 때 사용
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/24fa60ed-f153-4f22-bd46-615df071c7d6/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] filtering & Sorting]]></title>
            <link>https://velog.io/@jongyoon_insight/Python-filtering-Sorting</link>
            <guid>https://velog.io/@jongyoon_insight/Python-filtering-Sorting</guid>
            <pubDate>Thu, 22 Feb 2024 14:54:24 GMT</pubDate>
            <description><![CDATA[<pre><code>칼럼 조건 넣기
df[df[&#39;quantity&#39;]==3]

칼럼 두개면 대괄호 하나 더씀
df[[&#39;quantity&#39;,&#39;item_price&#39;]]


인덱스 초기화해서 칼럼 조건으로 데이터 가져오기
df.loc[df[&#39;quantity&#39;] == 3].head().reset_index(drop=TRUE)

::2는 짝수열
df.iloc[:,::2]</code></pre><blockquote>
<p>loc와 iloc은 둘 다 pandas 데이터프레임에서 행이나 열을 선택하는데 사용되는 함수입니다. 그러나 두 함수는 서로 다른 방식으로 데이터를 선택합니다.
loc: 라벨 기반의 데이터 선택 방식을 사용합니다. 즉, 행과 열의 라벨(이름)을 기준으로 데이터를 선택합니다. df.loc[&#39;item_price&#39;]
iloc: 정수 기반의 데이터 선택 방식을 사용합니다. 즉, 행과 열의 정수 인덱스를 기준으로 데이터를 선택합니다 df.iloc[1]</p>
</blockquote>
<pre><code>item_price에서 문자 읽기
df.item_price.str[1:].astype(&#39;float&#39;)
df.item_name.str.contains(&#39;문자&#39;)

기본 오름차순 + 인덱스 초기화
df.sort_values(&#39;new_price&#39;,ascending=False).reset_index(drop=TRUE)

df.drop_duplicates(&#39;열네임&#39;)

df.loc[df.new_price &gt;= df.new_price.mean()]

loc[행, 열]
df.loc[df.item_name==&#39;lzze&#39;, &#39;item_name&#39;] = &#39;Fizzy Lizzy&#39;

NaN 값 세기
df.choice_description.isnull().sum()

df.loc[&#39;choice_description&#39;.isnull(), &#39;choice_description&#39;] = &#39;NoData&#39;

df.choice_description.str.contains(&#39;Black&#39;) # 포함하는 글자
df.loc[&#39;choice_description&#39;==&#39;lizzy&#39;, &#39;choice_description&#39;] # 행열
Ans = df[df.item_name.str.startswith(&#39;N&#39;)] # 시작하는 글자
Ans = df[df.item_name.str.len() &gt;=15] # 글자수 세기


lst =[1.69, 2.39, 3.39, 4.45, 9.25, 10.98, 11.75, 16.98]
Ans = df.loc[df.new_price.isin(lst)]  # isin(list) 리스트에 있는걸 포함하는 것
display(Ans.head(3))
print(len(Ans))</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[통계] 회귀분석 (1)]]></title>
            <link>https://velog.io/@jongyoon_insight/%ED%86%B5%EA%B3%84-%ED%9A%8C%EA%B7%80%EB%B6%84%EC%84%9D-1</link>
            <guid>https://velog.io/@jongyoon_insight/%ED%86%B5%EA%B3%84-%ED%9A%8C%EA%B7%80%EB%B6%84%EC%84%9D-1</guid>
            <pubDate>Tue, 20 Feb 2024 06:39:00 GMT</pubDate>
            <description><![CDATA[<h1 id="1-회귀분석이란">1. 회귀분석이란?</h1>
<ul>
<li>회귀(Regression)이란 말은 어딘가로 돌아간다는 의미</li>
<li>어디로 돌아가는걸까?</li>
</ul>
<h2 id="회귀분석의-목적">회귀분석의 목적</h2>
<ul>
<li>주어진 독립변수로 종속변수를 예측하기 위해</li>
<li>단순 회귀(Simple regression)<ul>
<li>독립변수 1개 / <strong>종속변수 1개</strong></li>
</ul>
</li>
<li>다중 회귀(Multiple regression)<ul>
<li>독립변수 2개 이상 / <strong>종속변수 1개</strong></li>
</ul>
</li>
</ul>
<ul>
<li>만약 수입이 1억이라면? 지출은 얼마일까?
이를 예측하기 위해 필요한 건 <strong>추세선</strong>
이 추세선을 구하는 방법이 회귀분석</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/15f482d3-e0b1-45b5-8cc4-b195b01f1cfe/image.png" alt=""></p>
<h2 id="회귀분석의-오차가-발생error">회귀분석의 오차가 발생(error)</h2>
<p>오차 = 측정값 - 예측값</p>
<h3 id="그렇다면-가장-합리적인-추세선이란">그렇다면 가장 합리적인 추세선이란?</h3>
<p> 오차가 가장 작은 추세선?
 그런데 오차에 + - 가 혼재.. 어떻게할까?
 오차의 제곱이 최소화된 추세선
 -&gt; 오차의 제곱합이 최소화된 추세선</p>
<p> 어디서 본거 같은데...........?</p>
<h3 id="방법-중-하나-최소제곱법">방법 중 하나 [최소제곱법]</h3>
<p> 앞의 a와 b를 추정하는 방법
 궁극적으로는 평균을 지나는 추세선이 가장 합리적인 최소제곱법에 의해 구해짐</p>
<h2 id="결론">결론</h2>
<p> 주어진 데이터의 독립변수로 종속변수를 예측
 이를 위해 직선형태의 추세선을 구함
 이 추세선의 식은 y = a + bx (a 는 절편, b는 기울기)
 사용되는 방법은 최소제곱법(오차의 제곱의 합을 최소로 만듬)
 최소제곱법으로 구해진 직선이 우리가 원하는 회귀분석식</p>
<ul>
<li>이 직선은 평균을 지난다(<strong>평균으로의 회귀</strong>)</li>
<li>이 방법을 영어로 Ordinary Least Square(OLS)라고 함</li>
</ul>
<h1 id="2-회귀분석의-결과표-해석">2. 회귀분석의 결과표 해석</h1>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/0556cebd-0fc5-482b-9620-99ae0081d776/image.png" alt="">
intercept = 상수
SE(비표준화계수/ Standard error 표준오차) 
Estimate(비표준화계수/ B, 회귀계수)</p>
<h2 id="연구가설">연구가설</h2>
<p>거실의 크기가 클수록 매매가격이 비쌀 것이다.</p>
<h2 id="결과해석">결과해석</h2>
<p>거실크기가 1 feet^2 증가할 때, 매매가격은 281$ 증가</p>
<h1 id="3-회귀분석과-표준오차">3. 회귀분석과 표준오차</h1>
<p>통계적인 사고 방식 Remind!</p>
<ul>
<li>이 사건이 우연히 발생하지 않았을까?</li>
<li>x가 1증가할 때, y가 2.4증가하는게 우연이 아니었을까?</li>
</ul>
<p>최소제곱법은 오차의 제곱합이 최소가 되는 회귀방정식을 구해줄 뿐 이 회귀식의 회귀계수가 우연인지 아닌지 알려주지 않는다.
그렇다면 우리는 회귀계수 2.4가 우연인지 아닌지 어떻게 판단해야할까
<strong>비교 대상이 필요하다</strong></p>
<h2 id="표준오차se">표준오차(SE)</h2>
<p> 우리는 뭘 하든지 대부분 모집단이 아닌 표본으로 통계분석 함.
 우리가 가진 표본이 얼마나 모집단에 가까운지 아닌지 판단해야 함.
 모집단의 평균을 평균의 참값이라고 할 때,</p>
<ul>
<li>표본집단의 평균이 얼마나 모집단의 평균과 가까운지 먼지를 계산</li>
<li>이론적으로 같은 모집단에서 적합한 방법으로 표본을 구해도 표본집단의 평균은 매번 다를 수 밖에 없음<h3 id="표준오차--표본-평균들의-표준편차">표준오차 = 표본 평균들의 표준편차</h3>
</li>
</ul>
<p>결론적으로 표준오차가 작으면 참값에 더 가깝다는 것이고, 표준오차가 크면 참값에서 더 멀다는 것임</p>
<h2 id="결론-1">결론</h2>
<p>회귀계수는 최소제곱법으로 구해진다.
그러나! 그렇게 계산된 회귀계수가 우연인지 아닌지는 모른다.
그래서 이 회귀계수가 우연일 확률을 알기 위해 표준오차를 사용한다.</p>
<p>표준오차가 작으면 회귀계수가 우연일 확률이 낮다</p>
<ul>
<li>표준오차가 작다 = 데이터가 회귀직선 가까이에 퍼져있다.
표준오차가 크면 회귀계수가 우연일 확률이 크다</li>
<li>표준오차가 크다 = 데이터가 회귀직선에서 멀리 퍼져있다</li>
</ul>
<p>그렇다면 이 확률을 어떻게 계산할까?
 -&gt; t-test
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/20365964-e85b-49a9-8a34-6fef95519216/image.png" alt=""></p>
<h1 id="4-회귀분석과-t-test">4. 회귀분석과 t-test</h1>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/30f083f1-146f-45fa-95cd-abe80cc36606/image.png" alt=""></p>
<ul>
<li>유의미한 회귀계수 2.4가 됨
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/c8b80203-397b-4026-a0b0-b96873f643a7/image.png" alt=""></li>
<li>우연히 나온 회귀계수 2.4가 됨</li>
</ul>
<h2 id="회귀분석의-특징">회귀분석의 특징</h2>
<p>데이터가 곡선 형태로 되어 있다면 기울기는 0
원 형태로 되어 있다면 기울기는 0
직선의 형태로 되어 있지 않다면 분석할 수 없음</p>
<ul>
<li>회귀분석 전에 산포도를 찍어 보아야 함.<ul>
<li>직선 형태의 데이터분포가 나타나지 않으면 다른 방법 찾아야함</li>
<li>회귀분석은 y = a + bx니까!</li>
</ul>
</li>
<li>회귀계수(기울기)는 결국 t-test의 평균값 차이와 동일한 개념<ul>
<li>따라서 회귀계수는 t-test로 그 유의성을 테스트 함.</li>
</ul>
</li>
</ul>
<h2 id="회귀계수-t-test의-통계적-가설">회귀계수 t-test의 통계적 가설</h2>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/5473957e-359d-4b74-99fe-208f65bc1b4c/image.png" alt=""></p>
<h2 id="결론-2">결론</h2>
<ol>
<li>회귀분석은 독립변수와 종속변수의 직선관계만 분석가능
이를 위해 분석 전에 산포도 확인</li>
<li>직선관계가 아닌 경우 잘못된 회귀계수를 얻게 됨.</li>
<li>회귀분석 기울기의 테스트는 t-test와 동일한 개념
회귀계수를 표준오차로 나누면 회귀계수
이때 자유도는 1
독립변수가 증가할 수록 자유도가 증가<ul>
<li>무한대의 독립변수를 사용 못함</li>
<li>독립변수 1개의 추가는 곧 비용임(자유도 늘어나니까!)</li>
</ul>
</li>
</ol>
<h1 id="r²-를-어떻게-해석해야할까">R² 를 어떻게 해석해야할까</h1>
<ul>
<li>보통 회귀분석에서는 
종속변수와 독립변수의 인과관계를 논리적/이론적으로 전제하고
독립변수로 종속변수를 설명하려 한다.</li>
<li>그런데 회귀분석 뿐만 아니라 우리가 하는 통계는 결국
<strong>분산을 얼마나 잘 설명하는가</strong> 가 목적이다.
즉, 회귀분석이란 종속변수의 분산을 독립변수로 얼마나 설명할 수 있는가의 과정</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/cc266765-b50e-46af-b31e-ac3e5bb2e797/image.png" alt=""></p>
<h2 id="r²--모델의-분산-설명력">R² = 모델의 분산 설명력</h2>
<p>모델(독립변수)가 얼마나 데이터를 잘 설명했는지를 의미</p>
<h2 id="r²가-높으면-무조건-좋은-것인가">R²가 높으면 무조건 좋은 것인가?</h2>
<p>절대 그렇지 않음
나름 의미는 있으나 높은 R2가 모든 것을 완벽하게 하지는 못함</p>
<ul>
<li>잔차도가 랜덤하게 분포함을 확인해야함</li>
<li>의미 없는 독립변수의 추가 조차도 R²를 약간이라도 증가시킴</li>
<li>그러나 독립변수의 추가는 자유도를 1 증가시켜 비용이 발생</li>
<li>높은 R² 는 과적합 문제로부터 자유롭지 않음</li>
</ul>
<h3 id="잔차도residual-plot">잔차도(residual plot)</h3>
<p>종속변수의 분산을 모델(독립변수)로 설명하는데
여기서 모델이 큰 문제가 없다면, 모델로 설명하고 남은 오차는 random한 오차임</p>
<p>랜덤하지 않은 분포는 R²가 아무리 높더라도 모델 설명이 안됨.
뭔가 다른 이유가 있기 때문이라고 판단할 수 있음</p>
<h2 id="r²-대신-사용할-수-있는-것은">R² 대신 사용할 수 있는 것은?</h2>
<p>R²의 단점은
독립변수가 무한대로 증가하면 (변수가 무관하더라도) R²가 증가함
따라서 독립변수의 증가 = 자유도 1 손실
이에 대한 보정이 필요</p>
<ul>
<li>보정 ?<ul>
<li>추가된 독립변수가 자유도 1을 잃고도 충분히 분산을 설명했는지 여부</li>
<li>자유도가 감안된 R²가 필요 </li>
<li>이것이 adj. R²(수정 R²)</li>
<li>둘의 크기가 심하게 다르다면 의미 없는 독립변수를 너무 많이 넣었다는 의미</li>
</ul>
</li>
</ul>
<h2 id="과적합overfitting--overestimation">과적합(overfitting , overestimation)</h2>
<ul>
<li>여전히 주의할 것은 우리는 거의 표본만을 대상으로 분석한다는 사실</li>
<li>만약 모델이 이번에 수집한 표본에서만 높은 R²을 보인다면?<ul>
<li>이것은 단한번 우연히 이 표본에만 적합할 뿐</li>
<li>다른 표본에서는 절대 높은 R²을 확인할 수 없다는 것을 의미</li>
<li>이 표본에서만 우수함</li>
<li>따라서 이 모델은 큰의미 없음</li>
</ul>
</li>
</ul>
<h3 id="과적합-판단-및-해결책">과적합 판단 및 해결책</h3>
<ul>
<li>Cross-validation 을 적용
표본을 랜덤하게 둘로 나누어 한 표본에서 모델을 구축하고 난 뒤 
다른 표본에서 모델의 적합성을 다시 테스트함</li>
</ul>
<h2 id="결론-3">결론</h2>
<p>R²는 애증의 대상..</p>
<ul>
<li>R²는 모델이 데이터를 얼마나 잘 설명했는지 의미</li>
<li>R²가 높다는 건 모델의 설명력이 높으므로 나름 좋은 의미</li>
<li>그러나, 높은 R²가 모델의 정당성을 모두 해결해주지 않음</li>
</ul>
<p>R²의 단점</p>
<ul>
<li>R²를 높이는 것이 단일 목적인 경우 무한히 많은 독립변수를 추가</li>
<li>그러나 독립변수의 추가는 결국 비용이고 손해임(장ㅍ도 1손실)</li>
<li>그러므로 adj. R²를 사용 하는 것이 좋음</li>
</ul>
<p>R²보다 중요한 것</p>
<ul>
<li>모델에 사용된 독립변수의 논리성/이론적 근거</li>
</ul>
<hr>
<p>강의 자료
<a href="https://www.youtube.com/watch?v=dcMvKmkNn8w">https://www.youtube.com/watch?v=dcMvKmkNn8w</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[통계] 카이제곱 검정]]></title>
            <link>https://velog.io/@jongyoon_insight/%ED%86%B5%EA%B3%84-%EC%B9%B4%EC%9D%B4%EC%A0%9C%EA%B3%B1-%EA%B2%80%EC%A0%95</link>
            <guid>https://velog.io/@jongyoon_insight/%ED%86%B5%EA%B3%84-%EC%B9%B4%EC%9D%B4%EC%A0%9C%EA%B3%B1-%EA%B2%80%EC%A0%95</guid>
            <pubDate>Tue, 20 Feb 2024 05:05:19 GMT</pubDate>
            <description><![CDATA[<h1 id="1-카이제곱">1. 카이제곱?</h1>
<p>t-test anova 같은 경우 연속형 종속변수, 명목척도(범주형) 독립변수
만약 둘다 명목 척도라면? t-test,m ANOVA 못씀
이때 사용하는 것이 교차분석</p>
<h2 id="언제-카이제곱-검정을-할까">언제 카이제곱 검정을 할까?</h2>
<p>변수가 명목척도 일 때,
자료의 값은 개수여야함.</p>
<h2 id="카이제곱-검정의-목적">카이제곱 검정의 목적</h2>
<p>앞의 t-test나 ANOVA의 경우 둘/셋 이상의 집단의 같은지 다른지</p>
<p>카이제곱 검정의 목적은
변수가 한개인 경우 : 변수 내 그룹 간의 비율이 같은지 다른지
그룹이 단 2개인 경우에는 Binomial test
그룹이 여러개인 경우 카이제곱 검정</p>
<p>변수가 두개 인 경우 : 변수 사이의 연관성이 있는지 없는지
휴대폰 사용과 뇌암
인종과 특정 질병</p>
<h2 id="카이제곱-값">카이제곱 값</h2>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/440e9b11-8847-4cef-b0dd-daa6a3b6f3a7/image.png" alt=""></p>
<p>예시
관찰빈도 : 총 고객데이터
기대 빈도 : 총 1,000명의 고객데이터가 있다면 남성/여성 고객 빈도는 500 / 500</p>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/66cc6d33-1313-451b-a87d-9a46b6385cd9/image.png" alt=""></p>
<h1 id="2-일원-카이제곱-one-way-chi-square">2. 일원 카이제곱 One-way chi-square</h1>
<p>변수가 1개라는 의미. 변수가 한개이기 때문에 칼럼 한개로 넣어야함.
당연히 명목척도
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/f36bb6ed-709c-4376-8c1a-86ab78e92d85/image.png" alt=""></p>
<p>카이스퀘어 값이 278 확실이 큼.
=확실히 유의하다 = 확실히 누군가는 다름</p>
<h3 id="결론적으로">결론적으로</h3>
<p>일월 카이제곱 검정의 유의성이 의미하는 것은 무엇인가 다르다 정도임
여기서 다르다는 것 또한 사전에 정해진 기대빈도와 다르다라는 의미
만약 기존의 연구/이론에 의해서 각 범주의 빈도가 다르게 나온다면
기대 빈도 자체를 바꿔서 테스트해야함.</p>
<h2 id="그래서-카이제곱-검정을-적합도-검정이라고-부르기도-함goodness-of-fit">그래서 카이제곱 검정을 적합도 검정이라고 부르기도 함.(Goodness of fit)</h2>
<h1 id="3-이원-카이제곱-two-way-chi-square">3. 이원 카이제곱 Two-way chi-square</h1>
<p>변수가 2개라는 의미. 변수가 두개이기 때문에 칼럼도 두개로 나옴. 
당연히 명목척도
가장 단순한 형태는 2X2 분석
이때 사용하는 것이 분할 표. = 데이터의 빈도만 단순화 표 작성</p>
<p>예제)
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/5faeca59-1931-4fbe-a992-de8381f19551/image.png" alt=""></p>
<h3 id="카이제곱-결과는-인과관계를-나타내지-않음-연관성이-있다">카이제곱 결과는 인과관계를 나타내지 않음. 연관성이 있다!</h3>
<p>통계적 연관성을 찾을 수 있으나, 범주 간의 확률의 차이가 얼마나 큰지 알 수 없음
이러한 문제를 해결하기 위해 CI(confidence interval) 을 사용.</p>
<h1 id="4-카이제곱-심화">4. 카이제곱 심화</h1>
<h2 id="한계점">한계점</h2>
<ol>
<li><p>랜덤 샘플링</p>
</li>
<li><p>독립성</p>
<ul>
<li>각 범주가 서로 배타적이어야 함</li>
<li>한 대상이 하나 이상의 범주에 들어갈 수 없음</li>
</ul>
</li>
<li><p>각 셀의 기대빈도가 5 이상이어야 함.(셀 전체의 20%가 5보다 작으면 피셔)</p>
<ul>
<li>경우에 따라 범주를 합쳐야함</li>
<li>범주를 합칠 수 없다면, 피셔의 정확검정 or likelihood ratio test(G-test)를 해야함</li>
</ul>
</li>
<li><p>df가 1이라면?</p>
<ul>
<li>일원 카이제곱 검정의 경우 범주가 2개 이거나, 이원 카이제곱 검정에서 2x2 인 경우, 비연속성의 조건부 확률을 연속성의 카이제곱분포에 적용함으로써 문제 발생</li>
<li>연속성 보정을 하는 Yate&#39;s correction 또는 x2 continuity correction을 사용해야함</li>
<li>만약 이원 카이제곱 검정의 2x2인 경우 x2 test 결과와  Yate&#39;s correction이 다를 경우 피셔의 정확검정을 사용해야함</li>
</ul>
</li>
<li><p>상대 위험도 only 2x2 case</p>
<ul>
<li>상대 위험도(relative risk) = 두 확률의 차이인 P1-P2 가 아니라 P1/P2 </li>
<li>만약 상대 위험도가 1이라면 두사건이 발생활 확률은 동일</li>
<li>1보다 크다면 위험이 증가</li>
<li>1보다 작으면 위험이 감소</li>
</ul>
</li>
<li><p>교차비/오즈비(odds ratio)</p>
<ul>
<li>오즈란? Odds = p/1-p</li>
<li>확률이 1/2 인 경우 Odds는 1(같음)</li>
<li>확률이 3/4 인 경우 Odds는 3(3배 높다)</li>
<li>오즈비란? 두 오즈의 비율
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/4256cd44-151c-468d-a2ef-c29be0e39392/image.png" alt="">
결론 : 핸드폰 비사용자에 비해 3배 높다. </li>
<li>행렬을 바꿔도 오즈비는 거의 비슷하다.</li>
<li>그러나 단순 오즈나 상대 위험도는 변한다.</li>
</ul>
</li>
<li><p>두 명목척도인 변수가 연관성이 있을 경우</p>
<ul>
<li>얼마나 상관관계가 높은지 궁금할 때 상관계수를 구하는 방법</li>
<li>Phi and Cremer&#39;s B</li>
<li>분할계수</li>
<li>만약 변수가 순위척도인 경우 연관성이 있다면</li>
<li>역시 얼마나 상관관계까 높은지 알고 싶다면
kendalls tau-b
Gamma</li>
</ul>
</li>
</ol>
<h1 id="5-카이제곱-검정-실습">5. 카이제곱 검정 실습</h1>
<p>한국에서는 인구 통계변수와 내가 가진 변수를 논리없이 묶어서 실습하는 경향이 있음</p>
<p>R로 실행해보려했으나 오류로 나중에 해보기로함</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Git] branch / tag / readme]]></title>
            <link>https://velog.io/@jongyoon_insight/Git-branch-tag-readme</link>
            <guid>https://velog.io/@jongyoon_insight/Git-branch-tag-readme</guid>
            <pubDate>Sat, 17 Feb 2024 09:34:04 GMT</pubDate>
            <description><![CDATA[<h1 id="git-branch-">Git branch ?</h1>
<p>특정 버전에서 새로운 Branch를 만들어서 작업하다가 병합할 수 있다.</p>
<pre><code>git branch
git branch -r  #
git branch --all
git branch &lt;branch_name&gt;
git push origin &lt;branch_name&gt;
git branch --delete &lt;branch name&gt; ## local 만 지워짐
git push origin --delete &lt;branch name&gt; ## remote 에서도 삭제
git checkout &lt;branch_name&gt;</code></pre><h2 id="git-branch-생성-후-이동-한번에-하기">git branch 생성 후 이동 한번에 하기</h2>
<pre><code>git checkout -b &lt;branch name&gt; git</code></pre><h2 id="git-branch-삭제-후-remote-에서도-삭제">git branch 삭제 후 remote 에서도 삭제</h2>
<pre><code>git branch --delete dev2
여기서 아무것도 안한 빈파일이라 문제가 생김. 강제로 지우기 실행
git brnach -D dev2
그리고 remote에서도 지워주기
git push origin --delete  dev2</code></pre><h1 id="merge">merge</h1>
<p>현재 버전에 다른 버전을 병합하는 자겁
Branch를 병합하거나
Push Pull 할때도 일어난다.</p>
<pre><code>git merge dev</code></pre><h1 id="conflict">conflict</h1>
<p>merge 하다가 발생하는 문제들
git 이 auto merge 해준다</p>
<p>========= 를 기준으로 충돌 부분을 보여줌</p>
<h2 id="해결-과정">해결 과정</h2>
<h3 id="1-파일수정">1. 파일수정</h3>
<h3 id="2-git-add">2. git add</h3>
<h3 id="3-git-commit">3. git commit</h3>
<p>강제 commit &gt; git commit -i</p>
<h2 id="바로-push-하지말고-항상-pull-먼저하는-습관이-좋다">바로 push 하지말고 항상 pull 먼저하는 습관이 좋다!</h2>
<h1 id="tag-달기">tag 달기</h1>
<pre><code>git tag v0.2 &lt;log&gt;
git push origin &lt;tag_name&gt;git git</code></pre><h2 id="tag-삭제">tag 삭제</h2>
<pre><code>git tag --delete &lt;name&gt;
git push origin --delete v0.1</code></pre><h1 id="readme">Readme?</h1>
<p><strong>포트폴리오 관리!</strong>
내가 어떤 프로젝트를 했는지</p>
<p>순서 * , + , -</p>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/96ab25f3-d1b0-466a-934d-33b90ad4a80a/image.png" alt="">
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/bd49e32d-9c3f-4b19-83cf-f45440832e6c/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Git] PUSH / PULL]]></title>
            <link>https://velog.io/@jongyoon_insight/Git-PUSH-PULL</link>
            <guid>https://velog.io/@jongyoon_insight/Git-PUSH-PULL</guid>
            <pubDate>Fri, 16 Feb 2024 14:13:19 GMT</pubDate>
            <description><![CDATA[<p>중요한건 origin 을 넣어서 등록
git remote add origin <remote_repo_url></p>
<p>git remote rename &lt;기존 이름&gt; &lt;변경 이름&gt;
git remote set-url &lt;기존 url&gt; &lt;변경 url&gt;
git remote set-url origin &lt;변경 url&gt;
git remote remove origin</p>
<p>git remote -v 등록한 것들 보임</p>
<p>git remote show <repo_name></p>
<h1 id="pull">pull</h1>
<p>Remote Repository의 작업 내용을 Local Repo 에 동기화 하기
사실은 Fetch / Merge 과정</p>
<pre><code>git pull origin main</code></pre><h1 id="push">push</h1>
<p>Local repo &gt; Remote repo 로 보냄</p>
<pre><code>git push origin main </code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Git] 3. 파일등록/수정/삭제]]></title>
            <link>https://velog.io/@jongyoon_insight/Git-3.-%ED%8C%8C%EC%9D%BC%EB%93%B1%EB%A1%9D%EC%88%98%EC%A0%95%EC%82%AD</link>
            <guid>https://velog.io/@jongyoon_insight/Git-3.-%ED%8C%8C%EC%9D%BC%EB%93%B1%EB%A1%9D%EC%88%98%EC%A0%95%EC%82%AD</guid>
            <pubDate>Fri, 16 Feb 2024 13:25:27 GMT</pubDate>
            <description><![CDATA[<h2 id="파일-만들기">파일 만들기</h2>
<pre><code>touch test.txt</code></pre><h2 id="add---staged-상태-만들기">add -&gt; staged 상태 만들기</h2>
<pre><code>git add</code></pre><h2 id="commit---commit-보내기">commit -&gt; commit 보내기</h2>
<pre><code>git commit -m
m 메시지 필수
-a 모든거 무시
처음에는 무조건 add 한번이라도  해야 -a도 먹힘</code></pre><h3 id="git--add-는-조심하자-쓰레기도-다올라감">git * add 는 조심하자! 쓰레기도 다올라감</h3>
<h2 id="파일-내용-바꿔쓰기">파일 내용 바꿔쓰기</h2>
<p>저장은 컨트롤  + D</p>
<pre><code>cat &gt; test.txt
내용 바꾸기
Hello, git!</code></pre><pre><code>cat &gt;&gt; test.txt
내용추가하기</code></pre><h2 id="파일-옮기기-mv">파일 옮기기 mv</h2>
<pre><code>git mv test2 test1
git mv test2 src/</code></pre><h2 id="log-보기">log 보기</h2>
<pre><code>git log
git log -2
git log --skip 2
git log -p -1 #diff=변경 내용 포함
git log --oneline #간단하게 보기
git log --author=&lt;user_name or email&gt;
git log -S &lt;검색어&gt;
git log --grep &lt;검색어&gt; # 메시지 검색 코드
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Git] 2. 기본 사용]]></title>
            <link>https://velog.io/@jongyoon_insight/Git-2.-%EA%B8%B0%EB%B3%B8-%EC%82%AC%EC%9A%A9</link>
            <guid>https://velog.io/@jongyoon_insight/Git-2.-%EA%B8%B0%EB%B3%B8-%EC%82%AC%EC%9A%A9</guid>
            <pubDate>Fri, 16 Feb 2024 10:48:38 GMT</pubDate>
            <description><![CDATA[<h2 id="git-저장소-생성">Git 저장소 생성</h2>
<pre><code>git init</code></pre><p>폴더 안으로 들어가서 해야함(.git 이 생김)
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/b8054098-1854-4397-8e1d-04ff551c5f0f/image.png" alt=""></p>
<h2 id="git-저장소-remote에서-복제">Git 저장소 remote에서 복제</h2>
<pre><code>git clone</code></pre><p>반복 로그인을 줄이기 위해 토큰을 넣어줘야함
local과 remote는 수시로 데이터를 주고 받음</p>
<p>git clone <a href="http://token">http://token</a> <del>~</del>@github.com/jjyinsight/test_project2.git</p>
<h2 id="git-저장소-삭제">Git 저장소 삭제</h2>
<pre><code>rm -rf .git</code></pre><h2 id="git-내부-파일-보기">Git 내부 파일 보기</h2>
<pre><code>cd .git
ls -all </code></pre><h2 id="에디터-없이-편집하기">에디터 없이 편집하기</h2>
<pre><code>vi .config

나가는 건 :q
수정없이 강제 나가가 :q!</code></pre><h2 id="현재-위치-알아보기-pwd">현재 위치 알아보기 pwd</h2>
<h1 id="매우-중요-git-status">매우 중요 git status</h1>
<p>Working directory 와 Staging Area 상태를 표시
보통 파일의 상태를 확인할 때 사용</p>
<h1 id="git-add-file_name">git add <file_name></h1>
<p>Working Directory에서 생성된 파일을 Staging Area (index)에 추가
Modified 상태의 파일을 Staged 로 변경</p>
<h1 id="매우-중요-git-commit--m-commit_message">매우 중요 git commit -m <commit_message></h1>
<p>-a 옵션으로 Staged 상태를 생략가능 (Modified 상태에서 바로 Committed 상태로 변경)</p>
<h2 id="git-ignore">git ignore</h2>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/4caf62e3-b702-47b2-a09e-3900bf4763b4/image.png" alt=""></p>
<h1 id="git-rm-file_name">git rm <file_name></h1>
<p>git 에서 관리하는 파일 삭제
Staging Area 의 파일을 삭제하고 Commit
Working Directory에서도 삭제됨</p>
<h2 id="git-mv-old_namenew_name">git mv <old_name><new_name></h2>
<p>git에서 파일이름 변경시 사용</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Git] 1. VCS(version control system)]]></title>
            <link>https://velog.io/@jongyoon_insight/Git-1.-VCSversion-control-system</link>
            <guid>https://velog.io/@jongyoon_insight/Git-1.-VCSversion-control-system</guid>
            <pubDate>Tue, 13 Feb 2024 13:00:04 GMT</pubDate>
            <description><![CDATA[<h2 id="언제-쓰는가">언제 쓰는가?</h2>
<p>데이터가 날라가거나,
협업하거나,
이전 파일이 필요하거나, </p>
<p>but, 소스코드 보안이 중요한 경우 사용을 기피함.</p>
<h3 id="centralized-version-control-systems">Centralized Version Control Systems</h3>
<p>협업이 가능해짐
commit 하는 순간 배포되어 다수에게 버그 유발 가능
인터넷 안되면 작업 불가
자신만의 version history 가질 수 없음</p>
<p>CVS(rollback 안됨, 1980년대)  -&gt; SVN (2000년대 만들어짐, 요즘도 씀)</p>
<h3 id="distributed-version-control-systems">Distributed Version Control Systems</h3>
<p>Commit 을 하더라도 개인저장소 내에 적용됨
원하는 순간에 배포(Push) 가능
오프라인 가능
자신만의 version histry 가짐</p>
<p>Git(Global Information Tracker) - SVN보다 빠름, 가장 많이 쓰임</p>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/7700a7bd-ea83-4f42-b637-dbf5f0e98a57/image.png" alt=""></p>
<h1 id="git-설정-범위">Git 설정 범위</h1>
<p>System config
Global config
Local config</p>
<p>git config user.name(jjyinsight)
git config user.email(<a href="mailto:jjy.insight@gmail.com">jjy.insight@gmail.com</a>)</p>
<h2 id="crlf-줄바꿈-문자">CRLF (줄바꿈 문자)</h2>
<p>window \r \n
mac \n
공유시 충돌일어날 수 있어서 설정해야함</p>
<p>git config core.autocrlf=true</p>
<blockquote>
<p>CRLF 를 LF로 바꿔줌</p>
</blockquote>
<h2 id="주요-기본-설정들">주요 기본 설정들</h2>
<p>git config core.editor <editor_name></p>
<p>git config init.defaultBranch <branch_name></p>
<p>Github에서 master &gt; main으로 바꿔서 충돌일어 날 수 있음</p>
<h2 id="git-config---l">git config --l</h2>
<p>git config --l --show-origin #어디 범위까지 적용되었는지 보여줌
git config <key> ex. git config core.autocrlf</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Sample project 3] BANK_demand forcasting and target marketing]]></title>
            <link>https://velog.io/@jongyoon_insight/Sample-project-3-BANKdemand-forcasting-and-target-marketing</link>
            <guid>https://velog.io/@jongyoon_insight/Sample-project-3-BANKdemand-forcasting-and-target-marketing</guid>
            <pubDate>Tue, 13 Feb 2024 08:31:45 GMT</pubDate>
            <description><![CDATA[<h1 id="sample-project-의의">sample project 의의</h1>
<p>데이터 분석가도 머신러닝 딥러닝의 기초는 알아야 한다.
요건정의서가 매우 중요하다.
요건 정의서가 정확하지 않을 경우 진행하다가 방향을 잘못잡고 엎어지는 일이 많다.
분석가의 중요한 역량 중 하나
이 프로젝트를 진행했을 때 얻을 수 있는 효용 가치를 확인하는 사전 작업
매출 수요 예측 프로세스는 전처리를 이렇게하고 EDA를 하고 모델링을 이렇게 하는구나
이해하는 과정</p>
<h1 id="프로젝트-순서">프로젝트 순서</h1>
<h2 id="process-01">Process 01</h2>
<h3 id="데이터-살펴보기">데이터 살펴보기</h3>
<p>고객마다 과거 진행한 캠페인(마케팅)에 대한 이력과, 현재 캠페인에서 수행된 데이터가 존재
duration은 예측시 제외 (※ 통화 시간에 따라 Y(가입여부) 결정되므로 제외)
데이터 명세 ⬇ </p>
<h3 id="데이터-전처리">데이터 전처리</h3>
<p>수집된 데이터의 기본 정보들을 확인</p>
<p>(1) Data shape(형태) 확인</p>
<ul>
<li>df.shape()</li>
</ul>
<p>(2) Data type 확인</p>
<ul>
<li>df.info()
(3) Null값 확인 (※ 빈 값의 Data)</li>
<li>df.isnull().sum()
(4) Outlier 확인 (※ 정상적인 범주를 벗어난 Data)<pre><code>pd.DataFrame(df.decribe()) 좋다</code></pre><blockquote>
<p>Duration 만 max값 및 표준편차가 이상적으로 컸다.</p>
</blockquote>
</li>
</ul>
<blockquote>
<p>정기 예금 가입현황</p>
</blockquote>
<pre><code>df[&#39;y&#39;].value_counts()</code></pre><p>no     36548
yes     4640
4640 / (36548+4640) = 11%</p>
<h3 id="범주형-변수-파악">범주형 변수 파악</h3>
<pre><code># ▶ numerical, categorical data 나누기
numerical_list=[]
categorical_list=[]

for i in df.columns :
  if df[i].dtype == &#39;O&#39; :
    categorical_list.append(i)
  else :
    numerical_list.append(i)

print(&quot;numerical_list :&quot;, numerical_list)
print(&quot;categorical_list :&quot;, categorical_list)</code></pre><h3 id="범주형과-수치형으로-column-list를-생성">범주형과 수치형으로 column list를 생성</h3>
<pre><code># ▶ numerical, categorical data 나누기
numerical_list=[]
categorical_list=[]

for i in df.columns :
  if df[i].dtype == &#39;O&#39; :
    categorical_list.append(i)
  else :
    numerical_list.append(i)

print(&quot;numerical_list :&quot;, numerical_list)
print(&quot;categorical_list :&quot;, categorical_list)</code></pre><blockquote>
<p>numerical_list : [&#39;age&#39;, &#39;duration&#39;, &#39;campaign&#39;, &#39;pdays&#39;, &#39;previous&#39;, &#39;emp.var.rate&#39;, &#39;cons.price.idx&#39;, &#39;cons.conf.idx&#39;, &#39;euribor3m&#39;, &#39;nr.employed&#39;]
categorical_list : [&#39;job&#39;, &#39;marital&#39;, &#39;education&#39;, &#39;default&#39;, &#39;housing&#39;, &#39;loan&#39;, &#39;contact&#39;, &#39;month&#39;, &#39;day_of_week&#39;, &#39;poutcome&#39;, &#39;y&#39;]</p>
</blockquote>
<h3 id="직관-해석-catplot을-활용하여-categorical-변수의-구성형태와-정기예금-가입-상황을-한눈에-살펴봄">[직관 해석] catplot을 활용하여 Categorical 변수의 구성형태와 정기예금 가입 상황을 한눈에 살펴봄</h3>
<pre><code>import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use([&#39;dark_background&#39;])

for i in categorical_list :
  if i != &#39;y&#39;:
    sns.catplot(x=i, hue=&quot;y&quot;, kind=&quot;count&quot;,palette=&quot;pastel&quot;, edgecolor=&quot;.6&quot;,data=df);
    plt.gcf().set_size_inches(25, 3)
    plt.xticks(fontsize=16)</code></pre><blockquote>
<p>실행값
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/cba4ac5b-9307-46e3-a206-72eec976525b/image.png" alt=""></p>
</blockquote>
<h2 id="process-02-rule-base-기반-상품-가입-예측">Process 02 Rule base 기반 상품 가입 예측</h2>
<p>현업에서 경험적 지식에서 얻을 수 있는 노하우 기반
&quot;이런 사람들의 가입률이 높겠구나&quot; 하는 노하우, 데이터로 검증 후 적용</p>
<pre><code>import numpy as np
df[&#39;y&#39;] = np.where(df[&#39;y&#39;]==&#39;yes&#39;, 1, 0)
df_job = df.groupby(&#39;job&#39;)[&#39;y&#39;].agg([&#39;count&#39;, &#39;sum&#39;])
df_job[&#39;ratio&#39;] = round((df_job[&#39;sum&#39;] / df_job[&#39;count&#39;])*100, 2)
df_job.sort_values(by=[&#39;ratio&#39;], ascending = False)</code></pre><blockquote>
<h3 id="현재-가입자y를-값으로-하는-조건여기서는-직관에-의해-job으로-설정의-영향도를-확인해봄">현재 가입자[&#39;Y&#39;]를 값으로 하는 조건(여기서는 직관에 의해 JOB으로 설정)의 영향도를 확인해봄</h3>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/e5c3128c-9ce1-45cf-bf26-8e067cc7f70e/image.png" alt=""></p>
</blockquote>
<h3 id="고객-job직업에-따른-정기예금-가입률-비교">고객 Job(직업)에 따른 정기예금 가입률 비교</h3>
<pre><code>df_job=pd.DataFrame(df[&#39;y&#39;].groupby(df[&#39;job&#39;]).value_counts())
df_job.columns=[&#39;cnt&#39;]
df_job=df_job.reset_index()
df_job.head(5)</code></pre><p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/80eea077-8a2e-4f63-bb0f-aa5c0067a46d/image.png" alt=""></p>
<h3 id="pivot-table을-활용하여-하나의-row로-변환">pivot table을 활용하여 하나의 row로 변환</h3>
<pre><code>df_job = pd.pivot_table(df_job,        # 피벗할 데이터프레임
                     index = &#39;job&#39;,    # 행 위치에 들어갈 열
                     columns = &#39;y&#39;,    # 열 위치에 들어갈 열
                     values = &#39;cnt&#39;)   # 데이터로 사용할 열

df_job = df_job.reset_index()
df_job.head(5)

# 가입률(sign_ratio) 추가
df_job[&#39;sign_ratio&#39;] =   round((df_job[&#39;yes&#39;] / (df_job[&#39;yes&#39;] + df_job[&#39;no&#39;])) * 100,1)
df_job.sort_values(by=[&#39;sign_ratio&#39;], ascending =False)</code></pre><p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/175b3529-3d03-4203-824e-a5815b104def/image.png" alt=""></p>
<h3 id="student학생의-가입률이-가장-높고-뒤이어-은퇴-고객의-가입률이-높음--평균가입률-11">Student(학생)의 가입률이 가장 높고, 뒤이어 은퇴 고객의 가입률이 높음 (※ 평균가입률 11%)</h3>
<p>내림차순 정렬해봄</p>
<pre><code>import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use([&#39;dark_background&#39;])
order = df_job.groupby(&#39;job&#39;)[&#39;sign_ratio&#39;].sum().sort_values(ascending =False).index

avg_ratio = round((df_job[&#39;yes&#39;].sum() / (df_job[&#39;yes&#39;].sum() + df_job[&#39;no&#39;].sum())) * 100,1)
print(avg_ratio)

g = sns.catplot(x=&quot;job&quot;, y=&quot;sign_ratio&quot;, kind=&#39;bar&#39;, palette=&quot;ch:.25&quot;, data=df_job, order=order);
g.ax.axhline(11.3, ls=&#39;--&#39;, color=&#39;r&#39;, label = &#39;average&#39;)

plt.rc(&#39;xtick&#39;, labelsize=10)
plt.gcf().set_size_inches(25, 5)
g.ax.legend()
plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/c0295beb-50d4-4b08-9ed4-d7e31f1803f3/image.png" alt=""></p>
<h3 id="categorical범주형-변수에-대해서-가입률-비교를-모두-진행">Categorical(범주형) 변수에 대해서 가입률 비교를 모두 진행</h3>
<p> ▶ Feature별 가입률이 가장 높은 Row에 대해서만 출력</p>
<pre><code>
for i in categorical_list :
  # 1단계
  df_job=pd.DataFrame(df[&#39;y&#39;].groupby(df[i]).value_counts())
  df_job.columns=[&#39;cnt&#39;]
  df_job=df_job.reset_index()

  # 2단계
  df_job = pd.pivot_table(df_job,        # 피벗할 데이터프레임
                      index = i,         # 행 위치에 들어갈 열
                      columns = &#39;y&#39;,     # 열 위치에 들어갈 열
                      values = &#39;cnt&#39;)    # 데이터로 사용할 열

  # 3단계
  df_job = df_job.reset_index()

  # 4단계
  df_job[&#39;sign_ratio&#39;] =   round((df_job[&#39;yes&#39;] / (df_job[&#39;yes&#39;] + df_job[&#39;no&#39;])) * 100,1)

  df_job=df_job.sort_values(by=[&#39;sign_ratio&#39;], ascending=False)

  print(df_job.iloc[0:1,:])
  print(&#39;&#39;)
</code></pre><h3 id="▶-상위에서-평균-가입률11-대비-높았던-조건을-or조건으로-새로운-rule규칙을-정의">▶ 상위에서 평균 가입률(11%) 대비 높았던 조건을 OR조건으로 새로운 Rule(규칙)을 정의</h3>
<pre><code>df_rule = df[ (df[&#39;job&#39;] == &#39;student&#39;) |
# (df[&#39;marital&#39;] == &#39;unknown&#39;) |
# (df[&#39;education&#39;] == &#39;illiterate&#39;) |
# (df[&#39;default&#39;] == &#39;no&#39;) |
# (df[&#39;housing&#39;] == &#39;yes&#39;) |
# (df[&#39;loan&#39;] == &#39;no&#39;) |
(df[&#39;contact&#39;] == &#39;cellular&#39;) |
(df[&#39;month&#39;] == &#39;mar&#39;) |
# (df[&#39;day_of_week&#39;] == &#39;thu&#39;) |
(df[&#39;poutcome&#39;] == &#39;success&#39;) ]
a= df_rule[&#39;y&#39;].value_counts()[&#39;no&#39;]
b= df_rule[&#39;y&#39;].value_counts()[&#39;yes&#39;]
b/(a+b)</code></pre><blockquote>
<p>▶ Rule에 의한 타겟 고객군을 추출 했을 때 평균 14% 가입률을 보임
14.9448%</p>
</blockquote>
<h1 id="process-03-ml활용-상품-가입-예측">Process 03 ML활용 상품 가입 예측</h1>
<blockquote>
<p>모델링을 수행하기 위해 Feature와 예측값인 Y로 데이터를 나눔
학습과 예측을 위한 train/test set 분할
But, Train/Test set에는 문자(str) 형태 데이터를 input 할 수 없음
Model 에서 이해할 수 있는 1,0으로 변경 &gt; encoding</p>
</blockquote>
<pre><code>import numpy as np
df[&#39;y&#39;]=np.where(df[&#39;y&#39;]==&#39;yes&#39;, 1, 0)</code></pre><h2 id="모델링-데이터-전처리">모델링 데이터 전처리</h2>
<h3 id="▶-모델링을-학습하기-위한-featurex와-y데이터를-구분하는-단계">▶ 모델링을 학습하기 위한 Feature(X)와 Y데이터를 구분하는 단계</h3>
<pre><code>from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn import metrics

X=df.drop([&#39;duration&#39;,&#39;y&#39;], axis=1)
Y=df[&#39;y&#39;]

x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, stratify=Y)

print(x_train.shape)
print(y_train.shape)

print(x_test.shape)
print(y_test.shape)
</code></pre><blockquote>
<p>결과값
(28831, 19)
(28831,)
(12357, 19)
(12357,)</p>
</blockquote>
<pre><code>for i in categorical_list :
  print(i, df[i].nunique())</code></pre><blockquote>
<p>범주형 변수들의 문자 -&gt; 숫자화</p>
</blockquote>
<h3 id="▶-categorical범주형-변수는-one-hot-encoding-or-label-encoding을-통해-숫자형-변수로-변경해야함">▶ Categorical(범주형) 변수는 One-hot-encoding or Label-encoding을 통해 숫자형 변수로 변경해야함</h3>
<h3 id="▶-one-hot-encoding은-차원이-많은-변수에는-불리-label-encoding은-회귀관련-알고리즘에서는-사용-어려움tree-계열-알고리즘에서는-사용-가능">▶ One-hot-encoding은 차원이 많은 변수에는 불리, Label-encoding은 회귀관련 알고리즘에서는 사용 어려움.(※Tree 계열 알고리즘에서는 사용 가능)</h3>
<pre><code>from sklearn.preprocessing import LabelEncoder

for col in categorical_list:
    le = LabelEncoder()
    x_train[col] = le.fit_transform(x_train[col])
    x_test[col] = le.transform(x_test[col])

x_train[categorical_list].head()</code></pre><blockquote>
<p>테스트 데이터를 변환할 때는 학습 데이터에서 학습한 인코더를 그대로 사용해야 한다는 것입니다. 따라서 x_test에는 fit_transform 대신 transform을 사용하였습니다.</p>
</blockquote>
<h2 id="모델-학습-및-평가">모델 학습 및 평가</h2>
<h3 id="▶-학습">▶ 학습</h3>
<p>from sklearn.metrics import classification_report
rfc = RandomForestClassifier(random_state=123456)
rfc.fit(x_train, y_train)</p>
<h3 id="▶-예측">▶ 예측</h3>
<p>y_pred_train = rfc.predict(x_train)
y_pred_test = rfc.predict(x_test)</p>
<p>print(classification_report(y_train, y_pred_train))
print(classification_report(y_test, y_pred_test))
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/74bdbc99-2834-4bb4-8521-7c63f7ebb1b5/image.png" alt=""></p>
<blockquote>
<p>재현율이 30% test에 적합하지 않은 것으로 판단된다.
학습데이터에 과적합되었다 -&gt; 그래서 초매개변수 수정</p>
</blockquote>
<h2 id="hyper-parameter-튜닝">Hyper parameter 튜닝</h2>
<p>모델 성능을 올리기 위한 옵션 조절</p>
<h3 id="▶-randomforestclassifier-객체-생성-후-gridsearchcv-수행">▶ RandomForestClassifier 객체 생성 후 GridSearchCV 수행</h3>
<pre><code>from sklearn.model_selection import GridSearchCV

params = { &#39;n_estimators&#39; : [400],
           &#39;max_depth&#39; : [6, 8, 10]
            }


rf_clf = RandomForestClassifier(random_state = 12345, n_jobs = -1)
grid_cv = GridSearchCV(rf_clf, param_grid = params, cv = 3, n_jobs = -1, scoring=&#39;precision&#39;)
grid_cv.fit(x_train, y_train)

print(&#39;최적 하이퍼 파라미터: &#39;, grid_cv.best_params_)
print(&#39;최고 예측 정확도: {:.4f}&#39;.format(grid_cv.best_score_))</code></pre><blockquote>
<p>최적 하이퍼 파라미터:  {&#39;max_depth&#39;: 6, &#39;n_estimators&#39;: 500}
최고 예측 정확도: 0.7025</p>
</blockquote>
<h3 id="▶-best-score-기준-재학습">▶ Best score 기준 재학습</h3>
<pre><code>rfc = RandomForestClassifier(n_estimators=400, max_depth=6, random_state = 123456)
rfc.fit(x_train, y_train)

y_pred_train = rfc.predict(x_train)
y_pred_test = rfc.predict(x_test)

print(classification_report(y_train, y_pred_train))
print(classification_report(y_test, y_pred_test))</code></pre><p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/44ff36c2-f38b-4274-a204-254b2257a15b/image.png" alt=""></p>
<blockquote>
<p>f1 - score가 너무 떨어졌는데, test set과 유사한 수준으로 맞추는게 더 의미가 있다고함.</p>
</blockquote>
<h2 id="중요-변수-파악">중요 변수 파악</h2>
<p>Feature IMP 분석을 통한 중요변수 파악</p>
<pre><code>import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
plt.style.use([&#39;dark_background&#39;])

ftr_importances_values = rfc.feature_importances_
ftr_importances = pd.Series(ftr_importances_values, index = x_train.columns)
ftr_top20 = ftr_importances.sort_values(ascending=False)[:20]

plt.figure(figsize=(8,6))
plt.title(&#39;Feature Importances&#39;)
sns.barplot(x=ftr_top20, y=ftr_top20.index)
plt.show()

# ▶ 1위 변수 탐색
sns.distplot(df[&#39;age&#39;]);   ## nr.employer 대신 넣어봄
plt.gcf().set_size_inches(5 ,5)


# ▶ 구간화  &lt;&lt;&lt; age로 진행함
import numpy as np
# df[&#39;nr.employed_gp&#39;] = np.where (df[&#39;nr.employed&#39;] &lt;= 5000, &#39;5000 이하&#39;,
#                            np.where(df[&#39;nr.employed&#39;] &lt;= 5200, &#39;5000~5200&#39;, &#39;5200 초과&#39;))

df[&#39;age&#39;] = np.where(df[&#39;age&#39;] &lt;= 19, &#39;10대&#39;,
                     np.where(df[&#39;age&#39;] &lt;= 29, &#39;20대&#39;,
                     np.where(df[&#39;age&#39;] &lt;= 39, &#39;30대&#39;,
                     np.where(df[&#39;age&#39;] &lt;= 49, &#39;40대&#39;,
                     np.where(df[&#39;age&#39;] &lt;= 59, &#39;50대&#39;,
                     np.where(df[&#39;age&#39;] &lt;= 69, &#39;60대&#39;,
                     np.where(df[&#39;age&#39;] &lt;= 79, &#39;70대&#39;, &#39;80대 이상&#39;)))))))

# # ▶ 평가
# df_gp = df.groupby(&#39;nr.employed_gp&#39;)[&#39;y&#39;].agg([&#39;count&#39;, &#39;sum&#39;])
# df_gp[&#39;ratio&#39;] = round((df_gp[&#39;sum&#39;] / df_gp[&#39;count&#39;]) * 100, 1)
# df_gp

df_gp = df.groupby(&#39;age&#39;)[&#39;y&#39;].agg([&#39;count&#39;, &#39;sum&#39;])
df_gp[&#39;ratio&#39;] = round((df_gp[&#39;sum&#39;] / df_gp[&#39;count&#39;]) * 100, 1)
df_gp
</code></pre><p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/bf4a509a-db1b-4420-bb89-f71ccf7e0b6a/image.png" alt=""></p>
<h2 id="저장-및-불러오기">저장 및 불러오기</h2>
<pre><code>import pickle
# 모델 저장
saved_model = pickle.dumps(rfc)

# 모델 Read
clf_from_pickle = pickle.loads(saved_model)</code></pre><blockquote>
<h1 id="결론">결론</h1>
<p>유의미한 결과를 얻기 어려운 분석이라고 판단된다.
<del>nr.employer 는 판매직원 은행의 직원수라고 추정됨.</del>
=기업, 조직, 또는 경제 전체의 직원 수를 분기별로 나타내는 수치 지표를 의미
고객 정보보다 외부 변수(nr.number, 유리보 3개월금리, 실업율, cpi 등) 에 영향을 많이 받는 것 같음. 이 분석 결과로는 고객 정보에 대한 내용은 없고 &quot;nr.number가 높은 시기에 마케팅을 해야한다.&quot; 정도의 결과가 나오는 것 같다. 그래서 시작부터 외부 변수와 고객 변수를 나눠서 수행해야했지 않나 생각
 현재는 모든 변수를 하나로 묶어서 진행한 것 같은데, 아래와 같이 두가지 분석 목표를 가지고 설계하는 것은 어떤지 궁금해졌다.</p>
</blockquote>
<p>현 분석 목표 : 모든 변수를 포함하여 고객 가입률에 영향을 미치는 변수 찾기</p>
<p>변경 1. 분석 목표 : 가입할 가능성이 높은 고객의 성향 찾기
고객에 대한 변수만을 모아서 수행
poutcome, month, age, job과 같은 고객에게 매칭되는 정보로만 진행</p>
<p>변경 2. 분석 목표 : 외부 변수로 인한 가입률 높은 &quot;시기&quot; 추출 + 이 시기에 가입률 높은 &quot;고객 변수&quot; 추출</p>
<blockquote>
<p>멘토님은 변경 1안은 큰 의미 없어 보이고, 현 목표와 변경 2안을 진행해서 더 좋은 분석을 뽑아 보라고 함</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[통계] One-way ANOVA (3) F-value와 사후검정]]></title>
            <link>https://velog.io/@jongyoon_insight/%ED%86%B5%EA%B3%84-One-way-ANOVA-3-F-value%EC%99%80-%EC%82%AC%ED%9B%84%EA%B2%80%EC%A0%95</link>
            <guid>https://velog.io/@jongyoon_insight/%ED%86%B5%EA%B3%84-One-way-ANOVA-3-F-value%EC%99%80-%EC%82%AC%ED%9B%84%EA%B2%80%EC%A0%95</guid>
            <pubDate>Sat, 10 Feb 2024 09:04:09 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/b1e755da-8c50-43b4-8dfd-6b64ecc11667/image.png" alt="">
<img src="https://velog.velcdn.com/images/jongyoon_insight/post/63e462f7-4560-45a9-baf1-a644d2493dc2/image.png" alt=""></p>
<h2 id="유의하다는-것은-정확히-무엇인가">유의하다는 것은 정확히 무엇인가?</h2>
<blockquote>
<p>적어도 한 그룹의 평균은 다르다(NOT ALL means are equal)
셋 중 한 그룹의 평균이 다르다는 것 뿐이다.</p>
</blockquote>
<h2 id="사후검정의-필요성">사후검정의 필요성</h2>
<blockquote>
<p>One-way ANOVA 결과만으로는 어떤 그룹이 어떻게 다른지 알 수 없음
그러므로, 유의하다는 결과가 나오면 자동으로 사후검정을 해야함</p>
</blockquote>
<h1 id="사후검정post-hoc-test이란">사후검정(Post Hoc Test)이란?</h1>
<blockquote>
<p>일종의 여러 다발의 t-test
그러나 1종 오류를 발생시키지 않음
각 그룹의 평균이 다른 그룹의 평균과 같은지 다른지 개별 비교 가능</p>
</blockquote>
<h3 id="사후검정의-종류">사후검정의 종류</h3>
<blockquote>
<p>Fisher&#39;s LSD / Bonferroni / Scheffe / Turkey / Duncan</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/8ffc0f98-4e1b-4fc5-bce2-fde2432ef4a4/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[R] One-way ANOVA 실습]]></title>
            <link>https://velog.io/@jongyoon_insight/R-One-way-ANOVA-%EC%8B%A4%EC%8A%B5</link>
            <guid>https://velog.io/@jongyoon_insight/R-One-way-ANOVA-%EC%8B%A4%EC%8A%B5</guid>
            <pubDate>Sat, 10 Feb 2024 08:41:26 GMT</pubDate>
            <description><![CDATA[<h2 id="전처리">전처리</h2>
<p>독립변수가 열이 나뉘어져 있다면 전처리 작업을 해야함</p>
<p>예제1</p>
<pre><code>ind = c( rep(&quot;A반&quot;, 30),rep(&quot;B반&quot;, 30),rep(&quot;C반&quot;, 30))
dep = c( dt[,2],dt[,3],dt[,4])
dt_f = data.frame(ind, dep)

### boxplot
boxplot(dep~ind, dt_F)</code></pre><p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/f5ce3cb7-e490-4148-9ae1-bb2d83e66170/image.png" alt=""></p>
<p>예제2
이미 독립변수 열이 합쳐져 있음</p>
<pre><code>dt = as.data.frame(Telco)
dt$PaymentMethod &lt;- ordered(dt$PaymentMethod) ## 범주화 하기
dt &lt;- na.omit(dt) ## 결측치 제거</code></pre><h1 id="독립성-확인">독립성 확인</h1>
<h3 id="예제-1">예제 1</h3>
<p>각 반이 독립되어 있으므로 독립</p>
<h3 id="예제-2">예제 2</h3>
<p>각 결제 방식에 따라 나뉘어 있으므로 독립</p>
<h1 id="정규성-확인">정규성 확인</h1>
<h3 id="예제1">예제1</h3>
<p>각 반이 30명 이상이 되기 때문에 
정규성이 된다고 봄</p>
<h3 id="예제2">예제2</h3>
<pre><code>table(dt$PaymentMethod)
Bank transfer (automatic)   Credit card (automatic)          Electronic check 
                     1542                      1521                      2365 
             Mailed check 
                     1604 </code></pre><p>각 표본이 1000개가 넘으므로 정규성이 있다고 봄</p>
<h1 id="등분산-확인">등분산 확인</h1>
<h2 id="levene-test">levene test</h2>
<p>레벤 테스트(Levene&#39;s Test)는 통계학에서 분산의 동질성을 검정하는 방법입니다. 동질성이란 두 개 이상의 모집단에서 추출된 표본들이 공통적으로 가지는 분산(변동성)이 같음을 의미합니다.</p>
<p>레벤 테스트는 특히 분산 분석(ANOVA)과 같은 통계적 분석을 수행하기 전에, 해당 분석의 전제 조건 중 하나인 분산의 동질성을 만족하는지 검정하기 위해 사용됩니다.</p>
<p>레벤 테스트의 귀무 가설은 &quot;모든 표본 그룹들의 분산이 동일하다&quot;이며, 대립 가설은 &quot;적어도 하나의 그룹의 분산이 다른 그룹과 다르다&quot;입니다.</p>
<p>테스트 결과 p-value가 특정 유의 수준(예: 0.05)보다 낮으면, 귀무 가설을 기각하고 분산이 동질하지 않음을 결론지을 수 있습니다.</p>
<h3 id="예제-1-1">예제 1</h3>
<pre><code>library(lawstat) ##levene.test

levene.test(dt_f$dep, dt_f$ind, location =&#39;mean&#39;)

&gt; p-value = 0.8149 -&gt; 등분산성이 보장된다.</code></pre><h3 id="예제-2-1">예제 2</h3>
<pre><code>levene.test(dt$TotalCharges, dt$PaymentMethod, location =&#39;mean&#39;)

&gt; data:  dt$TotalCharges
 Test Statistic = 295.05, p-value &lt; 2.2e-16     
 등분산성이 보장되지 않는다</code></pre><blockquote>
<h3 id="chat-gpt-said">CHAT GPT said</h3>
<p>Levene 검정에서 p-value가 매우 작은 값을 갖는다면, 그것은 귀무가설(모든 그룹의 분산이 동일하다)을 기각한다는 것을 의미합니다. 즉, 그룹 간의 분산이 동일하지 않다는 것을 나타냅니다. 이는 등분산성 가정이 충족되지 않았음을 나타냅니다.
그러나 이것이 반드시 ANOVA 분석을 할 수 없다는 것을 의미하지는 않습니다. 분산이 동일하지 않은 경우에도 ANOVA를 사용할 수 있지만, 이 경우에는 조금더 견고한 버전의 ANOVA를 사용해야 합니다. 이를 위해 Welch&#39;s ANOVA 또는 Brown-Forsythe test 등을 사용할 수 있습니다.
또는, 데이터를 변환하여 분산을 동일하게 만드는 방법도 있습니다. 로그 변환, 제곱근 변환 등이 이에 해당합니다.
따라서, Levene 검정에서 등분산성이 충족되지 않더라도 다른 방법을 통해 분석을 계속 진행할 수 있습니다.</p>
</blockquote>
<h1 id="분산분석">분산분석</h1>
<h3 id="예제-1-2">예제 1</h3>
<blockquote>
<p>aov 패키지 이용
aov(formula , data = , projuections = , qr ...)</p>
</blockquote>
<pre><code>result = aov(dep~ind,dt_F)
summary(result)  ## 위의 aov 분석에는 p-value 가 안나와서 하는 것
p-value = 4.62e-15 </code></pre><p>p-value 가 0.05 보다 작아서 귀무가설이 기각된다.(유의미하다=사후검정 필요)</p>
<h3 id="예제-2-2">예제 2</h3>
<blockquote>
<p>기본적인 aov 와
  등분산성이 없을 때 사용하는 Welch&#39;s ANOVA - oneway.test()를 이용</p>
</blockquote>
<pre><code>result = aov(dt$TotalCharges~dt$PaymentMethod, dt)
summary(result)

                   Df    Sum Sq   Mean Sq F value Pr(&gt;F)    
dt$PaymentMethod    3 4.431e+09 1.477e+09   327.5 &lt;2e-16 ***
Residuals        7028 3.170e+10 4.510e+06  


result &lt;- oneway.test(TotalCharges ~ PaymentMethod, data = dt)
print(result)

data:  TotalCharges and PaymentMethod
F = 437.07, num df = 3.0, denom df = 3637.2, p-value &lt; 2.2e-16</code></pre><p>결과는 둘다 p-value 가 0.05 보다 작아서 귀무가설이 기각된다.(유의미하다=사후검정 필요)</p>
<h1 id="정규분포를-따르는-경우-사후검정의-분류">정규분포를 따르는 경우 사후검정의 분류</h1>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/8ffc0f98-4e1b-4fc5-bce2-fde2432ef4a4/image.png" alt=""></p>
<h3 id="예제-1tukey-투키-검정">예제 1(tukey 투키 검정)</h3>
<blockquote>
<p>등분산 + 표본크기 동일
TukeyHSD(x) 
x=aov result</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/8dfb2e12-67fc-40e0-9280-947908a70236/image.png" alt=""></p>
<blockquote>
<p>A반과 B반, A반과 C반의 유의미한 차이가 존재 -&gt; 이것이 귀무가설이 기각된 이유
B반과 C반은 차이가 없다.</p>
</blockquote>
<h3 id="예제-2games-howell-검정">예제 2(games-howell 검정)</h3>
<pre><code># 패키지 로드
library(PMCMRplus)
# Games-Howell 검정 실행
result &lt;- gamesHowellTest(TotalCharges ~ PaymentMethod, data = dt)
print(result)

                        Bank transfer (automatic) Credit card (automatic) Electronic check
Credit card (automatic) 1                         -                       -               
Electronic check        &lt; 2e-16                   &lt; 2e-16                 -               
Mailed check            &lt; 2e-16                   &lt; 2e-16                 2.3e-08         

P value adjustment method: none
alternative hypothesis: two.sided</code></pre><p>Estimated marginal means 를 보기 위해 패키지를 찾아봤다</p>
<pre><code># 패키지 로드
library(emmeans)
library(ggplot2)

# emmeans 계산

emmeans_results &lt;- emmeans(result1, &quot;PaymentMethod&quot;)

# emmeans 결과를 데이터프레임으로 변환
emmeans_df &lt;- as.data.frame(emmeans_results)

# ggplot2를 사용하여 그래프 출력
ggplot(emmeans_df, aes(x=PaymentMethod, y=emmean)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower.CL, ymax = upper.CL), width = 0.2) +
  theme_minimal() +
  labs(x = &quot;Payment Method&quot;, y = &quot;Estimated Marginal Mean&quot;, title = &quot;EMM Plot&quot;)</code></pre><p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/8e3389c6-936d-42d9-88e2-3e3e8510030b/image.png" alt=""></p>
<blockquote>
<h3 id="결과">결과</h3>
<p>credit car - bank transfer는 차이가 없다.
Electronic check - Bank transfer , -Credit card 는 차이가 있다.
Mailed check - Bank transfer, - Credit card, - Electronic check 는 차이가 있다.</p>
</blockquote>
<ul>
<li><ul>
<li>참고 링크
<a href="https://www.youtube.com/watch?v=2ZgdukOPnyU&amp;list=PLalb9l0_6WArk6oZej3KzduU8TRQA9gcV&amp;index=8">https://www.youtube.com/watch?v=2ZgdukOPnyU&amp;list=PLalb9l0_6WArk6oZej3KzduU8TRQA9gcV&amp;index=8</a>
<a href="https://www.youtube.com/watch?v=fym5J02BtnA">https://www.youtube.com/watch?v=fym5J02BtnA</a></li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[통계] One-way ANOVA (2) F-value]]></title>
            <link>https://velog.io/@jongyoon_insight/%ED%86%B5%EA%B3%84-One-way-ANOVA-2-F-value</link>
            <guid>https://velog.io/@jongyoon_insight/%ED%86%B5%EA%B3%84-One-way-ANOVA-2-F-value</guid>
            <pubDate>Sat, 10 Feb 2024 06:51:22 GMT</pubDate>
            <description><![CDATA[<h1 id="f-value-">F-value ?</h1>
<p>F값이란 두개의 분산의 비율이다.
그래서 우리는 이것을 분산 분석이라고 부른다.</p>
<p>두개의 분산으로 평균 값이 같은지 다른지를 어떻게 알 수 있을까?</p>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/c8fa3e5d-3c77-4ea6-bbd2-975986593d77/image.png" alt=""></p>
<h2 id="between-variance-첫번째-분산--gm전체-평균으로부터-각-그룹까지의-분산">[Between Variance] 첫번째 분산 : GM(전체 평균)으로부터 각 그룹까지의 분산</h2>
<p>전체 평균으로부터 각 그룹의 평균값이 멀리 떨어져있다 </p>
<blockquote>
<p>따라서, 적어도 어떤 그룹 한개는 다른 그룹과 평균이 다를 수 있다!</p>
</blockquote>
<h3 id="문제는-이-between-variance가-얼마나-커야-통계적으로-큰걸까--우연히-클-가능성은-확률적으로-얼마나-될까">문제는 이 Between Variance가 얼마나 커야 통계적으로 큰걸까? &gt; 우연히 클 가능성은 확률적으로 얼마나 될까?</h3>
<h2 id="within-variance-두번째-분산--그룹내의-분산">[Within Variance] 두번째 분산 : 그룹내의 분산</h2>
<p>t-test의 t-value 계산시의 분모(표준편차)와 같은 의미</p>
<blockquote>
<p>무의미한 변화의 정도(randomly)</p>
</blockquote>
<h2 id="bv가-wv보다-충분히-커야-우리는-bv가-통계적으로-크다고-말할-수-있고-적어도-어느-한그룹의-평균값이-전체-평균과는-다르다유의미고-말할-수-있다">BV가 WV보다 충분히 커야 우리는 BV가 통계적으로 크다고 말할 수 있고, 적어도 어느 한그룹의 평균값이 전체 평균과는 다르다(유의미)고 말할 수 있다.</h2>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/2ec18e22-128f-4405-bba9-8f6fa2048194/image.png" alt=""></p>
<h1 id="통계적-가설">통계적 가설</h1>
<p><img src="https://velog.velcdn.com/images/jongyoon_insight/post/b5759436-3bcb-4a9b-bd9d-9a9955ec7f45/image.png" alt=""></p>
]]></description>
        </item>
    </channel>
</rss>