<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>밤준</title>
    <link>https://bladesilver.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Wed, 8 Apr 2026 01:58:14 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>밤준맨</managingEditor>
    <item>
      <title>Airflow Slack 연동</title>
      <link>https://bladesilver.tistory.com/51</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Airflow - Slack&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;airflow에서 성공, 실패시 slack으로 알림을 받기 위해 작성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;603&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yHoNO/btsIsAZkpdC/AkDmm6Csv4CeLXY5Mv8VM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yHoNO/btsIsAZkpdC/AkDmm6Csv4CeLXY5Mv8VM1/img.png&quot; data-alt=&quot;airflow job&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yHoNO/btsIsAZkpdC/AkDmm6Csv4CeLXY5Mv8VM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyHoNO%2FbtsIsAZkpdC%2FAkDmm6Csv4CeLXY5Mv8VM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;685&quot; height=&quot;603&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;603&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;airflow job&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 내 잡은 이렇게 되어 있고, 실패시 알림을 받고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vxftq/btsIs6jb01W/fbiBSI1m04wvFkYhE9D3k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vxftq/btsIs6jb01W/fbiBSI1m04wvFkYhE9D3k0/img.png&quot; data-alt=&quot;airflow task 실패시 알림&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vxftq/btsIs6jb01W/fbiBSI1m04wvFkYhE9D3k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvxftq%2FbtsIs6jb01W%2FfbiBSI1m04wvFkYhE9D3k0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1272&quot; height=&quot;202&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;airflow task 실패시 알림&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;task 명과 내가 받은 알림의 task가 다른 예시용이니 참고 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[태스크 상세] 버튼을 누르면 airflow log로 한 번에 이동할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제부터 airflow - slack 설정하는 방법을 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Airflow 설정&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1307&quot; data-origin-height=&quot;881&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btq6ap/btsItJgHu5v/yCrEZlM0LRBcCE29DYhpF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btq6ap/btsItJgHu5v/yCrEZlM0LRBcCE29DYhpF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btq6ap/btsItJgHu5v/yCrEZlM0LRBcCE29DYhpF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbtq6ap%2FbtsItJgHu5v%2FyCrEZlM0LRBcCE29DYhpF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1307&quot; height=&quot;881&quot; data-origin-width=&quot;1307&quot; data-origin-height=&quot;881&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Airflow UI &amp;gt; Admin &amp;gt; Connections 에 들어가 connection을 위한 정보를 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Webhook Token은 본인이 만든 slack api에서 볼 수 있다. (&lt;a href=&quot;https://api.slack.com/apps&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://api.slack.com/apps&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Slack Alert Class&lt;/h3&gt;
&lt;pre id=&quot;code_1720516552016&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from airflow.providers.slack.notifications.slack_webhook import SlackWebhookNotifier
from urllib import parse
import pendulum

class SlackAlert():
    def __init__(self, webhook_conn_id):
        self.webhook_conn_id = webhook_conn_id
        self.airflow_url = &quot;http://xxx.xx.xx.xx:xxxx/dags&quot;
        self.local_tz = pendulum.timezone(&quot;Asia/Seoul&quot;)
        
    def send_slack_webhook_notification(self, context):
        ti = context['task_instance']

        dag_fail_slack_webhook = SlackWebhookNotifier(
            slack_webhook_conn_id = self.webhook_conn_id,
            text=f&quot;{ti.dag_id} &amp;gt; {ti.task_id} 실패&quot;,
            blocks=[
                # 메인 타이틀 + 메세지
                {
                    &quot;type&quot;: &quot;section&quot;,
                    &quot;text&quot;: {
                            &quot;type&quot;: &quot;plain_text&quot;,
                            &quot;text&quot;: f&quot;{ti.dag_id} &amp;gt; {ti.task_id} 실패&quot;
                            },
                    &quot;accessory&quot;: {
                        &quot;type&quot;: &quot;button&quot;,
                        &quot;text&quot;: {
                            &quot;type&quot;: &quot;plain_text&quot;,
                            &quot;text&quot;: &quot;:red_circle: 태스크 상세&quot;,
                            &quot;emoji&quot;: True
                        },
                        &quot;value&quot;: &quot;go_task&quot;,
                        &quot;url&quot;: f&quot;{self.airflow_url}/{ti.dag_id}/grid?dag_run_id={parse.quote(ti.run_id)}&amp;amp;task_id={ti.task_id}&quot;,
                        &quot;action_id&quot;: &quot;button-action&quot;
                    }
                }
            ],
            attachments=[
                    # 실패 태스크의 상세 정보
                    {
                        &quot;color&quot;: &quot;#FD8B2D&quot;,
                        &quot;fields&quot;: [
                            {
                                &quot;title&quot;: f&quot;{ti.task_id} (state: {ti.state}) 상세 Logs 내용을 확인해 주세요.&quot;,
                                &quot;value&quot;: f&quot;&quot;&quot;시작 시간 : {pendulum.instance(ti.start_date).in_timezone(self.local_tz).strftime('%Y-%m-%d %H:%M:%S')}&quot;&quot;&quot;,
                                &quot;short&quot;: False
                            }
                        ]
                    }
                ]
        )
        return dag_fail_slack_webhook.notify(context)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;slack alert를 위한 간단한 클래스를 작성하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 눈 여겨봐야할 점은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 서버에 따라 서버시간이 다르므로 나는 pendulum 라이브러리를 사용해 지역 시간을 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. ti.log_url을 사용하면 localhost로 불려지기 때문에, airflow_url을 수동 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 필요한 정보가 있다면 context 내에서 정보를 꺼내써도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Python 호출&lt;/h4&gt;
&lt;pre id=&quot;code_1720516878046&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from common import SlackAlert

# 본인이 설정한 conn_id 입력
slack_alert = SlackAlert('slack_ir_monitoring')

default_args = {
	...,
	'on_failure_callback' : slack_alert.send_webhook_notification
    }
    
with DAG(
	job_name,
    default_args = default_args,
    ...
    ) as dag:
    
    task1 = ..
    ..&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 설정하면 task 실패시, slack으로 알림이 오는걸 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론, task 성공시에도 알림을 받을 수 있는데 default_args내 on_success_callback 인자에 비슷하게 구현하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 배치 주기가 짧아 실패시에만 알림을 받고 있다.&lt;/p&gt;</description>
      <category>Airflow</category>
      <category>airflow</category>
      <category>python</category>
      <category>slack</category>
      <author>밤준맨</author>
      <guid isPermaLink="true">https://bladesilver.tistory.com/51</guid>
      <comments>https://bladesilver.tistory.com/51#entry51comment</comments>
      <pubDate>Tue, 9 Jul 2024 18:24:14 +0900</pubDate>
    </item>
    <item>
      <title>36. Valid Sudoku</title>
      <link>https://bladesilver.tistory.com/50</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Determine&amp;nbsp;if&amp;nbsp;a&amp;nbsp;9&amp;nbsp;x&amp;nbsp;9&amp;nbsp;Sudoku&amp;nbsp;board&amp;nbsp;is&amp;nbsp;valid.&amp;nbsp;Only&amp;nbsp;the&amp;nbsp;filled&amp;nbsp;cells&amp;nbsp;need&amp;nbsp;to&amp;nbsp;be&amp;nbsp;validated&amp;nbsp;according&amp;nbsp;to&amp;nbsp;the&amp;nbsp;following&amp;nbsp;rules: &lt;br /&gt;&lt;br /&gt;Each&amp;nbsp;row&amp;nbsp;must&amp;nbsp;contain&amp;nbsp;the&amp;nbsp;digits&amp;nbsp;1-9&amp;nbsp;without&amp;nbsp;repetition. &lt;br /&gt;Each&amp;nbsp;column&amp;nbsp;must&amp;nbsp;contain&amp;nbsp;the&amp;nbsp;digits&amp;nbsp;1-9&amp;nbsp;without&amp;nbsp;repetition. &lt;br /&gt;Each&amp;nbsp;of&amp;nbsp;the&amp;nbsp;nine&amp;nbsp;3&amp;nbsp;x&amp;nbsp;3&amp;nbsp;sub-boxes&amp;nbsp;of&amp;nbsp;the&amp;nbsp;grid&amp;nbsp;must&amp;nbsp;contain&amp;nbsp;the&amp;nbsp;digits&amp;nbsp;1-9&amp;nbsp;without&amp;nbsp;repetition. &lt;br /&gt;Note: &lt;br /&gt;&lt;br /&gt;A&amp;nbsp;Sudoku&amp;nbsp;board&amp;nbsp;(partially&amp;nbsp;filled)&amp;nbsp;could&amp;nbsp;be&amp;nbsp;valid&amp;nbsp;but&amp;nbsp;is&amp;nbsp;not&amp;nbsp;necessarily&amp;nbsp;solvable. &lt;br /&gt;Only&amp;nbsp;the&amp;nbsp;filled&amp;nbsp;cells&amp;nbsp;need&amp;nbsp;to&amp;nbsp;be&amp;nbsp;validated&amp;nbsp;according&amp;nbsp;to&amp;nbsp;the&amp;nbsp;mentioned&amp;nbsp;rules. &lt;br /&gt;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Example&amp;nbsp;1: &lt;br /&gt;&lt;br /&gt;Input:&amp;nbsp;board&amp;nbsp;=&amp;nbsp; &lt;br /&gt;[[&quot;5&quot;,&quot;3&quot;,&quot;.&quot;,&quot;.&quot;,&quot;7&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;] &lt;br /&gt;,[&quot;6&quot;,&quot;.&quot;,&quot;.&quot;,&quot;1&quot;,&quot;9&quot;,&quot;5&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;] &lt;br /&gt;,[&quot;.&quot;,&quot;9&quot;,&quot;8&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;6&quot;,&quot;.&quot;] &lt;br /&gt;,[&quot;8&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;6&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;3&quot;] &lt;br /&gt;,[&quot;4&quot;,&quot;.&quot;,&quot;.&quot;,&quot;8&quot;,&quot;.&quot;,&quot;3&quot;,&quot;.&quot;,&quot;.&quot;,&quot;1&quot;] &lt;br /&gt;,[&quot;7&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;2&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;6&quot;] &lt;br /&gt;,[&quot;.&quot;,&quot;6&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;2&quot;,&quot;8&quot;,&quot;.&quot;] &lt;br /&gt;,[&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;4&quot;,&quot;1&quot;,&quot;9&quot;,&quot;.&quot;,&quot;.&quot;,&quot;5&quot;] &lt;br /&gt;,[&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;8&quot;,&quot;.&quot;,&quot;.&quot;,&quot;7&quot;,&quot;9&quot;]] &lt;br /&gt;Output:&amp;nbsp;true &lt;br /&gt;Example&amp;nbsp;2: &lt;br /&gt;&lt;br /&gt;Input:&amp;nbsp;board&amp;nbsp;=&amp;nbsp; &lt;br /&gt;[[&quot;8&quot;,&quot;3&quot;,&quot;.&quot;,&quot;.&quot;,&quot;7&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;] &lt;br /&gt;,[&quot;6&quot;,&quot;.&quot;,&quot;.&quot;,&quot;1&quot;,&quot;9&quot;,&quot;5&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;] &lt;br /&gt;,[&quot;.&quot;,&quot;9&quot;,&quot;8&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;6&quot;,&quot;.&quot;] &lt;br /&gt;,[&quot;8&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;6&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;3&quot;] &lt;br /&gt;,[&quot;4&quot;,&quot;.&quot;,&quot;.&quot;,&quot;8&quot;,&quot;.&quot;,&quot;3&quot;,&quot;.&quot;,&quot;.&quot;,&quot;1&quot;] &lt;br /&gt;,[&quot;7&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;2&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;6&quot;] &lt;br /&gt;,[&quot;.&quot;,&quot;6&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;2&quot;,&quot;8&quot;,&quot;.&quot;] &lt;br /&gt;,[&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;4&quot;,&quot;1&quot;,&quot;9&quot;,&quot;.&quot;,&quot;.&quot;,&quot;5&quot;] &lt;br /&gt;,[&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;8&quot;,&quot;.&quot;,&quot;.&quot;,&quot;7&quot;,&quot;9&quot;]] &lt;br /&gt;Output:&amp;nbsp;false &lt;br /&gt;Explanation:&amp;nbsp;Same&amp;nbsp;as&amp;nbsp;Example&amp;nbsp;1,&amp;nbsp;except&amp;nbsp;with&amp;nbsp;the&amp;nbsp;5&amp;nbsp;in&amp;nbsp;the&amp;nbsp;top&amp;nbsp;left&amp;nbsp;corner&amp;nbsp;being&amp;nbsp;modified&amp;nbsp;to&amp;nbsp;8.&amp;nbsp;Since&amp;nbsp;there&amp;nbsp;are&amp;nbsp;two&amp;nbsp;8's&amp;nbsp;in&amp;nbsp;the&amp;nbsp;top&amp;nbsp;left&amp;nbsp;3x3&amp;nbsp;sub-box,&amp;nbsp;it&amp;nbsp;is&amp;nbsp;invalid. &lt;br /&gt;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Constraints:&lt;br /&gt;board.length&amp;nbsp;==&amp;nbsp;9 &lt;br /&gt;board[i].length&amp;nbsp;==&amp;nbsp;9 &lt;br /&gt;board[i][j]&amp;nbsp;is&amp;nbsp;a&amp;nbsp;digit&amp;nbsp;1-9&amp;nbsp;or&amp;nbsp;'.'.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1712994389800&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def isValidSudoku(self, board: List[List[str]]) -&amp;gt; bool:

        def check_row_and_col(r, c, n):
            for i in range(9):
                if (board[r][i] == n and i != c) or (board[i][c] == n and i != r):
                    return False

            # check rect
            start_row = (r // 3) * 3
            start_col = (c // 3) * 3
            for i in range(start_row, start_row + 3):
                for j in range(start_col, start_col + 3):
                    if board[i][j] == n and (i != r or j != c):
                        return False
            return True
        
        for i in range(9):
            for j in range(9):
                if board[i][j] != &quot;.&quot;:
                    if not check_row_and_col(i, j, board[i][j]):
                        return False
        return True&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스도쿠를 채우는 문제가 아니라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 스도쿠가 유효한지, 무효한지만 검사하면 되는 문제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;discussion을 보니&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비교해야하는 인덱스 값이 현재 체크하는 인덱스값과 동일한지를 체크해야 하는 부분을&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;놓치는 부분이 많은 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나도 놓쳐서 애먹었다 ㅋㅋ..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Leetcode</category>
      <category>leetcode</category>
      <author>밤준맨</author>
      <guid isPermaLink="true">https://bladesilver.tistory.com/50</guid>
      <comments>https://bladesilver.tistory.com/50#entry50comment</comments>
      <pubDate>Sat, 13 Apr 2024 16:47:21 +0900</pubDate>
    </item>
    <item>
      <title>35. Search Insert Position</title>
      <link>https://bladesilver.tistory.com/49</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Given&amp;nbsp;a&amp;nbsp;sorted&amp;nbsp;array&amp;nbsp;of&amp;nbsp;distinct&amp;nbsp;integers&amp;nbsp;and&amp;nbsp;a&amp;nbsp;target&amp;nbsp;value,&amp;nbsp;return&amp;nbsp;the&amp;nbsp;index&amp;nbsp;if&amp;nbsp;the&amp;nbsp;target&amp;nbsp;is&amp;nbsp;found.&amp;nbsp;If&amp;nbsp;not,&amp;nbsp;return&amp;nbsp;the&amp;nbsp;index&amp;nbsp;where&amp;nbsp;it&amp;nbsp;would&amp;nbsp;be&amp;nbsp;if&amp;nbsp;it&amp;nbsp;were&amp;nbsp;inserted&amp;nbsp;in&amp;nbsp;order. &lt;br /&gt;&lt;br /&gt;You&amp;nbsp;must&amp;nbsp;write&amp;nbsp;an&amp;nbsp;algorithm&amp;nbsp;with&amp;nbsp;O(log&amp;nbsp;n)&amp;nbsp;runtime&amp;nbsp;complexity. &lt;br /&gt;&lt;br /&gt;Example&amp;nbsp;1: &lt;br /&gt;&lt;br /&gt;Input:&amp;nbsp;nums&amp;nbsp;=&amp;nbsp;[1,3,5,6],&amp;nbsp;target&amp;nbsp;=&amp;nbsp;5 &lt;br /&gt;Output:&amp;nbsp;2 &lt;br /&gt;Example&amp;nbsp;2: &lt;br /&gt;&lt;br /&gt;Input:&amp;nbsp;nums&amp;nbsp;=&amp;nbsp;[1,3,5,6],&amp;nbsp;target&amp;nbsp;=&amp;nbsp;2 &lt;br /&gt;Output:&amp;nbsp;1 &lt;br /&gt;Example&amp;nbsp;3: &lt;br /&gt;&lt;br /&gt;Input:&amp;nbsp;nums&amp;nbsp;=&amp;nbsp;[1,3,5,6],&amp;nbsp;target&amp;nbsp;=&amp;nbsp;7 &lt;br /&gt;Output:&amp;nbsp;4 &lt;br /&gt;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Constraints: &lt;br /&gt;&lt;br /&gt;1&amp;nbsp;&amp;lt;=&amp;nbsp;nums.length&amp;nbsp;&amp;lt;=&amp;nbsp;104 &lt;br /&gt;-104&amp;nbsp;&amp;lt;=&amp;nbsp;nums[i]&amp;nbsp;&amp;lt;=&amp;nbsp;104 &lt;br /&gt;nums&amp;nbsp;contains&amp;nbsp;distinct&amp;nbsp;values&amp;nbsp;sorted&amp;nbsp;in&amp;nbsp;ascending&amp;nbsp;order. &lt;br /&gt;-104&amp;nbsp;&amp;lt;=&amp;nbsp;target&amp;nbsp;&amp;lt;=&amp;nbsp;104&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1712994261824&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def searchInsert(self, nums: List[int], target: int) -&amp;gt; int:
        return bisect.bisect_left(nums, target)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 좌, 우의 index를 옮겨가며 값을 찾는게 일반적이지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글링을 하다보니 binary search에 대한 라이브러리가 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관련 라이브러리 설명 글&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://yerimoh.github.io/Algo011/&quot;&gt;https://yerimoh.github.io/Algo011/&lt;/a&gt; &lt;/p&gt;</description>
      <category>Leetcode</category>
      <category>Bisect</category>
      <category>leetcode</category>
      <author>밤준맨</author>
      <guid isPermaLink="true">https://bladesilver.tistory.com/49</guid>
      <comments>https://bladesilver.tistory.com/49#entry49comment</comments>
      <pubDate>Sat, 13 Apr 2024 16:44:07 +0900</pubDate>
    </item>
    <item>
      <title>hadoop MR</title>
      <link>https://bladesilver.tistory.com/48</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;hadoop3 기준으로 설명&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1. hadoop MR 실행하기 위한 기본 쉘 파일&lt;/p&gt;
&lt;pre id=&quot;code_1665982555985&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;${HADOOP} --config ${HADOOP_CONF_DIR} jar ${JAR_PATH} \
	-files &quot;argvs, mapper.py, reducer.py&quot; \
	-D mapreduce.job.name=&quot;test job&quot; \
	-D mapreduce.job.reduces=1 \
	-D mapreduce.reduce.memory.mb=40960 \
	-D stream.num.map.output.key.fields=1 \
	-D stream.map.output.field.separator=&quot;\t&quot; \
	-D mapreduce.job.output.key.comparator.class=org.apache.hadoop.mapred.lib.KeyFieldBasedComparator \
	-D mapreduce.partition.keycomparator.options=&quot;-k1,1&quot; \
	-D mapreduce.partition.keypartitioner.options=&quot;-k1,1&quot; \
	-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \
	-cmdenv PYTHONPATH=. \
	-input &quot;HDFS INPUT&quot; \
	-output &quot;HDFS OUTPUT&quot; \
	-mapper &quot;python mapper.py argvs&quot; \
	-reducer &quot;python reducer.py&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1665982738143&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;${HADOOP} --config ${HADOOP_CONF_DIR} jar ${JAR_PATH}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하둡은 jar 파일을 통해 실행되므로 첫 line에서 설치된 하둡의 jar 파일을 config로 할당해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1665982804237&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-files &quot;argvs, mapper.py, reducer.py&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요한 파일들은 미리 선언해서 사용해야 하는데, python 파일외에 argvs로 사용할 파일들도 미리 선언해야 한다.&lt;br /&gt;만약 하둡내에 있는 파일이라면 다음과 같이 변경해서 사용해야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1665982891990&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-files &quot;hdfs://${HADOOP_ADDR}/args#argvs, mapper.py, reducer.py&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 할당하면 되고, #argvs 는 alias된 형태이므로, mapper 혹은 reducer 실행시 hdfs:// ~ 주소 전체를 인자로 넘길 필요 없이, argvs로만 넘기면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1665983011567&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-D mapreduce.job.name=&quot;test job&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;yarn에서 보여지는 job name으로, yarn 내에 다양한 잡들이 많기 때문에 이름을 할당하여 구분짓기 위함이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1665983064477&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-D mapreduce.job.reduces=1
-D mapreduce.reduce.memory.mb=40960&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리듀서를 1개만 할당하여, 결과파일을 1개만 생성한다는 의미로 part-00000 한 개의 파일만 생성될 것이고,&lt;br /&gt;한 리듀서에 40GB의 메모리를 할당한 다는 의미이다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1665983282607&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-D stream.num.map.output.key.fields=1
-D stream.map.output.field.separator=&quot;\t&quot;​&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mapper에서 1번째 &quot;\t&quot;을 구분자로 key값과 value값으로 나눈다는 의미이다.&lt;br /&gt;예시로, P1 \t val1 val2 val3 val4 값이 Mapper의 output으로 나왔다면,&lt;br /&gt;key : P1 , values : val1 val2 val3 val4 와 같이 reducer로 전달되게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1665983401126&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-D mapreduce.job.output.key.comparator.class=org.apache.hadoop.mapred.lib.KeyFieldBasedComparator
-D mapreduce.partition.keycomparator.options=&quot;-k1,1&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;class 명은 keycomparator를 사용하기 위해 기본적으로 선언하는 인자로 인식하면 되고,&lt;br /&gt;keycomparator의 의미는 mapper의 Output key값을 sorting하는 의미로 생각하면 된다.&lt;br /&gt;-k1,1 의 의미는 sort의 key값 중 1번 key는 1번째 필드라는 의미이다.&lt;br /&gt;&lt;br /&gt;n차 정렬을 하려면 다음과 같다&lt;br /&gt;&quot;-k1,1nr&amp;nbsp;-k2,2n&amp;nbsp;-k3,3nr&quot;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222;&quot;&gt;키1은 numeric reverse sort, 키2는 numeric sort, 키3은 numeric reverse sort&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1665983627399&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-D mapreduce.partition.keypartitioner.options=&quot;-k1,1&quot;
-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-partitioner option은 위 comparator에서 class 선언해준 것 처럼 기본적으로 선언해야 한다.( 아마 위치도 -D 옵션 사이말고.. -D 옵션 맨 뒤에 해야하는 걸로 알고 있는데.. 확실하진 않음 )&lt;br /&gt;keypartititioner의 의미는 mapper의 output Key을 partition을 나누어서 reducer에게 전달한다고 생각하면 된다.&lt;br /&gt;-k1,1의 경우 첫번째 키로 파티션을 나눈다고 생각하면 된다.&lt;br /&gt;만약 첫번째, 두번째 키로 파티션을 할당하고 싶다면, -k1,2와 같이 할당하면 된다.&lt;br /&gt;&lt;br /&gt;-k1,1 의 예시로 실행되면 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1665983919290&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mapper output 
P1 P2 P3
P1 P4 P5
P2 P2 P5
P3 P5 P2

reducer에게 input으로 전달될 시,
//part-00000( 파일명은 다를 수 있음 )
P1 P2 P3
P1 P4 P5

//part-00001
P2 P2 P5

//part-00002
P3 P5 P2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>HADOOP</category>
      <category>hadoop</category>
      <category>hadoop mr</category>
      <category>Hadoop3</category>
      <author>밤준맨</author>
      <guid isPermaLink="true">https://bladesilver.tistory.com/48</guid>
      <comments>https://bladesilver.tistory.com/48#entry48comment</comments>
      <pubDate>Mon, 17 Oct 2022 14:20:46 +0900</pubDate>
    </item>
    <item>
      <title>[MacOS] pyenv virtualenv 환경설정</title>
      <link>https://bladesilver.tistory.com/47</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://taewan.kim/post/python_virtual_env/&quot;&gt;http://taewan.kim/post/python_virtual_env/&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러 해결&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. sendfile 관련 에러 :&amp;nbsp;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://vipdeveloper.tistory.com/65&quot;&gt;https://vipdeveloper.tistory.com/65&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. failed to activate virtualenv 관련 에러 :&amp;nbsp;&lt;a href=&quot;https://velog.io/@limdongyoung0/pyenv-Failed-to-activate-virtualenv&quot;&gt;https://velog.io/@limdongyoung0/pyenv-Failed-to-activate-virtualenv&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>MacOS_ipadOS</category>
      <category>pyenv #virtualenv</category>
      <author>밤준맨</author>
      <guid isPermaLink="true">https://bladesilver.tistory.com/47</guid>
      <comments>https://bladesilver.tistory.com/47#entry47comment</comments>
      <pubDate>Thu, 30 Sep 2021 10:07:48 +0900</pubDate>
    </item>
    <item>
      <title>[MacOS] jupyter notebook 설치</title>
      <link>https://bladesilver.tistory.com/46</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1. Terminal 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. pip3 install --upgrade pip&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. pip3 install jupyter&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. jupyter notebook&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;(= jupyter lab)&lt;/p&gt;</description>
      <category>MacOS_ipadOS</category>
      <category>jupyter</category>
      <author>밤준맨</author>
      <guid isPermaLink="true">https://bladesilver.tistory.com/46</guid>
      <comments>https://bladesilver.tistory.com/46#entry46comment</comments>
      <pubDate>Wed, 29 Sep 2021 15:42:45 +0900</pubDate>
    </item>
    <item>
      <title>ML Hyperparameter tuning</title>
      <link>https://bladesilver.tistory.com/45</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;로컬에서 모델 개발시 :&amp;nbsp;&amp;nbsp;hyperopt, optuna, skopt&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 노드에서 모델 개발시 :&amp;nbsp;katib, ray&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;hyperopt 예제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://teddylee777.github.io/thoughts/hyper-opt&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://teddylee777.github.io/thoughts/hyper-opt&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1628123947963&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;베이지안 최적화에 기반한 HyperOpt를 활용한 하이퍼 파라미터 튜닝&quot; data-og-description=&quot;베이지안 최적화에 기반한 HyperOpt를 활용한 하이퍼 파라미터 튜닝 방법에 대하여 알아 보도록 하겠습니다.&quot; data-og-host=&quot;teddylee777.github.io&quot; data-og-source-url=&quot;https://teddylee777.github.io/thoughts/hyper-opt&quot; data-og-url=&quot;https://teddylee777.github.io/thoughts/hyper-opt&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b4mJL5/hyK7qeQWtz/4eSwqciNjV4L5VEIfBrYS1/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500,https://scrap.kakaocdn.net/dn/b3mc6C/hyK8zBfjfu/O2AocVHLz0rryVgTdNAWxk/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500,https://scrap.kakaocdn.net/dn/f5Bkw/hyK8qEjlSe/7HMyrwkitcgKFaIjtBQq6K/img.png?width=1280&amp;amp;height=840&amp;amp;face=0_0_1280_840&quot;&gt;&lt;a href=&quot;https://teddylee777.github.io/thoughts/hyper-opt&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://teddylee777.github.io/thoughts/hyper-opt&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b4mJL5/hyK7qeQWtz/4eSwqciNjV4L5VEIfBrYS1/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500,https://scrap.kakaocdn.net/dn/b3mc6C/hyK8zBfjfu/O2AocVHLz0rryVgTdNAWxk/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500,https://scrap.kakaocdn.net/dn/f5Bkw/hyK8qEjlSe/7HMyrwkitcgKFaIjtBQq6K/img.png?width=1280&amp;amp;height=840&amp;amp;face=0_0_1280_840');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;베이지안 최적화에 기반한 HyperOpt를 활용한 하이퍼 파라미터 튜닝&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;베이지안 최적화에 기반한 HyperOpt를 활용한 하이퍼 파라미터 튜닝 방법에 대하여 알아 보도록 하겠습니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;teddylee777.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>ML&amp;amp;DL</category>
      <category>ML</category>
      <author>밤준맨</author>
      <guid isPermaLink="true">https://bladesilver.tistory.com/45</guid>
      <comments>https://bladesilver.tistory.com/45#entry45comment</comments>
      <pubDate>Thu, 5 Aug 2021 09:39:28 +0900</pubDate>
    </item>
    <item>
      <title>30. Substring with Concatenation of All Words</title>
      <link>https://bladesilver.tistory.com/44</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;You are given a string&lt;span&gt;&amp;nbsp;&lt;/span&gt;s&lt;span&gt;&amp;nbsp;&lt;/span&gt;and an array of strings&lt;span&gt;&amp;nbsp;&lt;/span&gt;words&lt;span&gt;&amp;nbsp;&lt;/span&gt;of&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;the same length&lt;/b&gt;. Return&amp;nbsp;all starting indices of substring(s) in&lt;span&gt;&amp;nbsp;&lt;/span&gt;s&amp;nbsp;that is a concatenation of each word in&lt;span&gt;&amp;nbsp;&lt;/span&gt;words&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;exactly once&lt;/b&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;in any order&lt;/b&gt;,&amp;nbsp;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;without any intervening characters&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;You can return the answer in&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;any order&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Example 1:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Input:&lt;/b&gt; s = &quot;barfoothefoobarman&quot;, words = [&quot;foo&quot;,&quot;bar&quot;] &lt;b&gt;Output:&lt;/b&gt; [0,9] &lt;b&gt;Explanation:&lt;/b&gt; Substrings starting at index 0 and 9 are &quot;barfoo&quot; and &quot;foobar&quot; respectively. The output order does not matter, returning [9,0] is fine too.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Example 2:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Input:&lt;/b&gt; s = &quot;wordgoodgoodgoodbestword&quot;, words = [&quot;word&quot;,&quot;good&quot;,&quot;best&quot;,&quot;word&quot;] &lt;b&gt;Output:&lt;/b&gt; []&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Example 3:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Input:&lt;/b&gt; s = &quot;barfoofoobarthefoobarman&quot;, words = [&quot;bar&quot;,&quot;foo&quot;,&quot;the&quot;] &lt;b&gt;Output:&lt;/b&gt; [6,9,12]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Constraints:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1 &amp;lt;= s.length &amp;lt;= 104&lt;/li&gt;
&lt;li&gt;s&lt;span&gt;&amp;nbsp;&lt;/span&gt;consists of lower-case English letters.&lt;/li&gt;
&lt;li&gt;1 &amp;lt;= words.length &amp;lt;= 5000&lt;/li&gt;
&lt;li&gt;1 &amp;lt;= words[i].length &amp;lt;= 30&lt;/li&gt;
&lt;li&gt;words[i]&amp;nbsp;consists of lower-case English letters.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1624242762181&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def findSubstring(self, s: str, words: List[str]) -&amp;gt; List[int]:
        char = len(words[0])
        begin_idx = []
        i = 0
        while i &amp;lt;= len(s) - len(words) * char:
            tmp_words = list(words)
            if s[i:i+char] in tmp_words:
                tmp_words.remove(s[i:i+char])
        #         print(i,i+char)
                j = i+char
                while j &amp;lt;= len(s):
                    if s[j:j+char] in tmp_words:
                        tmp_words.remove(s[j:j+char])
                        j += char
                    else:
                        break
            if len(tmp_words) == 0:
                begin_idx.append(i)
            
            i += 1
        
        return begin_idx&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 성능이 좋지 못하다. discussion에 나온 다른 방법도 참고해봐야겠다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Runtime:&amp;nbsp;&lt;span style=&quot;color: #263238;&quot;&gt;1480 ms&lt;/span&gt;&lt;span&gt;, faster than&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #263238;&quot;&gt;23.33%&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;of&lt;span&gt;&amp;nbsp;&lt;/span&gt;Python3&lt;span&gt;&amp;nbsp;&lt;/span&gt;online submissions for&lt;span&gt;&amp;nbsp;&lt;/span&gt;Substring with Concatenation of All Words.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Memory Usage:&amp;nbsp;&lt;span style=&quot;color: #263238;&quot;&gt;14.7 MB&lt;/span&gt;&lt;span&gt;, less than&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #263238;&quot;&gt;27.56%&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;of&lt;span&gt;&amp;nbsp;&lt;/span&gt;Python3&lt;span&gt;&amp;nbsp;&lt;/span&gt;online submissions for&lt;span&gt;&amp;nbsp;&lt;/span&gt;Substring with Concatenation of All Words.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Leetcode</category>
      <category>leetcode</category>
      <author>밤준맨</author>
      <guid isPermaLink="true">https://bladesilver.tistory.com/44</guid>
      <comments>https://bladesilver.tistory.com/44#entry44comment</comments>
      <pubDate>Mon, 21 Jun 2021 11:33:55 +0900</pubDate>
    </item>
    <item>
      <title>31. Next Permutation</title>
      <link>https://bladesilver.tistory.com/43</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;31.&lt;span&gt;&amp;nbsp;&lt;/span&gt;Next Permutation&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Medium&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;5913&lt;/span&gt;&lt;span&gt;1980&lt;/span&gt;&lt;span&gt;Add to List&lt;/span&gt;&lt;span&gt;Share&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Implement&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;next permutation&lt;/b&gt;, which rearranges numbers into the lexicographically next greater permutation of numbers.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;If such an arrangement is not possible, it must rearrange it as the lowest possible order (i.e., sorted in ascending order).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The replacement must be&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/In-place_algorithm&quot;&gt;in place&lt;/a&gt;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and use only constant&amp;nbsp;extra memory.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Example 1:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Input:&lt;/b&gt; nums = [1,2,3] &lt;b&gt;Output:&lt;/b&gt; [1,3,2]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Example 2:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Input:&lt;/b&gt; nums = [3,2,1] &lt;b&gt;Output:&lt;/b&gt; [1,2,3]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Example 3:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Input:&lt;/b&gt; nums = [1,1,5] &lt;b&gt;Output:&lt;/b&gt; [1,5,1]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Example 4:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Input:&lt;/b&gt; nums = [1] &lt;b&gt;Output:&lt;/b&gt; [1]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Constraints:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1 &amp;lt;= nums.length &amp;lt;= 100&lt;/li&gt;
&lt;li&gt;0 &amp;lt;= nums[i] &amp;lt;= 100&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1623823842017&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def nextPermutation(self, nums: List[int]) -&amp;gt; None:
        &quot;&quot;&quot;
        Do not return anything, modify nums in-place instead.
        &quot;&quot;&quot;
        i = len(nums) - 2
        flag = False

        while i&amp;gt;=0:
            if nums[i] &amp;lt; nums[i+1]:
                flag = True
                break
            i -= 1

        if not flag:
            nums.sort()
            return nums
            print(nums)
        else:
            j = len(nums)-1
            while nums[j] &amp;lt;=nums[i] and j &amp;gt; i:
                j -= 1

            nums[i], nums[j] = nums[j], nums[i]
            nums[i+1:] = nums[i+1:][::-1]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- python은 inplace swap이 가능한 점&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 정렬 알고리즘 중 이러한 정렬 알고리즘도 있다는것..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;795&quot; data-origin-height=&quot;388&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cL4LEJ/btq7oIeWqT5/uZKXVCbUWqVbddRxqHGJ51/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cL4LEJ/btq7oIeWqT5/uZKXVCbUWqVbddRxqHGJ51/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cL4LEJ/btq7oIeWqT5/uZKXVCbUWqVbddRxqHGJ51/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/cL4LEJ/btq7oIeWqT5/uZKXVCbUWqVbddRxqHGJ51/img.gif&quot; data-origin-width=&quot;795&quot; data-origin-height=&quot;388&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Leetcode</category>
      <category>leetcode</category>
      <author>밤준맨</author>
      <guid isPermaLink="true">https://bladesilver.tistory.com/43</guid>
      <comments>https://bladesilver.tistory.com/43#entry43comment</comments>
      <pubDate>Wed, 16 Jun 2021 15:12:41 +0900</pubDate>
    </item>
    <item>
      <title>[dacon] 와인품질 EDA 및 1차 모델 개발</title>
      <link>https://bladesilver.tistory.com/42</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dacon.io/competitions/open/235610/overview/description&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://dacon.io/competitions/open/235610/overview/description&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1623650295221&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;[화학] 와인 품질 분류&quot; data-og-description=&quot;출처 : DACON - Data Science Competition&quot; data-og-host=&quot;dacon.io&quot; data-og-source-url=&quot;https://dacon.io/competitions/open/235610/overview/description&quot; data-og-url=&quot;https://dacon.io/competitions/official/235610/overview/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ciyyiv/hyKxCHtCQQ/B1yanBWwL4LbKfRzzm5h8k/img.jpg?width=305&amp;amp;height=305&amp;amp;face=0_0_305_305,https://scrap.kakaocdn.net/dn/cWvdfE/hyKxHWjr25/foxj3VxQbQhkYN6lrMU8j1/img.jpg?width=305&amp;amp;height=305&amp;amp;face=0_0_305_305&quot;&gt;&lt;a href=&quot;https://dacon.io/competitions/open/235610/overview/description&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://dacon.io/competitions/open/235610/overview/description&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ciyyiv/hyKxCHtCQQ/B1yanBWwL4LbKfRzzm5h8k/img.jpg?width=305&amp;amp;height=305&amp;amp;face=0_0_305_305,https://scrap.kakaocdn.net/dn/cWvdfE/hyKxHWjr25/foxj3VxQbQhkYN6lrMU8j1/img.jpg?width=305&amp;amp;height=305&amp;amp;face=0_0_305_305');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[화학] 와인 품질 분류&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;출처 : DACON - Data Science Competition&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;dacon.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 데이터를 활용했고, 기존에 작성했던 EDA글을 토대로 진행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1745&quot; data-origin-height=&quot;548&quot; data-filename=&quot;C9606633-6E9A-4954-A3FB-E8F38E907793.jpeg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n4Qk5/btq69XQWNnt/409nQC4dcXB7OVafOx8wk1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n4Qk5/btq69XQWNnt/409nQC4dcXB7OVafOx8wk1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n4Qk5/btq69XQWNnt/409nQC4dcXB7OVafOx8wk1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn4Qk5%2Fbtq69XQWNnt%2F409nQC4dcXB7OVafOx8wk1%2Fimg.jpg&quot; data-origin-width=&quot;1745&quot; data-origin-height=&quot;548&quot; data-filename=&quot;C9606633-6E9A-4954-A3FB-E8F38E907793.jpeg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 예측해야 하는 Y는 quality이며, 나머지는 feature로 사용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1020&quot; data-origin-height=&quot;946&quot; data-filename=&quot;BBA19391-5440-4FE4-89F4-9F25097CA0B0.jpeg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ASrJ2/btq665ba2ym/QFj4nl2kiokHTXB35rjeuK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ASrJ2/btq665ba2ym/QFj4nl2kiokHTXB35rjeuK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ASrJ2/btq665ba2ym/QFj4nl2kiokHTXB35rjeuK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FASrJ2%2Fbtq665ba2ym%2FQFj4nl2kiokHTXB35rjeuK%2Fimg.jpg&quot; data-origin-width=&quot;1020&quot; data-origin-height=&quot;946&quot; data-filename=&quot;BBA19391-5440-4FE4-89F4-9F25097CA0B0.jpeg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 컬럼의 &amp;nbsp;null값은 없고, type만 object 타입인 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;red, white 계열의 type만 존재하므로&lt;/p&gt;
&lt;pre id=&quot;code_1623650699466&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;df['type'] = df['type'].replace(['red', 'white'], [0, 1])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인코딩을 진행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기선 생략됐지만, 각 컬럼별로 분포가 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;scaling을 진행해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 변수별로 상관관계를 파악해봤다.&lt;/p&gt;
&lt;pre id=&quot;code_1623650807182&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;corr = df.corr(method = 'pearson')
sns.heatmap(data = corr, annot=True, fmt='.1f', cmap='Reds')
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1075&quot; data-origin-height=&quot;718&quot; data-filename=&quot;DC40BF7A-129E-4221-A70F-A2A289B06877.jpeg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chJyHH/btq7fbOGBBN/2qWTqOOscu7IhwPTJ7dXg0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chJyHH/btq7fbOGBBN/2qWTqOOscu7IhwPTJ7dXg0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chJyHH/btq7fbOGBBN/2qWTqOOscu7IhwPTJ7dXg0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchJyHH%2Fbtq7fbOGBBN%2F2qWTqOOscu7IhwPTJ7dXg0%2Fimg.jpg&quot; data-origin-width=&quot;1075&quot; data-origin-height=&quot;718&quot; data-filename=&quot;DC40BF7A-129E-4221-A70F-A2A289B06877.jpeg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 상관관계가 0.6~0.7이상이면 매우 상관관계가 높아 중요한 feature지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기선 quality와 상관관계가 가장 높은 feature는 volatile acidity, density, alcohol로 선택하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 세 컬럼에 대해 이상치 데이터를 제거하기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;892&quot; data-origin-height=&quot;1613&quot; data-filename=&quot;BE6C6852-6BD6-446B-AA57-F1AD21C54027.jpeg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ossvu/btq7ddlFZLG/9TkhuA9jm23svkruMMsXAK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ossvu/btq7ddlFZLG/9TkhuA9jm23svkruMMsXAK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ossvu/btq7ddlFZLG/9TkhuA9jm23svkruMMsXAK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fossvu%2Fbtq7ddlFZLG%2F9TkhuA9jm23svkruMMsXAK%2Fimg.jpg&quot; data-origin-width=&quot;892&quot; data-origin-height=&quot;1613&quot; data-filename=&quot;BE6C6852-6BD6-446B-AA57-F1AD21C54027.jpeg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;volatile acidity, density 같은 경우에는 이상치값들이 있는 것을 확인할 수 있는데,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 생각해보면 이상치값을 제거하면 안되는 요소인 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이상치 탐지 혹은 binary classification 문제였다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이상치를 제거하여 변수를 만들지 말아야 한다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 데이터에서 이상치라고 하기에는&amp;nbsp;값의 범위가 크지 않고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큰 영향을 주지 않을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이상치 제거&lt;/p&gt;
&lt;pre id=&quot;code_1623651383876&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def check_outlier(df, col):
    IQR = df[col].quantile(0.75) - df[col].quantile(0.25) 
    max_outlier = df[col].quantile(0.75) + 1.5*IQR
    min_outlier = df[col].quantile(0.25) - 1.5*IQR
    print(len(df[df[col] &amp;gt; max_outlier]), len(df[df[col] &amp;lt; min_outlier]))
    df = df.drop(df[df[col] &amp;gt; max_outlier].index, axis=0)
    df = df.drop(df[df[col] &amp;lt; min_outlier].index, axis=0)
    return df&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;값의 범위가 달라 일반적인 standardscaler를 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;type과 quality를 제거하고 scaling을 진행했다.&lt;/p&gt;
&lt;pre id=&quot;code_1623651515052&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sc = StandardScaler()
Y = df['quality']
X = df.drop(columns=['quality'])
X_scal = sc.fit_transform(X[X.columns[:-1]])
X_fin = np.column_stack((X_scal, X['type'].values))
Y = Y-3
## pred시 +3해서 예측할것

X_train, X_test, y_train, y_test = train_test_split(X_fin, Y, test_size = 0.33, random_state = 12)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 Y(quality)값 3을 뺀 이유는 lgbm모델 param선언시,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;num_classes 인자 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1623651631444&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;params = {
    'application' : 'multiclass',
    'num_boost_round' : 1300,
    'learning_rate' : 0.01,
    'num_leaves' : 31,
    'num_classes' : 7,
    'metric' : 'multi_error'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 quality가 3~9 까지여서 y값의 개수는 총 7개가 나올 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 lgbm num_classes를 7로 선언시 자동으로 [0, 7)로 인식하기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;predict한 결과에서 3을 더하는 방식으로 진행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1623651729718&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;lgb_train = lgbm.Dataset(X_train, label = y_train)
lgb_valid = lgbm.Dataset(X_test, label = y_test)
evals_result = {}
clf = lgbm.train(params, lgb_train, valid_sets=lgb_valid, evals_result=evals_result)
lgbm.plot_metric(evals_result)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] valid_0's multi_error: 0.555372&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1300] valid_0's multi_error: 0.369146&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로 에러가 점점 줄어들고, loss graph를 살펴보면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;278&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lHC7X/btq7iPqlFTZ/p4QLY1LbZqgkmz6X3U7R10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lHC7X/btq7iPqlFTZ/p4QLY1LbZqgkmz6X3U7R10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lHC7X/btq7iPqlFTZ/p4QLY1LbZqgkmz6X3U7R10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlHC7X%2Fbtq7iPqlFTZ%2Fp4QLY1LbZqgkmz6X3U7R10%2Fimg.png&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;278&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 이상 진행하면 overfitting이 발생할 수 있어 여기서 stop했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;predict하고 나면 결과는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[ 0.1 0.3 .. 0.1 0.2] 이런식으로 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과값이 가장 높은 값의 index를 가져와야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1623652046361&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;res_argmax = [np.argmax(n) for n in y_pred]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 테스트 데이터로 성능검증을 해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1962&quot; data-origin-height=&quot;1697&quot; data-filename=&quot;1051A08D-1E34-4380-A3AA-1C909D66DC4F.jpeg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PzRmu/btq7gWX4zjz/OgTI4waNl8bFGNHuZoeif0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PzRmu/btq7gWX4zjz/OgTI4waNl8bFGNHuZoeif0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PzRmu/btq7gWX4zjz/OgTI4waNl8bFGNHuZoeif0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPzRmu%2Fbtq7gWX4zjz%2FOgTI4waNl8bFGNHuZoeif0%2Fimg.jpg&quot; data-origin-width=&quot;1962&quot; data-origin-height=&quot;1697&quot; data-filename=&quot;1051A08D-1E34-4380-A3AA-1C909D66DC4F.jpeg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빠르고, 간단하게 만들었는데 0.662가 나왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이상치 데이터 제거하고 모델 학습도 해보고, 제거하지 않고도 학습해봤는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터의 양이적어 큰 비중은 없는 것같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 더 결과적으로 분석해보자면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예측 결과의 quality가 4~8사이밖에 나오지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나머지 0~3, 9에 대한 데이터를 늘려서 학습하거나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;scaling시 값이 너무 작아져 버려서 가중치가 작게 학습된거같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>ML&amp;amp;DL</category>
      <category>Dacon</category>
      <author>밤준맨</author>
      <guid isPermaLink="true">https://bladesilver.tistory.com/42</guid>
      <comments>https://bladesilver.tistory.com/42#entry42comment</comments>
      <pubDate>Mon, 14 Jun 2021 15:35:14 +0900</pubDate>
    </item>
  </channel>
</rss>