<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>k_chae1.log</title>
        <link>https://velog.io/</link>
        <description>잡다한 공부 기록용</description>
        <lastBuildDate>Wed, 10 May 2023 08:05:25 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. k_chae1.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/k_chae1" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[KT AIVLE [15주차] - django]]></title>
            <link>https://velog.io/@k_chae1/KT-AIVLE-15%EC%A3%BC%EC%B0%A8-django</link>
            <guid>https://velog.io/@k_chae1/KT-AIVLE-15%EC%A3%BC%EC%B0%A8-django</guid>
            <pubDate>Wed, 10 May 2023 08:05:25 GMT</pubDate>
            <description><![CDATA[<p>FE에서 보내는 데이터가 잘 갔는지 확인하기 어려웠는데 내가 장고를 다루면서 확인할 수 있는 방법이 생긴거니 편해졌다.
이래서 FE이든 BE이든 둘다 알아야한다는거구나...
근데 세상 사람들이 다 풀스택하면....왜 분업하죠...?쓸쓸...</p>
<hr>
<h2 id="이론-📝">이론 📝</h2>
<h3 id="mvt-📌">MVT 📌</h3>
<p>장고는 MVT 구조를 따름 
MVC에서 C를 그냥 Template으로 바꾼거임</p>
<ul>
<li>Model: DB와 소통 (채우는 알맹이)</li>
<li>View: 사용자 리퀘스트를 처리하기 위해 데이터를 Model에서 받고 Template을 써 이쁘게 만들어서 보여줌 (동작하는 부분)</li>
<li>Template: 주로 html, 뷰와 나눈 이유는 유지보수를 쉽게 하려고! (디자인 부분)</li>
</ul>
<h3 id="배포를-하는-법-📌">배포를 하는 법? 📌</h3>
<p>python anywhere에 회원가입!
<a href="https://www.pythonanywhere.com/">https://www.pythonanywhere.com/</a>
Web app에 들어감!
<img src="https://velog.velcdn.com/images/k_chae1/post/945cad2a-c88b-4201-ac9a-286aa29deb90/image.png" alt=""></p>
<p>원하는 프레임워크와 파이썬 버전을 택함...
나는 수업대로 장고와 버전 10!</p>
<p>urls.py를 내가 만든걸로 바꾸면 페이지가 배포가 되는데....
문제는 고작 300명이 한 번에 들어갔는데 너무 느리잖아~</p>
<h3 id="라우팅-📌">라우팅 📌</h3>
<p>경로를 확인하고 어떤 함수를 연결할지 결정하는 것!</p>
<p>정적 웹 서버: 아파치, nginx, IIS 등
동적 웹 애플리케이션 서버: 장고, 플라스크, php, jsp 등</p>
<p>urlpatterns: 주소록, url과 함수의 연결목록 작성
path: url과 함수를 묶어줌
re_path: regex를 이용, url과 함수를 연결
(* 함수 = view)
<img src="https://velog.velcdn.com/images/k_chae1/post/3d09ac5b-db5e-4a1a-82b9-3b71079ffff0/image.png" alt=""></p>
<p>path의 형태는 여러가지가 있다!</p>
<ul>
<li><p>기본형태
path(&#39;&#39;, index),</p>
</li>
<li><p>경로에서 parameter 전달
path(&#39;gugu/<num>/&#39;, gugu),</p>
</li>
<li><p>앱의 url.py로 하위 url routing
path(&#39;account/&#39;, include(&#39;account.urls&#39;)),</p>
</li>
<li><p>regular expression을 이용한 routing
re_path(r&#39;^search/(?P<year>[0-9]{4})/$&#39;, search_by_year),</p>
</li>
</ul>
<p>근데 이제 이 함수들을 views.py로 쫓아냄!!!
from . import view 해서 불러오는거임!!!</p>
<p>장고에서 그냥 웹 서버를 띄우면...걍 개발용임...효율적 동작 X
(AWS EC2에 장고 띄우기...같은거...)</p>
<p>대형 서비스가 되기 시작하면?! WSGI보다 앞에 있는 서버에게 맡겨야함!!!
앞단의 웹 서버에게 맡기는 거임 (nginx, apache 등) &gt; static의 역할을 얘들이 함!!!!!</p>
<p>장고나 플라스크는 그냥 자기 로직만 충실히 하면 됨....</p>
<h3 id="model-📌">Model 📌</h3>
<p>객체를 정의하고 
객체의 데이터 스키마를 선언하고 
객체의 행동을 정한다</p>
<p>얘가 있으면 디비랑 소통해서 디비 안의 스키마를 만들고 데이터를 저장가능
그리고 불러와서 웹에 띄우기도 가능!!!</p>
<p>모델 변경시 마이그레이션과 마이그레이트 필수</p>
<h3 id="orm-📌">ORM 📌</h3>
<p>오브젝트 관계 맵핑
오알엠 쉘이 따로 있음
sql문을 안 나오게 하는게 목적</p>
<p>관계형 DB에서 완전한 객체지향이 아니라 주소참조했던것처럼 완전한 객체지향으로 만들려고 상관관계에 있는 entity에 접근이 가능한거에요</p>
<ol>
<li>일대일 관계에서 서로에 해당하는 필드정보를 볼 수 있음</li>
<li>다대다 연결에서도 마찬가지 클래스이름_set.all()로 가능</li>
</ol>
<p>협업하기 때문에 이걸 권장!!!!</p>
<blockquote>
<p>django-extensions 라이브러리 설치
settings.py에 INSTALLED_APPS에 django_extensions 등록
python maage.py shell_plus 에 진입</p>
</blockquote>
<p>이것도 실습해서 작성ㄷ하자... 와 대박ㅇ신기하네....
모델의 데이터를 뷰로 보낼수가 있음 이 방식으로...</p>
<h3 id="structer-type-📌">Structer Type 📌</h3>
<pre><code class="language-python">class User:
    def __init__(self, id, name, email):
        self.id = id
        self.name = name
        self.email = email

users = [
    User(id=1, name=&#39;blackdew&#39;, email=&#39;blackdew7@gmail.com&#39;),
    User(id=2, name=&#39;django&#39;, email=&#39;django@naver.com&#39;),
    User(id=3, name=&#39;python&#39;, email=&#39;python@gmail.com&#39;),
]
</code></pre>
<h3 id="class-📌">Class 📌</h3>
<pre><code class="language-python">class User:
    def __init__(self, id, name, email):
        self.id = id
        self.name = name
        self.email = email

    def domain(self):
        return self.email.split(&#39;@&#39;)[-1]

users = [
    User(id=1, name=&#39;blackdew&#39;, email=&#39;blackdew7@gmail.com&#39;),
    User(id=2, name=&#39;django&#39;, email=&#39;django@naver.com&#39;),
    User(id=3, name=&#39;python&#39;, email=&#39;python@gmail.com&#39;),
]
</code></pre>
<h3 id="form-📌">Form 📌</h3>
<p>사용자와 상호작용</p>
<p>ModelForm은 모델과 폼이 연결되어 있어서 한번에 처리
그냥 폼은 그냥 폼...</p>
<h3 id="세션과-쿠키-📌">세션과 쿠키 📌</h3>
<p>웹을 위한 저장공간
쿠키는 브라우저(클라이언트)에 저장
  : 서버로 요청을 보낼 때 기억했어야 할 내용을 저장 (서버가 사용)
세션은 서버에 저장
  : 서버가 사용</p>
<p>사용자를 식별하고 사용자의 행동에 대한 정보를 기억할 수 있는 방법</p>
<hr>
<h2 id="실습-💻">실습 💻</h2>
<h3 id="웹-애플리케이션-만들기-📌">웹 애플리케이션 만들기 📌</h3>
<p>앱을 프로젝트 안에서 관리하는 이유: 유지보수와 재사용
하나의 사이트 내에 기능을 개별 애플리케이션으로 분리하여 정의</p>
<ol>
<li><p>django-admin startproject mysite (플젝 생성)</p>
</li>
<li><p>cd mysite</p>
</li>
<li><p>python manage.py startapp blog (blog(이름)앱 생성)</p>
</li>
<li><p>python manage.py migrate </p>
<ul>
<li>근데 정확히 마이그레이션이 뭘까? 스키마 변경을 트래킹!!</li>
<li>마이그레이트와 마이그레이션이 차이가 있다;</li>
<li>실제 DB 적용 / 스키마 변경 이력의 등록 </li>
</ul>
</li>
</ol>
<ol start="5">
<li>python manage.py createsuperuser (슈퍼 유저)</li>
<li>settings.py 파일의 INSTALLED_APPS 만든 앱 추가 (blog)</li>
<li>python manage.py runserver (서버 실행해서 확인)</li>
</ol>
<blockquote>
<p>  url.py : 사이트의 main URL 관리
    setting.py : 프로젝트 환경 설정
      view.py : 함수나 클래스가 들어감
      model.py : 데이터 구조 및 행동</p>
</blockquote>
<ol start="8">
<li><p>url 위임
밑의 사진처럼 경로 맞춰서 셋팅!!!
<img src="https://velog.velcdn.com/images/k_chae1/post/3e65ee28-a55e-4616-9fe4-2fc0610180bd/image.png" alt="">
<img src="https://velog.velcdn.com/images/k_chae1/post/d125dbdf-a973-4729-83c0-0d885f8966eb/image.png" alt="">
<img src="https://velog.velcdn.com/images/k_chae1/post/33194898-f4a8-472c-88b8-8512d46612c0/image.png" alt=""></p>
</li>
<li><p>모델 만들기
blog/model.py 에 작성 (project 말고 app으로 만든거에는 다 있음!)</p>
</li>
<li><p>DB 적용
<img src="https://velog.velcdn.com/images/k_chae1/post/c18ad4b2-55c1-4280-9de2-9db318e89e2a/image.png" alt="">
<img src="https://velog.velcdn.com/images/k_chae1/post/75380385-c48b-4467-9ad6-58ad2c846eda/image.png" alt=""></p>
</li>
<li><p>admin.py에 모델 등록
<img src="https://velog.velcdn.com/images/k_chae1/post/6b32151d-9b98-49d8-a509-9dfd046fc113/image.png" alt=""></p>
</li>
<li><p>blog 밑에 templates 폴더 생성
<img src="https://velog.velcdn.com/images/k_chae1/post/e3e15087-8450-49c7-8040-60db1377ca0e/image.png" alt=""></p>
</li>
</ol>
<ol start="13">
<li><p>랜더링
<img src="https://velog.velcdn.com/images/k_chae1/post/208b64f8-683e-4bc9-ae04-e88df88a87a9/image.png" alt=""></p>
<p>~ 여기까지 하고 서버 띄워서 접속하면 이렇게 됨~
<img src="https://velog.velcdn.com/images/k_chae1/post/c18462f6-609c-4ec1-8f5d-abd77635f19d/image.png" alt="">
(안의 내용은 admin 페이지에서 추가해준것!)</p>
</li>
<li><p>추가 페이지 작성 1
<img src="https://velog.velcdn.com/images/k_chae1/post/00034c67-e3bc-4376-9239-d64b9a3eb2b3/image.png" alt=""></p>
</li>
</ol>
<p> ~ 여기까지 하고 서버 띄워서 접속하면 이렇게 됨~
<img src="https://velog.velcdn.com/images/k_chae1/post/4e1996b8-4994-4db1-98e6-0eab82981c62/image.png" alt=""></p>
<ol start="15">
<li>추가 페이지 작성2</li>
</ol>
<ul>
<li>polls 앱 만들고
setting.py에 앱 등록
migrate polls</li>
<li>polls의 model.py에 모델 작성
makemigrations polls </li>
<li>polls의 admin.py에 모델 등록</li>
</ul>
<p>~ admin 페이지로 접속하면 object가 아닌 원하는걸로 보임 ~
polls/model.py 수정
<img src="https://velog.velcdn.com/images/k_chae1/post/71b8d22d-d846-4051-860e-4138c88c9f61/image.png" alt=""></p>
<p>~ 목록에 여러 필드 보이기 ~
polls/admin.py 수정
모델의 필드명과 동일해야함
<img src="https://velog.velcdn.com/images/k_chae1/post/fea7b28d-3abf-4599-b829-05a5f5503e07/image.png" alt=""></p>
<p>~ 그럼 이렇게 보임 ~
<img src="https://velog.velcdn.com/images/k_chae1/post/5e621dc7-2ce1-4fcf-81a3-03edc903fb3e/image.png" alt=""></p>
<p>~ 목록에서 필터 기능 넣기 ~
polls/admin.py 수정
<img src="https://velog.velcdn.com/images/k_chae1/post/c4974ee4-5ff6-4b6d-a5fb-5723d5ad91e5/image.png" alt=""></p>
<p>~ 상세보기 화면 정리 ~ 
polls/admin.py 수정</p>
<ul>
<li>필드가 여러개일 때 그룹화해서 모아주는 기능
<img src="https://velog.velcdn.com/images/k_chae1/post/98ab2f79-bc7d-470b-9647-fc38642e9d6c/image.png" alt=""></li>
</ul>
<p>~ 상세보기 화면에 inline ~
polls/admin.py 수정
<img src="https://velog.velcdn.com/images/k_chae1/post/c921a5d1-b091-4770-88dc-e6020a3b1e47/image.png" alt="">
<img src="https://velog.velcdn.com/images/k_chae1/post/1f4033dd-eda7-4ceb-85af-72b9c926c525/image.png" alt=""></p>
<ol start="16">
<li>추가 페이지 작성 3 (HTML Form + ORM)
<img src="https://velog.velcdn.com/images/k_chae1/post/14e75231-626e-430c-8772-1f10ca49ca9f/image.png" alt="">
<img src="https://velog.velcdn.com/images/k_chae1/post/6bcb8dfe-fdbe-4f1f-b1f0-9451cb50d2d9/image.png" alt="">
<img src="https://velog.velcdn.com/images/k_chae1/post/16123415-6322-45ef-9532-3f1288e1ed6d/image.png" alt=""></li>
</ol>
<p>blog/views.py 수정</p>
<ul>
<li>from django.shortcuts import render,redirect<br><img src="https://velog.velcdn.com/images/k_chae1/post/23c06749-b1bf-4336-9ada-8f3d4ff7f42a/image.png" alt=""></li>
</ul>
<ol start="17">
<li>16번 수정 (Form + ORM)
<img src="https://velog.velcdn.com/images/k_chae1/post/c920852b-4040-439a-8e2d-6fcd4fb49037/image.png" alt=""></li>
</ol>
<p>blog/views.py 수정
<img src="https://velog.velcdn.com/images/k_chae1/post/2a60a946-31e9-4c3e-a5d4-516aa7c2034c/image.png" alt=""></p>
<ol start="18">
<li>17번 수정 (Model Form + ORM)
<img src="https://velog.velcdn.com/images/k_chae1/post/a2f74c41-7b67-4d55-bde9-1a7e1122bd40/image.png" alt=""></li>
</ol>
<p>추가. static 폴더 만들기 (이미지나 아이콘, json 등 들어감)</p>
<blockquote>
<p>앱을 분리해서 만들면 다른 프로젝트에서 재사용이 가능!
  템플릿을 사용하려면 폴더 추가해서 views.py에서 템플릿 폴더 가지고 렌더링</p>
<p>render(req, &#39;blog/index.html&#39;) 처럼...</p>
<p>정리!</p>
</blockquote>
<p>프로젝트에 다른 프로젝트에 사용했던 앱 재사용 과정
blog 폴더를 신규 프로젝트에 복사 
settings.py에 앱 등록: INSTALLED_APPS 
db 생성: python manage.py migrate blog
프로젝트 urls.py에 연결: path(&#39;blog/&#39;, include(&#39;blog.urls&#39;))</p>
<hr>
<h3 id="session--cookie">Session &amp; Cookie</h3>
<ol>
<li>app 새로 만들고 코딩 📌
<img src="https://velog.velcdn.com/images/k_chae1/post/970dd1f1-05ea-4d73-8fe4-f58328b06391/image.png" alt=""></li>
</ol>
<ol start="2">
<li>마저 정리 필요....</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[KT AIVLE [15주차] - SQL]]></title>
            <link>https://velog.io/@k_chae1/KT-AIVLE-15%EC%A3%BC%EC%B0%A8-SQL</link>
            <guid>https://velog.io/@k_chae1/KT-AIVLE-15%EC%A3%BC%EC%B0%A8-SQL</guid>
            <pubDate>Mon, 08 May 2023 03:04:09 GMT</pubDate>
            <description><![CDATA[<p>이 수업은 거의 기본적인 것만 했다.
SQL쪽에 관심없고...자격증 공부쪽으로만 했는데 그래도 따라는 가지더라. BE쪽도 알아두는게 좋으니 조금 더 공부할 예정.</p>
<hr>
<h2 id="이론-📝">이론 📝</h2>
<h3 id="sql문-📌">SQL문 📌</h3>
<p>DB에서 데이터를 조회하거나 처리할 때 사용하는 구문
ex. 오라클, Mysql, SQLserver 등</p>
<p>/* */ : multi line 주석
-- : one line 주석</p>
<ul>
<li>구조(관계형 DB): server &gt; database &gt; schema &gt; table</li>
<li>MySQL은 DB = Schema</li>
</ul>
<h4 id="ddl--데이터-정의-언어">DDL : 데이터 정의 언어</h4>
<ul>
<li>CREATE</li>
<li>ALTER</li>
<li>DROP</li>
</ul>
<h4 id="dml--데이터-조작-언어">DML : 데이터 조작 언어</h4>
<ul>
<li>SELECT</li>
<li>INSERT</li>
<li>UPDATE</li>
<li>DELETE</li>
</ul>
<h4 id="dcl--데이터-권한컨트롤-언어">DCL : 데이터 (권한)컨트롤 언어</h4>
<ul>
<li>GRANT</li>
<li>REVOKE</li>
<li>DENY</li>
</ul>
<p>쿼리는 빠른 것이 성능이 좋다고 함 (정확도는 당연한거라...)</p>
<p>CHAR vs VARCHAR
: 데이터의 길이가 고정일 경우 CHAR, 가변일 경우 VARCHAR를 사용
공간낭비를 막기 위함, VARCHAR에서 max만 정해줌
VARCHAR는 실제 데이터 길이가 뭐인지 따로 관리가 됨 (오버헤드 존재)</p>
<ul>
<li>NULL
널값 관련으로 DB마다 함수가 다 다름;;
공통으로 쓸 수 있는건?ㅎㅎㅎ <em>COALESCE</em>!!!!!
(나열된 값 중에서 첫번째 NULL이 아닌 값)</li>
</ul>
<ul>
<li>MySQL은 +연산자는 숫자만 가능하다 (문자로 하면...에러는 안나도 0으로 됨...)
따라서 문자열은 CONCAT 함수로 결합함 </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[KT AIVLE [14주차] - 가상화 클라우드]]></title>
            <link>https://velog.io/@k_chae1/KT-AIVLE-14%EC%A3%BC%EC%B0%A8-%EA%B0%80%EC%83%81%ED%99%94-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C</link>
            <guid>https://velog.io/@k_chae1/KT-AIVLE-14%EC%A3%BC%EC%B0%A8-%EA%B0%80%EC%83%81%ED%99%94-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C</guid>
            <pubDate>Tue, 02 May 2023 08:09:03 GMT</pubDate>
            <description><![CDATA[<p>이 분야는 아~예 모른다. 생초보. AWS든 뭐든...써보지도 않았다.
그러나 써보니 왜 써야할진 알 것 같은..... 
작은 사이드 프로젝트를 하나 기획해서 AWS 배포까지 마쳐보는게 올해의 버킷리스트. </p>
<hr>
<h2 id="이론">이론</h2>
<h3 id="가상화">가상화</h3>
<p>기존 환경은 극도로 복잡하고 빈약한 인프라에 의존중
그래서 IT 예산 대부분이 현상유지에 사용됨
이걸 가상화 기술을 통해 해결함</p>
<p>** 하이퍼바이저를 통해 물리적인 코어들을 가상 아키텍쳐로 분리해서 할당
클라이언트 하이퍼바이저 &gt; 서버 하이퍼바이저 &gt; 가상 인프라 &gt; 클라우드</p>
<p>** 하이퍼바이저 : 시스템에서 다수의 운영 체제를 동시에 실행할 수 있게 해주는 논리적 플랫폼 (Type 1(Native 또는 Bare-metal) 또는 Type2 (Hosted))</p>
<p>네트워크도 가상화를 통해서 구현이 됨</p>
<h3 id="클라우드">클라우드</h3>
<ul>
<li><p>클라우드란? PC데이터를 PC에 보관하는 것이 아니라 인터넷을 통해 중앙 PC 또는 서버에 저장하는 공간</p>
</li>
<li><p>클라우드 컴퓨팅: 인터넷을 통해 IT 리소스를 원할 때 언제든지 사용하고 사용한 만큼 비용을 지불하는 서비스</p>
</li>
<li><p>퍼블릭 클라우드: 업체에게 자원들을 대여해서 사용</p>
</li>
<li><p>프라이빗 클라우드: 기업이 직접 클라우드 구축, 기업내부에서 활용</p>
</li>
<li><p>하이브리드 유형: 기존 On-premise에 구성되어있는 인프라(프라이빗 클라우드)와 퍼블릭 클라우드를 혼용 </p>
</li>
<li><p>멀티 클라우드 : 2개 이상 서로 다른 클라우드를 함께 사용하는 방식</p>
</li>
</ul>
<h3 id="ec2">EC2</h3>
<ul>
<li>가상 서버 서비스
엘라스틱 컴퓨트 클라우드: 트래픽에 맞춰 운용가능한 서비스</li>
</ul>
<h3 id="vpc">VPC</h3>
<p>사용자가 정의한 가상의 네트워크 환경
네트워크 관련으로 빌려줌. ip나 라우터 등등...</p>
<p>region 설정, IP대역 결정 &gt; 가용영역에 서브넷 생성 &gt; 라우팅 설정 &gt; 트래픽 통제</p>
<p>VPC 구성시 가장 먼저 고려하는건 IP대역폭
CIDR로 IP 개수를 관리
숫자가 커질수록 네트워크 내 할당 가능한 호스트 개수가 줄어듬
VPC CIDR 설정: VPC 내 위치한 서버들이 사용할 프라이빗 IP의 범위를 지정하는 것
생성 이후 변경 불가. 16~28 bit 사이로 가능</p>
<p>서비스의 규모와 IP소모률과 추후 서비스 확장 가능성, 타 시스템과 연계 가능성 등을 따져서 CIDR 결정</p>
<p>서브넷도 CIDR를 이용해 IP 범위를 지정
브로드캐스팅 영역 분리를 위해 서브넷을 사용</p>
<p>VPC는 외부 통신 단절, 통신하려면 인터넷 게이트웨이를 통해야만 함</p>
<h3 id="스토리지">스토리지</h3>
<ul>
<li>블록: 아마존 EBS
AWS에서 제공하는 블록 스토리지 서비스, EC2용 (VM)
볼륨과 인스턴스는 같은 어빌리티 존에 있는 경우 연결 가능
EBS 볼륨을 스냅샷 생성 후 다른 AZ(또는 리전)에 EBS 생성 가능</li>
<li>파일: 아마존 EFS</li>
<li>오브젝트: 아마존 S3</li>
</ul>
<h3 id="고가용성">고가용성</h3>
<p>가용성?워크로드를 사용할 수 있는 시간의 비율</p>
<p>AWS는 리전과 AZ로 이루어져 있음</p>
<h3 id="컨테이너">컨테이너</h3>
<h3 id="쿠버네티스">쿠버네티스</h3>
<h4 id="마스터노드">마스터노드</h4>
<ul>
<li>API Server : 통신 다리역할</li>
<li>Scheduler : Pod의 생성 명령이 있을경우 어떤 Node에 배포할지 결정</li>
<li>Controller Managers : 클러스터의 상태를 조절 하는 컨트롤러들을 생성, 배포</li>
<li>etcd : 모든 클러스터의 구성 데이터를 저장하는 저장소</li>
</ul>
<h4 id="워커머신">워커머신</h4>
<ul>
<li><p>컨테이너 런타임: 컨테이너를 실행하고 노드에서 컨테이너 이미지를 관리
ex. 도커, 크라이오, rkt 등</p>
</li>
<li><p>kubelet: 각 노드의 에이전트 (컨테이너 런타임이 만든 컨테이너가 잘 동작하는지 감시, 감시내용을 api 서버에게 주기적으로 보고, api가 etcd에 저장)</p>
</li>
<li><p>kube-proxy: 클러스터 각 노드마다 실행, 각 노드간 통신 담당(외부)</p>
</li>
</ul>
<h3 id="쿠버네티스-컨테이너-배포통신볼륨-관리">쿠버네티스 컨테이너 배포,통신,볼륨 관리</h3>
<p>오브젝트(가장 기본 구성단위)라는 객체를 가지고 클러스터 상태를 관리
오브젝트는 두 가지 필드로 구성되어 있다.
Spec(정의 상태)과 Status(현재 상태)</p>
<ul>
<li><p>컨트롤러: 클러스터의 상태를 관찰, 필요한 경우 오브젝트(pod나 svc 등등..) 생성,변경을 요청</p>
</li>
<li><p>컨트롤러가 오토 핸들링(어디서 pod가 삭제되면 재생성해서 Spec과 맞춤), 오토 스케일링(리소스 부하가 커지면 pod 추가 등 비용관련으로 컨트롤)을 해줌 </p>
</li>
<li><p>Update&amp;Rolback: ???????????</p>
</li>
<li><p>Job: 한번 실행되고 종료되어야 할 기능</p>
</li>
</ul>
<ul>
<li><p>Pod: 컨테이너를 담는 통, 쿠버네티스는 파드를 만들고 컨테이너를 담는다는 느낌 (컨테이너를 구성하는 가장 작은 단위)
컨테이너 여러개 넣을 수 있고, 그들끼리 네트워크와 볼륨 공유
파드는 yaml파일이 있음 &gt; 이거 사용해서 pod 생성 명령어를 침 </p>
</li>
<li><p>NameSpace: 단일 클러스터 내 리소스 그룹 격리를 위한 오브젝트
사용자가 여러 팀으로 구성하는 경우, 프로젝트를 진행함에 있어 환경을 분리 해야 하는 경우 사용</p>
</li>
<li><p>ReplicaSet: Pod 개수 유지역할, yaml 작성 시 replicas 개수 지정하면 그 개수에 따라 유지</p>
</li>
<li><p>Deployment: ReplicaSet을 관리,즉...Pod를 관리!!!!!
get deploy해서 3/3뜨면 이게 그 pod 개수임</p>
</li>
<li><p>롤백...리비전...뭐가 많음</p>
</li>
<li><p>Service: 쿠버네티스 외부 or 내부에서 Pod에 접근하기 위한 오브텍트
파드안의 애플리케이션을 네트워크 서비스로 노출시키는 오브젝트
셀렉터 라벨, 포트 설정 둘 다 있어야함 (고정된 주소를 이용하여 접근)
이 서비스의 유형에는 <em>ClusterIP, NodePort, Load Balancer</em>가 있음</p>
<ul>
<li>ClusterIP: 서비스가 기본적으로 갖고있음</li>
<li>NodePort: 모든 노드에 포트를 할당해서 접근, 노드IP와 port필요</li>
<li>Load Balancer: 로드밸런서플러그인을 설치해서 접근</li>
</ul>
</li>
</ul>
<p>서비스가 일단 포트를 뚫어 길을 만듦,근데 포트로 갔다고 바로 파드로 연결되진 않고 서비스로 먼저 감, 서비스에서 target port랑 selector(pod label)가 있음, 셀럭터 라벨기반 포트 포워드로 연결을 함(target port로 감) 즉 그래서 worker1로 가든 2로 가든 서비스 먼저 거쳐서 포워딩 되기 때문에 지정된 파드로 접속이 됨.</p>
<ul>
<li><p>FQDN: 이건 또 뭔제??????</p>
</li>
<li><p>Volume: Pod 컨테이너에서 접근할 수 있는 디렉터리, 컨테이너들이 공유해서 사용 </p>
</li>
<li><p>Emptydir: Pod가 생성 시 생성, 삭제 시 삭제, 파드 야믈에서 관리</p>
</li>
<li><p>HostPath: 볼륨으로 사용할 디렉터리를 지정하고 그걸 마운트하여 사용</p>
</li>
<li><p>PV/PVC: 영구볼륨, 파드에 직접 연결X, PVC를 통해 사용  </p>
</li>
</ul>
<h2 id="실습">실습</h2>
<p>정리하기...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[KT AIVLE [13주차] - 웹 프로그래밍]]></title>
            <link>https://velog.io/@k_chae1/KT-AIVLE-13%EC%A3%BC%EC%B0%A8-%EC%9B%B9-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</link>
            <guid>https://velog.io/@k_chae1/KT-AIVLE-13%EC%A3%BC%EC%B0%A8-%EC%9B%B9-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</guid>
            <pubDate>Tue, 25 Apr 2023 01:20:37 GMT</pubDate>
            <description><![CDATA[<h2 id="기초-실습">기초 실습</h2>
<h3 id="사전-환경-세팅">사전 환경 세팅</h3>
<p>[vscode 설치 목록] </p>
<ul>
<li>beautify css</li>
<li>javascript debugger</li>
<li>code runner</li>
<li>python IntelliSense</li>
<li>nodejs 설치 (이건 따로 윈도우에서 설치)</li>
<li>code runner setting<ul>
<li>set PYTHONIOENCODING=utf8 &amp;&amp; python -u</li>
</ul>
</li>
</ul>
<p>html 자동완성
! 입력 or html5 입력</p>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/f4b6e7d3-9f64-4a24-9e2b-375727baee51/image.png" alt="">
주석은 ctrl + /</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/c2676fdd-8086-423f-b629-32dbc285eee8/image.png" alt="">
라이브 프리뷰 (실시간) 
<img src="https://velog.velcdn.com/images/k_chae1/post/96719551-c5f8-45c1-9405-176352d9370a/image.png" alt=""></p>
</blockquote>
<h3 id="html-가벼운-문법">html 가벼운 문법</h3>
<p>웹 페이지 접근성을 위해 강조는 &lt;b태그보다 &lt;strong태그
&lt;em은 이탤릭 &lt;small은 작게 &lt;code는 코드 스타일로 (alt+shift+f) 하면 코드 스타일이 예쁘게 작성됨</p>
<p>예시)
<img src="https://velog.velcdn.com/images/k_chae1/post/ed1a0fd2-44ed-4c92-9702-2a5b4a792565/image.png" alt=""></p>
<h4 id="emmet-문법">emmet 문법)</h4>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/b016d257-f136-46e7-b67b-06bc429b8777/image.png" alt="">
ctrl + space + enter 로 하는데 나는 enter만 써도 됨;;;</p>
<p>부등호(&gt;) : 하위태그
플러스(+) : 동일레벨 태그
괄호() : 문법수식을 묶을 수 있음 (= 우선순위 설정)
콜론(:) : 태그의 type값 설정
샾(#) : 태그의 id값 설정
온점(.) : 태그의 class값 설정</p>
<p>[연습]
<img src="https://velog.velcdn.com/images/k_chae1/post/7590868b-efc7-40c0-a00a-2659b31857d6/image.png" alt="연습"></p>
<h4 id="table-문법">table 문법)</h4>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/a268162c-b8b1-4e94-900a-0f3f21417467/image.png" alt=""></p>
<h4 id="input-문법">input 문법)</h4>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/52a7cfd3-4502-4e9b-b788-716ca44ea8b0/image.png" alt=""></p>
<hr>
<p>주먹구구식으로 html,css를 다뤄왔는데..
좀 본격적으로 웹에 관심이 생겼다.
기초부터 튼튼히 해야하니 바닐라 JS부터 잘 해야겠지만..
쉽진 않네요. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[KT AIVLE [13주차] - IT 인프라]]></title>
            <link>https://velog.io/@k_chae1/KT-AIVLE-%EC%A3%BC%EC%B0%A8-IT-%EC%9D%B8%ED%94%84%EB%9D%BC</link>
            <guid>https://velog.io/@k_chae1/KT-AIVLE-%EC%A3%BC%EC%B0%A8-IT-%EC%9D%B8%ED%94%84%EB%9D%BC</guid>
            <pubDate>Mon, 24 Apr 2023 06:17:15 GMT</pubDate>
            <description><![CDATA[<p>기나긴 프로젝트 기간이 끝나고~
다시금 강의시간이 되었습니다. 저는 좋습니다.
cs와...정처기스러운...얕고 넓게...아주 만족합니다. 
힘들어서 다 정리는 못함. </p>
<hr>
<h2 id="이론-📝">이론 📝</h2>
<h3 id="서버와-클라이언트-📌">서버와 클라이언트 📌</h3>
<p>• 서버 : 클라이언트에게 네트워크를 통해 정보나 서비스를 제공하는 장치 (응답)
• 클라이언트 : 네트워크를 통하여 서버에 접속해 정보를 확인하거나 서비스를 이용하는 장치 (요청)</p>
<p>동적 콘텐츠는 웹 서버에서 처리 불가 &gt; 애플리케이션 서버에서 처리
근데!!! 애플리케이션 서버가 바로 웹 서버로 보내주지 않음!!!
중간에 리버스 프록시 서버를 거쳐야함 (대기화면..같은 느낌)</p>
<p>이때!! 똑같은 정보를 클라이언트가 요청했다면 포워드 프록시(캐시) 서버가 위 과정을 안 거치고 냅다 웹 서버한테 보냄</p>
<h3 id="네트워크-📌">네트워크 📌</h3>
<p>• 회선 교환 방식 : 데이터를 교환하기 위해 1:1로 연결된 데이터 통로를 만들고 교환이 완료될 때까지 회선을 계속 사용하는 방식
(통신 상태에 따라서 끊김)</p>
<p>• 패킷 교환 방식 : 데이터를 패킷이라는 작은 단위로 나누고, 헤더라는 정보를 붙여 데이터를 교환하는 방식
(헤더: 송수신 포트번호, 패킷 순서, 데이터 시작 위치, 한번에 전송가능한 데이터의 양 등이 포함)</p>
<p>• 프로토콜 : 패킷을 전송하기 위한 통신 규칙
(ex. HTTP, DNS, FTP, TCP, UDP, IEEE, ARP 등)</p>
<p>• 네트워크 계층 : 송수신시 데이터는 각 계층별로 처리 됨</p>
<blockquote>
<p>이거 관련 정리해서 추가로 붙이기</p>
</blockquote>
<p>  1) TCP/IP 참조 모델
  2) OSI 7 참조 모델</p>
<blockquote>
<p>7,6,5를 합쳐서 애플리케이션 계층으로 통합</p>
</blockquote>
<h4 id="네트워크-기기-l1">네트워크 기기 L1</h4>
<p>• NIC : PC나 서버를 네트워크에 연결해주는 하드웨어</p>
<p>• 허브 : 전달받은 패킷(비트)의 복사본을 포트에 연결된 다른 모든 기기로 전송 (네트워크 대역폭을 연결된 기기들이 나눠씀)</p>
<p>• AP : 패킷을 전차로 바꿔서 송출하는 기기, 무선과 유선의 다리역할 (공유기...)</p>
<h4 id="네트워크-기기-l2">네트워크 기기 L2</h4>
<p>• MAC 주소 : 컴퓨터들이 서로 데이터를 전송하기 위해 사용하는 물리적 주소 (NIC에 내장)</p>
<p>• 이더넷 : 네트워크 환경에서 데이터 교환을 위한 가장 대표적인 기술 규격
• UTP : 케이블로 단말기와 네트워크 기기를 연결</p>
<p>• L2 스위치: 단말기가 보낸 패킷(프레임)을 헤더에 있는 MAC 주소를 보고 같은 네트워크의 다른 단말기로 패킷을 전송 (이더넷 규격이라서 이더넷 스위치라고도 말함)</p>
<h4 id="네트워크-기기-l3">네트워크 기기 L3</h4>
<p>• IP 주소 : 서로 다른 네트워크에 연결되어 있는 컴퓨터들이 데이터를 전송하기 위해 사룔하는 논리적 주소 (OS상에서 설정)</p>
<p>• 라우터: 단말기가 보낸 패킷(IP 패킷)의 헤더에 있는 IP를 보고 다른 네트워크의 다른 단말기로 전송</p>
<p>• FPGA : 프로그래밍이 가능한 집적 회로 반도체 (용도에 따라 기능 변경 가능)</p>
<p>• ASIC : 특정 용도를 위해 설계된 주문형 집적회로 반도체 (용도 변경 불가)</p>
<p>• L3 스위치 : 라우터에 2 스위치를 추가한 네트워크 기기. 다수의 포트가 있어 여러 단말기 연결 가능, IP 패킷 라우팅도 가능</p>
<h4 id="네트워크-기기-l4">네트워크 기기 L4</h4>
<p>• L4 스위치 : IP주소와 포트번호를 참조, 트래픽을 분산해 서버로 전송하는 로드 밸런싱 기기
(로드 밸런싱: 들어오는 트래픽을 둘 이상의 서버로 분산 전송하여 부하를 줄임)</p>
<p>• 방화벽 : IP주소와 포트번호를 참조하여 통신을 허가하거나 차단하는 기기, 미리 정의된 보안 규칙에 따라 들어오고 나가는 트래픽을 제어</p>
<h4 id="네트워크-기기-l7">네트워크 기기 L7</h4>
<p>• L7 스위치 : IP 주소, 포트번호,, 애플리케이션 콘텐츠 정보들을 참조하여 로드밸런싱하는 기기</p>
<p>• 웹 방화벽 : 웹 애플리케이션 서버를 안전하게 보호하는 기기 (블랙리스트, 화이트리스트, 웹 트래픽 분석)</p>
<h4 id="네트워크-형태">네트워크 형태</h4>
<p>• LAN: 근거리 통신망, 가정이나 기업 내부 등 한정된 범위의 네트워크</p>
<p>• WAN: 원거리 통신망, 물리적으로 거리가 매우 떨어진 곳의 네트워크
(LAN 환경에 L3스위티를 추가해서 구성)</p>
<p>• VPN: 인터넷 상에서 가상의 전용선을 만들어 통신할 수 있게 하는 기술 (특정 네트워크만을 위한 전용 WAN)</p>
<p>• DMZ: 비무장지대, 외부망과 내부망의 중간 지점 (내부망에는 존재하나 외부망에서 접근할 수 없는 영역)</p>
<h3 id="스토리지-📌">스토리지 📌</h3>
<p>• 스토리지: 저장장치를 다수 장착한 대용량 고속 저장 장비 
저장뿐만 아니라 데이터 공유 목적으로도 주로 사용됨</p>
<p>•RAID: 여러 개의 디스크 중 일부에 데이터를 중복 저장하는 기술
(여러개의 디스크를 하나의 디스크 모듈로 사용 - 장애 발생 시 복구 편함)</p>
<p>•JBOD: 2개 이상의 디스크를 하나의 디스크처럼 만들어 주는 것 (성능 향상x, 용량 향상 o)</p>
<h4 id="스토리지-종류">스토리지 종류</h4>
<p>• DAS : 서버에 직접 연결한 스토리지 (ex. 외장하드 개념)
• NAS : 데이터 공유를 위한 파일 서버 용도로 주로 사용되며 파일 스토리지라고도 불림, 스토리지 전용 OS로 데이터를 관리 (네트워크 스위치 필요)</p>
<h4 id="스토리지-유형">스토리지 유형</h4>
<p>• 파일 스토리지 : 데이터를 파일과 폴더로 이루어진 계층 구조에 저장 (ex. NAS)
• 블록 스토리지 : 데이터를 일정한 크기의 블록으로 나눠서 분산 저장(ex. SAN)
• 오브젝트 스토리지 : 오브젝트라는 개별 데이터 단위로 분산 저장 (ex. AWS)</p>
<h4 id="백업">백업</h4>
<p>• 백업: 데이터를 임시로 다른 장치에 저장하여 문제가 있을 때 복구할 수 있도록 준비해 두는 것
• Full Backup : 백업 주기 마다 데이터 전체를 백업
• Incremental Backup : 첫째 날에 데이터 전체를 백업하고, 그 다음부터는 증가된 데이터만 백업</p>
<p>• 스냅샷: 특정 시점에 스토리지의 파일 시스템을 포착해 보관하는 기술 (ex. copy-on-write, redirect-on-write)</p>
<h4 id="데이터베이스">데이터베이스</h4>
<p>• 데이터베이스: 여러 사람이 공유, 사용할 목적으로 체계화해 통합, 관리하는 데이터의 집합 등을 저장하여 운영할 수 있는 공용 데이터들의 묶음</p>
<p>•DBMS: 사용자들이 DB안에 있는 데이터를 접근할 수 있도록 해주는 소프트웨어</p>
<p>•관계형 DBMS: 테이블이라는 최소단위로 구성</p>
<h3 id="온프레미스-📌">온프레미스 📌</h3>
<p>• 기업이 자체 시설에서 보유하고 직접 유지 관리하는 프라이빗 데이터 센터</p>
<p>• 3 Tier 아키텍처 : 애플리케이션 운영 환경이 컴퓨팅(서버), 네트워크, 스토리지로 구성괸 전통적인 아키텍처</p>
<h3 id="컨테이너-📌">컨테이너 📌</h3>
<p>• 컨테이너 : Container, 리눅스 기반 애플리케이션 운영을 위한 프로세스 격리 기술
• 컨테이너 런타임 : Container Runtime, 컨테이너를 다루는 도구
• 도커 : Docker, 컨테이너 기술을 누구나 쉽게 사용할 수 있도록 만든 컨테이너 런타임 중
가장 유명한 오픈소스 프로젝트</p>
<p>컨테이너 : 하나의 OS에 다양한 애플리케이션(프로세스 별)별로 가상화
가상머신 : OS별로 가상화</p>
<p>• 쿠버네티스 : 다수의 컨테이너를 효율적으로 운영, 관리하기 위한 도구</p>
<p>• 파드(Pod) : 앱이 운영되는 컨테이너들의 모음, 그룹
• 노드(Node) : 파드가 운영되는 물리 서버 또는 가상 머신, 워커 노드라고 부름
• 클러스터(Cluster) : 노드들의 집합
• 마스터(Master) : 다수의 워커 노드들 및 그 하위의 파드와 컨테이너를 관리하는 노드</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[KT AIVLE [9주차] - 언어지능 딥러닝 (수정중)]]></title>
            <link>https://velog.io/@k_chae1/KT-AIVLE-9%EC%A3%BC%EC%B0%A8-%EC%96%B8%EC%96%B4%EC%A7%80%EB%8A%A5-%EB%94%A5%EB%9F%AC%EB%8B%9D</link>
            <guid>https://velog.io/@k_chae1/KT-AIVLE-9%EC%A3%BC%EC%B0%A8-%EC%96%B8%EC%96%B4%EC%A7%80%EB%8A%A5-%EB%94%A5%EB%9F%AC%EB%8B%9D</guid>
            <pubDate>Mon, 27 Mar 2023 08:02:59 GMT</pubDate>
            <description><![CDATA[<p>8주차는 미니 프로젝트를 진행하였다.
<a href="https://github.com/chaewon0824/AIVILE_VehicleDamage">https://github.com/chaewon0824/AIVILE_VehicleDamage</a></p>
<hr>
<p>못 듣겠다 ...
추후 내 식대로 정리한걸 발전시켜 다듬기로... </p>
<hr>
<h2 id="이론-📝">이론 📝</h2>
<ul>
<li><p>MLops</p>
</li>
<li><p>간단한 용어 정리
<a href="https://docs.google.com/spreadsheets/d/16gPgtNMk6GqBbymMXPCnZ6TOK3Btn2hg5StIhGgWb8I/edit#gid=0">https://docs.google.com/spreadsheets/d/16gPgtNMk6GqBbymMXPCnZ6TOK3Btn2hg5StIhGgWb8I/edit#gid=0</a></p>
</li>
</ul>
<ul>
<li>return_sequences= Boolean
이전 레이어의 출력을 다음 레이어의 입력으로 사용 하는가 하지 않는가</li>
</ul>
<h3 id="rnn-📌">RNN 📌</h3>
<h3 id="gru-📌">GRU 📌</h3>
<h3 id="lstm-📌">LSTM 📌</h3>
<h3 id="bidirectional-lstm-📌">Bidirectional LSTM 📌</h3>
<h3 id="conv1d-📌">Conv1D 📌</h3>
<ul>
<li>kernel_size: 한 번에 관찰할 시점 수, 시점 별 feature는 전부 봄</li>
<li>filter: 특징 representation = 가중치의 모임</li>
</ul>
<h3 id="text-classification-📌">Text Classification 📌</h3>
<h2 id="실습-💻">실습 💻</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[KT AIVLE [7주차] - 시각지능 딥러닝 (수정중)]]></title>
            <link>https://velog.io/@k_chae1/KT-AIVLE-7%EC%A3%BC%EC%B0%A8-%EC%8B%9C%EA%B0%81%EC%A7%80%EB%8A%A5-%EB%94%A5%EB%9F%AC%EB%8B%9D</link>
            <guid>https://velog.io/@k_chae1/KT-AIVLE-7%EC%A3%BC%EC%B0%A8-%EC%8B%9C%EA%B0%81%EC%A7%80%EB%8A%A5-%EB%94%A5%EB%9F%AC%EB%8B%9D</guid>
            <pubDate>Mon, 13 Mar 2023 08:09:35 GMT</pubDate>
            <description><![CDATA[<p>특이한 컨볼루션 레이어들이 엄청 많다...
AIVLE 과정에서는 다루지 않고 내가 따로 공부하면서 알게된 것들이 많아서 그것에 대한 정리도 필요할듯....</p>
<hr>
<h2 id="이론-📝">이론 📝</h2>
<h3 id="cnn-📌">CNN 📌</h3>
<p>Convolutional Layer
이미지 구조를 파괴하지 않으며 위치정보 보존하기 위함
(이미지 구조를 유지한 채로 부분에서 특징을 뽑음)</p>
<ul>
<li>filters : 피처맵의 개수를 능동적으로 조절</li>
<li>strides : 몇 칸 띄우면서 사용할지 조절</li>
<li>padding : &#39;same&#39;으로 적용하면 피처맵 결과 사이즈가 인풋과 같음</li>
<li>kernel_size : 필터(윈도우)의 가로세로 사이즈</li>
<li>activation : 활성화 함수</li>
</ul>
<p>Feature map</p>
<ul>
<li>conv의 filter를 거치면 나옴</li>
<li>conv의 목적이 여기서 달성됨</li>
</ul>
<p>Pooling (Subsampling - downsampling)</p>
<ul>
<li>연산량 자체를 줄이기 위함</li>
<li>풀링 사이즈에 맞게 피처맵 사이즈가 줄음</li>
<li>pool_size</li>
<li>strides : 원래는 pool_size를 따라감</li>
<li>Maxpool은 가장 영향력이 큰 정보를 남김</li>
<li>AvgPool은 정보를 버리지 않고 요약</li>
</ul>
<p>preprocessing의 목적</p>
<ul>
<li>데이터를 문제 해결 가능한 구조로 변경</li>
<li>모델 성능 향상</li>
</ul>
<p>padding의 목적</p>
<ul>
<li>외곽 정보를 좀 더 추출</li>
<li>이미지 사이즈 유지</li>
</ul>
<p>모델의 구조만 보고 정보들을 파악할 수 있어야함
논문 갖고 연습필요</p>
<h3 id="💡-관련-계산">💡 관련 계산</h3>
<blockquote>
<p>파라미터개수등...찾아서 적기</p>
</blockquote>
<h3 id="object-detection-📌">object detection 📌</h3>
<ul>
<li>딥러닝에서 지도학습이란 error를 줄여나가는 방향으로 가중치를 업데이트 하는 것</li>
<li>CNN은 위치정보를 보존하면서 이미지의 특징을 추출하는 백본으로 사용됨</li>
<li>object detection = bounding box regression + multi class-classification
= localization + classification</li>
<li>대표적인 모델로 yolo가 있음 (one-stage detector)</li>
<li>two-stage detector는 속도가 너무 느려 실시간 처리가 불가함</li>
</ul>
<p>bounding box</p>
<ul>
<li>하나의 오브젝트가 포함되어 있는 최소 크기의 박스</li>
<li>x,y: 좌표 / w,h: 크기
<img src="https://velog.velcdn.com/images/k_chae1/post/4e97e684-9275-4247-9073-a6e06a9fefae/image.png" alt=""></li>
</ul>
<p>class classification</p>
<ul>
<li>어떤 클래스인지 알려주는 과정 </li>
</ul>
<p>confidence score</p>
<ul>
<li>어떤 오브젝트가 진짜 바운딩 박스안에 있는게 맞는지의 척도 </li>
<li>0~1</li>
<li>ground-truth boundung box는 1</li>
<li>object가 바운딩 박스에 있는지 여부와 iou값을 곱한것</li>
</ul>
<h3 id="pretrained-model-📌">pretrained model 📌</h3>
<p>유사한 문제를 해결하기 위해 다른 사람이 생성하고 대규모 데이터 세트에서 훈련된 모델 또는 저장된 네트워크 </p>
<h3 id="transfer-learning-📌">transfer learning 📌</h3>
<p>데이터셋을 해결하려는 문제에 맞춰 재구성하고 이 데이터셋을 사전학습 모델에 학습 시킴</p>
<p>Pre-trained model을 다음과 같은 형태로 사용될 수 있음</p>
<ol>
<li><p>Feature extraction
: output layer만 새로운 문제에 맞게 수정하고 그대로 사용</p>
</li>
<li><p>pre-trained model 아키텍쳐 사용
: 아키텍쳐만 채용하고 weight는 initialize</p>
</li>
<li><p>일부 layer만 training하고 나머지 layer는 고정
: 부분적으로 training 하는 방법. 보통 초기 layer (input에 가까운 layer)를 고정하고 상위 layer(output에 가까운 layer)를 training 하는 방법</p>
</li>
</ol>
<hr>
<hr>
<h2 id="실습-💻">실습 💻</h2>
<h3 id="mnist-복습-📌">MNIST 복습 📌</h3>
<p>데이터 로딩 및 구조 변경</p>
<pre><code>data = io.loadmat(&quot;notMNIST_small.mat&quot;)

X = data[&#39;images&#39;]
y = data[&#39;labels&#39;]
resolution = 28
classes = 10

X = np.transpose(X, (2, 0, 1))

y = y.astype(&#39;int32&#39;)
X = X.astype(&#39;float32&#39;) / 255.

# shape: (sample, x, y, channel)
X = X.reshape((-1, resolution, resolution, 1))

# y one-hot encoding
from tensorflow.keras.utils import to_categorical

num_classes = len(np.unique(y))
y = to_categorical(y,num_classes)

# splitting data
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=2023)
</code></pre><p>모델 정의</p>
<pre><code>from tensorflow import keras 

keras.backend.clear_session()

model = keras.models.Sequential()

model.add(keras.layers.Input(shape=(28,28,1)))
model.add(keras.layers.Flatten())

model.add(keras.layers.Dense(128,activation=&#39;relu&#39;))
model.add(keras.layers.Dense(128,activation=&#39;relu&#39;))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.Dropout(0.2))

model.add(keras.layers.Dense(64,activation=&#39;relu&#39;))
model.add(keras.layers.Dense(64,activation=&#39;relu&#39;))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.Dropout(0.2))

model.add(keras.layers.Dense(10,activation=&#39;softmax&#39;)) #output개수가 10개중 확률

model.compile(loss=&#39;categorical_crossentropy&#39;,
              optimizer = &#39;adam&#39;, metrics = [&#39;accuracy&#39;])

model.summary()</code></pre><p>early stopping 정의</p>
<pre><code>es = keras.callbacks.EarlyStopping(monitor=&#39;val_loss&#39;,         
                   min_delta=0,               
                   patience=10,                 
                   verbose=1,
                   restore_best_weights=True)  </code></pre><p>모델 훈련</p>
<pre><code>model.fit(x_train,y_train, epochs=100, validation_split=0.2, callbacks = [es])</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[KT AIVLE [6주차] - AI모델 해석 및 평가]]></title>
            <link>https://velog.io/@k_chae1/KT-AIVLE-6%EC%A3%BC%EC%B0%A8-AI%EB%AA%A8%EB%8D%B8-%ED%95%B4%EC%84%9D-%EB%B0%8F-%ED%8F%89%EA%B0%80</link>
            <guid>https://velog.io/@k_chae1/KT-AIVLE-6%EC%A3%BC%EC%B0%A8-AI%EB%AA%A8%EB%8D%B8-%ED%95%B4%EC%84%9D-%EB%B0%8F-%ED%8F%89%EA%B0%80</guid>
            <pubDate>Thu, 09 Mar 2023 03:07:20 GMT</pubDate>
            <description><![CDATA[<h2 id="이론-📝">이론 📝</h2>
<h3 id="0-review">0. Review</h3>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/36157798-9e07-4d43-a09b-6c5a0632ad63/image.png" alt=""></p>
<p>XAI: 설명가능 인공지능</p>
<h3 id="1-모델-해석하기-📌">1. 모델 해석하기 📌</h3>
<h4 id="💡-요약">💡 요약</h4>
<blockquote>
<p>Q1. 모델 전체에서 중요한 요인은?
A1. FI(tree 기반), PFI(tree 외 알고리즘)</p>
</blockquote>
<p>Q2. 중요한 변수의 값이 변할 때 예측 값에 영향은?
A2. PDP</p>
<blockquote>
</blockquote>
<p>Q3. 개별 데이터에서 어떤 feature 값이 예측값 영향을 끼친 정도
A3. SHAP (성능이 좋은 모델 &gt; explainer 선언 &gt; shap 값 추출 &gt; 그래프)</p>
<h4 id="1-비즈니스를-위한-인공지능-📌">1) 비즈니스를 위한 인공지능 📌</h4>
<p>pm을 하게 되면 변화관리에 주의</p>
<p>Q) 모델은 왜 그렇게 예측 했나요?</p>
<p>Q) 모델은 비즈니스 문제를 해결할 수 있을까요?</p>
<h4 id="2-왜-너를-믿어야하지-📌">2) 왜 너를 믿어야하지? 📌</h4>
<h4 id="해석">해석</h4>
<ul>
<li>input에 대해 모델이 왜 그런 output을 예측했는가?</li>
<li>어떤 변수가 모델에서 가장 중요한가?</li>
<li>whitebox model (본질적으로 해석 가능)</li>
</ul>
<h4 id="설명">설명</h4>
<ul>
<li>해석을 포함</li>
<li>추가로 투명성에 대한 요구</li>
<li>Model transparency : 모델이 어떻게 학습되는지 단계별 설명 가능해야 함.</li>
<li>최근 추세는 설명과 해석을 혼용해서 사용</li>
</ul>
<p>설명이 잘 되는 알고리즘은 대체로 성능이 낮다.</p>
<h4 id="3-모델에-대한-설명-📌">3) 모델에 대한 설명 📌</h4>
<blockquote>
<p>&lt; 전체 데이터 관점 &gt;</p>
</blockquote>
<ol>
<li>모델 전체에서 어떤 feature가 중요할까? (FI, PFI)</li>
<li>특정 feature 값의 변화에 따라 예측 값은 어떻게 달라질까? (PDP)
&lt; 개별 데이터 관점 &gt;</li>
<li>이 데이터(분석단위)는 왜 그러한 결과로 예측되었을까? (SHAP)</li>
</ol>
<h4 id="변수-중요도-fipfi">변수 중요도 (FI,PFI)</h4>
<p>성능 낮은 모델에선 의미 없음
예측값에 중요한 변수
트리기반 모델에서 뽑아낼 수 있음</p>
<blockquote>
<p>트리모델 말고는 FI를 어떻게 구함?
Permutation Feature Importance로 구함</p>
<p>• Permutation: 순서가 부여된 임의의 집합을 다른 순서로 뒤섞는 연산
• Feature 하나의 데이터를 무작위로 섞을 때, model의 score가 얼마나 감소되는 지로 계산</p>
<p>원래 스코어 - (섞었을 때 스코어*여러번)의 평균 = 최종 변수 중요도</p>
</blockquote>
<p>feature 순서 섞어서 predict했을 때 변화가 적다 = 어차피 영향이 없던거
변화가 크다 = 성능에 영향이 갈 정도로 중요하다</p>
<blockquote>
<p>⭐ 단점: 다중공선성이 있다면 score가 별 차이 없음 </p>
</blockquote>
<pre><code>from sklearn.inspection import permutation_importance

pfi = permutation_importance(model,x_val,y_val,n_repeats=10,random_state=2023)</code></pre><p>다중공선성: 분산 팽창 지수로 가려내야함</p>
<h4 id="pdp">PDP</h4>
<p>관심 feature의 값이 변할 때 모델에 미치는 영향을 시각화
x:관심 feature, y:예측값</p>
<h4 id="shap-shapley-additive-explanations">SHAP (SHapley Additive exPlanations)</h4>
<p>Shapley Value: 모든 가능한 조합에서, 하나의 feature에 대한 평균 기여도를 계산한 값</p>
<p>기여도 : 조합에 대한 예측값 - (조합(-특정 피처))의 예측 값
위 기여도에 가중치를 곱하여, 각 조합의 기여도를 합침
= 가중 평균 기여도</p>
<ul>
<li>예측값이 왜 이렇게 나왔습니까?에 대한 근거임</li>
</ul>
<p>1) Shapley Value 만들기</p>
<pre><code>explainer1 = shap.TreeExplainer(model1)
shap_values1 = explainer1.shap_values(x_train)</code></pre><p>+는 결과예측의 긍정요인, -는 결과예측의 부정요인
<img src="https://velog.velcdn.com/images/k_chae1/post/673a82ac-ef49-4d18-9b20-4c7588c56716/image.png" alt=""></p>
<pre><code># y_train의 평균
explainer1.expected_value

shap.initjs() # javascript 시각화 라이브러리 --&gt; colab에서는 모든 셀에 포함시켜야 함.

# force_plot(전체평균, shapley_values, input)
shap.force_plot(explainer1.expected_value, shap_values1[0, :], x_train.iloc[0,:])</code></pre><p><img src="https://velog.velcdn.com/images/k_chae1/post/468c9aee-4072-4f58-8f9c-6c447593b8b3/image.png" alt="">
예측값들의 평균은 base value (21.8)</p>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/3876fc63-4b99-43b1-be26-50d5867432c6/image.png" alt=""></p>
<p>0행의 예측값은 평균보다 작음, 그 값의 하락요인은 rm, dis, lstat 등이 화살표 범위(그래프의 폭)만큼 작용함(기여도), 숫자는 실제 데이터값
<img src="https://velog.velcdn.com/images/k_chae1/post/19a35cbe-1c95-4e48-914e-a277f830c26a/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/76cdaf83-6e60-48a6-a857-3bdc9ab28583/image.png" alt="">
위 사진과 같은 의미!</p>
<blockquote>
<p>전체 평균에 개별 데이터의 shap value를 다 더하면 그 행의 예측 값
shap 값이 그 차이에 대해 기여도를 계산한 것
분류문제면 shap value는 확률에 대한 기여도로 해석</p>
</blockquote>
<h4 id="전체-흐름에-벗어나는-값-분석">전체 흐름에 벗어나는 값 분석</h4>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/38c1e189-9ec2-4436-b18a-8efb57da18e5/image.png" alt="">
하위 계층의 비율이 높은데 214 인덱스는 집값은 높다, 이유가 뭘까?
같은 case에 대한 의문</p>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/725d8e46-b04b-4a89-914f-c7949df1fdd7/image.png" alt="">
그래서 예측값에 대한 분석 (실제값은 23.7)
확실히 예측값에선 lstat이 하락 요인으로 꼽힘
범죄율, 오염도, 연식 등등이 상승 요인으로 꼽힘
상승요인 덕에 근처랑 lstat이 비슷해도 실제 집 값이 높을 수 있음.
(ex. 하위계층 비율이 높은 다른 지역에 비해 상대적으로 범죄율이나 공기오염도가 상대적으로 낮다~)</p>
<p>각각의 기여도 sum = 베이스 값-예측값</p>
<h4 id="전체적으로-보기">전체적으로 보기</h4>
<p>점 하나: 분석단위별 feature 기여도
<img src="https://velog.velcdn.com/images/k_chae1/post/b3570b35-d95f-4fd2-be8c-da238d4f1b7e/image.png" alt="">
변수 중요도로 치환해서 볼 수 있다.
<img src="https://velog.velcdn.com/images/k_chae1/post/fe81f3c7-c8eb-4d10-bad7-850dce19f71f/image.png" alt=""></p>
<p>rm은 양의기여도가 분포가 크고 음의기여도가 분포가 작다. 
즉, rm값이 작을 때는 집값이 떨어질 때 크게 영향을 안줌
근데!!방의 수(rm)가 많으면!!집값 높이는데!!크게 영향을 줌!!!</p>
<hr>
<hr>
<h3 id="2-모델-평가하기-📌">2. 모델 평가하기 📌</h3>
<p>1) 비즈니스 문제 상황 파악</p>
<ul>
<li>ex. 수익 구조 등</li>
</ul>
<p>2) 평가 전 질문</p>
<ul>
<li>어떤 문제 해결을 위해 모델을 만들었는가?</li>
<li>실제 목적에 맞게 모델 결과는 평가하고 있는가?</li>
<li>모델 예측 결과에 대한 현장의 비즈니스 프로세스는 어떻게 정의되어 있는가?</li>
</ul>
<p>3) 문제 정의 및 평가</p>
<ul>
<li>고객사의 비즈니스 문제는 무엇?</li>
<li>모델의 예측 결과로 인한 비즈니스 프로세스는 무엇?</li>
<li>모델은 비즈니스 관점으로 어떻게 평가?</li>
</ul>
<p>4) 평가 지표</p>
<ul>
<li>RMSE나 f1-score나 이런건 고객사에게 설명한다고 이해가 될까? 안됨.
고객이 이해할 수 있는 지표로 평가해야함 </li>
<li>타겟 마케팅에서 모델 예측 결과표(confusion matrix)와 비즈니스 가치표(보통 고객사가 제시 또는 합의)를 곱해서 모델 기대가치를 계산 </li>
</ul>
<p>5) 회귀 모델은?</p>
<ul>
<li>예측값에 따른 후속 비즈니스 프로세스 정리</li>
<li>시뮬레이션을 돌려야 함</li>
<li>ex. 수요량 예측 문제라면 시물레이션 이후 재고 회전률 등으로 전체 계산 후 평가</li>
</ul>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/d61dbad8-f8f1-42f2-b40d-626ee0ed23e6/image.png" alt=""></p>
<p>0이라고 예측하면 거절할거임, 1이라고 예측하면 수익을 얻을 수 있음
따라서 -0.08은 1인데 0으로 예측함으로 얻을 수 있었던 수익을 못 얻는다는 가정하에 -임
0을 0으로 예측한건 그냥 모델이 잘 맞춰서 잘 피해간거니 +-0임</p>
<pre><code># 비즈니스 가치 매트릭스 정의
bv = np.array([[0,-0.18],[-0.08,0.08]])

# 모델 성적표 추출
cm1 = confusion_matrix(y_val,pred1)
cm1_p = cm1/np.sum(cm1)

# 기대가치 계산
np.sum(bv*cm1_p)*3200</code></pre><p>함수화, scoring에 넣어주기</p>
<pre><code>def biz_score(y, pred, biz_v):
    cm = confusion_matrix(y, pred)
    cm_p = cm / np.sum(cm)
    amt_mean = 3200

    return np.sum(biz_v * cm_p) * amt_mean

b_score = make_scorer(biz_score, greater_is_better= True, biz_v = bv )</code></pre><hr>
<hr>
<h3 id="3-기타">3. 기타</h3>
<p>.fit(): 전체 오차가 가장 적어지는 모델이라서 클래스 불균형이 있을 때 소수의 클래스를 잘 못 맞춰 recall이 떨어지는 현상이 발생</p>
<p>SMOTE: 보간법으로 upsamling 해줌
upsamling: 복원추출해서 upsamling 해줌</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[KT AIVLE [5주차] - 딥러닝]]></title>
            <link>https://velog.io/@k_chae1/KT-AIVLE-5%EC%A3%BC%EC%B0%A8-%EB%94%A5%EB%9F%AC%EB%8B%9D</link>
            <guid>https://velog.io/@k_chae1/KT-AIVLE-5%EC%A3%BC%EC%B0%A8-%EB%94%A5%EB%9F%AC%EB%8B%9D</guid>
            <pubDate>Mon, 27 Feb 2023 02:05:33 GMT</pubDate>
            <description><![CDATA[<p>KT의 과정은...사실 어마어마한 기대는 안 되고...
모두 다 기본은 이미 안다는 가정하에 수업을 구성하는게 좋지 않을까 하는... 그런 기분이 든다... 그리고 실습보다는 강의에 초점을 맞추는게...미니프로젝트도 과하게 많음
한 4차까지만 하고 강의로 채우는게 알찰것 같은데 KT예산문제인가?
그래도 대기업인데.... 타 교육 프로그램에 비해 상당히 대충 만든듯한 구성... </p>
<p>keras의 Sequential API랑 Functional API 연습을 중점적으로 함</p>
<hr>
<h2 id="이론-📝">이론 📝</h2>
<h3 id="딥러닝-connection-📌">딥러닝: connection 📌</h3>
<p>multi-input &amp; Concatenate layer에선 Sequential API는 불가능하다.
ex) 1234 5678 &gt; 1 2 3 4 5 6 7 8
connection layer output shape가 (None, 8)</p>
<pre><code>il_l = Input( shape=(2,) )
hl_l = Dense(2, activation=relu)(il_l)

il_w = Input( shape=(2,) )
hl_w = Dense(2, activation=relu)(il_w)

cl = Concatenate()([hl_l, hl_w])
ol = Dense(3, activation=softmax)(cl)

# 모델 시작과 끝 지정
model = Model([il_l,il_w],ol)</code></pre><p>multi-input &amp; Add layer에선 Sequential API는 불가능하다.
ex) 1234 5678 &gt; 1+5 2+6 3+7 4+8
add layer output shape가 (None, 4)</p>
<pre><code>li_se = keras.layers.Input(shape=(2,))
li_pe = keras.layers.Input(shape=(2,))

hl_se = keras.layers.Dense(4,activation=&#39;relu&#39;,name=&#39;hl_se&#39;)(li_se)
hl_pe =keras.layers.Dense(4,activation=&#39;relu&#39;,name=&#39;hl_pe&#39;)(li_pe)

add_l = keras.layers.Add()([hl_se,hl_pe])
ol = keras.layers.Dense(3,activation=&#39;softmax&#39;)(add_l)

model = keras.models.Model([li_se,li_pe],ol)

model.compile(loss=categorical_crossentropy, metrics=[&#39;accuracy&#39;],
              optimizer=Adam())</code></pre><p>from tensorflow.keras.utils import plot_model
plot_model(model, show_shapes=True)는 모델링 시각화용 코드</p>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/56e6c16c-f7f9-44fd-b13b-e31f023081dd/image.png" alt="">
엔드로피는 보조수단으로 metrics = &#39;accuracy&#39; 추가</p>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/942c8797-27ee-4a86-a19d-22d42df9cf6c/image.png" alt=""></p>
<hr>
<h2 id="실습-💻">실습 💻</h2>
<h3 id="1-sequential-api-📌">1. Sequential API 📌</h3>
<h4 id="모델-정의">모델 정의</h4>
<p>단순히 모델 정의에서 두 가지 방식이 차이가 나는 것이므로 
1번은 정의 코드만 첨부</p>
<pre><code># 세션 정리
keras.backend.clear_session()

# 모델 정의
model = keras.models.Sequential()

# 레이어 정의
model.add(keras.layers.Input(shape=(30,),))
model.add(keras.layers.Dense(1,activation=&#39;sigmoid&#39;))

# 컴파일 설정
model.compile(loss=&#39;binary_crossentropy&#39;,optimizer=&#39;adam&#39;,metrics=[&#39;accuracy&#39;])</code></pre><h3 id="2-functional-api-📌">2. Functional API 📌</h3>
<h4 id="라이브러리-불러오기">라이브러리 불러오기</h4>
<pre><code>import tensorflow as tf
from tensorflow import keras
from sklearn.model_selection import train_test_split
import numpy as np
from tensorflow.keras.callbacks import EarlyStopping</code></pre><h4 id="data-split">data split</h4>
<pre><code>x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=2023)
x_train, x_val, y_train, y_val = train_test_split(x_train,y_train,test_size=0.2,random_state=2023)</code></pre><h4 id="모델-정의-1">모델 정의</h4>
<pre><code># 1번 세션 클리어
keras.backend.clear_session()

# 2번 레이어 사슬처럼 엮기
# 동일 변수명 써도 되지만 구분 해야 될 때는 다른 변수명
il = keras.layers.Input(shape=(8,))
hl = keras.layers.Dense(128, activation=&#39;relu&#39;)(il)
hl = keras.layers.Dense(64, activation=&#39;relu&#39;)(hl)
hl = keras.layers.Dense(32, activation=&#39;relu&#39;)(hl)
ol = keras.layers.Dense(1)(hl)

# 3번 모델의 시작과 끝 지정
model = keras.models.Model(il, ol)

# 4번 컴파일
model.compile(loss=&#39;mse&#39;, optimizer=&#39;adam&#39;)

# 5번 요약
model.summary()</code></pre><h4 id="early-stopping-정의">early stopping 정의</h4>
<pre><code>es = EarlyStopping(monitor=&#39;val_loss&#39;,         # 관측 대상
                   min_delta=0,                # 관측 대상 Threshold
                   patience=7,                 
                   verbose=1,
                   restore_best_weights=True)  # 최적 epoch 시점의 가중치 설정</code></pre><h4 id="모델-학습">모델 학습</h4>
<pre><code>model.fit(x_train, y_train, epochs=1000, verbose=1,
          validation_data=(x_val,y_val), callbacks=[es])

# 굳이 validation set 분리를 안 했다면
# model.fit(x_train, y_train, epochs=1000, verbose=1,
#          validation_split=0.2, callbacks=[es])
</code></pre><h4 id="결과-예측-및-확인">결과 예측 및 확인</h4>
<pre><code>y_pred = model.predict(x_test)

y_pred[:10].reshape(-1)
y_test[:10]</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[코딩테스트 연습 Lv.1 마무리 2]]></title>
            <link>https://velog.io/@k_chae1/%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%97%B0%EC%8A%B5-Lv.1-%EB%A7%88%EB%AC%B4%EB%A6%AC-2</link>
            <guid>https://velog.io/@k_chae1/%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%97%B0%EC%8A%B5-Lv.1-%EB%A7%88%EB%AC%B4%EB%A6%AC-2</guid>
            <pubDate>Tue, 21 Feb 2023 00:19:38 GMT</pubDate>
            <description><![CDATA[<p>오늘도 힘내서...ㅠㅠ!!!
절대 안 쉬겠다했는데 어제 장렬히 쉼...
눈찜질이랑 안마기 엄청 써줬더니 그나마 낫네요....
8시간 모니터 보고 하는 수업은 피로도가 진짜 상당한...ㅠㅠ</p>
<hr>
<h2 id="lv1">Lv.1</h2>
<h3 id="옹알이2">옹알이(2)</h3>
<h4 id="틀린-코드">틀린 코드</h4>
<p>테케 55점...끙....</p>
<pre><code>def solution(babbling):
    answer = 0
    possible = [&quot;aya&quot;, &quot;ye&quot;, &quot;woo&quot;, &quot;ma&quot;]

    for i in range(len(babbling)):
        for j in possible:
            if j in babbling[i]:
                babbling[i] = babbling[i].replace(j, &#39;&#39;, 1)
        if babbling[i] == &#39;&#39;:
            answer += 1

    return answer</code></pre><h4 id="수정-코드">수정 코드</h4>
<ol>
<li><p><code>if v*2 not in i</code> 로 연속된 같은 발음이 없도록 체크해야한다.</p>
</li>
<li><p>발음을 치환할때 ‘ ‘로 하지않고 ”로 치환하면 yayae 같은 경우, aya를 치환 후 남은 문자열이 ye되어 ye도 치환되는 경우가 발생하여 오답을 야기.</p>
<pre><code>def solution(babbling):
 answer = 0
 possible = [&quot;aya&quot;, &quot;ye&quot;, &quot;woo&quot;, &quot;ma&quot;]

 for i in babbling:                  
     for v in possible:                
         if v*2 not in i:            
             i=i.replace(v,&#39; &#39;)      #&#39; &#39;으로 발음을 치환
     if i.strip()==&#39;&#39;:               #치환 완료된 문자열의 공백을 제거하고 &#39;&#39;와 같다면
         answer+=1

 return answer</code></pre></li>
</ol>
<h3 id="카카오-인턴-키패드-누르기">[카카오 인턴] 키패드 누르기</h3>
<p>맞긴 했으나...^^ 이런 노가다식 코드는...ㅎㅎㅎ;;; 
라고 생각했는데 남들 답도 비슷하네</p>
<pre><code>def solution(numbers, hand):
    answer = &#39;&#39;
    # left, right 현재 손가락 좌표 표시하는 변수
    left = (3,0)
    right = (3,2)
    # 0~9의 좌표를 미리 만들기
    dic = {1:(0,0),2:(0,1),3:(0,2),4:(1,0),5:(1,1),
           6:(1,2),7:(2,0),8:(2,1),9:(2,2),0:(3,1)}
    # 2,5,8,0 좌표에서 left,right를 각각 빼서 크기 비교
    for num in numbers:
        x,y = dic[num]
        if num in [1,4,7]:
            answer+=&#39;L&#39;
            left = (x,y) #위치 갱신
        elif num in [3,6,9]:
            answer+=&#39;R&#39;
            right = (x,y) #위치 갱신
        else:
            #sum(abs(x,y - 두손의 현 좌표 각각)) 
            xl,yl = left
            xr,yr = right
            distance_l = abs(x-xl)+abs(y-yl)
            distance_r = abs(x-xr)+abs(y-yr)
            #if min()
            #크기 동등하면 hand에 있는 쪽으로 기록
            if distance_l==distance_r:
                answer += hand[0].upper()
                if hand[0].upper()==&#39;L&#39;:
                    left = (x,y)
                else:
                    right = (x,y)
            elif min(distance_l,distance_r)==distance_l:
                answer+=&#39;L&#39;
                left = (x,y) #위치 갱신
            else:
                answer+=&quot;R&quot;
                right = (x,y) #위치 갱신

    return answer</code></pre><h3 id="크레인-인형뽑기-게임">크레인 인형뽑기 게임</h3>
<p>이거 처음에 board 형식이 감이 안 잡혀서 한참 헤맸다.
<img src="https://velog.velcdn.com/images/k_chae1/post/b82b94e8-9ebd-46d7-8903-0851b09cd484/image.png" alt="">
이런 식으로 생각해야 풀리는 문제;</p>
<pre><code>def solution(board, moves):
    answer = 0
    result = []
    for idx in moves:
        idx -= 1
        for row in range(len(board)):
            if board[row][idx] != 0 :
                result.append(board[row][idx])
                if len(result)&gt;=2 and result[-1]==result[-2]:
                    result.pop()
                    result.pop()
                    answer += 2
                board[row][idx] = 0
                break                 

    return answer</code></pre><h3 id="신규-아이디-추천">신규 아이디 추천</h3>
<p>정규표현식이랑 strip 둘 다 써봄</p>
<pre><code>import re

def solution(new_id):
    answer = &#39;&#39;

    new_id = new_id.lower()
    new_id = re.sub(r&quot;[^a-z0-9\-_.]&quot;, &quot;&quot;, new_id)
    new_id = re.sub(&#39;\.+&#39;, &#39;.&#39;, new_id)    
    new_id = new_id.strip(&#39;.&#39;)
    new_id = &#39;a&#39; if len(new_id) == 0 else new_id[:15]
    new_id = re.sub(&#39;^[.]|[.]$&#39;, &#39;&#39;, new_id)
    if len(new_id) &lt;= 2: 
        answer += (3-len(new_id))*new_id[-1]

    return new_id+answer</code></pre><p>마지막 부분을 한줄코딩으로 더 이쁘게 하셨다.</p>
<pre><code>import re

def solution(new_id):
    st = new_id
    st = st.lower()
    st = re.sub(&#39;[^a-z0-9\-_.]&#39;, &#39;&#39;, st)
    st = re.sub(&#39;\.+&#39;, &#39;.&#39;, st)
    st = re.sub(&#39;^[.]|[.]$&#39;, &#39;&#39;, st)
    st = &#39;a&#39; if len(st) == 0 else st[:15]
    st = re.sub(&#39;^[.]|[.]$&#39;, &#39;&#39;, st)
    st = st if len(st) &gt; 2 else st + &quot;&quot;.join([st[-1] for i in range(3-len(st))])
    return st</code></pre><h3 id="문자열-나누기">문자열 나누기</h3>
<pre><code>from collections import deque

def solution(s):
    ans = 0
    q = deque(s)    

    while q:
        a, b = 1, 0
        x = q.popleft()    
        while q:
            n = q.popleft()
            if n == x:
                a += 1
            else:
                b += 1

            if a == b:
                ans += 1
                break
    if a != b:
        ans += 1

    return ans</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[KT AIVLE [4주차] - 머신러닝]]></title>
            <link>https://velog.io/@k_chae1/KT-AIVLE-4%EC%A3%BC%EC%B0%A8-%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D</link>
            <guid>https://velog.io/@k_chae1/KT-AIVLE-4%EC%A3%BC%EC%B0%A8-%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D</guid>
            <pubDate>Mon, 20 Feb 2023 03:29:26 GMT</pubDate>
            <description><![CDATA[<h2 id="이론-📝">이론 📝</h2>
<h3 id="00-전처리">00. 전처리</h3>
<h4 id="01-불필요한-변수-제거">01. 불필요한 변수 제거</h4>
<p>df.drop(drop_cols, axis=1, inplace=True)
default는 axis=0 </p>
<h4 id="02-nan-조치-제거-or-채우기">02. NaN 조치 (제거 or 채우기)</h4>
<p>titanic.isna().sum() / len(titanic)*100
전체 데이터에서 결측치의 비율을 확인 후 시작!</p>
<ul>
<li>모든 행 제거, 일부 행 제거, 변수 제거</li>
<li>평균값 채우기, 최빈값 채우기, 앞/뒤값 채우기, 선형보간법</li>
</ul>
<h4 id="03-가변수화">03. 가변수화</h4>
<p>범주형 값을 갖는 변수에 대한 One-Hot Encoding (get_dummies)
다중공선성 문제를 없애기 위해 drop_first=True 옵션 지정</p>
<h3 id="01-용어">01. 용어</h3>
<ul>
<li>모델: 데이터로부터 패턴을 찾아 수학식으로 정리해 놓은 것</li>
<li>모델링(Modeling): 오차가 적은 모델을 만드는 과정</li>
<li>평균보다는 좋은 모델을 만들어야함 (=평균보다 오차가 적다.)</li>
<li>모델 목적: 샘플을 가지고 전체를 추정</li>
</ul>
<h3 id="02-scikit-learn-모델링-구조">02. scikit-learn 모델링 구조</h3>
<ol>
<li>라이브러리 iimport</li>
<li>사용한 알고리즘을 모델로 선언</li>
<li>학습 (model.fit(x_train,y_train))</li>
</ol>
<ul>
<li>데이터 분리 시</li>
<li>x = data.drop(target,axis=1)
y = data.loc[:,target]</li>
</ul>
<ol start="4">
<li>예측 (model.predict(x_test))</li>
<li>평가 (예측 값과 실제 값 비교)</li>
</ol>
<h3 id="03-회귀-모델-평가-지표">03. 회귀 모델 평가 지표</h3>
<blockquote>
<ol>
<li>오차 합: 모든 오차의 합을 더함, but 합이 0이 되는 경우가 생겨서 못씀</li>
<li>오차 제곱의 합: $\displaystyle\sum(y-\hat y)^2  = SSE$</li>
<li>오차 절대값의 합: $\displaystyle\sum\frac{|(y-\hat y|}{n}  = MAE$</li>
</ol>
</blockquote>
<ul>
<li>실제값은 y, 예측값은 hat-y</li>
</ul>
<blockquote>
<ul>
<li>SSE(그냥 합), MSE(Mean Sum Squared Error, 합의 평균), RMSE (MSE에 Root)를 사용</li>
</ul>
</blockquote>
<ul>
<li>고객에게 얘기할만한건 RMSE뿐</li>
<li>MAE(Mean Absolute Error), MAPE(퍼센트,n으로 나누기 전에 y로 먼저 나눔)</li>
</ul>
<blockquote>
<ul>
<li>STT: 전체 오차 (=허용된 전체 오차 범위,STT=SSE+SSR)
$\displaystyle\sum(실제값 - 평균값)^2  = SST$</li>
</ul>
</blockquote>
<ul>
<li>SSR: 전체 오차 중 회귀식이 잡아낸 오차 (예측값-평균값)</li>
<li>SSE: 전체 오차 중 회귀식이 잡아내지 못한 오타 (실제값-예측값)</li>
</ul>
<p>SSE가 0이면 제일 좋고 SSR == SST면 제일 좋음
<img src="https://velog.velcdn.com/images/k_chae1/post/8ad7b7ce-116a-4ab6-9d32-48fcfbaf61a8/image.png" alt=""></p>
<blockquote>
<ul>
<li>결정 계수 R-Squared
$\displaystyle\ R^2  = \frac{SSR}{SST} (=1-\frac{SSE}{SST})$</li>
</ul>
</blockquote>
<p>여기서 R은 Regression
가장 큰 값은 1 (클 수록 좋음)
우리 모델이 얼마나 설명을 잘 했는지 알려줌</p>
<h3 id="04-분류-모델-평가-지표">04. 분류 모델 평가 지표</h3>
<h4 id="혼동-행렬-confusion-matrix">혼동 행렬 (Confusion Matrix)</h4>
<ol>
<li>정확도(Accuracy): 0,1을 정확히 예측한 비율 (맞춘 갯수/전체 갯수)</li>
<li>정밀도(Precision): 예측한 것 중 진짜 0,1의 갯수/예측한 0,1의 전체 갯수</li>
<li>재현율(Recall,민감도): 그중 예측한 0,1의 갯수/진짜 0,1의 갯수</li>
<li>특이도(Specificity): 실제 N비율(TN+FP) 중 N으로 예측한 비율(TN)</li>
<li>F1-Score: 정밀도와 재현율의 조화평균, 분자가 같지만 분모가 다를 경우 사용 (정밀도와 재현율 적절히 요구 될 때 사용)</li>
</ol>
<p>cassification_report 사용하면 다 보임 </p>
<h3 id="05-learning_curve">05. learning_curve</h3>
<p>데이터의 양이 어느정도 필요하고 성능이 어느정도 나오는지 확인하는 그래프</p>
<pre><code># 모듈 둘러오기
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import learning_curve

# 모셀선언
model = DecisionTreeClassifier(max_depth=3)

# Learning Curve 수행
tr_size, tr_scores, val_scores = learning_curve(model, 
                                                x, 
                                                y,
                                                train_sizes=range(10, 7900, 20),
                                                shuffle=True,
                                                cv=5)</code></pre><pre><code># CV 결과 --&gt; 평균
val_scores_3_mean = val_scores.mean(axis=1)

# 시각화
plt.figure(figsize=(8, 5))
plt.plot(tr_size, val_scores_3_mean)
plt.title(&#39;Learning Curve&#39;, size=20, pad=15)
plt.ylabel(&#39;Score&#39;)
plt.xlabel(&#39;Training Size&#39;)
plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/k_chae1/post/dd7cf2d3-8d50-4fb1-a747-709bd1ea392c/image.png" alt=""></p>
<h3 id="06-다중공선성-확인">06. 다중공선성 확인</h3>
<p>다른 변수가 또 다른 변수를 얼마나 설명하는지 확인</p>
<ol>
<li>원본 데이터 대상으로 VIF 확인 : $$VIF_i=\frac{1}{1-R_i^2}$$<pre><code># 모듈 불러오기
from statsmodels.stats.outliers_influence import variance_inflation_factor
</code></pre></li>
</ol>
<h1 id="빈-데이터프레임-만들기">빈 데이터프레임 만들기</h1>
<p>vif = pd.DataFrame()</p>
<h1 id="vif-확인-및-기록">VIF 확인 및 기록</h1>
<p>vif[&#39;feature&#39;] = x.columns 
vif[&#39;vif_factor&#39;] = [variance_inflation_factor(x.values, i) for i in range(x.shape[1])]</p>
<h1 id="vif-기준으로-정렬렬">VIF 기준으로 정렬렬</h1>
<p>vif.sort_values(by=&#39;vif_factor&#39;, ascending=False, inplace=True)
vif.reset_index(drop=True, inplace=True)</p>
<h1 id="확인">확인</h1>
<p>vif</p>
<pre><code>
2. 데이터를 표준화하고 확인

### 07. Regularization (규제)
선형회귀는 x값이 많을수록 과한 복잡성이 생김 &gt; 성능 down
ridge, rasso 등으로 해결할 가능성이 있다.

1.Ridge 
- Ridge 알고리즘을 사용하면 변수들의 가중치 크기를 제어
- 전체적으로 가중치의 크기를 줄여줌
- but 특정 변수의 가중치를 0으로 바꾸지는 않음</code></pre><h1 id="모델링ridge-cv">모델링(Ridge CV)</h1>
<p>from sklearn.linear_model import RidgeCV</p>
<p>alpha = np.linspace(0.1, 30, 20)
model = RidgeCV(alphas=alpha, cv=5)
model.fit(x_train, y_train)</p>
<h1 id="성능-확인">성능 확인</h1>
<p>print(&#39;학습성능:&#39;, model.score(x_train, y_train))
print(&#39;평가성능:&#39;, model.score(x_test, y_test))
print(&#39;-&#39; * 28)
print(&#39;alpha:&#39;, model.alpha_)</p>
<pre><code>

2. Lasso
- 필요없는 변수의 가중치는 0
- 불필요한 변수 제거 가능</code></pre><h1 id="모델링lassocv">모델링(LassoCV)</h1>
<p>from sklearn.linear_model import LassoCV</p>
<p>alpha = np.linspace(0.1, 10, 50)
model = LassoCV(alphas=alpha, cv=5, random_state=1)
model.fit(x_train, y_train)</p>
<h1 id="성능-확인-1">성능 확인</h1>
<p>print(&#39;학습성능:&#39;, model.score(x_train, y_train))
print(&#39;평가성능:&#39;, model.score(x_test, y_test))
print(&#39;-&#39; * 28)
print(&#39;alpha:&#39;, model.alpha_)</p>
<pre><code>
3. ElasticNet
- 릿지랑 라쏘를 다 씀</code></pre><h1 id="모델링elasticnetcv">모델링(ElasticNetCV)</h1>
<p>from sklearn.linear_model import ElasticNetCV</p>
<p>l1 = np.linspace(0.1, 1, 10)<br>alpha = np.linspace(0.1, 10, 50)
model = ElasticNetCV(l1_ratio=l1, alphas=alpha, cv=5, random_state=1)
model.fit(x_train, y_train)</p>
<h1 id="성능-확인-2">성능 확인</h1>
<p>print(&#39;학습성능:&#39;, model.score(x_train, y_train))
print(&#39;평가성능:&#39;, model.score(x_test, y_test))
print(&#39;-&#39; * 28)
print(&#39;l1_ratio:&#39;, model.l1_ratio_)
print(&#39;alpha:&#39;, model.alpha_)</p>
<pre><code>### 08. 거리 구하기
별에서 원까지 거리 구할 때의 두 가지 방식
![](https://velog.velcdn.com/images/k_chae1/post/21bbeead-4fcf-47d8-a489-eabda7abec57/image.png)

* 맨하튼 거리는 유클리드 거리보다 항상 크거나 같다.

### 09. 정규화
![](https://velog.velcdn.com/images/k_chae1/post/65976c85-b423-4e65-bbdb-29a3fda405f2/image.png)

### 10. 불순도
- 결정트리
(부모 불순도 - 자녀 불순도)가 클 수록 좋다.
부모 노드 --&gt; 자식 노드로의 분기가 되는데 정보이득이 큰 분기를 찾음
정보 이득이 크다 == 속성으로 분할 시 불순도가 작아짐
== 정보 이득이 가장 큰 속성부터 분할


밑은 변수 중요도 시각화 코드</code></pre><p>plt.figure(figsize=(5, 5))
plt.barh(list(x), model.feature_importances_)
plt.show()</p>
<pre><code>
밑은 중요도를 정렬해서 시각화</code></pre><h1 id="데이터프레임-만들기">데이터프레임 만들기</h1>
<p>perf_dic = {&#39;feature&#39;:list(x), &#39;importance&#39;: model.feature_importances_}
df = pd.DataFrame(perf_dic)
df.sort_values(by=&#39;importance&#39;, ascending=True, inplace=True)</p>
<h1 id="시각화">시각화</h1>
<p>plt.figure(figsize=(5, 5))
plt.barh(df[&#39;feature&#39;], df[&#39;importance&#39;])
plt.show()</p>
<pre><code>### 11. 앙상블

1. 보팅 (Voting)
같은 데이터셋 서로 다른 알고리즘의 예측값을 가지고 투표
- 하드 보팅 
서로 다른 알고리즘을 돌려 예측값을 투표, 단순히 많이 나온 것을 결과로
- 소프트 보팅
서로 다른 알고리즘을 돌려 예측값을 **확률**로 투표

2. 배깅 (Bagging)
다르게 샘플링(복원추출)된 데이터셋과 **같은** 알고리즘을 사용
범주형은 voting, 연속형은 평균으로 결과 집계 (aggregating)
ex) 랜덤 포레스트 

3. 부스팅 (Boosting)
오류를 예측하는 모델을 만들어서 반영 (gradient boost)
어디에서 멈출지 파라미터 튜닝해야함

4. 스태킹 (Stacking)
raw데이터를 가지고 모델들이 예측한 값을 input으로 받는 최종 모델을 만들어 결과를 예측</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[KT AIVLE [3주차] - 웹 크롤링 2]]></title>
            <link>https://velog.io/@k_chae1/KT-AIVLE-3%EC%A3%BC%EC%B0%A8-%EC%9B%B9-%ED%81%AC%EB%A1%A4%EB%A7%81-2</link>
            <guid>https://velog.io/@k_chae1/KT-AIVLE-3%EC%A3%BC%EC%B0%A8-%EC%9B%B9-%ED%81%AC%EB%A1%A4%EB%A7%81-2</guid>
            <pubDate>Fri, 17 Feb 2023 05:04:57 GMT</pubDate>
            <description><![CDATA[<h2 id="이론-📝">이론 📝</h2>
<ul>
<li><p>동적 페이지: URL 변화 없이 페이지의 데이터 수정 : json(str) &gt; reponse.json() &gt; DataFrame</p>
</li>
<li><p>정적 페이지: URL 변화 있이 페이지의 데이터 수정: html(str) &gt; BeautifulSoup &gt; css selector &gt; DataFrame </p>
</li>
<li><p>셀레니움: 웹 브라우저를 파이썬 코드로 컨트롤해서 데이터 수집</p>
</li>
</ul>
<ul>
<li>웹 크롤링 절차</li>
<li><ol>
<li>웹 서비스 분석 (개발자 도구,API 문서) : URL 찾기</li>
</ol>
</li>
<li><ol start="2">
<li>request(URL) &gt; response(data) : data(json(str),html(str))</li>
</ol>
</li>
<li><ol start="3">
<li>파싱 (response.json(), BeautifulSoup(css-selector))</li>
</ol>
</li>
</ul>
<hr>
<h2 id="실습-💻">실습 💻</h2>
<h3 id="1-복잡한-웹-페이지-크롤링-json-📌">1. 복잡한 웹 페이지 크롤링 (json) 📌</h3>
<h4 id="직방-웹페이지-크롤링">직방 웹페이지 크롤링</h4>
<ol>
<li>search로 시작하는 URL 따서 위도,경도 구하기
<img src="https://velog.velcdn.com/images/k_chae1/post/9cde014f-ba4c-4f31-898f-c24086511359/image.png" alt=""><pre><code>address = &#39;부원동&#39;
url = f&#39;https://apis.zigbang.com/v2/search?leaseYn=N&amp;q={address}&amp;serviceType=원룸&#39;
</code></pre></li>
</ol>
<p>response = requests.get(url)
data = response.json()[&#39;items&#39;][0]
lat,lng = data[&#39;lat&#39;],data[&#39;lng&#39;]</p>
<pre><code>
2. 위도, 경도로 geohash 알아내기</code></pre><p>import geohash2</p>
<h1 id="precision--숫자-클수록-영역이-작아짐">precision : 숫자 클수록 영역이 작아짐</h1>
<p>geohash = geohash2.encode(lat,lng,precision=5)
geohash</p>
<pre><code>
3. geohash로 매물 아이디 가져오기 (item으로 시작하는 URL)
![](https://velog.velcdn.com/images/k_chae1/post/9cde014f-ba4c-4f31-898f-c24086511359/image.png)</code></pre><p>url = f&#39;<a href="https://apis.zigbang.com/v2/items?deposit_gteq=0&amp;domain=zigbang&amp;geohash=%7Bgeohash%7D&amp;needHasNoFiltered=true&amp;%5C">https://apis.zigbang.com/v2/items?deposit_gteq=0&amp;domain=zigbang&amp;geohash={geohash}&amp;needHasNoFiltered=true&amp;\</a>
rent_gteq=0&amp;sales_type_in=전세|월세&amp;service_type_eq=원룸&#39;</p>
<p>response = requests.get(url)</p>
<p>data = response.json()[&#39;items&#39;]
ids = [item[&#39;item_id&#39;] for item in data]</p>
<pre><code>
4. 매물 아이디로 매물 정보 가져오기

![](https://velog.velcdn.com/images/k_chae1/post/4937a069-3ffa-4955-8cc5-44f089e19da9/image.png)
post 방식인거 확인, url 확인

![](https://velog.velcdn.com/images/k_chae1/post/3650b632-2a02-44ad-ac4f-90f22fa00ca7/image.png)
payload에서 params 항목 알아보기</code></pre><p>url = &#39;<a href="https://apis.zigbang.com/v2/items/list&#39;">https://apis.zigbang.com/v2/items/list&#39;</a></p>
<p>params = {
    &#39;domain&#39;: &#39;zigbang&#39;,
    &#39;withCoalition&#39;:&#39;true&#39;,
    &#39;item_ids&#39;: ids, #위에서 만든거!
}</p>
<p>response = requests.post(url,params)
data = response.json()[&#39;items&#39;]
df = pd.DataFrame(data)</p>
<pre><code>

---------------

### 2. html 📌
#### [html 구성 요소]
&gt; - Document : 한페이지를 나타내는 단위
- Element : 하나의 레이아웃을 나타내는 단위 : 시작태그, 끝태그, 텍스트로 구성
- Tag : 엘리먼트의 종류를 정의 : 시작태그(속성값), 끝태그
- Attribute : 시작태그에서 태그의 특정 기능을 하는 값
    - id : 웹 페이지에서 유일한 값
    - class : 동일한 여러개의 값 사용 가능 : element를 그룹핑 할때 사용
    - attr : id와 class를 제외한 나머지 속성들s
- Text : 시작태그와 끝태그 사이에 있는 문자열
- 엘리먼트는 서로 계층적 구조를 가질수 있습니다.
- 엘리먼트는 선택하는게 css-selector

**[웹 페이지 구성 요소]**
레이아웃 및 문자열 구성 : html
이벤트 발생 시 대처 : 자바스크립트
화면 스타일 구성 : css


![](https://velog.velcdn.com/images/k_chae1/post/e35ef0a5-f07f-46cf-9680-32c39c87e4f8/image.png)
기본적으로 id와 class를 이용해서 요소를 선택

![](https://velog.velcdn.com/images/k_chae1/post/2236ea34-26c1-49fa-aa40-7070e0c398a1/image.png)
엘리먼트 안에 엘리멘트가 들어가서 총 엘리먼트가 3개인 모습

![](https://velog.velcdn.com/images/k_chae1/post/7b8f0d78-d95d-4b1a-9179-e180cf14adbf/image.png)
#아이디 값을 이용해서 조정 (css-selector 작성)

![](https://velog.velcdn.com/images/k_chae1/post/27409136-3b8b-445c-b2de-48b9ee786f22/image.png)
.클래스 값을 이용해서 조정 (css-selector 작성)


![](https://velog.velcdn.com/images/k_chae1/post/51ebc925-8264-49db-ad52-d15a8c095818/image.png)
특정 엘리먼트 제외


![](https://velog.velcdn.com/images/k_chae1/post/b287ed45-23a0-4900-bdeb-c7aafa44e29e/image.png)
단계 상관없이 밑에 있는 거 다 됨 (바로 밑만 하려면 .contains &gt; h1)


&gt; css selctor
&gt;
tag(div) , id(#div), class(.div), attr([name=&#39;div&#39;])
&gt;
여러개의 엘리먼트 선택: .div1, .div2
특정 엘리먼트 제외: .div:not(.div1)
n번째 엘리먼트 선택: .div nth-child(n)

-----------------------------------------------------

### 3. 정적 페이지 크롤링 (html) 📌

#### 1) 웹 페이지 분석 : URL

![](https://velog.velcdn.com/images/k_chae1/post/1217dc76-e9de-4f95-ad91-9e6858c2c5f8/image.png)
여기에 우리가 찾으려는 정보가 있는지 ctrl+F로 미리 확인
있으면 URL 사용

#### 2) 엘리먼트 확인
![](https://velog.velcdn.com/images/k_chae1/post/b8e3a4f7-fc4c-41b0-a9ec-a099b68087ff/image.png)
우클릭 &gt; copy &gt; copy selector
100%는 아니고 적당한 틀을 만들어준다.
#nx_right_related_keywords &gt; div &gt; div.related_srch &gt; ul &gt; li

![](https://velog.velcdn.com/images/k_chae1/post/0f6260b2-90e2-4100-8241-3558d1f96080/image.png)


#### 3) 코드
</code></pre><p>query = &#39;삼성전자&#39;
url = f&#39;<a href="https://search.naver.com/search.naver?query=%7Bquery%7D&#39;">https://search.naver.com/search.naver?query={query}&#39;</a>
respone = requests.get(url)
dom = BeautifulSoup(respone.text,&#39;html.parser&#39;)
elements = dom.select(&#39;#nx_right_related_keywords &gt; div &gt; div.related_srch &gt; ul &gt; li&#39;)
keywords = [element.select_one(&#39;.tit&#39;).text for element in elements]</p>
<p>df = pd.DataFrame({&#39;keyword&#39;:keywords})
df[&#39;query&#39;] = query</p>
<pre><code>
---------------------------------------------------

### 4. 어려운 정적 페이지 크롤링 (html) 📌

![](https://velog.velcdn.com/images/k_chae1/post/e776ae61-1891-4d52-9733-28f0f4cf0e89/image.png)

가져올 데이터가 여러 종류라서 dict 형태로 만든다.
elements[0]해서 확인
![](https://velog.velcdn.com/images/k_chae1/post/856be507-08ae-438e-80f0-7d70fd265891/image.png)</code></pre><p>data = {
    &#39;title&#39; : element.select_one(&#39;.itemname&#39;).text,
    &#39;link&#39; : element.select_one(&#39;.itemname&#39;).get(&#39;href&#39;),
    &#39;img&#39; : &#39;http:&#39;+ element.select_one(&#39;img&#39;).get(&#39;data-original&#39;),
    &#39;o_price&#39; : element.select_one(&#39;.o-price&#39;).text,
    &#39;s_price&#39; : element.select_one(&#39;.s-price&#39;).text.strip().split(&#39;\n&#39;)[0],
}</p>
<pre><code>

데이터 프레임으로 만들기
![](https://velog.velcdn.com/images/k_chae1/post/b71d120e-8eae-42b8-8f85-1f8ae90aa7eb/image.png)



### 📎 .iterrows()
&gt;![](https://velog.velcdn.com/images/k_chae1/post/59445366-73b2-4293-aadc-eb0f63577be1/image.png)
&gt;
튜플 형태로 인덱스와 아이템을 반환</code></pre><p>for idx, data in df[:5].iterrows():
    name = &#39;0&#39;*(2-len(str(idx)))+str(idx)
    name = f&#39;data/{idx}.png&#39;
    print(idx,data[&#39;img&#39;],name)
    reponse = requests.get(img_link)
    with open(name,&#39;wb&#39;) as file:
        file.write(reponse.content)</p>
<blockquote>
<p> from PIL import Image as pil
 pil.open(&#39;./data/0.png&#39;)</p>
</blockquote>
<pre><code>
---------------------------------------------------------

### 5. 셀레니움 📌

1. 셀레니움 설치 (conda install 등..)
2. chromedriver를 본인 버전에 맞게 설치 
(정석적으로 하면 환경변수 설정이 필요하나 간편하게 그냥 같은 dir에 넣는걸로 해결)

3. import하고 객체 만들기</code></pre><p>import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.by import By</p>
<p>driver = webdriver.Chrome() #새로운 크롬창이 뜬다.
driver.get(&#39;<a href="https://daum.net&#39;">https://daum.net&#39;</a>) #페이지 이동</p>
<pre><code>
4. selector 찾기
![](https://velog.velcdn.com/images/k_chae1/post/75699a75-277f-4577-bf20-2846be7c6433/image.png)</code></pre><p>driver.find_element(By.CSS_SELECTOR,&#39;#q&#39;).send_keys(&#39;파이썬&#39;) #검색어 입력</p>
<p>selector = &#39;.inner_search &gt; .ico_pctop.btn_search&#39;
driver.find_element(By.CSS_SELECTOR,selector).click() #클릭 이벤트 </p>
<p>selector = &#39;#netizen_lists_top &gt; .wsn&#39;
elements = driver.find_elements(By.CSS_SELECTOR,selector) #연관검색어 클래스 찾아서 수집</p>
<p>keywords = [element.text for element in elements]</p>
<h1 id="driverfind_elementbycss_selector-selectortext">driver.find_element(By.CSS_SELECTOR, selector).text</h1>
<h1 id="위는-텍스트-데이터-수집">위는 텍스트 데이터 수집</h1>
<pre><code>
#### + 자바스크립트 코드 실행, 브라우저 종료
</code></pre><p>driver.execute_script(&#39;window.scrollTo(200, 300);&#39;)
driver.quit()</p>
<pre><code>

---------------------

### 6. Xpath 📌
💡 scrapy는 Xpath를 사용하며 현업에서 쓴다.


&gt; xpath 이용한 엘리먼트 선택
&gt;
//*[@id=&quot;shoji&quot;]/div[2]/div/div[2]/header/div/div[1]
// : 최상위 엘리먼트
*(별표) : 모든 하위 엘리먼트
&gt;
[@id=&quot;shoji&quot;] : 속성값으로 엘리먼트 선택
/ :한단계 하위 엘리먼트
div[2] : 태그[n번째]

</code></pre><p>selector = &#39;//*[@id=&quot;shoji&quot;]/div[2]/div/div[2]/header/div/div[1]&#39; 
driver.find_element(By.XPATH, selector).text</p>
<pre><code>


-----------------------

### 7.Headless 📌

- 브라우져를 화면에 띄우지 않고 메모리상에서만 올려서 크롤링하는 방법 
- window가 지원되지 않는 환경에서 사용이 가능
- chrome version 60.0.0.0 이상부터 지원 합니다.
</code></pre><p>op = webdriver.ChromeOptions()
op.add_argument(&#39;headless&#39;)
driver = webdriver.Chrome(options=op) 
driver.get(&#39;<a href="https://www.ted.com/talks&#39;">https://www.ted.com/talks&#39;</a>)
selector = &#39;.talks-header__title&#39; 
driver.find_element(By.CSS_SELECTOR, selector).text</p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[KT AIVLE [3주차] - 웹 크롤링]]></title>
            <link>https://velog.io/@k_chae1/KT-AIVLE-3%EC%A3%BC%EC%B0%A8-%EC%9B%B9-%ED%81%AC%EB%A1%A4%EB%A7%81</link>
            <guid>https://velog.io/@k_chae1/KT-AIVLE-3%EC%A3%BC%EC%B0%A8-%EC%9B%B9-%ED%81%AC%EB%A1%A4%EB%A7%81</guid>
            <pubDate>Thu, 16 Feb 2023 05:35:53 GMT</pubDate>
            <description><![CDATA[<h2 id="이론-📝">이론 📝</h2>
<h3 id="1-url-📌">1. URL 📌</h3>
<p>DNS : 도메인 &gt; IP
Protocol : 클라이언트와 서버 사이의 인터넷 통신 규약
Port : IP주소를 알면 서버 컴퓨터까진 도착, 서비스하는 프로그램을 정확히 찾기 위함
Path : 컴퓨터는 기본적으로 파일 시스템이 있음. 어떤 디렉토리로 들어갈지 결정
fragment : 특정 위치의 화면에 이동, 패킷을 보내는데, 네트워크망안에서 보낼 수 있는 사이즈가 제한이 걸린다면 이를 잘라서 보내게 되는데, 잘려진 패킷조각</p>
<h3 id="2-데이터-요청-방식-📌">2. 데이터 요청 방식 📌</h3>
<ul>
<li>Get: url에 데이터가 포함 (데이터 노출), 길이 제한 있음</li>
<li>Post: body에 데이터가 포함 </li>
</ul>
<p>01010101 전기적 신호를 케이블을 통해 공유기를 거쳐 사설망(kt)에서 백본망(한전)으로 감 &gt; 해저케이블을 따라 외국으로 .. (무선 인터넷은 케이블 대신 주파수를 매체로 사용)</p>
<h3 id="3-cookie-session-cache-📌">3. Cookie, Session, Cache 📌</h3>
<ul>
<li>쿠기: 하드디스트에 저장되는 데이터</li>
<li>세션: 연결 정보</li>
<li>캐시: Client나 Server의 메모리에 저장하여 빠르게 데이터를 가져오는 목적의 저장소</li>
</ul>
<p>클라이언트는 브라우저(프론트엔드) 서버는 WAS+DB(백엔드)</p>
<h3 id="4-웹-크롤링-📌">4. 웹 크롤링 📌</h3>
<p>1) url 필요 (어떻게 알아내지?)
2) request (데이터 요청)
3) 받아진 데이터를 원하는 모양으로 파싱</p>
<hr>
<h2 id="실습-💻">실습 💻</h2>
<ul>
<li><p>requests 이용
받아오는 문자열에 따라 두가지 방법으로 구분</p>
<ul>
<li>json 문자열로 받아서 파싱하는 방법 : 주로 동적 페이지 크롤링할때 사용</li>
<li>html 문자열로 받아서 파싱하는 방법 : 주로 정적 페이지 크롤링할때 사용</li>
</ul>
</li>
<li><p>selenium 이용
브라우져를 직접 열어서 데이터를 받는 방법</p>
</li>
</ul>
<h3 id="1-동적-페이지--request---json-📌">1. 동적 페이지 : request - json 📌</h3>
<p>모바일 페이지로 여는 방법 (pc가 복잡할 경우) - F12 개발자 도구
<img src="https://velog.velcdn.com/images/k_chae1/post/319eb5ad-529d-4932-8930-9408a9474828/image.png" alt=""></p>
<p>트래픽 확인
<img src="https://velog.velcdn.com/images/k_chae1/post/10afa2dc-b605-4a38-baa1-567765d271d4/image.png" alt=""></p>
<p>url 확인
<img src="https://velog.velcdn.com/images/k_chae1/post/95df7024-f350-4b25-8aaa-265aadc8b3b9/image.png" alt=""></p>
<p>정상 확인
<img src="https://velog.velcdn.com/images/k_chae1/post/e3a09e10-c9ee-48e2-8c52-ef7c8a10a815/image.png" alt=""></p>
<p>문자열 형태 변경 (list,dict)
<img src="https://velog.velcdn.com/images/k_chae1/post/361ef1d1-0e60-4133-a7a7-9cc397acea24/image.png" alt=""></p>
<p>데이터 프레임으로 만들기
<img src="https://velog.velcdn.com/images/k_chae1/post/ad6ce0d0-de76-403f-94f7-5477c120d493/image.png" alt=""></p>
<p>함수화</p>
<pre><code>def stock_price(code, page, page_size):
    &#39;&#39;&#39; 이 함수는 주식 가격을 네이버에서 크롤링하는 함수입니다.
    params:
        code: str : KOSPI, KOSDAQ
        page : int
        page_size : int
    return:
        type : DataFrame
    &#39;&#39;&#39;
    # 1. URL
    url = f&#39;https://m.stock.naver.com/api/index/{code}/price?pageSize={page_size}&amp;page={page}&#39;
    # 2. reuest(URL) &gt; reponse: json(Str)
    response = requests.get(url)
    # 3. json(str) &gt; list,dict &gt; DataFrame
    data = response.json()
    return pd.DataFrame(data)[[&#39;localTradedAt&#39;,&#39;closePrice&#39;]]</code></pre><p>📎 얕은 복사, 깊은 복사
<img src="https://velog.velcdn.com/images/k_chae1/post/c79cda53-dbdf-43bc-aa77-25501cbd5033/image.png" alt=""></p>
<blockquote>
<p>파이썬과 판다스의 깊은 복사가 다른가?</p>
</blockquote>
<p>파이썬 copy() 메소드는 리스트가 오브젝트를 포함할 경우 그 오브젝트들은 얕은복사가 된다. deepcopy()는 무조건 깊은 복사</p>
<blockquote>
</blockquote>
<p>판다스 df.copy(deep=True)가 있다.</p>
<h3 id="2-서버에서-어뷰징을-막은-경우-해결-방법-📌">2. 서버에서 어뷰징을 막은 경우 해결 방법 📌</h3>
<p>이런 경우....
<img src="https://velog.velcdn.com/images/k_chae1/post/c74fd9f4-4581-44c7-8096-77250f536ee3/image.png" alt=""></p>
<p>유저 에이전트 (+레퍼러)를 추가해서 요청한다!
<img src="https://velog.velcdn.com/images/k_chae1/post/aa05933a-65fa-44b0-aef3-e42de6da4f42/image.png" alt=""></p>
<h4 id="💡-크롤링-정책">💡 크롤링 정책</h4>
<blockquote>
<p>/robots.txt를 url 뒤에 붙여서 확인해봄
웹 페이지의 크롤링 정책을 설명한 페이지임</p>
</blockquote>
<p>과도한 크롤링으로 서비스에 영향을 주었을 경우 업무방해 혐의</p>
<blockquote>
</blockquote>
<p>법적문제: 지적재산권, 서비스 과부화, 데이터 사용 표준</p>
<blockquote>
</blockquote>
<p>API: 업체에서 데이터를 가져갈 수 있도록 하는 서비스</p>
<h3 id="3-api-📌">3. API 📌</h3>
<p>클라이언트의 app 등록 &gt; 서버의 key 값 전달 &gt; URL 확인 (서비스의 document에 있음) &gt; req(key 포함) - resp 함 </p>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/9639942e-7891-4256-95ce-278434ff69cd/image.png" alt="">
위 가이드에 따라 밑처럼 준비 + get인지 post인지 가이드 잘 보기
<img src="https://velog.velcdn.com/images/k_chae1/post/98e744b9-f9e7-41ab-9201-3ddfde764b3e/image.png" alt=""></p>
<p>POST 형식이라서 .post
json.dumps() &lt; 한글이라 인코딩을 해서 데이터 요청
<img src="https://velog.velcdn.com/images/k_chae1/post/4c381796-abfa-4cd1-9bf5-78c800a54377/image.png" alt=""></p>
<p>결과
<img src="https://velog.velcdn.com/images/k_chae1/post/00ee0ad6-d94f-4ce0-a4a9-4f31b4711d2d/image.png" alt=""></p>
<p>함수화</p>
<pre><code>def translate(txt, source=&#39;ko&#39;, target=&#39;en&#39;): 
    Client_ID, Client_Secret = &#39;니 ID&#39;, &#39;니 Key&#39;
    url = &#39;https://openapi.naver.com/v1/papago/n2mt&#39; 

    headers = { &#39;Content-Type&#39;: &#39;application/json&#39;, 
               &#39;X-Naver-Client-Id&#39;: Client_ID, 
               &#39;X-Naver-Client-Secret&#39;: Client_Secret, } 
    params = {&#39;source&#39;: source, &#39;target&#39;: target, &#39;text&#39;: txt} 

    response = requests.post(url, json.dumps(params), headers=headers) 

    return response.json()[&#39;message&#39;][&#39;result&#39;][&#39;translatedText&#39;]</code></pre><h4 id="💡-whos--현재-선언-변수-목록">💡 %whos : 현재 선언 변수 목록</h4>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/5b5fb726-adcf-4fe8-b947-52a05808f51e/image.png" alt=""></p>
<h4 id="💡-dfpivot">💡 df.pivot()</h4>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/0b9bb92d-96af-42cc-953b-05deac898861/image.png" alt=""></p>
<blockquote>
<p>plot 선명하게 하는 매직 커맨드</p>
</blockquote>
<p>%config InlineBackend.figure_formats = {&#39;png&#39;, &#39;retina&#39;}</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[KT AIVLE [2주차] - 데이터 분석 및 의미 찾기]]></title>
            <link>https://velog.io/@k_chae1/KT-AIVLE-2%EC%A3%BC%EC%B0%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B6%84%EC%84%9D-%EB%B0%8F-%EC%9D%98%EB%AF%B8-%EC%B0%BE%EA%B8%B0</link>
            <guid>https://velog.io/@k_chae1/KT-AIVLE-2%EC%A3%BC%EC%B0%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B6%84%EC%84%9D-%EB%B0%8F-%EC%9D%98%EB%AF%B8-%EC%B0%BE%EA%B8%B0</guid>
            <pubDate>Thu, 09 Feb 2023 03:11:32 GMT</pubDate>
            <description><![CDATA[<h2 id="실습-💻">실습 💻</h2>
<h3 id="1-단변량-분석-종합-실습-📌">1. 단변량 분석 종합 실습 📌</h3>
<p>결과 사진은 캡쳐하기도 귀찮고...
그냥 분석하면서 생각한 부분을 적는걸로.
이변량부터 재밌을듯 합니다.</p>
<h4 id="카시트-판매량-분석">카시트 판매량 분석</h4>
<h4 id="💡-문제-정의">💡 문제 정의</h4>
<blockquote>
<p>카시트 판매량 하락</p>
</blockquote>
<h4 id="💡-가설-수립">💡 가설 수립</h4>
<blockquote>
<p><strong>내 가설</strong> </p>
</blockquote>
<p>평균 소득이 높으면 부자동네, 여유로우니 애기들을 낳을 여건이 됨. 
카시트 판매량이 높을거임 + 비싼 카시트를 살 수 있음=구매력이 있는 지역 
즉, 여기서 카시트 판매량이 높은지, 또 판매하는 카시트의 가격이 높은지를 같이 봐야함 </p>
<blockquote>
<p><strong>내 가설과 다르다면?</strong> <br>
&#39;Age&#39;를 통해 지역별 연령대가 어떤지 봐야함 
연령대가 10대 or 40대 이후 (=가임 가능한 부부가 아닌) 라면 구매력이 낮은게 말이됨 . 또, 인구수가 적을 수도 있음. (고령층이 많은 동네)
판매량이 낮다면 경쟁사 물건이 우리꺼에 비해 가격이 낮은지도 체크</p>
</blockquote>
<h4 id="income">Income</h4>
<p>지역별 소득은 특별히 눈에 띄게 잘 버는 지역은 없다.
25%이하를 못 번다고 설정할 시, 못 버는 지역은 히스토그램으로 보니 꽤 있다.
따라서 판매량이 낮아질 수는 있다. 때에 따라 0이 나올 가능성도 있다.
차가 없는 집이 있을 수도 있기 때문에.</p>
<p>어느 지역이 잘 벌고 어느지역이 못 버는지 알 수 있는 변수가 있나?
안타깝게도 지역이 표시된 변수가 없아서 groupby 등을 쓸 수가 없다.</p>
<h4 id="price">Price</h4>
<p>mean보다 median이 살짝 높은데 전반적으로 가격이 살짝 높은편인듯?
타회사가 가격이 낮으면 안 팔릴 수도 있겠다....
유독 가격이 낮은 지역도 있는데 이건 특가인가?
유독 높은건 지역은 또 뭐지? Income과 겹치나?
인덱스 별로 다른 지역이라고 봐야 하는가? ㅠ</p>
<h4 id="compprice">CompPrice</h4>
<p>경쟁사 제품의 가격은
오히려 자사 제품보다 좀 높다
가격 경쟁력은 우리가 있는 편</p>
<p>다만 우리 제품은 max값이 더 높은 경향이 있어서
이건 왜 그렇게 비싼지 살펴봐야한다.
지역별로 가격을 너무 다르게 잡은 것이 아닌지?
그게 경쟁사와 교차되는 지역이면 경쟁사 제품을 살듯하다</p>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/387dd1a0-7014-4584-bd3b-32bd1865a8fa/image.png" alt=""></p>
<p>타사가 가격통일 자체는 잘 되어 있다.</p>
<h4 id="population">Population</h4>
<p>딱히 정규분포도 따르지 않고 굉장히 골고루 있다.
= 대도시가 아닌 지역이 많다. = 구매력 하락 가능성 있음</p>
<p>인구수가 적은 지역도 상당한데 고령층이 많은 시골지역일수도 있겠다. = 구매력 하락, 이런 곳에선 회사 빼는게 이득일듯</p>
<h4 id="age">Age</h4>
<p>지역 인구의 평균 연령.... 균등분포가 뜬다...;;;
이거 걍 데이터를 그렇게 모아놓은건가? (표본제어)
게다가 평균;;; 이게 ⭐<strong>지역별 평균 나이인가 지역별 구매자의 평균 나이인가?</strong></p>
<p>25~80세 까지 있는데
애를 50세부터 못낳는다고 가정하면 (좋게봐줘도 45로 가정하면)
평균 연령이 높은 지역이 월등히 많다.... 이쯤되면 자식이 2n살임.
그러니 평균이 올라가지...
= 애 없음 = 카시트 필요 없음 (but, 자식의 자식이면 혹시 또 모른다.)</p>
<p>구매 주 연령층은 평균 내더라도 30,40대에 몰려있음</p>
<h4 id="advertising">Advertising</h4>
<p>오....0에 몰린게 엄청 많다.
그래서 다른광고 예산이 어떻게 집행되어 있는지 잘 모른다.
따라서 data.loc[data[&#39;Advertising&#39;]&gt;0]으로 빼서 보고 분포 살피기.
광고예산 만달러 미만과 이상의 두 부류로 나뉘는 양상을 보이는데,
(박스플롯은 딱히 효과없는 상황)
그렇게 되는 원인이 있나?</p>
<h4 id="urban">Urban</h4>
<p>도심지역이 확실히 많다! 
보통은 차가 있을테니, 또 도심지역에는 젊은 사람들이 오려 할테니.
출생률이 올라갈 가능성이 있고, 그러면 카시트 판매량이 늘 가능성이 있다.
물론...우리나라는 오히려 반대다...ㅋㅋㅋ 일하느라 애를 안 낳으니까!
또, 경기가 어려워서 결혼을 안 할수도 있다!!!
이게 미국에도 통용되나?를 생각해야한다.</p>
<p>but, 인프라(=대중교통)이 잘 되어 있어서 오히려 구매를 안 하게 되나?도 생각해야함.</p>
<h4 id="us">US</h4>
<p>주로 국내(미국)가 많다. 
그러나 해외 35%로 균형잡힌 회사 비율...?
혹시 해외에서 판매하는건 싸거나 비쌀까?</p>
<hr>
<h3 id="2-이변량-분석-숫자숫자-📌">2. 이변량 분석 (숫자&gt;숫자) 📌</h3>
<h4 id="x숫자--y숫자">X:숫자 &gt; Y:숫자</h4>
<p>두 숫자형 변수의 관계는 산점도로 알아보고 얼마나 직선에 모이는지 봐야한다. (공분산, 상관계수)</p>
<p>직선의 관계를 수치화 &gt; 상관계수 (-1~1, -1와 1에 가까울수록 강한관계)
상관계수가 유의미한지 검정 &gt; 상관분석</p>
<p>scipy.stats 모듈 : 가설검정 등 다양한 통계 함수들 제공
<img src="https://velog.velcdn.com/images/k_chae1/post/f02dfc93-dd13-42b8-b2e5-782803db5767/image.png" alt="">
빨강 : 상관계수 (r)
파랑 : p-value (상관계수가 의미가 있는지 판단하는 숫자)
<code>&lt; 0.05 면 통계량이 의미있다.</code> = 관계 있다.
X의 모든 구간에서 그러한 의미가 있는지 확인해야함
구간을 다르게 바꿔보는것도 중요!!! (구간끼리 평균 비교)
구간에 따라 차이가 있다면 X축의 비즈니스 관점을 생각
(ex. 그러한 양상이 되도록 영향을 미친 문화?법령?지역의 무언가?)
확인이 된다면 숫자를 범주로 바꿔서 anova등을 실행해서 가설 검정이 가능</p>
<p>++
그래프를 처음 보았을때는 상관관계가 안보이는데 pearsonr 을 출력했을때 상관관계가 있는 것으로 결과가 나온다면 이후에 구간을 잘라서 분석하는 방향도 좋다.</p>
<h3 id="3-이변량-분석-범주숫자-📌">3. 이변량 분석 (범주&gt;숫자) 📌</h3>
<h4 id="x범주--y숫자">X:범주 &gt; Y:숫자</h4>
<p>💡 범주가 2개: 두 평균의 <code>차이</code> 비교 (T-test: abs(2)이상)
: 통계량이 유의미한것은 차이가 있다고 해석
t-통계량이 유의미한지는 p-value 보고 판단</p>
<p>전수조사: 전체(모집단) 조사
표본조사: 일부 무작위 조사 </p>
<p>⭐ 표본은 왜 뽑지? 모집단을 추정하기 위해서.
표본 평균은 왜 뽑지? 모평균을 추정하기 위해서.
표본평균: 모 평균에 대한 추정치 
표본평균과 모평균은 오차가 존재: 표준 오차(SE)</p>
<p>sns.barplot : 범주별 평균값을 비교
두 평균의 차이가 크고, 신뢰구간은 겹치지 않을 때: 대립가설이 맞다.
(빨강 : 신뢰구간)</p>
<p><img src="https://velog.velcdn.com/images/k_chae1/post/851808b7-909a-4242-9e4b-3724b6ee32f5/image.png" alt="">
가로로 표현하면 아래와 같다.
<img src="https://velog.velcdn.com/images/k_chae1/post/6cf5f258-9643-43ec-8bc6-999de291ff0c/image.png" alt="">
이 경우 대립가설이 틀렸다!</p>
<p>95% 신뢰구간: 모집단의 평균이 그 안에 속할 확률 95%
신뢰구간이 겹치지 않는다. : 평균의 차이가 크다.</p>
<p>💡 범주가 3개 이상: 전체 평균과 각 범주의 평균비교 (anova)
<code>전체 평균과 그룹평균의 차이(분산), 그룹 내 차이(분산)</code></p>
<p>분산: 평균으로부터 다른 데이터들이 얼마나 떨어져 있는지 나타내는 값</p>
<p>F 통계량 = (전체 평균-각 집단 평균)/(각 집단의 평균-개별값)
통계량이 크면? 차이가 크다.확연하게 집단 간 구분이 된다. 
근데 통계량이 진짜 큰건지 어떻게 알음? 분포를 보면 된다!
값이 대략 2~3 이상이면 차이가 있다고 판단</p>
<p>⭐ 요약
중점: 평균 비교
시각화: sns.barplot
수치화: 범주 2개 t-test / 범주 3개 이상 anova</p>
<p>++
대략적인 해석 기준
<img src="https://velog.velcdn.com/images/k_chae1/post/951a4c88-e82a-4988-b13e-bb6f21179509/image.png" alt=""></p>
<hr>
<h3 id="4-이변량-분석-종합-실습-📌">4. 이변량 분석 종합 실습 📌</h3>
<h4 id="카시트-판매량-분석-1">카시트 판매량 분석</h4>
<h4 id="💡-문제-정의-1">💡 문제 정의</h4>
<blockquote>
<p>카시트 판매량 하락</p>
</blockquote>
<p>📎 y는 해결해야 할 대상, 초기 정의한 문제가 바뀌면 y도 바뀐다.</p>
<h4 id="💡-가설-수립-고객사가-했다고-가정">💡 가설 수립 (고객사가 했다고 가정)</h4>
<blockquote>
<p><strong>가설</strong> </p>
</blockquote>
<p>판매량 하락의 원인이 무엇일까?
수입이 부족, 광고 안 함, 필요가 없음 (연령대), 경쟁사가 더 좋음 등등의 data의 cols 들</p>
<p>이건 동적 변수 생성...귀찮아서 코드하나 짜둠</p>
<pre><code>def make_data(data,var,df_lst):   
    unique = data[var].unique()
    for name in unique:
        print(name)
        globals()[name] = data.loc[data[var]==name, target]
        df_lst.append(globals()[name])


lst = []
make_data(data,&#39;ShelveLoc&#39;,lst)

spst.f_oneway(*lst)</code></pre><h4 id="💡-가설-수정">💡 가설 수정</h4>
<blockquote>
<p>📎 가설: 타사 가격은 자사 판매량에 영향을 준다.</p>
</blockquote>
<h4 id="compsprice">CompsPrice</h4>
<p>경쟁사 탓을 하긴 좀 어려울듯 
경쟁사는 경쟁사대로 우리 회사는 우리 회사대로....
경쟁사 가격이 이러할때 자사 판매량이 얼마이다 인데...
골고루 분포되어있넵...ㅎ</p>
<p>이건 가설이 잘못되어서 원하는 결과를 못 얻은거!</p>
<p>그렇다면?가설을 새로 세운다.
New 가설 : 가격경쟁력은 자사 판매량에 영향을 준다.
[&#39;가격경쟁력&#39;]이란 feature를 새로 생성!
가격경쟁력 = 타사 가격 - 자사 가격으로 정의</p>
<h4 id="income-1">Income</h4>
<p>지역 평균 소득이 높은 지역의 사람들이 비교적 낮은 사람들과 구매량이 큰 차이가 없는 이유는 아이의 수는 비슷하니 구매량은 큰 차이가 없고 판매된 제품의 가격이 차이가 있을 수도 있다.</p>
<hr>
<h3 id="5-이변량-분석-범주범주-📌">5. 이변량 분석 (범주&gt;범주) 📌</h3>
<p>교차표 만들기 (normalize = &#39;columns&#39;,&#39;index&#39;,&#39;all&#39;)
<img src="https://velog.velcdn.com/images/k_chae1/post/53a9733c-d03e-4cd2-9eca-70f017f2f348/image.png" alt=""></p>
<p>mosaic plot: </p>
<pre><code>from statsmodels.graphics.mosaicplot import mosaic 

mosaic(titanic, [&#39;X&#39;,&#39;Y&#39;])
plt.axhline(1- titanic[&#39;Survived&#39;].mean(), color = &#39;r&#39;)
plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/k_chae1/post/71db746a-c2a3-49a4-9396-c561f6a9601b/image.png" alt="">
1에서 뺐으니 사망자가 어느정도인지 알 수 있음</p>
<h4 id="카이제곱-검정">카이제곱 검정</h4>
<p>기대빈도: 귀무가설이 참이기를 바라는 숫자</p>
<ul>
<li><p>카이 제곱 통계량은</p>
<ul>
<li>클수록 기대빈도로부터 실제 값에 차이가 크다는 의미.</li>
<li>계산식으로 볼 때, 범주의 수가 늘어날 수록 값은 커지게 되어 있음.</li>
<li>보통, 자유도의 2~3배 보다 크면, 차이가 있다고 본다. </li>
</ul>
</li>
<li><p>범주형 변수의 자유도 : 범주의 수 - 1</p>
</li>
<li><p>카이제곱검정에서는</p>
<ul>
<li>x 변수의 자유도 × y 변수의 자유도</li>
<li>예 : Pclass --&gt; Survived<ul>
<li>Pclass : 범주가 3개, Survived : 2개</li>
<li>(3-1) * (2-1) = 2</li>
<li>그러므로, 2의 2 ~ 3배인 4 ~ 6 보다 카이제곱 통계량이 크면, 차이가 있다고 볼수 있음.</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code>spst.chi2_contingency(교차표)</code></pre><p><img src="https://velog.velcdn.com/images/k_chae1/post/a77b3df1-877f-4f8e-a282-1ad490f95388/image.png" alt=""></p>
<p>1) 카이제곱 통계량: 자유도 2배보다 큰가? 클수록 관련
2) p-value
3) 자유도 (3-1)*(2-1)=2
4) 기대빈도</p>
<p>자유도 3 : Pclass.unique() 3개라서
자유도 2 : Survived.unique() 2개라서</p>
<p>++
원래 엄밀하게 하려면 계산하여 구한 카이제곱 통계량과 카이제곱 분포표에서 유의수준이 0.05(이건 꼭 0.05가 아니여도 됩니다)이고, 자유도가 n인 부분을 찾아 비교하여 카이제곱 통계량이 더 크다면 귀무가설 기각(귀무가설을 받아드릴 수 없다.) 카이제곱 통계량이 더 작다면 귀무가설을 기각할 수 없다(귀무가설을 받아드린다.)라고 생각</p>
<h3 id="6-이변량-분석-숫자범주-📌">6. 이변량 분석 (숫자&gt;범주) 📌</h3>
<p>kde 그래프 (예측치로 0이하도 나옴, 신경 안 써도 됨)
target 클래스가 크로스 되는 순간(겹치는)은 전체 평균</p>
<blockquote>
<p>특정구간이 전체평균보다 높은지 낮은지 판별</p>
</blockquote>
<p>kde 할 때 common_norm = False (각각의 면적을 1로 만듦)
hue = &#39;열 이름&#39;</p>
<pre><code>plt.figure(figsize = (8,10)) 

plt.subplot(2,1,1) 
sns.kdeplot(x=&#39;Age&#39;, data = titanic, hue =&#39;Survived&#39;, common_norm = False) 

plt.subplot(2,1,2) 
sns.kdeplot(x=&#39;Age&#39;, data = titanic, hue =&#39;Survived&#39;, multiple = &#39;fill&#39;) 

plt.axhline(titanic[&#39;Survived&#39;].mean(), color = &#39;r&#39;) plt.show()</code></pre><h4 id="미봉책">미봉책</h4>
<p>1) X를 범주로 변환 가능하면 변환해서 카이제곱검정 가능
2) Y를 숫자로 변환 가능하면 상관분석 가능
3) 로지스틱 회귀 &gt; 회귀계수 p-value 구해서 판단</p>
<hr>
<h3 id="7-이변량-분석-종합-실습-2-📌">7. 이변량 분석 종합 실습 2 📌</h3>
<p>이건 내가 따로....해보는걸로...체력 딸려서 실습시간에 푹 쉬었다....</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[코딩테스트 연습 Lv.1 마무리 1]]></title>
            <link>https://velog.io/@k_chae1/lv1%EC%97%B0%EC%8A%B5%EB%A7%88%EB%AC%B4%EB%A6%AC1</link>
            <guid>https://velog.io/@k_chae1/lv1%EC%97%B0%EC%8A%B5%EB%A7%88%EB%AC%B4%EB%A6%AC1</guid>
            <pubDate>Wed, 08 Feb 2023 01:53:01 GMT</pubDate>
            <description><![CDATA[<p>몸이 안 좋은 시기라서..^^;
효율이 왕창 떨어졌네요.
부끄럽습니다.
이번주 내로 Lv.1 마무리 하겠습니다.</p>
<hr>
<h2 id="lv1">Lv.1</h2>
<h3 id="실패율">실패율</h3>
<p>if문이 없으니 처음에는 약 70점만 나왔다...
관련 조건: <code>스테이지에 도달한 유저가 없는 경우 해당 스테이지의 실패율은 0 으로 정의한다.</code></p>
<pre><code>def solution(N, stages):
    answer = {}
    deno = len(stages)

    for i in range(1,N+1):
        nume = stages.count(i) 
        if nume == 0:
            answer[i] = 0
        else:
            answer[i] = (nume/deno) #실패율
            deno = deno - nume

    lst = sorted(answer.items(), key=lambda x: x[1], reverse=True)   

    return [item[0] for item in lst]</code></pre><p><code>매번 count 하지 않고 초반에 사전으로 미리 각 스테이지별 인원을 집계해두면 정렬을 제외 했을 때 O(n)의 시간복잡도로 풀 수 있습니다.</code></p>
<p>밑 코드가 훨씬 시간이 짧게 걸린다고 한다.
효율성이 너무 어렵다...ㅠㅠ</p>
<pre><code>def solution(N, stages):
    answer = []
    fail = []
    info = [0] * (N + 2)
    for stage in stages:
        info[stage] += 1
    for i in range(N):
        be = sum(info[(i + 1):])
        yet = info[i + 1]
        if be == 0:
            fail.append((str(i + 1), 0))
        else:
            fail.append((str(i + 1), yet / be))
    for item in sorted(fail, key=lambda x: x[1], reverse=True):
        answer.append(int(item[0]))
    return answer</code></pre><h3 id="1차-다트-게임">[1차] 다트 게임</h3>
<p><strong>틀린 코드</strong>
채점 전 테케조차 다 통과못했다...일부 조건을 놓치고 있나봄..
어렵다...ㅠㅠ</p>
<pre><code>def solution(dartResult):
    stack = []
    sdt = [&#39;S&#39;,&#39;D&#39;,&#39;T&#39;]
    dartResult = dartResult.replace(&quot;10&quot;,&quot;A&quot;)
    for item in dartResult:
        if item.isnumeric(): #숫자저장
            stack.append(int(item))
        elif item == &#39;A&#39;: #10저장
            stack.append(10)
        elif item in sdt: #문자 제곱처리
            stack.append(stack.pop()**(sdt.index(item)+1))
        elif item == &quot;*&quot;:
            stack.append(stack.pop()*2)
        elif item == &quot;#&quot;:
            stack.append(stack.pop()*(-1))

    return sum(stack)</code></pre><blockquote>
<p>스타상(<em>)은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상(</em>)의 점수만 2배가 된다. (예제 4번 참고)</p>
</blockquote>
<p>스타상(<em>)의 효과는 다른 스타상(</em>)의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상(*) 점수는 4배가 된다. (예제 4번 참고)</p>
<blockquote>
</blockquote>
<p>스타상(*)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다. (예제 5번 참고)</p>
<p>이 조건을 놓치고 있는데 사실...잘 모르겠음^^;
첫번째 기회라는게 무조건 첫번째 점수일때인가?싶다.
국어해석이 안되니 원...;;</p>
<p>하 드디어...근데 이케 더럽게 푸는게 맞나? ㅠㅠ</p>
<pre><code>def solution(dartResult):
    stack = []
    answer = []
    sdt = [&#39;S&#39;,&#39;D&#39;,&#39;T&#39;]
    dartResult = dartResult.replace(&quot;10&quot;,&quot;A&quot;)
    for item in dartResult:
        if item.isnumeric(): #숫자저장
            stack.append(int(item))
        elif item == &#39;A&#39;: #10저장
            stack.append(10)

        elif item in sdt: #문자 제곱처리
            answer.append(stack.pop()**(sdt.index(item)+1))
        elif item == &quot;*&quot;:
            if len(answer) &gt; 1:
                answer[-2] *= 2
                answer[-1] *= 2
            else:
                answer[-1] *= 2
        elif item == &quot;#&quot;:
            answer[-1] *= -1

    return sum(answer)</code></pre><p><strong>정규 표현식을 사용한 코드</strong></p>
<pre><code>import re

def solution(dartResult):
    bonus = {&#39;S&#39; : 1, &#39;D&#39; : 2, &#39;T&#39; : 3}
    option = {&#39;&#39; : 1, &#39;*&#39; : 2, &#39;#&#39; : -1}
    p = re.compile(&#39;(\d+)([SDT])([*#]?)&#39;)
    dart = p.findall(dartResult)
    for i in range(len(dart)):
        if dart[i][2] == &#39;*&#39; and i &gt; 0:
            dart[i-1] *= 2
        dart[i] = int(dart[i][0]) ** bonus[dart[i][1]] * option[dart[i][2]]

    answer = sum(dart)
    return answer</code></pre><h3 id="과일-장수">과일 장수</h3>
<p>리스트 컴프리헨션</p>
<pre><code>def solution(k, m, score):
    answer = []
    score.sort(reverse=True) #계산 편하려고 정렬
    result = [score[i*m:(i+1)*m] for i in range((len(score)+ m-1)//m)] # m개씩 묶기    
    answer = [min(item)*m for item in result if len(item)==m] #계산
    return sum(answer)</code></pre><p>덧셈 반복문</p>
<pre><code>def solution(k, m, score):
    answer = []
    score.sort(reverse=True) #계산 편하려고 정렬
    result = [score[i*m:(i+1)*m] for i in range((len(score)+ m-1)//m)] # m개씩 묶기 
    # m개 묶음이 된 리스트만 수식으로 계산
     for item in result:
         if len(item) == m:
             answer += min(item)*m    
    return answer</code></pre><p>숏코딩... 나는 왜 그런 헛된 시간을....</p>
<pre><code>def solution(k, m, score):
    return sum(sorted(score)[len(score)%m::m])*m</code></pre><h3 id="명예의-전당1">명예의 전당(1)</h3>
<p>단순하게...내림차순해서 -1번째 값을 계속 뽑아내기</p>
<pre><code>def solution(k, score):
    answer = []
    rank = []
    for i in score:
        rank.append(i)
        rank.sort(reverse=True)
        if len(rank)&gt;k:
            del rank[-1]
        answer.append(rank[-1])
    return answer</code></pre><h3 id="로또의-최고-순위와-최저-순위">로또의 최고 순위와 최저 순위</h3>
<pre><code>def solution(lottos, win_nums):
    prize_lst = [6,6,5,4,3,2,1] #idx: 맞은 개수, value: 등수

    lst = [item for item in lottos if item != 0] #0을 다 제거
    cnt_0 = 6 - len(lst) #0의 개수

    cnt_min = 0
    for item in lst:
        if item in win_nums:
            cnt_min += 1 #최저 등수

    return [prize_lst[cnt_0 + cnt_min],prize_lst[cnt_min]]</code></pre><p>count 메서드 이용</p>
<pre><code>def solution(lottos, win_nums):

    rank=[6,6,5,4,3,2,1]

    cnt_0 = lottos.count(0)
    ans = 0
    for x in win_nums:
        if x in lottos:
            ans += 1
    return rank[cnt_0 + ans],rank[ans]</code></pre><h3 id="체육복">체육복</h3>
<pre><code>def solution(n, lost, reserve):

    reserve_1 = set(reserve) - set(lost) #확실히 여분이 있는 학생 
    lost_1 = set(lost) - set(reserve) #lost랑 reserve에서 중복되는 학생 제거

    reserve_2 = sorted(list(reserve_1), reverse = True) #정렬
    lost_2 = sorted(list(lost_1), reverse = True)

    for i in reserve_2:
        if i+1 in lost_2:
            lost_2.remove(i+1)
        elif i-1 in lost_2:
            lost_2.remove(i-1)

    return n - len(lost_2)</code></pre><h3 id="완주하지-못한-선수">완주하지 못한 선수</h3>
<pre><code>import collections

def solution(participant, completion):
    #participant-completion=answer 완주하지 못한 선수
    answer = collections.Counter(participant)-collections.Counter(completion)
    answer = list(answer.keys())[0]

    return answer</code></pre><h3 id="숫자-짝꿍">숫자 짝꿍</h3>
<p>count쓰면 터진다고 한다...
그래서 Counter 모듈을 써야한다...
시간복잡도란...ㅠㅠ</p>
<pre><code>from collections import Counter
    #각 원소가 몇번씩 나오는지 세고, 교집합하고
    #교집합의 elements로 카운터 숫자만큼 요소 반환
    #리스트로 만들고 정렬
def solution(X,Y):
    result = sorted(list((Counter((int(i) for i in X))&amp;Counter((int(i) for i in Y))).elements()), reverse=True)
    if len(result) == 0:
        return &#39;-1&#39;
    if result[0] == 0:
        return &#39;0&#39;

    return &#39;&#39;.join((str(i) for i in result))
</code></pre><h3 id="기사단원의-무기">기사단원의 무기</h3>
<p>제곱근만큼 반복문으로 약수 구하기
제곱근이면 1개만 카운트 (5*5=25 같은 경우...)
아니면 2개 카운트 
약수 개수가 limit 넘어가면 그냥 power 반환</p>
<pre><code>def cnt_division(n,limit,power):
    cnt = 0
    for i in range(1, int(n**(1/2))+1): 
        if n%i == 0:
            if i == n//i: 
                cnt += 1
            else:
                cnt += 2 
        if cnt &gt; limit:  
            return power 
    return cnt

def solution(number, limit, power):
    answer = 1 #1의 약수의 개수는 1, 하나라서 여기서 시작
    for i in range(2, number+1):
        answer += cnt_division(i, limit, power)

    return answer</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[KT AIVLE [2주차] - 데이터 처리]]></title>
            <link>https://velog.io/@k_chae1/KT-AIVLE-2%EC%A3%BC%EC%B0%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@k_chae1/KT-AIVLE-2%EC%A3%BC%EC%B0%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Tue, 07 Feb 2023 03:30:34 GMT</pubDate>
            <description><![CDATA[<h2 id="이론-📝">이론 📝</h2>
<h3 id="1-과정-overview-📌">1. 과정 Overview 📌</h3>
<p>데이터 전처리 2가지 단계</p>
<p>1) 데이터 구조 만들기 (raw &gt; dataset)
2) 모델링을 위한 전처리 (dataset &gt; 모델링 가능한 형태)</p>
<p>⭐ 모델링 가능한 형태
: 모든 셀은 값이 있다, 모든 값은 숫자, (필요시) 숫자의 범위를 맞춘다.</p>
<h3 id="2-데이터-프레임-변경-📌">2. 데이터 프레임 변경 📌</h3>
<h4 id="1-열-이름-변경">1) 열 이름 변경</h4>
<p>.columns = [&#39;모든 열 이름&#39;]: 개수 맞춰야함
.rename(columns={&#39;원래&#39; : &#39;바꿈&#39;}): 지정한 열 이름 변경
inplace = True 옵션: 원래 df에 변경사항 적용</p>
<h4 id="2-열-삭제">2) 열 삭제</h4>
<p>.drop()
axis = 1 : 열</p>
<p>++
얕은 복사: 주소값 참조
깊은 복사: 데이터 값 자체 복사</p>
<p>파이썬의 .copy()는 얕은 복사</p>
<h4 id="3-값-변경">3) 값 변경</h4>
<p>.map({&#39;원래 값&#39;:&#39;새 값&#39;}): 딕셔너리 입력</p>
<p>pd.cut(): 함수를 이용하여, <code>숫자&gt;범주</code> 변환
값을 균등 분할 (주: 각 등분의 개수가 균형 X)
pd.cut(df[&#39;열 이름&#39;], 등분, labels=[&#39;등분 수 만큼&#39;])
원하는 구간으로 자르려면 등분 자리에 bins = []
구간은 (left,right]가 됨 (left &lt; 구간 &lt;= right)</p>
<p>++
map은 기존의 값들을 맵핑하여 변환하기 때문에, 딕셔너리에 값이 존재하지 않으면 맵핑할 수 없어 NaN을 반환한 것이고, replace는 값을 바꿔주는 용도이기 때문에, 값이 존재하지 않아도 기존 값을 그대로 유지한다는 차이가 있다.</p>
<p><code>숫자&gt;범주</code> : 관점은 비즈니스 
묶는다 : 공통된 특징이 있다.</p>
<h3 id="3-데이터-프레임-결합-📌">3. 데이터 프레임 결합 📌</h3>
<p><strong>1) pd.concat()</strong>
: 매핑 기준 - 인덱스(행), col 이름(열) (=df의 구조)</p>
<p>axis = 0: 세로로 합치기 (행이 추가)
axis = 1: 가로로 합치기 (열이 추가)</p>
<p>join = &#39;outer&#39;: 모든 행열 합치기
join = &#39;inner&#39;: 매핑되는 행열만 합치기</p>
<p><strong>2) pd.merge()</strong>
: 매핑 기준 - 특정 col(key)의 값 기준 (=데이터의 값)
= DB의 join</p>
<p>how = &#39;&#39;: left,right,outer,inner
on = &#39;열 이름&#39;: key 값
방향은 항상 옆으로 합쳐짐</p>
<p><strong>3) pivot</strong>
: 집계된 데이터 재구성
df.pivot(index,col,values)</p>
<h3 id="4-시계열-데이터-처리-📌">4. 시계열 데이터 처리 📌</h3>
<p>⭐*<em>시계열 데이터 *</em>
행과 행에 시간의 순서(흐름)가 있음
행과 행의 시간간격의 동일한 데이터
시계열 데이터 &lt; 시퀀셜 데이터 </p>
<p><strong>날짜 요소 뽑기</strong>
.dt.날짜요소</p>
<p><strong>시계열만 사용 가능</strong>
.shift(): 시간의 흐름 전후로 정보를 이동</p>
<p>.rolling().집계함수(): 일정 기간 동안 집계함수를 이동하면서 구하기 </p>
<ul>
<li>min_periods =1 : 값이 하나라도 있으면 NaN처리 말고 만들어내!</li>
</ul>
<p>.diff(): 특정 시점 데이터, 이전 시점 데이터와의 차이 구하기 (차분)</p>
<h3 id="5-데이터-분석-방법론-📌">5. 데이터 분석 방법론 📌</h3>
<p>파일럿 : 전체 프젝 전 범위 축소해서 한 바퀴 돌고 가능성 보는 방법
밑의 순서는 그 과정을 설명</p>
<p>1) 무엇이 문제인가?</p>
<ul>
<li>문제 정의 (평가 지표 설계) : <code>문제는 수치화</code></li>
<li>분석 목표 설정</li>
<li>가설 수립 </li>
</ul>
<p>2) 데이터 수집/가설 검증</p>
<ul>
<li>데이터 원본 식별 (최대한 가용 영역으로 끌어와서 사용)</li>
<li>가설이 진짜인지 확인 (EDA:그래프, 통계량, CDA:가설 검정 등)</li>
<li>목적: 가설 확인, 전처리 대상 정리, data와 비즈니스 이해
(EDA에서 단변량, 이변량(feature-target), 이변량(features) 분석)</li>
</ul>
<p>3) 모델링에 적합한 구조로 데이터 처리</p>
<ul>
<li>결측치 X</li>
<li>전부 숫자</li>
<li>(옵션) 값의 범위 일치</li>
</ul>
<p>4) 모델링
하나의 수식으로 표현, 오차를 최소화하는 패턴을 데이터로부터 추출</p>
<p>5) 문제는 해결되었는가?
test set 등을 이용 + 비즈니스 기대가치 평가</p>
<p>6) 배포</p>
<h3 id="6-데이터의-시각화-📌">6. 데이터의 시각화 📌</h3>
<p>수 많은 데이터를 파악하는 2가지 방법 : 그래프, 통계량</p>
<p>데이터에는 비즈니스가 담겨 있다. 통계적인 해석을 넘어 <code>인사이트를 파악</code>
한계: 요약된 정보 표현, 관점에 따른 다른 해석 결과, 정보의 손실</p>
<h4 id="matplotlib">matplotlib</h4>
<p>간단한 그래프 그리기</p>
<pre><code>plt.plot(data[&#39;X&#39;], data[&#39;y&#39;]
         ,color=&#39;green&#39;                
         , linestyle=&#39;dotted&#39;         
         , marker=&#39;o&#39;,                   
         label=&#39;y)                

plt.xlabel(&#39;X legend&#39;) 
plt.ylabel(&#39;y legend&#39;)
plt.title(&#39;Title of Plot&#39;)
plt.xticks(rotation=45)
plt.legend(loc=&#39;upper right&#39;)   
plt.grid()

plt.show()</code></pre><p>여러 feature를 겹쳐서 그리려면 plt.plot을 2번 쓰면 된다.</p>
<h3 id="7-단변량-분석-📌">7. 단변량 분석 📌</h3>
<h4 id="1-숫자형-변수">1) 숫자형 변수</h4>
<ul>
<li><p>숫자로 요약: 정보의 대표값 (ex. mean,median,mode,quantile 등)</p>
</li>
<li><p>구간을 나누고 빈도수 계산 (도수분포표)</p>
</li>
<li><p>평균 </p>
<ul>
<li>산술평균 : sum(모든 값)/개수 (평균의 함정...)</li>
<li>기하평균</li>
<li>조화평균 : 분자가 동일한 두 비율의 평균</li>
</ul>
</li>
</ul>
<p>IQR = Q3-Q1
박스플롯 : 이상치 판정 기준 제시 (정규분포 하에)
양측 펜스는 1.5*IQR 값을 가지고 산정 </p>
<p>히스토그램, 밀도함수, 박스 그래프 등을 사용</p>
<h4 id="2-범주형-변수">2) 범주형 변수</h4>
<ul>
<li>범주별 빈도수: 시리즈.value_counts()</li>
<li>범주별 비율: 범주별 빈도수/전체 count(df.shape[0])</li>
</ul>
<p>bar plot, pie plot 등을 사용</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[코딩테스트 연습 9,10일차]]></title>
            <link>https://velog.io/@k_chae1/%EC%97%B0%EC%8A%B59-10%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@k_chae1/%EC%97%B0%EC%8A%B59-10%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Mon, 06 Feb 2023 12:28:31 GMT</pubDate>
            <description><![CDATA[<p>9일차는 아침부터 밤까지 일정이 있어 쉬어갔습니다 ㅎㅎ
또 월요일이네요
월요일은 컨디션 조절이 참 힘들죠. 가볍게 풀고 일찍 자는걸로 ㅎㅎ 
내일부터는 강의를 듣고 유형별 백준 문제도 풀 계획입니다.
저녁 먹기전 힘들어서 뻗어있는 시간과 먹은 후 힘들어서 뻗어있는 시간이 좀 아깝습니다. 그렇다고 잠을 줄이기엔 도저히 그건 안되는 사람..
잠죽자 생활을 2년간 해봤는데, 단물 빼먹히고 진짜 죽습니다. ㅎㅎ
아무도 고마워하지 않아요.
아예 음식이 안 받아서 하루에 간신히 커피만 한 잔 먹었던 생활..ㅎ;;
그래서 그 때부터 건강 챙기며 쉬어가자고 생각했습니다.</p>
<hr>
<h2 id="lv1">Lv.1</h2>
<h3 id="소수-찾기">소수 찾기</h3>
<p>단순 소수찾기가 뜬금없이 나올 일은 없으니 효율성이 관련된 문제</p>
<h3 id="📎-에라토스테네스의-체">📎 에라토스테네스의 체</h3>
<blockquote>
<ol>
<li>2부터 𝑁까지의 모든 자연수를 나열한다</li>
<li>남은 수 중에서 아직 처리하지 않은 가장 작은 수 𝑖를 찾는다</li>
<li>남은 수 중에서 i의 배수를 모두 제거한다(𝑖는 제거하지 않는다)</li>
<li>더 이상 반복할 수 없을 때까지 2번과 3번의 과정을 반복한다</li>
</ol>
</blockquote>
<pre><code>def solution(n):
    lst = [1]*(n + 1) # 1=True

    for i in range(2, int(n**(1/2)) + 1): 
        if lst[i] == 1: 
            for j in range(i*i,n+1,i):
                lst[j] = 0

    answer = lst.count(1)
    return answer-2 #0,1제외</code></pre><p>i*i하면 4부터 시작! step도 i로 두면서 2의 배수 충족!</p>
<pre><code>def solution(n):
    num=set(range(2,n+1))

    for i in range(2,n+1):
        if i in num:
            num-=set(range(2*i,n+1,i))
    return len(num)</code></pre><p>이게 진짜 코딩이군...반성하고 갑니다....한 번에 배수를 다 빼버리다니.... for문을 2번씩이나 돌 필요가 없당 ㅠㅠ</p>
<h3 id="모의고사">모의고사</h3>
<p>이거...처음에 조건문을 if말고 elif로 했더니
동점이 답인 case에서 if만 실행하고 반복이 넘어가버리는 사태가 발생...
그래서 전부 if로 처리해야 넘어가지 않는다............
무서운 코딩의 세상</p>
<pre><code>def solution(answers):
    answer = []
    p1 = [1,2,3,4,5]
    p2 = [2,1,2,3,2,4,2,5]
    p3 = [3,3,1,1,2,2,4,4,5,5]
    score = [0,0,0]

    for idx,v in enumerate(answers):
        if v == p1[idx%len(p1)]:
            score[0] += 1
        if v == p2[idx%len(p2)]:
            score[1] += 1
        if v == p3[idx%len(p3)]:
            score[2] +=1

    for idx,v in enumerate(score):          
        if v==max(score):
            answer.append(idx+1)

    return answer</code></pre><h3 id="소수-만들기">소수 만들기</h3>
<p>나는 itertools 없으면 못 살듯...</p>
<pre><code>from itertools import combinations

def solution(nums):
    answer = 0
    for c in combinations(nums,3):
        flag = 0
        num = sum(c)
        for i in range(2,int(num**(1/2))+1):
            if num % i == 0:
                flag = 1
                break
        if flag == 0 :
            answer += 1
    return answer</code></pre><p>for - else 구문이 신기하다.</p>
<pre><code>def solution(nums):
    from itertools import combinations as cb
    answer = 0
    for a in cb(nums, 3):
        cand = sum(a)
        for j in range(2, cand):
            if cand%j==0:
                break
        else:
            answer += 1
    return answer</code></pre><h3 id="가장-가까운-글자">가장 가까운 글자</h3>
<pre><code>def solution(s):
    answer = []
    dic = {}

    for idx in range(len(s)):
        if s[idx] not in dic:
            answer.append(-1)
        else:
            answer.append(idx-dic[s[idx]])
        dic[s[idx]] = idx

    return answer</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[KT AIVLE [2주차] - Python 라이브러리]]></title>
            <link>https://velog.io/@k_chae1/KT-AIVLE-2%EC%A3%BC%EC%B0%A8-Python-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC</link>
            <guid>https://velog.io/@k_chae1/KT-AIVLE-2%EC%A3%BC%EC%B0%A8-Python-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC</guid>
            <pubDate>Mon, 06 Feb 2023 03:31:04 GMT</pubDate>
            <description><![CDATA[<p>주말이 지나고 새 일주일이 시작 됐습니다.
이번주도 힘내보겠습니다!!!!
이번주는 끝까지 한기영 강사님께서 맡으셨다.
다음주에 미니 프로젝트의 시작이다.... 아마도 EDA가 될듯하다.</p>
<hr>
<h2 id="이론-📝">이론 📝</h2>
<h3 id="1-데이터-구조-📌">1. 데이터 구조 📌</h3>
<p>[ 분석을 위한 데이터 구조 ] </p>
<h4 id="1-crisp-dm">1) CRISP-DM</h4>
<p>Cross-Industry Standard Process for Data Mining</p>
<blockquote>
<p>1) 비즈니스 이해: 무엇이 문제인가? (문제 정의, 정보 도출)
2) 데이터 이해 
3) 데이터 준비: 모델링을 위한 데이터 구조 준비
4) 모델링: 학습, 검증
5) 평가: 문제가 해결되는가? 
6) 배포 </p>
</blockquote>
<h4 id="2-분석할-수-있는-데이터">2) 분석할 수 있는 데이터</h4>
<p>⭐ 숫자, 범주</p>
<p>2-1) 범주형 : 질적 데이터 (정성적 데이터)</p>
<ul>
<li>명목형: grouping (ex. 성별, 지역 등)</li>
<li>순서형: (ex. 연령대, 매출등급 등)</li>
</ul>
<p>2-2) 수치형 : 양적 데이터 (정량적 데이터) </p>
<ul>
<li>이산형: countable (ex. 판매량, 매출액 등)</li>
<li>연속형: uncountable (ex. 온도, 몸무게 등 연속적)</li>
</ul>
<p>ex. 날짜 자체는 아무데도 속하지 않는다. 떼어낸 요소를 분류 가능.</p>
<p><strong>기본 2차원 : table, 2 dim array, data frame</strong>
columns: 정보, <code>변수</code>, <code>요인</code> (feature,X,input,독립변수)
rows: <code>분석단위</code>, 샘플, 관측치, 데이터 건수 (target,y,output,종속변수)</p>
<h3 id="2-numpy-📌">2. Numpy 📌</h3>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/NumPy_logo_2020.svg/330px-NumPy_logo_2020.svg.png" alt="">
데이터 구조를 다루는 패키지 : 수치 연산에 강함</p>
<h4 id="1-리스트">1) 리스트</h4>
<p>값의 집합(collection) 
다른 타입의 데이터도 한꺼번에 저장 가능
요소 변경, 추가, 제거 용이
but, 계산이 느리거나 불가능 할 수 있다.</p>
<blockquote>
<p>데이터 분석에서의 필요는 <code>수학적 계산이 가능</code>하고 <code>대량의 데이터 처리가 가능</code>해야 한다.</p>
</blockquote>
<h4 id="2-넘파이-배열">2) 넘파이 배열</h4>
<p>• Axis: 배열의 각 축
• Rank: 축의 개수(차원)
• Shape: 축의 길이 : element의 개수</p>
<p>길이 = 개수</p>
<p>⭐ ex. 3차원 배열 읽기 (2,3,3)
axis = 0의 의미가 중요 : 배열이 몇 개 있는가
= 행이 몇 개 있는가 = <code>분석단위의 개수</code>
3x3짜리 2차원 배열이 2개 있다는 뜻</p>
<p>reshape에는 원래 데이터 형태(arr.shape으로 확인)의 약수만 가능</p>
<p>함수: np.sum()처럼 다양한 자료구조를 넣을 수 있음 
메서드: data.method 하고 . 뒤에 붙는 함수 (자료구조마다 메서드가 다름)</p>
<h4 id="3-데이터-조회">3) 데이터 조회</h4>
<p>arr[행,열] (열은 생략 가능)
값, 단일 인덱스 arr[2,3]
값, 여러 인덱스 arr [[2,3]] (2,3번째 행 조회)
범위, 슬라이싱 arr[2:7,]<br>조건, boolean</p>
<p>np.where(조건문,참 값,거짓 값) 
np.argmax(arr, axis=0) : 가장 큰 값의 인덱스 반환</p>
<p>[[1,2,3],
[5,6,7]] 이면</p>
<ul>
<li><p>axis = 0 : 열축 따라감
즉, 3개의 인덱스가 나옴</p>
</li>
<li><p>axis = 1 : 행축 따라감
2개의 인덱스가 나옴</p>
</li>
</ul>
<h3 id="3-pandas-📌">3. Pandas 📌</h3>
<img src='https://blog.kakaocdn.net/dn/zy1Or/btqM39h0uLB/fHnntePsHiwAIFStdqGsLk/img.png' width=300 />

<p>데이터 구조를 다루는 패키지 : 비즈니스 시각에 강함</p>
<h4 id="1-데이터-프레임">1) 데이터 프레임</h4>
<p>데이터 분석에서 가장 중요한 데이터 구조
2차원 구조, 변수들의 집합</p>
<h4 id="2-시리즈">2) 시리즈</h4>
<p>하나의 정보에 대한 데이터들의 집합
데이터 프레임에서 하나의 열을 떼어낸 것 (1차원)</p>
<blockquote>
<p>데이터 조회하면서 비즈니스 가설들을 일단 주르륵 뽑아내야함
(아무말이라도 하면서....)</p>
</blockquote>
<h4 id="3-dfloc행-조건-열-이름">3) df.loc[행 조건, 열 이름]</h4>
<p>and 대신 &amp;
or 대신 |
조건 여러개 묶으려면 각 조건을 ()안에
열 이름은 생략 가능
인덱스를 넣어서도 검색 가능
⭐but, 인덱스가 아닌 <code>행번호</code>임
인덱스는 iloc! </p>
<h4 id="4-dfisin리스트">4) df.isin([리스트])</h4>
<p>[1,4]면 1~3이 아니라 1 or 4</p>
<h4 id="5-dfbetween">5) df.between()</h4>
<p>(1,5)면 1~5까지
1.3버전 이후로 inclusive 옵션이 생김</p>
<h4 id="6-dfgroupby그룹핑할-기준-열-이름-as_indextrue">6) df.groupby(그룹핑할 기준 열 이름, as_index=True)</h4>
<p>as_index=True : 집계 기준 변수를 인덱스로 사용 (F로 하면 같이 열로 나옴)</p>
<p>df.groupby()[&#39;열&#39;] : 결과 시리즈
df.groupby()[[&#39;열&#39;]] : 결과 데이터 프레임</p>
<h4 id="7-dfgroupby열-이름agg함수1함수2-">7) df.groupby(&#39;열 이름&#39;).agg([&#39;함수1&#39;,&#39;함수2&#39;, ...])</h4>
<p>여러 함수로 한꺼번에 집계 
원하는 집계함수 이름을 리스트 형태로 지정</p>
<p>열 마다 집계 방법을 다르게 하고 싶다면?
&#39;열 이름&#39;:&#39;집계 방법&#39; 형태의 key:value를 갖는 딕셔너리 형태로 지정</p>
<ul>
<li>예외: as_index<ul>
<li>.agg()를 사용하면 as_index=False가 적용 X</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[코딩테스트 연습 8일차]]></title>
            <link>https://velog.io/@k_chae1/%EC%97%B0%EC%8A%B58%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@k_chae1/%EC%97%B0%EC%8A%B58%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Sat, 04 Feb 2023 03:38:03 GMT</pubDate>
            <description><![CDATA[<p>어느새 주말이네요.
그리고 Lv.1 문제도 절반을 넘겼습니다.
다음주가 끝날 때엔 Lv.2를 풀고 있도록 노력해보겠습니다.</p>
<hr>
<h2 id="lv1">Lv.1</h2>
<h3 id="문자열-내-마음대로-정렬하기">문자열 내 마음대로 정렬하기</h3>
<p><strong>틀린 코드</strong>
&quot;인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.&quot; &lt; 이 조건이 어렵다.</p>
<pre><code>def solution(strings, n):
    answer = []
    sort_dic = {}

    for idx,item in enumerate(strings):
        if item[n] in sort_dic.keys():
            sort_dic[item[n+1]] = idx  
        sort_dic[item[n]] = idx

    sort_dic = dict(sorted(sort_dic.items()))
    for idx in sort_dic.values():
        answer.append(strings[idx])

    return answer</code></pre><p>그냥...sort부터 때리고 n기준으로 바꾸면 어떨까?
그럼 동일 문자는 사전순으로 그대로 유지될테고 n번째가 다른 item만 순서가 바뀔듯?</p>
<p><strong>틀린 코드 2</strong>
테스트 케이스는 통과하는데 채점하니 처참하다...ㅠㅠ
내가 정렬 알고리즘을 잘 모르나보다.
일단 전체 정렬부터 하는게 올바른 접근 방법임을 알았다!</p>
<pre><code>def solution(strings, n):
    strings.sort()

    for idx in range(len(strings)-1):
        if strings[idx][n] &gt; strings[idx+1][n]:
            strings[idx],strings[idx+1] = strings[idx+1],strings[idx]  

    return strings</code></pre><p><strong>수정 코드</strong>
sorted에 key가 혹시라도 될까 싶었는데 되더라...
윽....ㅠㅠ</p>
<pre><code>def solution(strings, n):
    strings.sort()     
    return sorted(strings, key=lambda x:x[n])
</code></pre><h3 id="k번째-수">K번째 수</h3>
<p><strong>틀린 코드</strong>
index error가 뜬다...대체 왜....?
범위를 초과할 수가 없는데 왜 테케도 통과 못하는거지?</p>
<pre><code>def solution(array, commands):
    answer = []
    for item in commands:
        array = sorted(array[item[0]-1:item[1]])
        answer.append(array[item[2]-1])   
    return answer</code></pre><p><strong>수정 코드</strong>
이럴수가..ㅎㅎㅎ...어이없다....</p>
<pre><code>def solution(array, commands):
    answer = []
    for item in commands:
        tmp = sorted(array[item[0]-1:item[1]])
        answer.append(tmp[item[2]-1])
    return answer</code></pre><p>숏코딩</p>
<pre><code>def solution(array, commands):
    return [sorted(array[c[0]-1:c[1]])[c[2]-1] for c in commands]</code></pre><h3 id="숫자-문자열과-영단어">숫자 문자열과 영단어</h3>
<p>쪼갤까?하다가 제한시간 10초를 보고 쪼개면 안될 것 같았다..
또 문자문자 붙어있는건 쪼갤 수 있는 방법이...ㅠㅠ
못 쪼개면 대체로 넘어가자.</p>
<p><strong>틀린 코드</strong>
대체도 안되네???ㅠㅠ뭐지.... 
뜨는 에러는 무려..문자열을 숫자로 바꿀 수 없습니다...
대체가 아예 안 됐다는 뜻이다...</p>
<pre><code>def solution(s):
    answer = 0
    num_str = {&quot;zero&quot;:&quot;0&quot;,&quot;one&quot;:&quot;1&quot;,&quot;two&quot;:&quot;2&quot;,&quot;three&quot;:&quot;3&quot;,
              &quot;four&quot;:&quot;4&quot;,&quot;five&quot;:&quot;5&quot;,&quot;six&quot;:&quot;6&quot;,&quot;seven&quot;:&quot;7&quot;,
              &quot;eight&quot;:&quot;8&quot;,&quot;nine&quot;:&quot;9&quot;}
    for k,v in num_str.items():
        answer = s.replace(k,v)
    return int(answer)</code></pre><p>이건 왜 되는데? 프로그래머스 자식들아</p>
<pre><code>def solution(s):
    num_str = {&quot;zero&quot;:&quot;0&quot;,&quot;one&quot;:&quot;1&quot;,&quot;two&quot;:&quot;2&quot;,&quot;three&quot;:&quot;3&quot;,
              &quot;four&quot;:&quot;4&quot;,&quot;five&quot;:&quot;5&quot;,&quot;six&quot;:&quot;6&quot;,&quot;seven&quot;:&quot;7&quot;,
              &quot;eight&quot;:&quot;8&quot;,&quot;nine&quot;:&quot;9&quot;}

    for k,v in num_str.items():
        s = s.replace(k,v)
    return int(s)</code></pre><h3 id="두-개-뽑아서-더하기">두 개 뽑아서 더하기</h3>
<p><strong>틀린 코드</strong>
제일 먼저 생각난건 이런 방법.
근데 테케 2개 통과 못함 ㅠㅠ</p>
<pre><code>import itertools 

def solution(numbers):
    answer = sorted([sum(c) for c in itertools.combinations(numbers, 2)])
    answer = list(set(answer))
    return answer</code></pre><p><strong>수정 코드</strong>
set으로 변환하면 정렬이 보장되지 않는다고 한다...
몰랐던 사실. 정렬 한 번 더하니 정답!</p>
<pre><code>import itertools 

def solution(numbers):
    answer = sorted([sum(c) for c in itertools.combinations(numbers, 2)])
    answer = sorted(list(set(answer)))
    return answer</code></pre><h3 id="2016년">2016년</h3>
<p><strong>datetime 라이브러리 사용</strong>
근데..ㅎ 쓰면 안되겠지?</p>
<pre><code>import datetime

def solution(a, b):
    day = datetime.datetime(2016, a, b).strftime(&quot;%A&quot;)
    day = day.upper()
    return day[0:3]</code></pre><p><strong>안 쓴 코드</strong>
와 이거 두고두고 기억해야겠다.
왜 fri부터인지 사실 아직 이해가 되지 않는다.</p>
<pre><code>def getDayName(a,b):
    months = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    days = [&#39;FRI&#39;, &#39;SAT&#39;, &#39;SUN&#39;, &#39;MON&#39;, &#39;TUE&#39;, &#39;WED&#39;, &#39;THU&#39;]
    return days[(sum(months[:a-1])+b-1)%7]</code></pre><h3 id="폰켓몬">폰켓몬</h3>
<pre><code>def solution(nums):
    ans = 0
    max_len = len(nums)//2 
    nums = list(set(nums)) #중복제거

    for i in nums:
        if ans &lt; max_len:
            ans += 1

    return ans</code></pre><p>숏코딩
와...............</p>
<pre><code>def solution(ls):
    return min(len(ls)/2, len(set(ls)))</code></pre><h3 id="크기가-작은-부분-문자열">크기가 작은 부분 문자열</h3>
<p>부분 문자열 어떻게 만들지..생각했는데,
자세히 보니까 크기비교만 하면 되는 문제라서
굳이 append해서 복잡하게 셀 필요가 없었다.
range()범위 조절이 관건, 슬라이싱 할 때 꼭 기억하자.
이렇게 하면 부분 문자열도 만들어서 출력할 수 있겠네....</p>
<pre><code>def solution(t, p):
    answer = 0

    for i in range(len(t) - len(p) + 1):
        if int(p) &gt;= int(t[i:i+len(p)]):
            answer += 1

    return answer</code></pre><h3 id="콜라-문제">콜라 문제</h3>
<p><strong>틀린 코드</strong>
채점 개같이 실패...
찬찬히 뜯어보니 이 코드는 b=1일때만 성립한다;</p>
<pre><code>def solution(a, b, n):
    answer = 0

    while n &gt;= a:
        lst = [c*a  for c in range(1,n) if c*a &lt;= n] #교환이 가능한 최대 수
        n = n - max(lst) + int(max(lst)/a) 
        answer += int(max(lst)/a) 

    return answer</code></pre><p>테스트 케이스 12번에서 시간초과가 뜬다ㅠㅠ
아무래도 12번이 엄청 큰 수고 리스트를 만드는데 꽤 걸리나 싶다.
그럼 저 부분을 for랑 if, 리스트를 쓰지않고 max(lst)를 대체해야 한다.</p>
<pre><code>def solution(a, b, n):
    answer = 0

    while n &gt;= a:
        lst = [c*a  for c in range(1,n) if c*a &lt;= n] #교환이 가능한 최대 수
        n = n - max(lst) + int(max(lst)//a)*b
        answer += int(max(lst)//a)*b 

    return answer</code></pre><p>answer만큼은 다시 받은거니까 무조건 더해지고
교환하고 남은 병의 개수도 더해야한다. (나머지)</p>
<pre><code>def solution(a, b, n):
    answer = 0

    while n &gt;= a:
        answer += (n//a)*b
        n = (n//a)*b + (n%a)

    return answer</code></pre><h3 id="푸드-파이트-대회">푸드 파이트 대회</h3>
<p>내 코드</p>
<pre><code>def solution(food):
    front = &quot;&quot;
    for idx in range(1,len(food)):
        if food[idx] &lt; 2:
            continue
        else:
            front += str(idx)*(int(food[idx])//2)
    return front+&quot;0&quot;+front[::-1]</code></pre><p>for문 안이 더 단순하네...
그렇네....1//2 해봤자 몫이 0이라서 굳이 if문 처리가 필요 없었다ㅠㅠ</p>
<pre><code>def solution(food):
    answer = &#39;&#39;

    for i in range(1,len(food)):
        answer+=str(i)*(food[i]//2)

    return answer+&quot;0&quot;+answer[::-1]</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[코딩테스트 연습 7일차]]></title>
            <link>https://velog.io/@k_chae1/%EC%97%B0%EC%8A%B57%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@k_chae1/%EC%97%B0%EC%8A%B57%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Fri, 03 Feb 2023 07:39:18 GMT</pubDate>
            <description><![CDATA[<h2 id="lv1">Lv.1</h2>
<h3 id="시저-암호">시저 암호</h3>
<p><strong>틀린 코드</strong>
아스키코드를 써야하는 것만 감을 잡고 뼈대를 만들었다.
이 경우 n이 커지면 밀어도 다른 문자가 나온다.
알파벳 범위 내에서 돌려면 a,A를 이용한 수식이 필요하다.</p>
<blockquote>
<p>(chr((ord(j)-ord(&#39;A&#39;)+n)%26+ord(&#39;A&#39;)))</p>
</blockquote>
<pre><code>def solution(s, n):
    answer = []
    word=s.split(&quot; &quot;)

    for i in word:
        part=[]
        for j in i: 
            part.append(chr(ord(j)+n)) 
        result =&quot;&quot;.join(part) 

    answer.append(result)
    answer=&quot; &quot;.join(answer)
    return answer</code></pre><p><strong>수정 코드</strong></p>
<pre><code>def solution(s, n):
    answer = []
    word=s.split(&quot; &quot;)

    for i in word:
        part=[]
        for j in i: 
            if j.islower():
                part.append((chr((ord(j)-ord(&#39;a&#39;)+n)%26+ord(&#39;a&#39;))))
            else:
                part.append((chr((ord(j)-ord(&#39;A&#39;)+n)%26+ord(&#39;A&#39;))))
        part=&quot;&quot;.join(part)
        answer.append(part)
    answer = &quot; &quot;.join(answer)               

    return answer</code></pre><p>들여쓰기 실수해서 삽질함..;;;</p>
<h3 id="삼총사">삼총사</h3>
<p>내 코드</p>
<pre><code>from itertools import combinations

def solution(number):
    cnt = 0
    for c in combinations(number, 3):
        if sum(c) == 0:
            cnt += 1

    return cnt</code></pre><p>숏코딩
아직...이해가 안 됐다.
저 not sum(c) 부분을 모르겠다.</p>
<pre><code>from itertools import combinations

def solution(number):
    return sum(not sum(c) for c in combinations(number, 3))</code></pre><h3 id="최소-직사각형">최소 직사각형</h3>
<p>가로세로 신경 안 쓰는게 관건</p>
<pre><code>def solution(sizes):
    width = []
    height = []

    for i in range(len(sizes)):
        width.append(max(sizes[i])) # 둘중에 큰걸 가로로
        height.append(min(sizes[i])) #작은걸 세로로

    return max(width)*max(height)
</code></pre><p>이걸 그냥 한줄로...ㅠㅠ</p>
<pre><code>
def solution(sizes):
    return max(max(x) for x in sizes) * max(min(x) for x in sizes)</code></pre><h3 id="📎-sumlist-">📎 sum(list, [])</h3>
<blockquote>
<p><a href="https://stackoverflow.com/questions/33541947/what-does-the-built-in-function-sum-do-with-sumlist">https://stackoverflow.com/questions/33541947/what-does-the-built-in-function-sum-do-with-sumlist</a> </p>
</blockquote>
<pre><code>
solution = lambda sizes: max(sum(sizes, [])) * max(min(size) for size in sizes)</code></pre><h3 id="1차-비밀지도">[1차] 비밀지도</h3>
<h3 id="📎-bin">📎 bin()</h3>
<blockquote>
<p>0b가 붙은 이진수 변환</p>
</blockquote>
<h3 id="📎-zfilln">📎 zfill(n)</h3>
<blockquote>
<p>지정한 자리수에서 모자란 자리수에는 0을 채움</p>
</blockquote>
<pre><code>def solution(n, arr1, arr2):
    answer = []
    for i in range(n):
        a = bin(arr1[i] | arr2[i])[2:].zfill(n)
        b = a.replace(&quot;1&quot;, &quot;#&quot;).replace(&quot;0&quot;, &quot; &quot;)
        answer.append(b)

    return answer</code></pre><p>체력이 딸려서... 오늘은 여기까지... 
하루에 정해놓은 최저 개수가 3개니까...</p>
]]></description>
        </item>
    </channel>
</rss>