<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>vVbb</title>
        <link>https://velog.io/</link>
        <description>개똥이 </description>
        <lastBuildDate>Tue, 22 Feb 2022 05:25:37 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>vVbb</title>
            <url>https://images.velog.io/images/k_dah/profile/fd6ce972-74bc-4fa8-a392-f2b45ec58c5e/pin_hilaryheid.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. vVbb. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/k_dah" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[BOJ / Sorting / 카드 / Python ]]></title>
            <link>https://velog.io/@k_dah/%EB%B0%B1%EC%A4%80-%EC%A0%95%EB%A0%AC-11652%EB%B2%88-%EC%B9%B4%EB%93%9C-%ED%8C%8C%EC%9D%B4%EC%8D%AC</link>
            <guid>https://velog.io/@k_dah/%EB%B0%B1%EC%A4%80-%EC%A0%95%EB%A0%AC-11652%EB%B2%88-%EC%B9%B4%EB%93%9C-%ED%8C%8C%EC%9D%B4%EC%8D%AC</guid>
            <pubDate>Tue, 22 Feb 2022 05:25:37 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/11652">카드</a></p>
<h2 id="✍️-문제-풀이">✍️ 문제 풀이</h2>
<p>딕셔너리를 이용했다.
n개의 숫자를 입력받을 때마다 그 숫자가 딕셔너리에 존재한다면 <code>딕셔너리[입력받은숫자] += 1</code>, 
만약 존재하지 않는다면 <code>딕셔너리[입력받은숫자] = 1</code>.
숫자를 전부 입력받은 뒤에는 딕셔너리를 우선 value값을 기준으로 내림차순 정렬을 하고, key값을 기준으로 오름차순 정렬을 한번 더 해준다. </p>
<h2 id="💻-코드">💻 코드</h2>
<pre><code class="language-python">import sys
input = sys.stdin.readline

n = int(input())
nums = {}
for _ in range(n):
    num = int(input())
    if num in nums.keys():
        nums[num] += 1
    else:
        nums[num] = 1

nums = sorted(nums.items(), key = lambda x: (-x[1], x[0]))
print(nums[0][0]) </code></pre>
<hr>
<h2 id="👀-문제-풀면서">👀 문제 풀면서</h2>
<ul>
<li>딕셔너리
딕셔너리[key] = value , item = key + value<pre><code class="language-python"># 딕셔너리 정렬
nums = sorted(nums.items(), key = lambda x: (-x[1], x[0]))</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[BOJ / Sorting / 올림픽 / Python]]></title>
            <link>https://velog.io/@k_dah/%EB%B0%B1%EC%A4%80-%EC%A0%95%EB%A0%AC-8979%EB%B2%88-%EC%98%AC%EB%A6%BC%ED%94%BD-%ED%8C%8C%EC%9D%B4%EC%8D%AC</link>
            <guid>https://velog.io/@k_dah/%EB%B0%B1%EC%A4%80-%EC%A0%95%EB%A0%AC-8979%EB%B2%88-%EC%98%AC%EB%A6%BC%ED%94%BD-%ED%8C%8C%EC%9D%B4%EC%8D%AC</guid>
            <pubDate>Tue, 22 Feb 2022 04:58:30 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/8979">&lt;8979번&gt;</a></p>
<h2 id="✍️-문제-풀이">✍️ 문제 풀이</h2>
<p>우선 금메달 개수를 기준으로 정렬한다.
금메달 개수가 같다면 은메달, 은메달 개수도 같다면
동메달을 기준으로 정렬한다.
sort()와 lambda로 구현했다.</p>
<h2 id="💻-코드">💻 코드</h2>
<pre><code class="language-python">import sys
input = sys.stdin.readline

n, k = map(int, input().split())

scores = [[] for _ in range(n)]

for i in range(n):
    nation, gold, silver, bronze = map(int, input().split())
    scores[nation-1] = [gold, silver, bronze] 

k_score = scores[k-1]
scores.sort(key = lambda x: (-x[0],-x[1],-x[2]))

for i in range(n):
    if k_score[:] == scores[i][:]:
        print(i+1)
        break    </code></pre>
<hr>
<h2 id="👀-문제-풀면서">👀 문제 풀면서</h2>
<ul>
<li><p>.sort(key = lambda ~)
sort()는 key 값을 기준으로 정렬하며 기본값은 오름차순이다. </p>
<pre><code class="language-python"># 인덱스 0의 값으로 오름차순 정렬 후, 인덱스 1의 값으로 내림차순 정렬
리스트.sort(key = lambda x : x[0], -x[1])</code></pre>
</li>
<li><p>배열 비교하기</p>
<pre><code class="language-python">if k_score[:] == score[i][:]:</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[BOJ / Implementation / 통계학 / Python ]]></title>
            <link>https://velog.io/@k_dah/%EB%B0%B1%EC%A4%80-%EA%B5%AC%ED%98%84-2108%EB%B2%88-%ED%86%B5%EA%B3%84%ED%95%99-%ED%8C%8C%EC%9D%B4%EC%8D%AC</link>
            <guid>https://velog.io/@k_dah/%EB%B0%B1%EC%A4%80-%EA%B5%AC%ED%98%84-2108%EB%B2%88-%ED%86%B5%EA%B3%84%ED%95%99-%ED%8C%8C%EC%9D%B4%EC%8D%AC</guid>
            <pubDate>Thu, 27 Jan 2022 06:31:45 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/2108">&lt;2108번&gt;</a></p>
<h2 id="✍️-문제-풀이">✍️ 문제 풀이</h2>
<h2 id="💻-코드">💻 코드</h2>
<pre><code class="language-python">from collections import Counter
import sys
input = sys.stdin.readline

n = int(input())
nums = [int(input()) for _ in range(n)]

print(round(sum(nums)/len(nums)))
nums.sort()
print(nums[len(nums)//2])

counts = Counter(nums).most_common()
if len(counts)&gt;1 and (counts[0][1] == counts[1][1]):
    print(counts[1][0])
else:
    print(counts[0][0])

print(max(nums)-min(nums))</code></pre>
<hr>
<h2 id="👀-문제-풀면서">👀 문제 풀면서</h2>
<ul>
<li>반올림
소수점 n번째 자리까지만 표현하고 반올림하고 싶을 때
<code>round(실수, n)</code></li>
</ul>
<pre><code class="language-python">import math
math.ceil()  # 올림
math.floor()  # 내림
math.trunc()  # 버림</code></pre>
<ul>
<li>collections 모듈의 Counter 클래스<pre><code class="language-python">from collections import Counter
</code></pre>
</li>
</ul>
<p>sample = &quot;hihello&quot;</p>
<h1 id="딕셔너리-형태--내림차순-형태로-반환">딕셔너리 형태 + 내림차순 형태로 반환</h1>
<p>counter = Counter(sample)
print(counter)</p>
<blockquote>
<blockquote>
<blockquote>
<p>Counter({&#39;h&#39;: 2, &#39;l&#39;: 2, &#39;i&#39;: 1, &#39;e&#39;: 1, 
&#39;o&#39;: 1})</p>
</blockquote>
</blockquote>
</blockquote>
<h1 id="리스트튜플--내림차순-형태로-반환">[리스트(튜플)] + 내림차순 형태로 반환</h1>
<p>counter = Counter(sample).most_common()
print(counter)</p>
<blockquote>
<blockquote>
<blockquote>
<p>[(&#39;h&#39;, 2), (&#39;l&#39;, 2), (&#39;i&#39;, 1), (&#39;e&#39;, 1), (&#39;o&#39;, 1)]</p>
</blockquote>
</blockquote>
</blockquote>
<h1 id="지정한-개수만큼-출력">지정한 개수만큼 출력</h1>
<p>counter = Counter(sample).most_common(2)
print(counter)</p>
<blockquote>
<blockquote>
<blockquote>
<p>[(&#39;h&#39;, 2), (&#39;l&#39;, 2)]
```</p>
</blockquote>
</blockquote>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[BOJ / Implementation / 집합 / Python]]></title>
            <link>https://velog.io/@k_dah/BOJ-%EA%B5%AC%ED%98%84-%EC%A7%91%ED%95%A9-Python</link>
            <guid>https://velog.io/@k_dah/BOJ-%EA%B5%AC%ED%98%84-%EC%A7%91%ED%95%A9-Python</guid>
            <pubDate>Sat, 22 Jan 2022 03:38:22 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/11723">&lt;11723번&gt;</a></p>
<h3 id="풀면서">풀면서</h3>
<h4 id="집합-자료형">집합 자료형</h4>
<ul>
<li>중복 허용x</li>
<li>순서 x</li>
</ul>
<p>리스트, 튜플과 달리 사전 &amp; 집합 자료형은 순서가 없기 때문에 인덱싱으로 값을 얻을 수 없다.
<strong>&#39;특정 데이터가 이미 등장한 적이 있는지&#39;</strong>를 확인할 때 효과적이다.</p>
<ul>
<li>집합 자료형의 연산<ul>
<li>합집합 : |</li>
<li>교집합 : &amp;</li>
<li>차집합 : -</li>
</ul>
</li>
<li>집합 자료형 관련 함수<ul>
<li>집합에 값을 추가 : .add()</li>
<li>여러 개의 값을 추가 : .update()</li>
<li>특정한 값을 제거 : .remove()
  +안전한 제거 : .discard()</li>
</ul>
</li>
</ul>
<h3 id="내-코드">내 코드</h3>
<pre><code class="language-python">import sys
input = sys.stdin.readline

S = set()

for _ in range(int(input())):
    command = list(input().split())

    if command[0] == &quot;all&quot;:
        # for문보다 실행시간이 짧다.
        S = set([&#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, &#39;5&#39;, &#39;6&#39;, &#39;7&#39;, &#39;8&#39;, &#39;9&#39;, &#39;10&#39;, &#39;11&#39;, &#39;12&#39;, &#39;13&#39;, &#39;14&#39;, &#39;15&#39;, &#39;16&#39;, &#39;17&#39;, &#39;18&#39;, &#39;19&#39;, &#39;20&#39;])
    elif command[0] == &quot;empty&quot;:
        S = set()
    elif command[0] == &quot;add&quot;:
        S.add(command[1])
    elif command[0] == &quot;remove&quot;:
        S.discard(command[1])
    elif command[0] == &quot;check&quot;:
        print(int(command[1] in S))
    elif command[0] == &quot;toggle&quot;:
        if command[1] in S:
            S.remove(command[1])
        else:
            S.add(command[1])</code></pre>
<ul>
<li>집합 개념</li>
<li>for문을 사용하지 않고 일일이 작성해 주는게 실행 시간이 짧다. (상황에 맞게 잘 선택하기)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[BOJ / Implementation / 프린터 큐 / Python ]]></title>
            <link>https://velog.io/@k_dah/BOJ-%EA%B5%AC%ED%98%84-%ED%94%84%EB%A6%B0%ED%84%B0-%ED%81%90-Python</link>
            <guid>https://velog.io/@k_dah/BOJ-%EA%B5%AC%ED%98%84-%ED%94%84%EB%A6%B0%ED%84%B0-%ED%81%90-Python</guid>
            <pubDate>Fri, 21 Jan 2022 06:51:48 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/1966">&lt;1966번&gt;</a></p>
<h2 id="문제-풀이">문제 풀이</h2>
<p>n개 문서의 중요도를 저장할 리스트(<code>files</code>)와 몇 번째로 인쇄되는지 궁금한 문서의 위치를 표시한 리스트(<code>check</code>), 총 2개의 리스트가 필요하다. 
<code>files</code>과 그때의 리스트의 최댓값(<code>max(files</code>)을 비교해 나간다.
비교 결과에 따라 문서를 출력, 즉 <code>files.pop()</code>을 하여 리스트에서 해당 값을 빼내거나
리스트의 가장 뒤로 값을 옮기게 되는데 <code>files.append(files.pop())</code>
위와 같은 작업을 <code>check</code>에도 똑같이 수행한다.
이를 통해 <code>files</code> 내에서 문서들의 위치가 계속 변경이 되더라도 내가 표시해둔 문서의 위치 정보를 계속 유지할 수 있다. </p>
<h2 id="코드">코드</h2>
<pre><code class="language-python">import sys
input = sys.stdin.readline

cases = int(input())

for _ in range(cases):
    n, idx = map(int, input().split())
    files = list(map(int, input().split()))
    check = [0 for _ in range(n)]
    check[idx] = 1

    count = 0
    while files:
        if max(files) == files[0]:
            files.pop(0)
            count += 1
            if check.pop(0):
                print(count)
                break
        else:
            files.append(files.pop(0))
            check.append(check.pop(0))</code></pre>
<h2 id="📝-문제-풀면서">📝 문제 풀면서</h2>
<p>문제 제대로 읽기</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[BOJ / Implementation / 제로 / Python]]></title>
            <link>https://velog.io/@k_dah/BOJ-%EA%B5%AC%ED%98%84-%EC%A0%9C%EB%A1%9C-Python</link>
            <guid>https://velog.io/@k_dah/BOJ-%EA%B5%AC%ED%98%84-%EC%A0%9C%EB%A1%9C-Python</guid>
            <pubDate>Wed, 19 Jan 2022 14:08:54 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/10773">&lt;10773번&gt;</a></p>
<h2 id="문제-풀이">문제 풀이</h2>
<p>k번 숫자를 입력받고 0이라면 정수리스트.pop(), 0이 아니라면 정수리스트.append(정수)를 해준다.</p>
<h2 id="코드">코드</h2>
<pre><code class="language-python">import sys
input = sys.stdin.readline

k = int(input())
nums = []

for _ in range(k):
    num = int(input())
    if num == 0:
        nums.pop()
    else:
        nums.append(num)

print(sum(nums))</code></pre>
<h2 id="📝-문제-풀면서">📝 문제 풀면서</h2>
<ol>
<li>sys.stdin.readline()
한 줄 단위로 입력받으며 개행문자까지 입력받는다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[BOJ / Implementation / 요세푸스 문제 0 / Python]]></title>
            <link>https://velog.io/@k_dah/BOJ-%EA%B5%AC%ED%98%84-%EC%9A%94%EC%84%B8%ED%91%B8%EC%8A%A4-%EB%AC%B8%EC%A0%9C-0-Python</link>
            <guid>https://velog.io/@k_dah/BOJ-%EA%B5%AC%ED%98%84-%EC%9A%94%EC%84%B8%ED%91%B8%EC%8A%A4-%EB%AC%B8%EC%A0%9C-0-Python</guid>
            <pubDate>Tue, 18 Jan 2022 03:43:31 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/11866">&lt;11866번&gt;</a></p>
<h2 id="풀이">풀이</h2>
<h3 id="내-코드1">내 코드1</h3>
<pre><code class="language-python">import sys
input = sys.stdin.readline

n, k = map(int, input().split())

people = [num+1 for num in range(n)]
idx = 0

print(&quot;&lt;&quot;, end=&quot;&quot;)
while people:
    idx += k-1
    if idx &gt; len(people)-1:
        idx %= len(people)
    print(f&quot;{people.pop(idx)}&quot;, end=&quot;&quot;)
    if people:
        print(&quot;, &quot;, end=&quot;&quot;)

print(&quot;&gt;&quot;)</code></pre>
<p>idx=0 에서 시작해서 k-1을 더해주면서 k번째 차례가 된 원소를 기존리스트.pop(idx)로 기존리스트에서 삭제함과 동시에 바로 출력한다.
기존 리스트의 길이가 0이 될때까지 위의 과정을 반복한다. 이때 idx가 인덱스 범위를 초과했다면 리스트의 길이만큼 나눠준다.(원개념) 
출력형태를 맞추는 것도 꽤 신경 써야 했다.</p>
<h3 id="내-코드2">내 코드2</h3>
<pre><code class="language-python">import sys
input = sys.stdin.readline

n, k = map(int, input().split())

# 1.
people = list(range(1, n+1))
ans = []
idx = 0

while people:
    # 2.
    idx = (idx + k - 1) % len(people)
    ans.append(str(people.pop(idx)))

# 3.
print(&quot;&lt;&quot; + &quot;, &quot;.join(ans) + &quot;&gt;&quot;)</code></pre>
<p>빈 배열 ans[]를 준비한다. 
people 배열이 빌 때까지 <code>idx  = (idx + k - 1) % len(people)</code>를 반복하여 그때의 배열 내의 k번째 원소를 찾아낸다.
이때 그 k번째 원소를 ans 배열에 <strong>문자열로 바꿔서 저장</strong>한다.
그래야 마지막 결과를 출력할 때 .join()을 사용할 수 있다.</p>
<hr>
<h2 id="📝-문제-풀면서">📝 문제 풀면서</h2>
<ol>
<li><p>리스트 생성 방법 익히기</p>
<pre><code class="language-python">list(range(숫자범위))</code></pre>
</li>
<li><p>인덱스가 범위를 초과하지 않는 경우 len(people)로 나눈 나머지값과 같기 때문에 모든 경우에 len(people)로 나눠줘서 코드를 단축한다.</p>
</li>
<li><p>출력 방법 익히기
*ans배열에 저장할때 <strong>문자열로</strong> 바꾸고 저장</p>
</li>
</ol>
<p>*join함수 익히기</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[BOJ / Implementation / 그룹 단어 체커 / Python
]]></title>
            <link>https://velog.io/@k_dah/BOJ-%EA%B5%AC%ED%98%84-%EA%B7%B8%EB%A3%B9-%EB%8B%A8%EC%96%B4-%EC%B2%B4%EC%BB%A4-Python</link>
            <guid>https://velog.io/@k_dah/BOJ-%EA%B5%AC%ED%98%84-%EA%B7%B8%EB%A3%B9-%EB%8B%A8%EC%96%B4-%EC%B2%B4%EC%BB%A4-Python</guid>
            <pubDate>Fri, 14 Jan 2022 06:38:19 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/1316">&lt;1316번&gt;</a></p>
<h3 id="코드1">코드1</h3>
<pre><code class="language-python">import sys
input = sys.stdin.readline


n = int(input())
ans = n

for i in range(n):
    vocabs = input().rstrip()
    ch = []
    idx = 0

    while idx &lt; len(vocabs) - 1:
        if vocabs[idx] != vocabs[idx+1]:
            if vocabs[idx] in ch:
                ans -= 1
                break
            else:
                ch.append(vocabs[idx])
        idx += 1
    if idx == len(vocabs) - 1 and vocabs[idx] in ch:
        ans -= 1

print(ans)</code></pre>
<p>while문으로 현재 인덱스의 문자와 인덱스+1의 문자를 비교하고 문자를 따로 리스트에 저장한다. 
이때 리스트에 이미 존재하는 문자인지 확인을 하는데 이미 존재한다면 그룹 단어가 아닌 것.
인덱스 와 인덱스+1을 비교하기 때문에 맨 마지막 문자의 경우 인덱스+1을 하면 에러가 발생한다. 그래서 맨 마지막 문자는 while문 밖에서 따로 검사하도록 했다.
while문 안에서 깔끔하게 다 넣고 싶었는데 생각해보다가 말았다. 고쳐봐야지.
효율적인 코드로 짜고 싶었는데 방법을 모르겠어서 그냥 일단 100점 맞추는 것만 생각하고 풀었다.
다른 코드들 찾아봐야겠다.</p>
<h3 id="코드2">코드2</h3>
<pre><code class="language-python">import sys
input = sys.stdin.readline

ans = 0

for i in range(int(input())):
    vocab = input().rstrip()
    if list(vocab) == sorted(vocab, key=vocab.find):
        ans += 1

print(ans)</code></pre>
<ul>
<li>문자열.find(&#39;문자&#39;)
문자열 내에서 가장 먼저 발견되는 &#39;문자&#39;의 인덱스를 반환한다.
즉, &#39;문자&#39;가 문자열 내에서 여러 번 반복되더라도 가장 첫 번째 위치를 반환한다.</li>
<li>sorted(vocab, key = vocab.find)
key의 인수로 함수를 전달받고 vocab 내의 모든 문자들에게 해당 함수를 적용한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[BOJ / Greedy / 30 / Python]]></title>
            <link>https://velog.io/@k_dah/BOJ-Greedy-30-Python</link>
            <guid>https://velog.io/@k_dah/BOJ-Greedy-30-Python</guid>
            <pubDate>Wed, 12 Jan 2022 06:47:16 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/10610">30</a></p>
<p><del>n을 리스트로 입력받아서 숫자 한 자리씩 떼어내서 저장
itertools.permutations로 가능한 모든 숫자 조합을 만들어 리스트로 저장
그 리스트를 내림차순으로 정렬 후
30으로 나눠가며 나누어 떨어지면 해당 값이 정답이 된다.
위와 같이 풀어봤는데 메모리 초과가 떴다.
쓸데없이 복잡하게 생각했다.</del></p>
<h3 id="풀면서">풀면서</h3>
<ul>
<li><p>개행문자 빼고 문자열 입력받기</p>
<pre><code class="language-python">n = input().rstrip()</code></pre>
</li>
<li><p>&quot;구분자&quot;.join(리스트)
구분자를 기준으로 리스트 내의 문자들을 합쳐준다.</p>
</li>
<li><p>형변환, map(함수, 반복 가능한 자료형)
여러 개의 데이터를 한 번에 자료형으로 변환할 때
두 번째 인자로는 주로 리스트나 튜플이 들어간다.</p>
<pre><code class="language-python">nums = list(map(int, input().rstrip()))
nums = map(str, nums)</code></pre>
</li>
</ul>
<h3 id="내-코드1">내 코드1</h3>
<pre><code class="language-python">import sys
input = sys.stdin.readline

# 개행문자빼고 입력받은 문자열을 map(int,~)로 정수형으로 변환 후 리스트화
nums = list(map(int, input().rstrip()))
if 0 not in nums or sum(nums) % 3 != 0:
    print(-1)
else:
    # 최댓값을 찾는 거니까 + 0은 자동으로 가장 끝자리에 위치
    nums.sort(reverse=True)
    # 정수형으로 저장된 nums 리스트내의 모든 값들을 str형으로 변환
    nums = (map(str, nums))
    print(&quot;&quot;.join(nums))</code></pre>
<p><strong>30의 배수</strong>를 찾아내는 조건문을 만들어 주면 된다.
3의 배수는 각 자릿수의 합이 3의 배수다.
즉, 0이 반드시 1개 이상 존재하고 모든 자릿수들의 합이 3의 배수라면 30의 배수가 된다.</p>
<h3 id="내-코드2">내 코드2</h3>
<pre><code class="language-python">import sys
input = sys.stdin.readline

nums = list(input().rstrip())
nums.sort(reverse=True)

if nums[-1] != &#39;0&#39; or sum(map(int, nums)) % 3 != 0:
    print(-1)
else:
    print(&quot;&quot;.join(nums))</code></pre>
<p>sum을 구할 때만 nums내의 값들이 정수형이면 된다.
실행 시간이 줄었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[BOJ / Greedy / 신입 사원 / Python]]></title>
            <link>https://velog.io/@k_dah/BOJ-Greedy-%EC%8B%A0%EC%9E%85-%EC%82%AC%EC%9B%90-Python</link>
            <guid>https://velog.io/@k_dah/BOJ-Greedy-%EC%8B%A0%EC%9E%85-%EC%82%AC%EC%9B%90-Python</guid>
            <pubDate>Tue, 11 Jan 2022 05:28:52 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/1946">백준 1946번 : 신입 사원</a>
못 풀었다.</p>
<h3 id="다른-풀이">다른 풀이</h3>
<p>오름차순으로 정렬할 생각을 못했다.
입력받은 리스트를 정렬을 통해 정리를 하고 문제를 풀어나가는 경우가 꽤 많은 것 같다.</p>
<p>여기저기 참고한 코드</p>
<pre><code class="language-python">import sys
input = sys.stdin.readline

t = int(input())
rank = []

for _ in range(t):
    n = int(input())
    ans = 1
    rank.clear()
    rank = [list(map(int, input().split())) for i in range(n)]
    rank.sort()

    min = rank[0][1]
    for j in range(1, len(rank)):
        if min &gt; rank[j][1]:
            ans += 1
            min = rank[j][1]

    print(ans)</code></pre>
<ul>
<li>우선 서류심사 성적을 기준으로 정렬한다.</li>
<li>이제 면접시험 성적을 비교해 본다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[BOJ / Greedy / 로프 / Python]]></title>
            <link>https://velog.io/@k_dah/BOJ-Greedy-%EB%A1%9C%ED%94%84-Python</link>
            <guid>https://velog.io/@k_dah/BOJ-Greedy-%EB%A1%9C%ED%94%84-Python</guid>
            <pubDate>Mon, 10 Jan 2022 07:49:21 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/2217">백준 2217번 : 로프</a></p>
<h3 id="내-코드">내 코드</h3>
<pre><code class="language-python">import sys
input = sys.stdin.readline

n = int(input())

ropes = []
for _ in range(n):
    ropes.append(int(input()))

ropes.sort(reverse=True)
ans = 0
for i in range(1, n+1):
    tmp = (i * ropes[i-1])
    ans = max(tmp, ans)

print(ans)</code></pre>
<p>가장 적은 무게를 드는 로프가 기준이 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[BOJ / Greedy / 잃어버린 괄호 / Python]]></title>
            <link>https://velog.io/@k_dah/BOJ-Greedy-%EC%9E%83%EC%96%B4%EB%B2%84%EB%A6%B0-%EA%B4%84%ED%98%B8-Python</link>
            <guid>https://velog.io/@k_dah/BOJ-Greedy-%EC%9E%83%EC%96%B4%EB%B2%84%EB%A6%B0-%EA%B4%84%ED%98%B8-Python</guid>
            <pubDate>Sat, 08 Jan 2022 17:27:52 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/1541">백준 1541번 : 잃어버린 괄호</a></p>
<h3 id="내-코드">내 코드</h3>
<pre><code class="language-python">import sys
input = sys.stdin.readline

string = input()

tmp = &quot;&quot;
f = 1
ans = 0

for c in (string):
    # 숫자
    if c != &quot;+&quot; and c != &quot;-&quot;:
        tmp += c
    else:
        ans += f * int(tmp)
        if c == &quot;-&quot; and f != -1:
            f *= -1
        tmp = &quot;&quot;

print(ans + (f * int(tmp)))</code></pre>
<h3 id="다른-풀이">다른 풀이</h3>
<pre><code class="language-python">import sys
input = sys.stdin.readline

string = input().split(&quot;-&quot;)

ans = 0
for i in string[0].split(&quot;+&quot;):
    ans += int(i)
for i in string[1:]:
    for j in i.split(&quot;+&quot;):
        ans -= int(j)

print(ans)</code></pre>
<ul>
<li>-를 기준으로 문자열 분리</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[BOJ / Greedy / 보물 / Python]]></title>
            <link>https://velog.io/@k_dah/BOJ-Greedy-%EB%B3%B4%EB%AC%BC-Python</link>
            <guid>https://velog.io/@k_dah/BOJ-Greedy-%EB%B3%B4%EB%AC%BC-Python</guid>
            <pubDate>Thu, 06 Jan 2022 05:47:55 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/1026">백준 1026번 : 보물</a></p>
<h3 id="문제-풀면서">문제 풀면서</h3>
<ul>
<li>배열에서 최댓값의 인덱스 가져오기<pre><code class="language-python">print(list.index(max(list)))</code></pre>
</li>
</ul>
<h3 id="내-코드1">내 코드1</h3>
<pre><code class="language-python">import sys
input = sys.stdin.readline

n = int(input())
list_A = []
list_B = []

list_A = list(map(int, input().split()))
list_B = list(map(int, input().split()))

# B의 큰 수와 A의 작은 수가 곱해지도록

list_A.sort()
ans = 0
for n in (list_A):
    B_max = max(list_B)
    ans += n * B_max
    list_B.pop(list_B.index(B_max))


print(ans)
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[BOJ / Greedy / 회의실 배정 / Python]]></title>
            <link>https://velog.io/@k_dah/BOJ-Greedy-%ED%9A%8C%EC%9D%98%EC%8B%A4-%EB%B0%B0%EC%A0%95-Python</link>
            <guid>https://velog.io/@k_dah/BOJ-Greedy-%ED%9A%8C%EC%9D%98%EC%8B%A4-%EB%B0%B0%EC%A0%95-Python</guid>
            <pubDate>Wed, 05 Jan 2022 16:47:20 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/1931">&lt;1931번&gt;</a></p>
<h2 id="문제-풀이">문제 풀이</h2>
<p><em>&#39;너무 늦게 끝나는 회의를 시작해버리면 다른 회의들을 진행할 수가 없다.&#39;</em></p>
<p>입력 받은 회의의 시작시간과 끝나는 시간을 저장한 리스트를 <strong>두 번 정렬</strong>하는 과정이 필요하다.
우선, 회의 <strong>시작시간을 기준으로</strong> 오름차순 정렬을 한다.</p>
<pre><code class="language-python">times.sort()</code></pre>
<p>이때 만약 회의의 시작시간(times[<del>][0])이 같다면 그 다음 인덱스 값인 끝나는 시간(times[</del>][1])을 기준으로 정렬이 된다.
이후 이번에는 회의 <strong>종료시간을 기준으로</strong> 정렬을 한다.</p>
<pre><code class="language-python">times.sort(key=lambda a: a[1])</code></pre>
<p>앞에서 언급했듯 회의 시작시간이 같다면 종료시간을 기준으로 정렬이 되는데 왜 또 다시 종료시간을 기준으로 정렬을 해줘야 할까
문제에서 원하는 답은 <strong>가능한 회의의 최대 개수</strong>를 출력하는 것이었다.
예를들어 시작시간, 종료시간이 아래와 같은 회의를 입력받았다고 하자.</p>
<pre><code>(0, 15) (1, 4) (4, 6)</code></pre><p>시작시간을 기준으로 정렬을 한 번만 한다면 0시 시작 15시 종료인 회의 1개밖에 진행할 수 없다. 
종료시간을 기준으로 다시 정렬을 진행하면</p>
<pre><code>(1, 4) (4, 6) (0, 15)</code></pre><p>2개의 회의를 진행할 수 있다.</p>
<h2 id="코드">코드</h2>
<pre><code class="language-python">import sys

input = sys.stdin.readline

n = int(input())
times = []

for _ in range(n):
    time = list(map(int, input().split()))
    times.append(time)

times.sort()
times.sort(key=lambda a: a[1])

end = times[0][1]
ans = 1
for i in range(1, len(times)):
    if times[i][0] &gt;= end:
        ans += 1
        end = times[i][1]

print(ans)</code></pre>
<hr>
<h2 id="📝-문제-풀면서">📝 문제 풀면서</h2>
<ol>
<li>리스트에서 특정 인덱스값으로 정렬하기</li>
</ol>
<p><strong>key</strong>를 이용한다.</p>
<pre><code class="language-python">times = [[1, 4], [3, 5], [0, 6], [5, 7], [3, 8], [5, 9], [6, 10], [8, 11], [8, 12], [2, 13], [12, 14]]

# 방법1
times.sort(key = lambda a: a[0])
# 방법2
sorted(times, key = lambda a: a[0])</code></pre>
<p>첫 번째 인덱스값으로 정렬을 원하면 그냥 times.sort()를 해줘도 되는 것 같다.
2차원배열.sort()를 하면 첫 번째 키 값이 동일하면 자동으로 그 다음 키 값에 따라 정렬된다. </p>
<ol start="2">
<li><p>리스트에서 특정 값 삭제하기</p>
<ul>
<li>인덱스로 제거 <ul>
<li>del 리스트[인덱스]
슬라이싱도 가능하다.</li>
<li>리스트.pop(인덱스)
매개 변수가 없을 때는 자동으로 -1값이 들어가서 리스트의 맨 마지막 요소를 제거한다.</li>
</ul>
</li>
<li>값으로 제거<ul>
<li>리스트.remove(값)
넘겨준 값을 가지는 원소를 삭제한다.
해당 값이 여러 개라면 가장 앞에 있는 요소 1개를 삭제한다.</li>
</ul>
</li>
<li>모든 원소 제거<ul>
<li>리스트.clear()</li>
</ul>
</li>
</ul>
</li>
<li><p>for문에서 zip
두 개의 리스트를 for문에서 동시에 돌리고 싶을 때</p>
<pre><code class="language-python">l1 = [1, 2, 3]
l2 = [4, 5, 6]
</code></pre>
</li>
</ol>
<p>for n1, n2 in zip(l1, l2):
    print(n1, n2)</p>
<blockquote>
<blockquote>
<blockquote>
</blockquote>
<p>1 4
2 5
3 6</p>
</blockquote>
</blockquote>
<pre><code>

_처음에는 문제를 너무 단순하게 생각했다.
회의의 최대 개수를 출력해야 한다는 것에 대해 깊게 생각하지 않았다. _
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[ML] 11주차-2 : 끝]]></title>
            <link>https://velog.io/@k_dah/ML-11%EC%A3%BC%EC%B0%A8-2-%EB%81%9D</link>
            <guid>https://velog.io/@k_dah/ML-11%EC%A3%BC%EC%B0%A8-2-%EB%81%9D</guid>
            <pubDate>Tue, 04 Jan 2022 08:12:32 GMT</pubDate>
            <description><![CDATA[<p><strong><span style="color:rgb(102, 153, 204)">Machine Learning by professor Andrew Ng in Coursera</span></strong></p>
<h1 id="summary">Summary</h1>
<h3 id="summary-main-topics">Summary: Main topics</h3>
<hr>
<ul>
<li><p>Supervised Learning</p>
<ul>
<li>Linear regression, logistic regression, neural networks, SVMs</li>
</ul>
</li>
<li><p>Unsupervised Learning</p>
<ul>
<li>K-means, PCA, Anomaly detection</li>
</ul>
</li>
<li><p>Special applications/special topics</p>
<ul>
<li>Recommender systems, large scale machine learning</li>
</ul>
</li>
<li><p>Advice on building a machine learning system</p>
<ul>
<li>Bias/variance, regularization; deciding what to work on next: evaluation of learning algorithms, learning curves, error analysis, ceiling analysis. </li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ML] 11주차-1 : Photo OCR, Sliding Window, Ceiling Analysis]]></title>
            <link>https://velog.io/@k_dah/ML-11%EC%A3%BC%EC%B0%A8-1-Photo-OCR-Sliding-Window</link>
            <guid>https://velog.io/@k_dah/ML-11%EC%A3%BC%EC%B0%A8-1-Photo-OCR-Sliding-Window</guid>
            <pubDate>Tue, 04 Jan 2022 07:47:25 GMT</pubDate>
            <description><![CDATA[<p><strong><span style="color:rgb(102, 153, 204)">Machine Learning by professor Andrew Ng in Coursera</span></strong></p>
<h1 id="photo-ocr">Photo OCR</h1>
<h2 id="1-problem-description-and-pipeline">1) Problem Description and Pipeline</h2>
<h3 id="the-photo-ocr-problem">The Photo OCR problem</h3>
<hr>
<p>Photo Optical Character Recognition</p>
<ol>
<li>Text detection
주어진 사진에서 텍스트 부분을 감지한다.</li>
</ol>
<p><strong>sliding window</strong></p>
<ol start="2">
<li><p>Character segmentation
<img src="https://images.velog.io/images/k_dah/post/7b049410-1967-46cc-b2af-9eab263d58f2/image.png" alt=""><strong>1D sliding window</strong></p>
</li>
<li><p>Character classification
<img src="https://images.velog.io/images/k_dah/post/cd463e8a-9c39-4e40-aff1-772eb7480db7/image.png" alt="">
이러한 시스템을 파이프라인 이라고 한다.
<img src="https://images.velog.io/images/k_dah/post/7e8cb228-d8c8-4703-958b-6139ff5e1eb3/image.png" alt=""></p>
</li>
</ol>
<h2 id="2-sliding-windows">2) Sliding Windows</h2>
<h3 id="text-detection">Text detection</h3>
<hr>
<p><img src="https://images.velog.io/images/k_dah/post/92526028-68b5-41ac-8773-187fcca083b3/ml.jpg" alt=""></p>
<h3 id="1d-sliding-window-for-character-segmentation">1D Sliding window for character segmentation</h3>
<hr>
<p><img src="https://images.velog.io/images/k_dah/post/26c18c2a-e448-4dd7-8fb1-63201df8dca0/ml.jpg" alt=""></p>
<h2 id="3-getting-lots-of-data-and-artificial-data">3) Getting Lots of Data and Artificial Data</h2>
<h3 id="aritificial-data-synthesis-for-photo-ocr">Aritificial data synthesis for photo OCR</h3>
<hr>
<p><img src="https://images.velog.io/images/k_dah/post/8603663c-8909-4d78-b244-8379b91b237e/image.png" alt="">
데이터를 무한으로 만들어낼 수 있다.</p>
<h3 id="synthesizing-data-by-introducing-distortions">Synthesizing data by introducing distortions</h3>
<hr>
<p><img src="https://images.velog.io/images/k_dah/post/3229c46b-2781-477e-b8f9-25247aa48d07/image.png" alt=""></p>
<p>16개의 새로운 데이터를 만들어 냈다.
<em>amplify</em></p>
<p><img src="https://images.velog.io/images/k_dah/post/2b251c8d-436d-42cc-ad6b-63b7047c5df8/image.png" alt="">의미없는 노이즈는 별 도움이 되지 않는다.</p>
<h3 id="discussion-on-getting-more-data">Discussion on getting more data</h3>
<hr>
<ol>
<li>위와 같이 데이터를 늘리는 노력을 하기 전에 우선 <strong>분류기가 low bias를 가졌는지</strong>를 확인해야 한다. 그래야 데이터를 늘리는 것이 의미가 있기 때문이다.
plot curve 그래프를 통해 low bias 여부를 확인한다.
만약 low bias 분류기가 아니라면 low bias가 될 때까지 feature의 개수를 늘리거나 neural network의 hidden unit 개수를 늘린다. </li>
<li>&quot;How much work would it be to get 10x as much data as we currently have?&quot;
라는 질문에 대해 생각해 본다.<ul>
<li>Artificial data synthesis</li>
<li>Collect / label it yourself</li>
<li>&quot;Crowd source&quot;</li>
</ul>
</li>
</ol>
<h2 id="3-ceiling-analysis-what-part-of-the-pipeline-to-work-on-next">3) Ceiling Analysis: What Part of the Pipeline to Work on Next</h2>
<h3 id="estimating-the-errors-due-to-each-component-ceiling-analysis">Estimating the errors due to each component (ceiling analysis)</h3>
<hr>
<p><img src="https://images.velog.io/images/k_dah/post/fd2b3b6e-2327-4844-b772-4dcf411d289c/image.png" alt="">
<img src="https://images.velog.io/images/k_dah/post/c39f7bc4-3583-400c-bf19-3f4a42642d7b/ml.jpg" alt="">
우선 전체 시스템의 accuracy는 72% 다.
1.
Text detection이 100%의 정확도를 가진다고 가정한다.
100% 정확도를 갖는 결과를 가지고 이후의 Character segmentation, Character recognition을 진행한다.
그러면 전체 시스템의 정확도는 <strong>89%</strong>가 된다.
2. 
Character segmentation이 100%의 정확도를 가진다고 가정하고 나머지 단계들을 실행한다.
전체 시스템의 정확도는 <strong>90%</strong>가 된다.
3.
Character recognition이 100%의 정확도를 가진다고 가정한다.
전체 시스템의 정확도는 당연히 <strong>100%</strong>가 된다.</p>
<p>정리하면</p>
<ul>
<li>Text detection에 시간을 들여 정확도를 최대한 올렸을 때 <strong>최대</strong> 17(89 - 82)% 만큼의 성능을 높일 수 있다.</li>
<li>Character segmentation에 시간들 들여 정확도를 최대한 올렸을 때 최대 1(90 - 89)% 만큼의 성능을 높일 수 있다.</li>
<li>Character recognition에 시간을 들여 정확도를 최대한 올렸을 때 최대 10(100 - 90)% 만큼의 성능을 높일 수 있다.</li>
</ul>
<p><em>ceiling , 최대 얼만큼 성능 향상을 할 수 있는지</em></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ML] 10주차-2 : 온라인 학습,  Map-reduce]]></title>
            <link>https://velog.io/@k_dah/ML-10%EC%A3%BC%EC%B0%A8-2-%EC%98%A8%EB%9D%BC%EC%9D%B8-%ED%95%99%EC%8A%B5</link>
            <guid>https://velog.io/@k_dah/ML-10%EC%A3%BC%EC%B0%A8-2-%EC%98%A8%EB%9D%BC%EC%9D%B8-%ED%95%99%EC%8A%B5</guid>
            <pubDate>Mon, 03 Jan 2022 09:58:09 GMT</pubDate>
            <description><![CDATA[<p><strong><span style="color:rgb(102, 153, 204)">Machine Learning by professor Andrew Ng in Coursera</span></strong></p>
<h1 id="advanced-topics">Advanced Topics</h1>
<h2 id="1-online-learning">1) Online Learning</h2>
<p>온라인 학습 알고리즘은 <strong>실시간으로 유입되는 데이터</strong>를 모델링하고 학습한다. 
고정된 훈련 세트라는 개념이 없다.
지속적으로 새롭게 유입되는 데이터로 학습을 하고, <strong>학습을 했다면 해당 샘플은 폐기</strong>한다. 
데이터가 지속적으로 계속 유입된다면 충분히 새로운 데이터를 확보할 수 있기 때문에 한 번 사용했던 샘플은 다시 사용하지 않는다. 
온라인 학습 알고리즘은 <strong>연속적인 데이터 스트림이 발생하는 환경</strong>에서 매우 효과적이다.</p>
<p><em>Can adapt to changing user preference.
Can keep track of changes</em>
유입되는 데이터의 변화에 따라 자동으로 파라미터를 조정한다.</p>
<ul>
<li>CTR(click-through rate)
실제 예측 클릭률</li>
</ul>
<p>온라인 학습 알고리즘은 확률적(Stochastic) 경사 하강법 알고리즘과 매우 유사하다. 
하지만 이때 온라인 학습의 경우 고정된 데이터가 아닌 새롭게 유입되는 샘플 데이터 1개씩으로 훈련을 하며 한 번 사용한 샘플은 폐기한다.</p>
<h2 id="2-map-reduce-and-data-parallelism">2) Map Reduce and Data Parallelism</h2>
<h3 id="map-reduce">Map-reduce</h3>
<hr>
<p><img src="https://images.velog.io/images/k_dah/post/9fb75182-8d8c-4068-8caa-3135cf07c75d/ml.jpg" alt=""></p>
<ul>
<li>훈련 세트를 쪼갠다.</li>
<li>쪼갠 각 훈련 세트들을 서로 다른 컴퓨터로 보낸다.
(또는 컴퓨터 한 대 내에서 각각 다른 core로 보낸다. 이 경우에는 네트워크 지연율은 고려하지 않아도 된다.)
각 컴퓨터들은 연산을 수행한다.</li>
<li>각 컴퓨터들의 연산 결과를 하나의 중앙 서버로 보낸다.</li>
</ul>
<p><em>병렬화</em></p>
<h3 id="map-reduce-and-summation-over-the-training-set">Map-reduce and summation over the training set</h3>
<hr>
<blockquote>
<p><strong>Q.</strong>
Suppose you apply the map-reduce method to train a neural network on ten machines. In each iteration, what will each of the machines do?
: Compute <strong>forward propagation and back propagation</strong> on 1/10 of the data to compute the derivative with respect to that 1/10 of the data.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ML] 10주차-1 : Batch / Stochastic / Mini-batch gradient  descent, 학습률]]></title>
            <link>https://velog.io/@k_dah/ML-10%EC%A3%BC%EC%B0%A8-1-Gradient-Descent-with-Large-Datasets</link>
            <guid>https://velog.io/@k_dah/ML-10%EC%A3%BC%EC%B0%A8-1-Gradient-Descent-with-Large-Datasets</guid>
            <pubDate>Sat, 01 Jan 2022 08:36:17 GMT</pubDate>
            <description><![CDATA[<p><strong><span style="color:rgb(102, 153, 204)">Machine Learning by professor Andrew Ng in Coursera</span></strong></p>
<h1 id="gradient-descent-with-large-datasets">Gradient Descent with Large Datasets</h1>
<h2 id="1-learning-with-large-datasets">1) Learning With Large Datasets</h2>
<p>학습알고리즘이 이전보다 더 잘 동작하는 이유는 학습알고리즘을 훈련시킬 수 있는 데이터셋이 커졌기 때문이다.
데이터셋이 커지면 왜 성능이 좋아질까?</p>
<h3 id="machine-learning-and-data">Machine learning and data</h3>
<hr>
<p>이전에 배웠던 성능이 좋은 학습 알고리즘을 얻는 방법 중 하나는 low bias 알고리즘을 크기가 큰 데이터셋으로 훈련시키는 것이었다. 
<img src="https://images.velog.io/images/k_dah/post/d0648eae-6020-4d75-abf9-f463c273a0cc/image.png" alt=""></p>
<h3 id="learning-with-large-datasets">Learning with large datasets</h3>
<hr>
<p>크기가 큰 데이터셋으로 학습할 때에 연산비용과 관련한 문제점이 발생한다.</p>
<p>훈련 세트의 크기 m이 아래와 같다고 할 때.
$$
m = 100,000,000
$$
$$
\theta_j := \theta_j - \alpha\frac{1}{m}\sum_{i=1}^{m}(h_\theta(x^{(i)} - y^{(i)})x_j^{(i)}
$$
$\theta_j$ 하나를 계산할 때마다 매번 100,000,000 개의 값을 더하는 과정이 필요하며, 이 계산 비용은 꽤 크다.
<em>이후의 강의에서 이 과정을 좀 더 효율적으로 바꿔줄 방법에 대해 배운다.</em>
100,000,000개의 데이터를 전부 다 활용하지 않고 그 중 랜덤으로 1000개만을 뽑아서 사용하는 방법도 있다.
우선 1000개만으로 학습을 해본 뒤, 
learning curve를 그려보고 전체 데이터셋을 사용하지 않아도 충분한 학습이 가능한지 확인한다.
<img src="https://images.velog.io/images/k_dah/post/d8093278-bb93-4250-9c7a-27e9c312fc51/ml.jpg" alt="">
<strong>High bias 라면 데이터를 더 늘리는 것이 의미가 없다.</strong></p>
<h2 id="2-stochastic-gradient-descent">2) Stochastic Gradient Descent</h2>
<p><em>데이터셋이 클 경우 경사하강법 연산 비용이 커지게 된다.</em></p>
<h3 id="linear-regression-with-gradient-descent">Linear regression with gradient descent</h3>
<hr>
<p>경사하강법을 사용해서 Linear regression을 훈련하고자 할 때 가설과 비용함수는 아래와 같으며, 비용함수의 그래프는 활 모양을 띈다.
$$
h_\theta(x) = \sum_{j=0}^{n}\theta_jx_j
$$
$$
J_{train}(\theta) = \frac{1}{2m}\sum_{i=1}^{m}(h_\theta(x^{(i)} - y^{(i)})^2
$$
경사하강법 수행은 다음과 같다.
$$
\text{Repeat} {<br>\theta_j := \theta_j - \alpha\frac{1}{m}\sum_{i=1}^{m}(h_\theta(x^{(i)}) - y^{(i)})x_j^{(i)}<br>\text{( for every j=0, ... , n) }}
$$
이때 m의 크기가 크다면 derivative term ($\frac{1}{m}\sum_{i=1}^{m}(h_\theta(x^{(i)}) - y^{(i)})x_j^{(i)}$)의 연산비용이 커지게 된다.
<img src="https://images.velog.io/images/k_dah/post/632c7a0f-490c-4e6b-9d94-3022110af206/ml.jpg" alt="">
derivative term에서 <strong>m의 값을 전체 훈련 세트로 설정</strong>해두고 계산하는 것을 <strong>Batch gradient descent</strong>라고 한다.
매 iteration마다 훈련세트 전체를 고려하지 않는 것은 <strong>Stochastic gradient descent</strong>.
<img src="https://images.velog.io/images/k_dah/post/99c6d205-9ac9-4552-9301-98169b5f5c3b/ml.jpg" alt=""></p>
<h3 id="stochastic-gradient-descent">Stochastic gradient descent</h3>
<hr>
<p>Stochastic의 경우 Batch와 달리 전체 훈련세트를 훑고 $\theta_j$를 업데이트 하는 것이 아니기 때문에 최적값에 도달하는 과정에서 아래 그림과 같이 방향 전환이 많이 발생한다. 하지만 이때 속도는 더 빠르다.
<img src="https://images.velog.io/images/k_dah/post/9fb900f5-f19d-4e9e-8652-c2a4bf7236b3/ml.jpg" alt="">
<em>GD : 전체 데이터셋 , SGD : 샘플 1개</em></p>
<h2 id="3-mini-batch-gradient-descent">3) Mini-Batch Gradient Descent</h2>
<ul>
<li><strong>Batch gradient descent</strong> : Use all $m$ examples in each iteration</li>
<li><strong>Stochastic gradient descent</strong> : Use 1 example in each iteration</li>
<li><strong>Mini-batch gradient descent</strong> : Use $b$ examples in each iteration
이때 $b$를 mini-batch size 라고 한다.</li>
</ul>
<h3 id="mini-batch-gradient-descent">Mini-Batch Gradient Descent</h3>
<hr>
<p><img src="https://images.velog.io/images/k_dah/post/9cd91ac3-8fe5-4a8c-9c9f-c7ad639ba9da/ml.jpg" alt=""></p>
<p><em>mini-batch vs stochastic
mini-batch는 stochastic 보다 더 많은 샘플들을 살펴봐야 하지만 벡터를 이용한다면 오히려 더 빠른 연산이 가능하다.</em></p>
<h2 id="4-stochastic-gradient-descent-convergence">4) Stochastic Gradient Descent Convergence</h2>
<h3 id="checking-for-convergence">Checking for convergence</h3>
<hr>
<p>각각의 경사하강법들에서 convergence를 확인하는 방법.
<img src="https://images.velog.io/images/k_dah/post/d1de3949-ab87-4e30-a341-6341dd1f18db/ml.jpg" alt=""></p>
<p>Plot $cost(\theta, (x^{(i)}, y^{(i)})),$ averaged over the last 1000(say) examepls
<img src="https://images.velog.io/images/k_dah/post/d8d11218-8b38-484a-bc02-ef2b699d1c3e/ml.jpg" alt="">
<img src="https://images.velog.io/images/k_dah/post/b98794d5-3d84-4b2a-bf57-4119871b2986/ml.jpg" alt=""></p>
<h3 id="stochastic-gradient-descent-1">Stochastic gradient descent</h3>
<hr>
<p><img src="https://images.velog.io/images/k_dah/post/fc62e9ef-6cd5-43a3-b9bc-9566e0cafa7f/image.png" alt="">
학습률의 값을 위와 같이 점점 감소시키면 같은 값을 유지한 것보다 더 좋은 결과를 얻을 수 있다. 
<em>If we reduce the learning rate α (and run stochastic gradient descent long enough), it’s possible that we may find a set of better parameters than with larger α.</em></p>
<p><del>비용 함수를 최적화하는 관점에서 stochastic gradient descent를 모니터링하는 방법에 대해 배웠다. 
이 방법은 <strong>훈련 세트 전체가 아닌 일부만</strong> 이용한다. 
이 방법으로 stochastic gradient descent가 제대로 동작하고 있는지, 즉 최적값으로 잘 수렴하고 있는지 확인할 수 있고 또한 학습률 α를 조정할 수 있다.</del></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ML] 9주차-6 : Low Rank Matrix Factorization]]></title>
            <link>https://velog.io/@k_dah/ML-9%EC%A3%BC%EC%B0%A8-6-Low-Rank-Matrix-Factorization</link>
            <guid>https://velog.io/@k_dah/ML-9%EC%A3%BC%EC%B0%A8-6-Low-Rank-Matrix-Factorization</guid>
            <pubDate>Wed, 08 Dec 2021 11:04:39 GMT</pubDate>
            <description><![CDATA[<p><strong><span style="color:rgb(102, 153, 204)">Machine Learning by professor Andrew Ng in Coursera</span></strong></p>
<h1 id="recommender-systems">Recommender Systems</h1>
<h2 id="1-vectorization-low-rank-matrix-factorization">1) Vectorization: Low Rank Matrix Factorization</h2>
<p>Collaborative filtering을 matrix로 나타내면 다음과 같다.
<img src="https://images.velog.io/images/k_dah/post/627ec4aa-4fa9-4abf-a6e7-fe60b693648f/ml.jpg" alt=""></p>
<h3 id="collaborative-filtering">Collaborative filtering</h3>
<hr>
<p><img src="https://images.velog.io/images/k_dah/post/82182002-5589-49ff-88d6-d7bd8151a109/ml.jpg" alt=""></p>
<h3 id="finding-related-movies">Finding related movies</h3>
<hr>
<p><img src="https://images.velog.io/images/k_dah/post/ad16b03b-f724-4e51-956d-72f64e922624/ml.jpg" alt=""></p>
<h2 id="2-implementation-detail--mean-normalization">2) Implementation Detail : Mean Normalization</h2>
<p><img src="https://images.velog.io/images/k_dah/post/1f9b1933-2e77-4b4b-b5a9-305b7241af6d/ml.jpg" alt=""></p>
<h3 id="mean-normalization">Mean normalization</h3>
<hr>
<p><img src="https://images.velog.io/images/k_dah/post/24bd668f-3cc8-42c8-8c74-e2da6a15062a/ml.jpg" alt=""><img src="https://images.velog.io/images/k_dah/post/7c6d2934-5682-4c5e-9a22-33bef2450df9/ml.jpg" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ML] 9주차-5 : Collaborative Filtering]]></title>
            <link>https://velog.io/@k_dah/ML-9%EC%A3%BC%EC%B0%A8-5-Collaborative-Filtering</link>
            <guid>https://velog.io/@k_dah/ML-9%EC%A3%BC%EC%B0%A8-5-Collaborative-Filtering</guid>
            <pubDate>Wed, 08 Dec 2021 10:50:56 GMT</pubDate>
            <description><![CDATA[<p><strong><span style="color:rgb(102, 153, 204)">Machine Learning by professor Andrew Ng in Coursera</span></strong></p>
<h1 id="recommender-systems">Recommender Systems</h1>
<h2 id="1-multivariate-gaussian-distribution">1) Multivariate Gaussian Distribution</h2>
<p><img src="https://images.velog.io/images/k_dah/post/f176d70e-6299-407e-8dc7-673228a87ec6/ml.jpg" alt="">
<em>&#39; $x^{(<del>)}$ 는 영화에 대한, $\theta^{(</del>)}$는 사용자들에 대한 데이터 &#39;</em>
<em>&#39; <del>$\theta^{(</del>)}$에서 가장 첫 번째 항은 기본으로 0이 들어감~~ &#39;</em>
<img src="https://images.velog.io/images/k_dah/post/1ea1f3b5-4daf-4b2c-851b-53d12e6bfb4d/ml.jpg" alt="">
위의 데이터를 보고
Alice와 Bob은 $x^{(1)}$을 좋아한다.
Carol과 Dave는 $x^{(1)}$을 안 좋아한다.</p>
<p>위의 사용자별로 주어진 $\theta^{(~)}$에서 Alice와 Bob은 romance를 좋아했다.
반면 Carol과 Dave는 action을 좋아했다.
따라서 이를 바탕으로 아래와 같이 추측할 수 있다.</p>
<table>
<thead>
<tr>
<th align="center">$x_1$</th>
<th align="center">$x_2$</th>
</tr>
</thead>
<tbody><tr>
<td align="center">1.0</td>
<td align="center">1.0</td>
</tr>
<tr>
<td align="center">내가 <strong>구하려는 것은 $x^{(1)}$의 feature vector</strong></td>
<td align="center"></td>
</tr>
<tr>
<td align="center">아래의 식들을 만족하는 $x^{(1)}$을 구하면 된다.</td>
<td align="center"></td>
</tr>
<tr>
<td align="center"><img src="https://images.velog.io/images/k_dah/post/e73a2a23-a285-4c5c-908f-f3920ee1b5eb/ml.jpg" alt=""></td>
<td align="center"></td>
</tr>
</tbody></table>
<h3 id="optimization-algorithm">Optimization algorithm</h3>
<hr>
<p><img src="https://images.velog.io/images/k_dah/post/e63d8a7c-b787-4232-a063-4f9136775042/ml.jpg" alt=""></p>
<h3 id="collaborative-filtering">Collaborative filtering</h3>
<hr>
<p><img src="https://images.velog.io/images/k_dah/post/a09a3d10-668e-4d61-9041-f73cee0cacef/ml.jpg" alt=""></p>
<h2 id="2-collaborative-filtering-algorithm">2) Collaborative filtering algorithm</h2>
<p><img src="https://images.velog.io/images/k_dah/post/cf86a356-3999-4250-a276-6c9693d6e04f/ml.jpg" alt=""></p>
<h3 id="collaborative-filtering-algorithm">Collaborative filtering algorithm</h3>
<hr>
<p><img src="https://images.velog.io/images/k_dah/post/a1448009-a047-4bf6-ae0c-f3219700211c/ml.jpg" alt=""></p>
<blockquote>
<p>$Q :$ 초기값을 작은 값으로 초기화하는 이유
<img src="https://images.velog.io/images/k_dah/post/7f4faa94-a335-4635-8261-c472c885ba6b/ml.jpg" alt=""></p>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>