<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>ryeoooool.log</title>
        <link>https://velog.io/</link>
        <description>느려도 내 것으로 만드는게 좋잖아?</description>
        <lastBuildDate>Tue, 23 Jan 2024 02:00:32 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>ryeoooool.log</title>
            <url>https://velog.velcdn.com/images/young_ryeol/profile/9f9df135-3ae0-48f8-8bb6-d27c957bccd7/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. ryeoooool.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/young_ryeol" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[KT 에이블스쿨] 빅프로젝트]]></title>
            <link>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Tue, 23 Jan 2024 02:00:32 GMT</pubDate>
            <description><![CDATA[<h2 id="📚-빅프로젝트">📚 빅프로젝트</h2>
<p><strong>사용자 맞춤형 오디오북 서비스</strong></p>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/e96b274a-59c3-4dae-a77f-d8234a323b4a/image.jpeg" alt=""></p>
<h3 id="주제-선정-배경">주제 선정 배경</h3>
<ul>
<li><p>오디오북 시장규모 성장</p>
</li>
<li><p>다양한 플랫폼이 존재하나 TTS 음성이 부자연스러움</p>
</li>
<li><p>사용자가 목소리를 학습하여 책을 청취하는 서비스가 없음</p>
</li>
<li><p>개인화된 도서 청취 경험을 서비스하는 것을 목적</p>
<h3 id="주요-서비스">주요 서비스</h3>
</li>
<li><p>소셜 로그인</p>
</li>
<li><p>게시판</p>
</li>
<li><p>오디오북 청취</p>
</li>
<li><p>책 수요 변화에 따른 책 표지 생성</p>
</li>
<li><p>사용자가 학습한 음성으로 책 청취</p>
</li>
</ul>
<h3 id="활용-기술">활용 기술</h3>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/ff5995fc-9515-40c1-989f-e25cd19270f7/image.png" alt="">
<img src="https://velog.velcdn.com/images/young_ryeol/post/bb10447a-4b67-4b54-9c17-cbd57e258ba7/image.png" alt=""></p>
<h3 id="타-서비스와-차별점">타 서비스와 차별점</h3>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/43ed9eed-4b6e-4423-a03b-3e958891f4a5/image.png" alt=""></p>
<h3 id="웹-ui">웹 UI</h3>
<h4 id="홈-화면">홈 화면</h4>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/88cd9977-6323-4375-ab5e-61c03855ac95/image.png" alt=""></p>
<h4 id="로그인">로그인</h4>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/159ed353-9775-4804-9de2-8a3b0c2f99b0/image.png" alt=""></p>
<h4 id="메인-페이지">메인 페이지</h4>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/db186a49-9008-42a4-ab0b-9739b7205d4c/image.png" alt=""></p>
<h4 id="목소리-커스터마이징">목소리 커스터마이징</h4>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/9827d821-055e-48ff-83d9-462f5b047d31/image.png" alt=""></p>
<h4 id="도서-청취">도서 청취</h4>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/6b8fd4fe-40bd-400f-8701-60075f1f064d/image.png" alt=""></p>
<h4 id="책-표지-생성">책 표지 생성</h4>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/74441d87-6cd0-4406-b69b-752404fed2e1/image.png" alt=""></p>
<h4 id="기대효과">기대효과</h4>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/e586bef6-f6f5-46a1-b294-91c539ce0883/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[KT 에이블스쿨] 7차 미니프로젝트]]></title>
            <link>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-7%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-7%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Tue, 23 Jan 2024 01:50:43 GMT</pubDate>
            <description><![CDATA[<h2 id="🚗-7차-미니-프로젝트">🚗 7차 미니 프로젝트</h2>
<p><strong>미션: 수어를 통한 챗봇 웹피이지 만들기</strong></p>
<p><strong>Framework</strong> </p>
<p>Django</p>
<p><strong>목표</strong></p>
<ul>
<li>Django를 활용한 웹 페이지 만들기.</li>
<li>수어 번역 AI 모델링</li>
<li>ChatGPT API 연동</li>
<li>웹서비스 데모 구현</li>
</ul>
<p><strong>활용기술</strong></p>
<ul>
<li>ML-FLOW,</li>
<li>ChatGPT API</li>
<li>AWS 클라우드</li>
</ul>
<h3 id="mlflow-활용-모델관리">MLFLOW 활용 모델관리</h3>
<p>mlflow란?</p>
<p>모델의 실행을 추적(tracking), 모델링 결과를 저장, 관리, 배포 관리하도록 돕는 오픈 소스 도구</p>
<p>운영중인 모델 로딩하기 --&gt; model uri 지정하여 불러옴</p>
<pre><code class="language-python">mlflow.sklearn.log_model(model, &quot;model&quot;, registerd_model_name=&quot;RF_Model&quot;)

# 버전으로 가져오기
model_uri = &quot;models:/RF_model/6&quot;
model = mlflow.sklearn.load_model(model_url)

# 최신 버전으로 가져오기
model_uri = &quot;models:/RF_model/latest&quot;
model = mlflow.sklearn.load_model(model_url)

# 운영 중인 버전으로 가져오기
model_uri = &quot;models:/RF_model/production&quot;
model = mlflow.sklearn.load_model(model_url)
</code></pre>
<h3 id="서버-세팅">서버 세팅</h3>
<p>(1) 클라우드 환경 구축(Django 서버 구축하여 AWS로 배포)</p>
<ul>
<li>Django 서버 구축</li>
</ul>
<p>① 장고 프로젝트 준비</p>
<p>② 가상환경 만들기</p>
<p>$conda create -n &lt;가상환경명&gt; python=3.10 -y</p>
<p>$conda activate &lt;가상환경명&gt;</p>
<p>$conda env list</p>
<p>③ 필요 라이브러리 설치</p>
<p>$pip install -r requirements.txt</p>
<p>④ 장고 구동</p>
<p>$python manage.py runserver</p>
<p>⑤ 서버 접속 및 화면 확인 (<a href="http://127.0.0.1:8000/">http://127.0.0.1:8000/)</a>)</p>
<ul>
<li>AWS 서버 구축</li>
</ul>
<p>① VPC 생성</p>
<p>② 서브넷 생성</p>
<p>③ ec2 인스턴스 생성</p>
<ul>
<li>배포(로컬 소스를 서버로 이동)</li>
</ul>
<p>ssh 접속을 위한 putty 설정(콘솔 명령어 수행)</p>
<p>① putty 설치 링크</p>
<p><a href="https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html">https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html</a></p>
<p>② putty 접속 후 ppk 설정(계정은 ubuntu)</p>
<p>③ private key 등록 후 오픈</p>
<p>④ ssh 접속 성공</p>
<ul>
<li>접속 후 폴더 하나 생성</li>
</ul>
<p>$ mkdir deploy</p>
<ul>
<li>폴더 목록 확인(소문자 L 두개)</li>
</ul>
<p>$ ll</p>
<p>sftp 접속을 위한 winscp 설정(파일 전송 수행)</p>
<p>① winscp 설치 링크</p>
<p><a href="https://winscp.net/eng/index.php">https://winscp.net/eng/index.php</a></p>
<p><a href="https://winscp.net/eng/index.php"><strong>WinSCP</strong>
WinSCP is a popular free SFTP and FTP client for Windows, a powerful file manager that will improve your productivity. It supports also local-local mode and FTPS, S3, SCP and WebDAV protocols. Power users can automate WinSCP using .NET assembly.
winscp.net</a></p>
<p><a href="https://dthumb-phinf.pstatic.net/?src=%22https%3A%2F%2Fwinscp.net%2Fassets%2Fimages%2Flogos%2Flogo%40240.jpg%22&amp;type=ff120">https://dthumb-phinf.pstatic.net/?src=%22https%3A%2F%2Fwinscp.net%2Fassets%2Fimages%2Flogos%2Flogo%40240.jpg%22&amp;type=ff120</a></p>
<p>② 로그인&gt;고급&gt;private key 인증</p>
<p>③ 접속</p>
<p>④ 로컬 파일 영역에서 장고 소스를 찾아 서버로 드래그(전송)</p>
<ul>
<li>패키지 설치</li>
</ul>
<p>① putty에서 anaconda 다운로드</p>
<p>$wget <a href="https://repo.anaconda.com/archive/Anaconda3-2022.10-Linux-x86_64.sh">https://repo.anaconda.com/archive/Anaconda3-2022.10-Linux-x86_64.sh</a></p>
<p>② anaconda 파일 유효성 검증</p>
<p>$shasum -a 256 /home/ubuntu/Anaconda3-2022.10-Linux-x86_64.sh</p>
<p>③ anaconda 설치</p>
<p>$bash ./Anaconda3-2022.10-Linux-x86_64.sh</p>
<p>yes/no가 나올 때까지 스페이스바 후 yes 입력</p>
<p>④ 설치 후 putty 재접속하면 콘다 가상환경이 기본 설정됨</p>
<p>⑤ 파이썬 버전을 맞추기 위해 파이썬 3.10 기반의 가상환경 생성</p>
<p>$conda create -n &lt;가상환경명&gt; python=3.10 -y</p>
<p>가상환경 접속!</p>
<p>⑥ 장고 소스가 있는 폴더로 이동 후 패키지, 추가 라이브러리 설치</p>
<p>$cd deploy/&lt;폴더명&gt;</p>
<p>$pip install -r requirements_linux.txt</p>
<p>$sudo apt install libgl1-mesa-glx</p>
<ul>
<li>구동</li>
</ul>
<p>$sudo /home/ubuntu/anaconda3/envs/mini7/bin/python manage.py runserver 0:80</p>
<ul>
<li>터미널을 꺼도 웹이 구동 되도록 하는 법 --&gt; nohup 명령어 사용</li>
</ul>
<p>$nohup sudo /home/ubuntu/anaconda3/envs/mini7/bin/python manage.py runserve r 0:80&amp;</p>
<ul>
<li>서버 중단</li>
</ul>
<p>$sudo fuser -k -n tcp 80</p>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/273b5f04-9162-4be0-ab11-ab5cadaeab54/image.png" alt="">
<img src="https://velog.velcdn.com/images/young_ryeol/post/a501cd34-bbdd-4492-9108-374f80ad5a89/image.png" alt="">
<img src="https://velog.velcdn.com/images/young_ryeol/post/5c15d7bc-b156-41b2-8f59-ca10b41fa573/image.png" alt="">
<img src="https://velog.velcdn.com/images/young_ryeol/post/4cf7fae8-3d20-4e86-afca-9898abc42009/image.png" alt="">
<img src="https://velog.velcdn.com/images/young_ryeol/post/29a1a7f9-7c6e-4bfb-8fbb-704a29b62352/image.png" alt="">
<img src="https://velog.velcdn.com/images/young_ryeol/post/05a0713d-b039-4d7c-9044-493a22cc891d/image.png" alt=""></p>
<p>🚩7차 미니 프로젝트를 마치며</p>
<p>벌써 마지막 미니 프로젝트가 끝났다. 이번 프로젝트는 Django를 통한 웹 서비스 구현으로 수어 서비스를 진행했다. openai api키를 활용하여 서비스를 하니, 세상이 많이 바뀌었다는 것을 몸소 체험할 수 있었다. 또한 mlflow로 효과적인 모델 관리를 하고 AWS를 통한 배포까지 경험을 해보며 하나의 서비스를 완성할 수 있었던 경험이였다. 다음은 빅프로젝트! 가보자고👊</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[KT 에이블스쿨] 6차 미니프로젝트]]></title>
            <link>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-6%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-6%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Mon, 06 Nov 2023 04:57:02 GMT</pubDate>
            <description><![CDATA[<h2 id="🚗-6차-미니-프로젝트">🚗 6차 미니 프로젝트</h2>
<p>*<em>미션: 차량 공유업체의 차량 파손 여부 분류 *</em></p>
<p><strong>활용 데이터셋</strong> </p>
<p>자체 제작 데이터 : Car_images.zip</p>
<p><strong>도메인 이해</strong></p>
<p>차량공유업체에게 필요한 차량 파손 여부를 알려주는 서비스를 개발하는 것이 목표.
차량을 공유하고, 반납 시에 파손 여부를 자동화하는 것이다.</p>
<p><strong>데이터 분석 및 전처리</strong></p>
<ul>
<li>모델1 전처리</li>
</ul>
<pre><code># 압축 해제

data = zipfile.ZipFile(path+file1)

try :
    print(&#39;압축을 해제합니다.&#39;)
    data.extractall(path)
    print(&#39;압축 해제가 완료되었습니다.&#39;)
except :
    pass
    print(&#39;압축이 이미 해제되었거나 이미 폴더가 존재합니다.&#39;)

# 폴더별 이미지 데이터 갯수 확인

print(f&quot;정상 차량 이미지 데이터는 {len(glob.glob(path+&#39;normal/*&#39;))}장 입니다.&quot;)
print(f&quot;파손 차량 이미지 데이터는 {len(glob.glob(path+&#39;abnormal/*&#39;))}장 입니다.&quot;)

#정상 차량 이미지 데이터는 302장 입니다.
#파손 차량 이미지 데이터는 303장 입니다.
</code></pre><pre><code># Load &quot;normal&quot; images
normal_images = glob.glob(path + &#39;normal/*&#39;)
for image_path in normal_images:
    img = image.load_img(image_path, target_size=(280, 280))
    img = image.img_to_array(img)
    img = np.expand_dims(img, axis=0)
    X.append(img)


# Load &quot;abnormal&quot; images
abnormal_images = glob.glob(path + &#39;abnormal/*&#39;)
for image_path in abnormal_images:
    img = image.load_img(image_path, target_size=(280, 280))
    img = image.img_to_array(img)
    img = np.expand_dims(img, axis=0)
    X.append(img)


# Combine all images into a single numpy array
X = np.vstack(X)

print(f&quot;총 이미지 개수: {len(X)}&quot;)

#총 이미지 개수: 605</code></pre><pre><code># X와 Y 데이터를 분할
X_train, X_temp, Y_train, Y_temp = train_test_split(X, Y1, test_size=0.2, random_state=42)
X_valid, X_test, Y_valid, Y_test = train_test_split(X_temp, Y_temp, test_size=0.5, random_state=42)

# 각 데이터셋의 크기 확인
print(f&quot;Train set 크기: {len(X_train)}&quot;)
print(f&quot;Validation set 크기: {len(X_valid)}&quot;)
print(f&quot;Test set 크기: {len(X_test)}&quot;)

#Train set 크기: 484
#Validation set 크기: 60
#Test set 크기: 61</code></pre><ul>
<li>모델2 전처리<pre><code>import os
import shutil
import random
</code></pre></li>
</ul>
<h1 id="폴더-경로-설정">폴더 경로 설정</h1>
<p>project_dir = &#39;/content/drive/MyDrive/project/&#39;
source_normal_dir = os.path.join(project_dir, &quot;normal&quot;)
source_abnormal_dir = os.path.join(project_dir, &quot;abnormal&quot;)</p>
<p>train_dir = os.path.join(project_dir, &quot;Car_Images_train&quot;)
val_dir = os.path.join(project_dir, &quot;Car_Images_val&quot;)
test_dir = os.path.join(project_dir, &quot;Car_Images_test&quot;)</p>
<h1 id="대상-폴더-생성">대상 폴더 생성</h1>
<p>for dir_path in [train_dir, val_dir, test_dir]:
    os.makedirs(os.path.join(dir_path, &quot;normal&quot;), exist_ok=True)
    os.makedirs(os.path.join(dir_path, &quot;abnormal&quot;), exist_ok=True)</p>
<h1 id="이미지-파일-목록-가져오기">이미지 파일 목록 가져오기</h1>
<p>normal_images = os.listdir(source_normal_dir)
abnormal_images = os.listdir(source_abnormal_dir)</p>
<h1 id="이미지-무작위-섞기">이미지 무작위 섞기</h1>
<p>random.shuffle(normal_images)
random.shuffle(abnormal_images)</p>
<h1 id="이미지-분배-비율-설정-811">이미지 분배 비율 설정 (8:1:1)</h1>
<p>total_normal = len(normal_images)
total_abnormal = len(abnormal_images)</p>
<p>train_ratio = 0.8
val_ratio = 0.1
test_ratio = 0.1</p>
<p>train_normal_count = int(total_normal * train_ratio)
val_normal_count = int(total_normal * val_ratio)
test_normal_count = int(total_normal * test_ratio)</p>
<p>train_abnormal_count = int(total_abnormal * train_ratio)
val_abnormal_count = int(total_abnormal * val_ratio)
test_abnormal_count = int(total_abnormal * test_ratio)</p>
<h1 id="이미지를-대상-폴더로-복사">이미지를 대상 폴더로 복사</h1>
<p>for i in range(train_normal_count):
    image_name = normal_images[i]
    source_path = os.path.join(source_normal_dir, image_name)
    target_path = os.path.join(train_dir, &quot;normal&quot;, image_name)
    shutil.copy(source_path, target_path)</p>
<p>for i in range(train_abnormal_count):
    image_name = abnormal_images[i]
    source_path = os.path.join(source_abnormal_dir, image_name)
    target_path = os.path.join(train_dir, &quot;abnormal&quot;, image_name)
    shutil.copy(source_path, target_path)</p>
<p>for i in range(train_normal_count, train_normal_count + val_normal_count):
    image_name = normal_images[i]
    source_path = os.path.join(source_normal_dir, image_name)
    target_path = os.path.join(val_dir, &quot;normal&quot;, image_name)
    shutil.copy(source_path, target_path)</p>
<p>for i in range(train_abnormal_count, train_abnormal_count + val_abnormal_count):
    image_name = abnormal_images[i]
    source_path = os.path.join(source_abnormal_dir, image_name)
    target_path = os.path.join(val_dir, &quot;abnormal&quot;, image_name)
    shutil.copy(source_path, target_path)</p>
<p>for i in range(train_normal_count + val_normal_count, total_normal):
    image_name = normal_images[i]
    source_path = os.path.join(source_normal_dir, image_name)
    target_path = os.path.join(test_dir, &quot;normal&quot;, image_name)
    shutil.copy(source_path, target_path)</p>
<p>for i in range(train_abnormal_count + val_abnormal_count, total_abnormal):
    image_name = abnormal_images[i]
    source_path = os.path.join(source_abnormal_dir, image_name)
    target_path = os.path.join(test_dir, &quot;abnormal&quot;, image_name)
    shutil.copy(source_path, target_path)</p>
<pre><code>
**모델링**
- 모델 1</code></pre><p>model = Sequential()
model.add(Conv2D(32, (3, 3), activation=&#39;relu&#39;, input_shape=(280, 280, 3)))
model.add(MaxPool2D((2, 2)))
model.add(Conv2D(64, (3, 3), activation=&#39;relu&#39;))
model.add(MaxPool2D((2, 2)))
model.add(Conv2D(128, (3, 3), activation=&#39;relu&#39;))
model.add(MaxPool2D((2, 2)))
model.add(Flatten())
model.add(Dense(128, activation=&#39;relu&#39;))
model.add(Dense(1, activation=&#39;sigmoid&#39;))
model.compile(optimizer=&#39;adam&#39;, loss=&#39;binary_crossentropy&#39;, metrics=[&#39;accuracy&#39;])
early_stopping = EarlyStopping(patience=5, restore_best_weights=True)</p>
<p>history = model.fit(X_train, Y_train, epochs=50, validation_data=(X_valid, Y_valid), callbacks=[early_stopping])</p>
<h1 id="모델-평가">모델 평가</h1>
<p>Y_pred = model.predict(X_test)
Y_pred_binary = (Y_pred &gt; 0.5)
print(&quot;Confusion Matrix:&quot;)
print(confusion_matrix(Y_test, Y_pred_binary))
print(&quot;Classification Report:&quot;)
print(classification_report(Y_test, Y_pred_binary))</p>
<pre><code>![](https://velog.velcdn.com/images/young_ryeol/post/8c198804-5625-430f-a1a6-d5e1f661ab2f/image.png)


- ResNet50</code></pre><p>import keras
from keras.applications import ResNet50
from keras.models import Sequential
from keras.layers import Dense, GlobalAveragePooling2D
from keras.callbacks import EarlyStopping
from sklearn.metrics import classification_report, confusion_matrix</p>
<h1 id="resnet-50-모델-불러오기-weightsimagenet은-사전-훈련된-가중치를-사용">ResNet-50 모델 불러오기 (weights=&#39;imagenet&#39;은 사전 훈련된 가중치를 사용)</h1>
<p>base_model = ResNet50(weights=&#39;imagenet&#39;, include_top=False)</p>
<h1 id="모델-설계">모델 설계</h1>
<p>model3 = Sequential()</p>
<h1 id="resnet-50-모델을-포함하고-global-average-pooling-레이어를-추가">ResNet-50 모델을 포함하고, Global Average Pooling 레이어를 추가</h1>
<p>model3.add(base_model)
model3.add(GlobalAveragePooling2D())</p>
<h1 id="fully-connected-레이어-추가">Fully Connected 레이어 추가</h1>
<p>model3.add(Dense(256, activation=&#39;relu&#39;))
model3.add(Dense(1, activation=&#39;sigmoid&#39;))</p>
<h1 id="모델-컴파일">모델 컴파일</h1>
<p>model3.compile(optimizer=&#39;adam&#39;, loss=&#39;binary_crossentropy&#39;, metrics=[&#39;accuracy&#39;])</p>
<h1 id="early-stopping-설정">Early Stopping 설정</h1>
<p>early_stopping = EarlyStopping(patience=5, restore_best_weights=True)
lr = ReduceLROnPlateau(monitor = &#39;val_accuracy&#39;,
                       factor = 0.1,
                       patience = 3,
                       verbose = 1,
                       mode = &#39;auto&#39;,
                       min_delta = 0.01,
                       min_lr = 0)
checkpoint = ModelCheckpoint(&quot;model_checkpoint.h5&quot;, save_best_only=True)</p>
<p>x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(128, activation=&#39;relu&#39;)(x)
x = Dropout(0.3)(x)
predictions = Dense(1, activation=&#39;sigmoid&#39;)(x)</p>
<p>resnet50 = Model(inputs=base_model.input , outputs=predictions)</p>
<p>resnet50.compile(loss=keras.losses.binary_crossentropy,
               metrics=[&#39;accuracy&#39;],
               optimizer= keras.optimizers.Adam(learning_rate = 0.0001))</p>
<p>history3 = resnet50.fit(X_train, Y_train, epochs=9, validation_data=(X_valid, Y_valid), callbacks=[early_stopping,lr,checkpoint])</p>
<h1 id="모델-평가-1">모델 평가</h1>
<p>Y_pred = resnet50.predict(X_test)
Y_pred_binary = (Y_pred &gt; 0.5)
print(&quot;Confusion Matrix:&quot;)
print(confusion_matrix(Y_test, Y_pred_binary))
print(&quot;Classification Report:&quot;)
print(classification_report(Y_test, Y_pred_binary))</p>
<pre><code>
![](https://velog.velcdn.com/images/young_ryeol/post/89a9cc96-bdbd-4514-ad2f-2297e74c4ecc/image.png)

- Data Augmentation</code></pre><p>train_datagen = ImageDataGenerator(
    rescale=1./255,  # 이미지 픽셀값 0<del>255를 0</del>1로 정규화
    rotation_range=10,  # 이미지 회전 각도 범위
    zoom_range=0.3,  # 이미지 확대/축소 범위
    brightness_range=[0.5, 1.5],  # 이미지 명도 범위
    channel_shift_range=50,  # 이미지 채도 범위
    horizontal_flip=True,  # 수평 방향으로 이미지 뒤집기
    vertical_flip=True,  # 수직 방향으로 이미지 뒤집기
    fill_mode=&#39;nearest&#39;  # 이미지 변환 후 빈 영역을 채우는 방법
)</p>
<p>valid_datagen = ImageDataGenerator(
    rescale=1./255,
)</p>
<p>test_datagen = ImageDataGenerator(
    rescale=1./255,
)</p>
<p>train_generator = train_datagen.flow_from_directory(
          train_path,
          target_size=(280, 280),
          class_mode=&#39;binary&#39;,
          shuffle = True,
          )</p>
<p>valid_generator = valid_datagen.flow_from_directory(
          valid_path,
          target_size=(280, 280),
          class_mode=&#39;binary&#39;,
          shuffle = True,
          )</p>
<p>test_generator = test_datagen.flow_from_directory(
          test_path,
          target_size=(280, 280),
          class_mode=&#39;binary&#39;,
          shuffle = False,
          )</p>
<pre><code>
- VGG16</code></pre><p>from tensorflow.keras.applications import VGG16
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Dense</p>
<h1 id="vgg16-모델-불러오기-사전-학습된-가중치를-포함">VGG16 모델 불러오기 (사전 학습된 가중치를 포함)</h1>
<p>base_model = VGG16(weights=&#39;imagenet&#39;, include_top=False, input_shape=(280, 280, 3))</p>
<h1 id="vgg16-모델의-가중치를-동결-fine-tuning-전에-동결하는-것이-일반적">VGG16 모델의 가중치를 동결 (fine-tuning 전에 동결하는 것이 일반적)</h1>
<p>for layer in base_model.layers:
    layer.trainable = False</p>
<h1 id="새로운-분류-레이어를-추가한-모델-설계">새로운 분류 레이어를 추가한 모델 설계</h1>
<p>vggmodel = Sequential()
vggmodel.add(base_model)  # VGG16 모델을 추가
vggmodel.add(Flatten())  # Flatten 레이어 추가
vggmodel.add(Dense(128, activation=&#39;relu&#39;))  # 완전 연결(Dense) 레이어 추가
vggmodel.add(Dense(1, activation=&#39;sigmoid&#39;))  # 이진 분류를 위한 출력 레이어 (클래스가 2개인 경우)</p>
<h1 id="모델-컴파일-1">모델 컴파일</h1>
<p>vggmodel.compile(optimizer=&#39;adam&#39;, loss=&#39;binary_crossentropy&#39;, metrics=[&#39;accuracy&#39;])</p>
<h1 id="모델-요약-확인">모델 요약 확인</h1>
<p>vggmodel.summary()</p>
<p>from tensorflow.keras.models import load_model</p>
<h1 id="early-stopping-콜백-설정">Early Stopping 콜백 설정</h1>
<p>early_stopping = EarlyStopping(monitor=&#39;val_loss&#39;, patience=5, verbose=1, restore_best_weights=True)</p>
<h1 id="modelcheckpoint-콜백-설정-최적-가중치-저장">ModelCheckpoint 콜백 설정 (최적 가중치 저장)</h1>
<p>model_checkpoint = ModelCheckpoint(&#39;best_model.h5&#39;, monitor=&#39;val_loss&#39;, save_best_only=True)</p>
<p>lr = ReduceLROnPlateau(monitor = &#39;val_accuracy&#39;,
                       factor = 0.1,
                       patience = 3,
                       verbose = 1,
                       mode = &#39;auto&#39;,
                       min_delta = 0.01,
                       min_lr = 0)</p>
<h1 id="모델-학습">모델 학습</h1>
<p>epochs = 100  # 적절한 학습 에포크 수를 설정하세요.</p>
<p>history = vggmodel.fit(
    train_datagen.flow_from_directory(train_path, target_size=(280, 280), class_mode=&#39;binary&#39;, batch_size=32),
    validation_data=valid_generator,
    epochs=epochs,
    callbacks=[early_stopping, model_checkpoint,lr],  # Early Stopping 및 ModelCheckpoint 콜백 사용
    verbose=1
)</p>
<h1 id="최적-모델-가중치를-불러옵니다">최적 모델 가중치를 불러옵니다.</h1>
<p>best_model = load_model(&#39;best_model.h5&#39;)</p>
<h1 id="최적-모델로-평가">최적 모델로 평가</h1>
<p>test_loss, test_accuracy = best_model.evaluate(test_generator, verbose=1)
print(f&#39;Test Accuracy with Best Model: {test_accuracy * 100:.2f}%&#39;)</p>
<h1 id="테스트-데이터로-모델-평가">테스트 데이터로 모델 평가</h1>
<p>test_results = best_model.evaluate(test_generator, steps=test_generator.samples // test_generator.batch_size)</p>
<h1 id="예측-결과-계산">예측 결과 계산</h1>
<p>Y_pred = best_model.predict(test_generator)
Y_pred_binary = (Y_pred &gt; 0.5)</p>
<h1 id="모델-평가-결과-출력">모델 평가 결과 출력</h1>
<p>print(&quot;Test Loss:&quot;, test_results[0])
print(&quot;Test Accuracy:&quot;, test_results[1])</p>
<h1 id="confusion-matrix-및-classification-report-출력">Confusion Matrix 및 Classification Report 출력</h1>
<p>print(&quot;Confusion Matrix:&quot;)
print(confusion_matrix(test_generator.classes, Y_pred_binary))
print(&quot;Classification Report:&quot;)
print(classification_report(test_generator.classes, Y_pred_binary))</p>
<pre><code>
![](https://velog.velcdn.com/images/young_ryeol/post/a41242ae-702d-4a32-a97e-c1f2df2fbe28/image.png)


- EfficientNetV2B0</code></pre><p>from tensorflow.keras.applications import EfficientNetV2B0
keras.backend.clear_session()</p>
<p>base_model = EfficientNetV2B0(weights=&#39;imagenet&#39;, include_top=False, input_shape=(280, 280,3))
base_model.trainable = True</p>
<h1 id="새로운-분류-레이어를-추가한-모델-설계-1">새로운 분류 레이어를 추가한 모델 설계</h1>
<p>effmodel = Sequential()
effmodel.add(base_model)  # EfficientNetV2B0 모델을 추가
effmodel.add(Flatten())  # Flatten 레이어 추가
effmodel.add(Dense(128, activation=&#39;relu&#39;))  # 완전 연결(Dense) 레이어 추가
effmodel.add(Dense(1, activation=&#39;sigmoid&#39;))  # 이진 분류를 위한 출력 레이어 (클래스가 2개인 경우)</p>
<h1 id="모델-컴파일-2">모델 컴파일</h1>
<p>effmodel.compile(optimizer=&#39;adam&#39;, loss=&#39;binary_crossentropy&#39;, metrics=[&#39;accuracy&#39;])</p>
<h1 id="모델-요약-확인-1">모델 요약 확인</h1>
<p>effmodel.summary()</p>
<p>from tensorflow.keras.models import load_model</p>
<h1 id="early-stopping-콜백-설정-1">Early Stopping 콜백 설정</h1>
<p>early_stopping = EarlyStopping(monitor=&#39;val_loss&#39;, patience=5, verbose=1, restore_best_weights=True)</p>
<h1 id="modelcheckpoint-콜백-설정-최적-가중치-저장-1">ModelCheckpoint 콜백 설정 (최적 가중치 저장)</h1>
<p>model_checkpoint = ModelCheckpoint(&#39;best_model_eff.h5&#39;, monitor=&#39;val_loss&#39;, save_best_only=True)</p>
<p>lr = ReduceLROnPlateau(monitor = &#39;val_accuracy&#39;,
                       factor = 0.1,
                       patience = 3,
                       verbose = 1,
                       mode = &#39;auto&#39;,
                       min_delta = 0.01,
                       min_lr = 0)</p>
<h1 id="모델-학습-1">모델 학습</h1>
<p>epochs = 100  # 적절한 학습 에포크 수를 설정하세요.</p>
<p>history = effmodel.fit(
    train_datagen.flow_from_directory(train_path, target_size=(280, 280), class_mode=&#39;binary&#39;, batch_size=32),
    validation_data=valid_generator,
    epochs=epochs,
    callbacks=[early_stopping, model_checkpoint,lr],  # Early Stopping 및 ModelCheckpoint 콜백 사용
    verbose=1
)</p>
<h1 id="최적-모델-가중치를-불러옵니다-1">최적 모델 가중치를 불러옵니다.</h1>
<p>best_model_eff = load_model(&#39;best_model_eff.h5&#39;)</p>
<h1 id="최적-모델로-평가-1">최적 모델로 평가</h1>
<p>test_loss, test_accuracy = best_model_eff.evaluate(test_generator, verbose=1)
print(f&#39;Test Accuracy with Best Model: {test_accuracy * 100:.2f}%&#39;)</p>
<h1 id="테스트-데이터로-모델-평가-1">테스트 데이터로 모델 평가</h1>
<p>test_results = best_model_eff.evaluate(test_generator, steps=test_generator.samples // test_generator.batch_size)</p>
<h1 id="예측-결과-계산-1">예측 결과 계산</h1>
<p>Y_pred = best_model_eff.predict(test_generator)
Y_pred_binary = (Y_pred &gt; 0.5)</p>
<h1 id="모델-평가-결과-출력-1">모델 평가 결과 출력</h1>
<p>print(&quot;Test Loss:&quot;, test_results[0])
print(&quot;Test Accuracy:&quot;, test_results[1])</p>
<h1 id="confusion-matrix-및-classification-report-출력-1">Confusion Matrix 및 Classification Report 출력</h1>
<p>print(&quot;Confusion Matrix:&quot;)
print(confusion_matrix(test_generator.classes, Y_pred_binary))
print(&quot;Classification Report:&quot;)
print(classification_report(test_generator.classes, Y_pred_binary))</p>
<pre><code>
![](https://velog.velcdn.com/images/young_ryeol/post/4f52587e-3564-4690-93c8-62371ec72e2d/image.png)


&gt; 🚩6차 미니 프로젝트를 마치며
눈 깜빡하니 벌써 미프 6차다. 이번 프로젝트는 차량 파손 여부를 판별하는 주제로 진행했다. 이미지라서 그런지 학습 중에 런타임이 끊기기도 했다. 이번에 프로젝트에서도 느꼈듯이 pre-trained model을 잘 사용하는 것이 성능을 높일 수 있는 지름길이다. 미프 6차가 끝났다는 건 벌써 6개월의 교육기간 중 3개월이 지났다는 뜻! 3개월동안 성장한 부분도 있지만, 아쉬운 부분도 있다. 남은 3개월은 더 알차게 보내보자!</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[코테 준비 : day22] ]]></title>
            <link>https://velog.io/@young_ryeol/%EC%BD%94%ED%85%8C-%EC%A4%80%EB%B9%84-day22</link>
            <guid>https://velog.io/@young_ryeol/%EC%BD%94%ED%85%8C-%EC%A4%80%EB%B9%84-day22</guid>
            <pubDate>Sat, 28 Oct 2023 08:31:01 GMT</pubDate>
            <description><![CDATA[<h4 id="해야지-해야해">해야지,, 해야해!!!</h4>
<blockquote>
<ol>
<li>한 줄로 서기
<a href="https://www.acmicpc.net/problem/1138">https://www.acmicpc.net/problem/1138</a>
<img src="https://velog.velcdn.com/images/young_ryeol/post/7786de1f-ea50-42d1-aeab-e66115994b94/image.png" alt=""></li>
</ol>
</blockquote>
<pre><code>
n = int(input())
height = list(map(int, input().split()))
answer = [0] * n

for i in range(n):
    cnt = 0 
    for j in range(n):
        if cnt == height[i] and answer[j] == 0:
            answer[j] = i + 1
            break
        elif answer[j] == 0:
            cnt += 1

print(*answer)
</code></pre><blockquote>
<ol start="2">
<li>1, 2, 3 더하기 4
<a href="https://www.acmicpc.net/problem/15989">https://www.acmicpc.net/problem/15989</a>
<img src="https://velog.velcdn.com/images/young_ryeol/post/4dc897a8-012c-4f89-bd59-50f93676728f/image.png" alt=""></li>
</ol>
</blockquote>
<pre><code>import sys
input = sys.stdin.readline
dp = [1]*(10001)

for i in range(2,10001):
    dp[i] += dp[i - 2]

for i in range(3,10001):
    dp[i] += dp[i - 3]

T = int(input())

for _ in range(T):
    n = int(input())
    print(dp[n])

</code></pre><blockquote>
<p>3.트럭
<a href="https://www.acmicpc.net/problem/13335">https://www.acmicpc.net/problem/13335</a>
<img src="https://velog.velcdn.com/images/young_ryeol/post/48b710e3-bf9c-4e18-8801-b12019490491/image.png" alt=""></p>
</blockquote>
<pre><code># 트럭 수 n
# 다리길이 w
# 다리 하중 L

n,w,L=map(int,input().split())
tw=list(map(int,input().split()))
bridge = [0] * w
second=0
while bridge:
    second += 1
    bridge.pop(0)
    if tw:
        if sum(bridge) + tw[0] &lt;= L:
            bridge.append(tw.pop(0))
        else:
            bridge.append(0)
print(second)


</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[KT 에이블스쿨] 5차 미니프로젝트]]></title>
            <link>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-5%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-jsx9rh06</link>
            <guid>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-5%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-jsx9rh06</guid>
            <pubDate>Sat, 28 Oct 2023 07:03:30 GMT</pubDate>
            <description><![CDATA[<h2 id="🏃♂️-5차-미니-프로젝트">🏃‍♂️ 5차 미니 프로젝트</h2>
<p>*<em>미션: 스마트폰 센서 기반 데이터를 활용한 행동 인식 *</em></p>
<p><strong>활용 데이터셋</strong> </p>
<p>UCL Machine Learning Repository(Tabular) - data.csv</p>
<p><strong>도메인 이해</strong></p>
<p>다양한 센서 데이터를 통해 사람의 모션을 인식하는 것이다.</p>
<p>가속도 센서 : 일직선으로 움직이는 물체의 선형의 가속도를 측정하는 센서
자이로스코프 센서 : 회전하는 물체의 각속도를 측정하는 센서</p>
<p>x,y,z로 나눠져있다. 즉 일어서고, 쓰러지는 등 모션에 따라 값이 다를 것이므로 잘 관찰할 것</p>
<p>피쳐가 561개로 많다. 수많은 피쳐들을 모두 살펴보는 것은 힘들기에 선택과 집중을 해야한다</p>
<p>모션 분류</p>
<ul>
<li>STANDING</li>
<li>SITTING</li>
<li>LAYING</li>
<li>WAIKING</li>
<li>WAIKING_UPSTAIRS</li>
<li>WAIKING_DOWNSTAIRS</li>
</ul>
<p>** ✔️데이터 분석**</p>
<pre><code>import matplotlib.pyplot as plt

# 막대 그래프 생성
plt.figure(figsize=(10, 6))
category_counts.plot(kind=&#39;bar&#39;)
plt.title(&#39;Activity별 빈도수&#39;)
plt.xlabel(&#39;Activity&#39;)
plt.ylabel(&#39;빈도수&#39;)
plt.xticks(rotation=45)  
plt.show()
</code></pre><p><img src="https://velog.velcdn.com/images/young_ryeol/post/66be78e2-c944-448d-8312-a9a3fd30ee69/image.png" alt=""></p>
<p>클래스는 불균형없이 괜찮은 수준으로 보여진다.</p>
<p>다음으로 피처 중요도를 확인한다. 이는 나중에 변수를 추출할 때 사용될 것이다.</p>
<pre><code># 2. features와 변수 중요도 결과 병합
merged_data_01 = pd.merge(features, fi_df_all, left_on=&#39;feature_name&#39;, right_on=&#39;feature_name&#39;, how=&#39;inner&#39;)

# 3. sensor 별 중요도 합계 계산 및 상위 변수 그룹별 비교 분석
sensor_importance = merged_data_01.groupby(&#39;sensor&#39;)[&#39;feature_importance&#39;].sum().reset_index()
sensor_importance = sensor_importance.sort_values(by=&#39;feature_importance&#39;, ascending=False)

# 4. sensor + agg 별 중요도 합계 계산 및 상위 변수 그룹별 비교 분석
sensor_agg_importance = merged_data_01.groupby([&#39;sensor&#39;, &#39;agg&#39;])[&#39;feature_importance&#39;].sum().reset_index()
sensor_agg_importance = sensor_agg_importance.sort_values(by=&#39;feature_importance&#39;, ascending=False)

merged_data_01.rename(columns={&#39;feature_importance&#39;: &#39;feature_importance_01&#39;}, inplace=True)</code></pre><p><img src="https://velog.velcdn.com/images/young_ryeol/post/e88e6698-9c0e-4f5c-ab2a-5736b2a061bd/image.png" alt=""></p>
<p>다음으로 6개의 행동에 대해 정적, 동적행동으로 구분해서 분석해보자.</p>
<pre><code>data[&#39;is_dynamic&#39;] = data[&#39;Activity&#39;].apply(lambda x: 0 if x in [&quot;STANDING&quot;, &quot;SITTING&quot;, &quot;LAYING&quot;] else 1)

# 2. features와 변수 중요도 결과 병합
merged_data_02 = pd.merge(features, fi_df_all, left_on=&#39;feature_name&#39;, right_on=&#39;feature_name&#39;, how=&#39;inner&#39;)

# 3. sensor 별 중요도 합계 계산 및 상위 변수 그룹별 비교 분석
sensor_importance = merged_data_02.groupby(&#39;sensor&#39;)[&#39;feature_importance&#39;].sum().reset_index()
sensor_importance = sensor_importance.sort_values(by=&#39;feature_importance&#39;, ascending=False)

# 상위 변수 그룹별 비교 분석을 위한 코드
# sensor_importance 에서 필요한 그룹만 선택하거나 시각화 등의 분석을 수행합니다.

# 4. sensor + agg 별 중요도 합계 계산 및 상위 변수 그룹별 비교 분석
sensor_agg_importance = merged_data_02.groupby([&#39;sensor&#39;, &#39;agg&#39;])[&#39;feature_importance&#39;].sum().reset_index()
sensor_agg_importance = sensor_agg_importance.sort_values(by=&#39;feature_importance&#39;, ascending=False)</code></pre><p>이 후 개별 동작에 대해 분석한다. STANDING,SITTING 등 6개 동작을 하나씩 분석해본다. 아래 코드를 수정하며 6번 반복했다.</p>
<pre><code>sample=pd.read_csv(r&#39;/content/drive/MyDrive/2023.10.25_미니프로젝트5차_실습자료밀 데이터/데이터/data01_train.csv&#39;)

sample[&#39;is_sitting&#39;] = (sample[&#39;Activity&#39;] == &#39;SITTING&#39;).astype(int)
sample.drop(&#39;Activity&#39;, axis=1, inplace=True)

from sklearn.model_selection import train_test_split

# 특성과 목표 변수 선택
x = sample.drop([&#39;is_sitting&#39;], axis=1)
y = sample[&#39;is_sitting&#39;]

# 데이터 분할
x_train, x_valid, y_train, y_valid = train_test_split(x, y, test_size=0.2, random_state=42)

from sklearn.ensemble import RandomForestClassifier

# 랜덤 포레스트 기본 모델 생성
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)
rf_model.fit(x_train, y_train)

# 모델 평가
y_pred = rf_model.predict(x_valid)
accuracy = accuracy_score(y_valid, y_pred)
print(&quot;정확도:&quot;, accuracy)

importance = rf_model.feature_importances_
feature_names = x.columns

fi_df_5 = plot_feature_importance(importance, feature_names, topn=5)
print(fi_df_5)

fi_df_all = plot_feature_importance(importance, feature_names, topn=&#39;all&#39;)

# 2. features와 변수 중요도 결과 병합
merged_data_04 = pd.merge(features, fi_df_all, left_on=&#39;feature_name&#39;, right_on=&#39;feature_name&#39;, how=&#39;inner&#39;)

merged_data_04.rename(columns={&#39;feature_importance&#39;: &#39;feature_importance_04&#39;}, inplace=True)
merged_data_04
# 3. sensor 별 중요도 합계 계산 및 상위 변수 그룹별 비교 분석
sensor_importance = merged_data_04.groupby(&#39;sensor&#39;)[&#39;feature_importance_04&#39;].sum().reset_index()
sensor_importance = sensor_importance.sort_values(by=&#39;feature_importance_04&#39;, ascending=False)

# 상위 변수 그룹별 비교 분석을 위한 코드
# sensor_importance 에서 필요한 그룹만 선택하거나 시각화 등의 분석을 수행합니다.

# 4. sensor + agg 별 중요도 합계 계산 및 상위 변수 그룹별 비교 분석
sensor_agg_importance = merged_data_04.groupby([&#39;sensor&#39;, &#39;agg&#39;])[&#39;feature_importance_04&#39;].sum().reset_index()
sensor_agg_importance = sensor_agg_importance.sort_values(by=&#39;feature_importance_04&#39;, ascending=False)

# 출력
print(&quot;Sensor별 중요한 변수 그룹:&quot;)
print(sensor_importance)

print(&quot;Sensor+Agg별 중요한 변수 그룹:&quot;)
print(sensor_agg_importance)</code></pre><p>마지막으로 위에서 확인한 관점별 피쳐 중요도들을 하나의 데이터프레임으로 합쳐보았다.</p>
<ul>
<li>관점1 : 6개 행동 구분</li>
<li>관점2 : 동적, 정적 행동 구분</li>
<li>관점3 : Standing 여부 구분</li>
<li>관점4 : Sitting 여부 구분</li>
<li>관점5 : Laying 여부 구분</li>
<li>관점6 : Walking 여부 구분</li>
<li>관점7 : Walking_upstairs 여부 구분</li>
<li>관점8 : Walking_downstairs 여부 구분<pre><code>merged_data_01 = pd.merge(merged_data_01, merged_data_02, on=[&quot;sensor&quot;, &quot;agg&quot;, &quot;axis&quot;, &quot;feature_name&quot;], how=&quot;inner&quot;)
merged_data_01 = pd.merge(merged_data_01, merged_data_03, on=[&quot;sensor&quot;, &quot;agg&quot;, &quot;axis&quot;, &quot;feature_name&quot;], how=&quot;inner&quot;)
merged_data_01 = pd.merge(merged_data_01, merged_data_04, on=[&quot;sensor&quot;, &quot;agg&quot;, &quot;axis&quot;, &quot;feature_name&quot;], how=&quot;inner&quot;)
merged_data_01 = pd.merge(merged_data_01, merged_data_05, on=[&quot;sensor&quot;, &quot;agg&quot;, &quot;axis&quot;, &quot;feature_name&quot;], how=&quot;inner&quot;)
merged_data_01 = pd.merge(merged_data_01, merged_data_06, on=[&quot;sensor&quot;, &quot;agg&quot;, &quot;axis&quot;, &quot;feature_name&quot;], how=&quot;inner&quot;)
merged_data_01 = pd.merge(merged_data_01, merged_data_07, on=[&quot;sensor&quot;, &quot;agg&quot;, &quot;axis&quot;, &quot;feature_name&quot;], how=&quot;inner&quot;)
merged_data = pd.merge(merged_data_01, merged_data_08, on=[&quot;sensor&quot;, &quot;agg&quot;, &quot;axis&quot;, &quot;feature_name&quot;], how=&quot;inner&quot;)</code></pre></li>
</ul>
<p>** ✔️모델링**</p>
<pre><code>import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
import xgboost as xgb
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import accuracy_score

def create_classification_models(data):
    # Step 1: Create a model to classify static (0) or dynamic (1) activities
    data[&#39;Activity_dynamic&#39;] = data[&#39;Activity&#39;].apply(lambda x: 0 if x in [&quot;STANDING&quot;, &quot;SITTING&quot;, &quot;LAYING&quot;] else 1)

    # Step 2: Create models for detailed activity classification
    x = data.drop(columns=[&#39;Activity&#39;, &#39;Activity_dynamic&#39;])
    y1 = data[&#39;Activity&#39;]
    y2 = data[&#39;Activity_dynamic&#39;]

    # Split the data for both stage 1 and stage 2 models
    x_train, x_valid, y_train_01, y_valid_01, y_train_02, y_valid_02 = train_test_split(x, y1, y2, test_size=0.2, random_state=42)

    # Stage 1 model: Classify static (0) or dynamic (1)
    model_stage1 = LogisticRegression(C=20, max_iter=1000)
    model_stage1.fit(x_train, y_train_02)


    # Static (0) classification model
    x_static = x_train[y_train_02 == 0]
    y_static = y_train_01[y_train_02 == 0]

    model_static = RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42)
    model_static.fit(x_static, y_static)

    # Dynamic (1) classification model
    x_dynamic = x_train[y_train_02 == 1]
    y_dynamic = y_train_01[y_train_02 == 1]
    model_dynamic = LogisticRegression(C=20, max_iter=1000)
    model_dynamic.fit(x_dynamic, y_dynamic)

    return model_stage1, model_static, model_dynamic, x_valid, y_valid_01

def main():
    path=&#39;/content/drive/MyDrive/2023.10.25_미니프로젝트5차_실습자료밀 데이터/데이터/data01_train.csv&#39;
    data = pd.read_csv(path)
    data.drop(columns=[&#39;subject&#39;], inplace=True)

    model_stage1, model_static, model_dynamic, x_valid, y_valid_01 = create_classification_models(data)

    # Predictions using the models
    y_pred_stage1 = model_stage1.predict(x_valid)
    y_pred_static = model_static.predict(x_valid[y_pred_stage1 == 0])
    y_pred_dynamic = model_dynamic.predict(x_valid[y_pred_stage1 == 1])

    # Calculate accuracies
    accuracy_stage1 = accuracy_score(y_valid_02, y_pred_stage1)
    accuracy_static = accuracy_score(y_valid_01[y_pred_stage1 == 0], y_pred_static)
    accuracy_dynamic = accuracy_score(y_valid_01[y_pred_stage1 == 1], y_pred_dynamic)

    print(f&quot;Stage 1 Model Accuracy: {accuracy_stage1}&quot;)
    print(f&quot;Static (0) Classification Model Accuracy: {accuracy_static}&quot;)
    print(f&quot;Dynamic (1) Classification Model Accuracy: {accuracy_dynamic}&quot;)
    total_samples = len(y_valid_02)
    total_static_samples = len(y_pred_static)
    total_dynamic_samples = len(y_pred_dynamic)

    weighted_accuracy = (accuracy_stage1 * total_samples +
                        accuracy_static * total_static_samples +
                        accuracy_dynamic * total_dynamic_samples) / (total_samples + total_static_samples + total_dynamic_samples)

    print(f&quot;전체 정확도: {weighted_accuracy}&quot;)

    # Assuming y_pred_static and y_pred_dynamic are NumPy arrays or lists
    y_pred_static_list = y_pred_static.tolist()
    y_pred_dynamic_list = y_pred_dynamic.tolist()

    # Combine the two lists
    combined_predictions = y_pred_static_list + y_pred_dynamic_list

    # Create a DataFrame for the combined results
    results_df = pd.DataFrame({&#39;combined_predictions&#39;: combined_predictions})

    # Save the DataFrame to a CSV file
    results_df.to_csv(&#39;./results.csv&#39;, index=False)

if __name__ == &quot;__main__&quot;:
    main()
</code></pre><p>위 코드는 먼저 데이터를 정적, 동적으로 구분한다. 그리고 정적인 것에 대해 3가지 행동으로 분류, 동적인 것에 대해 3가지 행동으로 분류한다. 즉 3개의 모델을 사용하여 하나의 프로세스로 만들어서 함수화한 것이다. 내일은 위 내용을 바탕으로 캐글대회를 참가한다! 데이터가 바뀔 것이기 때문에 내일 빠른 시간 안에 분석해서 좋은 성능을 내보도록 해야겠다! 위에서 공부한 내용들을 적극 활용해보자구요👊👊</p>
<p>** 🚩캐글**</p>
<p>저번 프로젝트에서도 마지막날 캐글 대회를 했던것과 같이 이번에도 마무리는 캐글 컴피티션..!
6시간안에 새로운 데이터를 분석해서 성능을 끌어올려야한다. 일단 결과를 먼저 말하자면 33등정도로 마무리해서 50등안에 들었기에  A를 받았다😎</p>
<p>먼저 데이터를 봤을 때 100000 rows × 9 columns.. 데이터 양 실화..? 일단 11가지의 행동으로 분류하는 문제였다.</p>
<pre><code>import matplotlib.pyplot as plt

# 막대 그래프 생성
plt.figure(figsize=(10, 6))
category_counts.plot(kind=&#39;bar&#39;)
plt.title(&#39;Activity별 빈도수&#39;)
plt.xlabel(&#39;Activity&#39;)
plt.ylabel(&#39;빈도수&#39;)
plt.xticks(rotation=45)
plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/young_ryeol/post/9ae4fe47-b0f5-42ab-ad71-22cf43dd2769/image.png" alt=""></p>
<p>이것을 보았을 때 클래스 불균형이 있는듯하여 나중에 맞춰줘야겠다! 라고 생각했다.</p>
<pre><code>data.info()

 #   Column      Non-Null Count   Dtype  
---  ------      --------------   -----  
 0   Unnamed: 0  100000 non-null  int64  
 1   timestamp   100000 non-null  object 
 2   A_x         90000 non-null   float64
 3   A_y         90000 non-null   float64
 4   A_z         90000 non-null   float64
 5   B_x         90000 non-null   float64
 6   B_y         90000 non-null   float64
 7   B_z         90000 non-null   float64
 8   label       100000 non-null  int64  </code></pre><p>결측치가 각 데이터마다 만개씩 있는 것으로 보아 결측치를 잘 채워주는 것이 중요하겠다고 생각했다. 그리고 timestamp가 있는 것을 보고, 시간을 잘 활용해야겠다고 생각했다. 그래서 timestamp로 정렬해보았을 때 역시나 같은 시간대에는 같은 행동으로 분류하고있었다. 0.02초?간격으로 센서가 행동을 인식했는데 비슷한 시간에 행동이 비슷하다면? timestamp열에서 데이터를 만들어내야겠다라고 생각했다.</p>
<pre><code>data[&#39;timestamp&#39;] = pd.to_datetime(data[&#39;timestamp&#39;])

# Timestamp 열의 각 구성 요소를 추출
data[&#39;Year&#39;] = data[&#39;timestamp&#39;].dt.year
data[&#39;Month&#39;] = data[&#39;timestamp&#39;].dt.month
data[&#39;Day&#39;] = data[&#39;timestamp&#39;].dt.day
data[&#39;Hour&#39;] = data[&#39;timestamp&#39;].dt.hour
data[&#39;Minute&#39;] = data[&#39;timestamp&#39;].dt.minute
data[&#39;Second&#39;] = data[&#39;timestamp&#39;].dt.second

# 각 구성 요소를 하나의 정수로 결합
data[&#39;Combined&#39;] = data[&#39;Year&#39;] * 10000000000 + data[&#39;Month&#39;] * 100000000 + data[&#39;Day&#39;] * 1000000 + data[&#39;Hour&#39;] * 10000 + data[&#39;Minute&#39;] * 100 + data[&#39;Second&#39;]

# 출력
print(data)</code></pre><p>일단 XGBClassifier로 모델링 했을 때 결과는..? 0.9901...? 응..? 이게 맞아?? 하며 캐글 테스트 데이터로 예측하고 제출했더니 바로 상위권,,,
이게 오전만에 일어난일이다. 그래서 얼른 팀원들에게 timestamp의 중요성을 설명해주고 맛점을 했다.</p>
<p>오후에는 바로 SMOTE, 데이터 스케일링, 하이퍼파라미터튜닝을 진행했다. 원래 0.99가 넘었어서 상위권은 정말 0.0001 싸움이였다. 성능이 너무 잘 나왔길래 더 이상 전처리를 하지않고 모델 튜닝에 집중해서 0.99282!! 이 스코어로 캐글을 마무리했다.</p>
<pre><code>from sklearn.model_selection import train_test_split
from imblearn.over_sampling import SMOTE
from sklearn.preprocessing import MinMaxScaler
x=data.drop(columns=[&#39;label&#39;,&#39;timestamp&#39;,&#39;Unnamed: 0&#39;])
y=data[&#39;label&#39;]
from imblearn.over_sampling import SMOTE

# SMOTE 객체 생성
smote = SMOTE(random_state=42)

# SMOTE를 적용하여 훈련 데이터를 오버 샘플링
x, y = smote.fit_resample(x, y)

# Min-Max 스케일러 객체 생성
scaler = MinMaxScaler()

# 훈련 데이터를 사용하여 변환 스케일러를 학습하고 적용
x = scaler.fit_transform(x)
x_test = scaler.transform(x_test)

from sklearn.preprocessing import LabelEncoder
import xgboost as xgb
from sklearn.metrics import accuracy_score
# 레이블 인코더 생성
label_encoder = LabelEncoder()
xgb_model = xgb.XGBClassifier(max_depth=12,n_estimators=500)

y_train_encoded = label_encoder.fit_transform(y)

# XGBoost 모델을 훈련
xgb_model.fit(x, y_train_encoded)


# 테스트 데이터로 예측
y_pred_encoded = xgb_model.predict(x_test)  # 0부터 시작하는 클래스 레이블로 예측됩니다

# 0부터 시작하는 클래스 레이블을 1부터 시작하는 형식으로 변환
y_pred = label_encoder.inverse_transform(y_pred_encoded)
# 예측 결과를 DataFrame으로 만듭니다.
result_df = pd.DataFrame({&#39;ID&#39;: range(len(test)), &#39;label&#39;: y_pred})

# 예측 결과를 CSV 파일로 저장
result_df.to_csv(&#39;prediction_results.csv&#39;, index=False)</code></pre><blockquote>
<p>🚩5차 미니 프로젝트를 마치며
전처리 때 결측치를 버리기도 하고, 선형보간법을 통해 채웠을 때 성능에서 별 차이가 없어서 깔끔하게 결측치를 다 제거하고 시작했다. 그리고 모델 튜닝에 더 힘 썼는데 결과적으로 봤을 때 결측치를 채운 후 튜닝을 거쳤다면 아마도 성능이 더 좋았을 것이라고 생각한다. 또한 automl을 사용하여 모델 별 비교를 통해 모델을 선택했다면 성능 향상에 도움을 받았을 것이라고 생각한다. <strong>항상 아쉬움은 남지만, 후회는 없도록 했다!</strong> A를 받았기에 만족한다. 교육을 받으며 느끼는거지만 캐글과 같은 대회에서 성장하고 있다고 느낀다. 정해진 시간안에 역량을 보여주는 연습을 하는 것이 좋고, 성장할 수 있는 기회서 좋다. 앞으로 남은 프로젝트도 잘해내고싶고, 성장하고싶다. 5차도 끝<del>~</del>👊</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Ready-For-Tech-Interview]_04]]></title>
            <link>https://velog.io/@young_ryeol/Ready-For-Tech-Interview04</link>
            <guid>https://velog.io/@young_ryeol/Ready-For-Tech-Interview04</guid>
            <pubDate>Sat, 28 Oct 2023 06:30:56 GMT</pubDate>
            <description><![CDATA[<p>이번 포스팅은 기사나 기술 리뷰가 아닌 개발자로서의 태도를 배울 수 있었던 영상들에 대해 써보고자 한다. 예전부터 EO라는 유튜브 채널을 즐겨봤다. 사업가, 개발자 등 자신의 스토리를 덤덤하게 말해주는 것이 좋았고 배울 수 있어서 좋았다. 내가 좋아하는 몇 개의 영상을 소개하고, 느낀점을 적어보고자 한다.</p>
<p><a href="https://www.youtube.com/watch?v=d14cQHBtZc4">25년차고요, 제 직업은 개발자를 키우는 개발자입니다 | 오늘의집 CTO</a></p>
<p>이 영상의 주인공은 오늘의집 엔지니어팀 리드 저스틴님이다. 삼성전자, 구글을 거쳐 오늘의집까지 이직을 하셨다고한다. 항상 컴포트존에 들어오면 커리어에서 불안감을 느끼도록 이직을 하셨다는 점에서 놀랐고, 이해도 갔다. 나는 안정적인 것을 추구하지만 안정적인 곳에서 성장이 하기보다 오히려 불안하고, 경쟁하는 곳에서 성장했던 경험이 많은 것 같다. 자신의 현재 위치를 객관적으로 파악하고 성장할 수 있는 위치로 옮겨가는 것이 대단하다는 생각이 들고 배우고 싶다는 생각을 했다. 또한 가장 인상 깊었던 말씀은 &#39;<em><strong>개발자의 커리어를 생각한다면, 차의 뒷자리에 탔다고 생각하지말고 운전대를 잡았다고 생각해라</strong></em>&#39; 이다. 개발자는 끝없이 배우고 새로운 기술을 취득하는 일을 반복해야하고, 배움과 변화에서 긍정적인 에너지를 가져야한다.</p>
<p><a href="https://www.youtube.com/watch?v=3H4umWD5bwI">배달의민족 CEO에게 뽑고 싶은 개발자를 물어보았다</a></p>
<p>이 영상의 주인공은 배달의민족을 운영하는 우아한형제들 김범준 대표님이다. 개발자는 단순히 코딩을 하는 것이 아닌 문제를 해결하는 능력을 가진 사람이여야 한다고 말하셨다. 사람들이 문제점을 제기했을 때 개발을 하지 않아도, 해결할 수 있다면 개발을 하지 않는 것이 베스트라는 것이다. 단순히 개발자라는 직업에 갇혀서 코딩만을 하기보다, 문제를 해결하려는 문제해결자로 성장핟고싶다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[KT 에이블스쿨] 4차 미니프로젝트_02]]></title>
            <link>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-5%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-5%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Sat, 21 Oct 2023 06:53:01 GMT</pubDate>
            <description><![CDATA[<h2 id="✍️-4차-미니-프로젝트">✍️ 4차 미니 프로젝트</h2>
<p>*<em>📌미션: AIVLE-EDU 1:1 문의 유형 분류하기 *</em></p>
<p><strong>활용 데이터</strong> 
AIVLE School 2기 1 대 1 게시판 데이터(text, label)</p>
<p><strong>도메인 이해</strong>
내가 참여하고있는 에이블스쿨에서는 일대일문의를 통해 코드, 이론, 시스템운영에 관한 궁금증을 해소한다.
이 때 텍스트 분류를 통해 문의 유형을 분류한다면 더욱 빠른 피드백을 받을 수 있을 것이다!
문의 내용을 분석, 전처리해서 문의 유형 분류기를 만들어보자😝</p>
<p>** ✔️데이터 분석**</p>
<pre><code>display(train_df.head(10))
# label 데이터 분포를 확인합니다.
display(train_df.label.value_counts())
print(&quot;-&quot;*100)
norm_label = train_df.label.value_counts(normalize=True)
display(norm_label)
norm_label.plot.bar(figsize=(5,5),color=sns.color_palette(&#39;hls&#39;,n_colors = len(norm_label)))
plt.show()
train_df.info()
display(train_df.describe(include=&#39;all&#39;))</code></pre><p><img src="https://velog.velcdn.com/images/young_ryeol/post/32ebf5e1-612c-4802-a456-35017d4db282/image.png" alt=""></p>
<p>코드에 대한 질문이 가장 많았고, 원격에 관한 질문은 데이터가 현저히 적었다. 추후에 오버샘플링과 같은 클래스 불균형 처리를 시도해봐도 좋겠다고 생각했다.</p>
<pre><code>plt.figure(figsize=(8,4))
plt.title(&quot;명사 개수 : &quot; + str(len(nltk_nouns.tokens)))
nltk_nouns.plot(20)
plt.show()
plt.figure(figsize=(8,4))
plt.title(&quot;품사 태깅 개수 : &quot; + str(len(nltk_pos.tokens)))
nltk_pos.plot(20)
plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/young_ryeol/post/d43ab283-e5fc-46ad-80e8-8cf15bf835f5/image.png" alt=""></p>
<p>명사 태깅을 통해 분포를 보았을 때 &#39;것&#39;, &#39;수&#39;등이 많았다. 지금 정리하며 다시 보니 것과 같은 단어를 처리해주는 것도 하나의 방법이 될 수 있었을 것 같다.</p>
<pre><code>cloud = WordCloud(
        max_font_size=100, max_words=50,
        background_color=&#39;white&#39;, relative_scaling=.5,
        width=800, height=600, font_path=FONT_PATH).generate(&quot; &quot;.join(nltk_nouns))
plt.figure(figsize=(12, 6))
plt.imshow(cloud, interpolation=&#39;bilinear&#39;)
plt.axis(&#39;off&#39;)
plt.show()
cloud = WordCloud(
        max_font_size=100, max_words=50,
        background_color=&#39;white&#39;, relative_scaling=.5,
        width=800, height=600, font_path=FONT_PATH).generate(&quot; &quot;.join(nltk_morphs))
plt.figure(figsize=(12, 6))
plt.imshow(cloud, interpolation=&#39;bilinear&#39;)
plt.axis(&#39;off&#39;)
plt.show()</code></pre><p>워드 클라우드를 통해 명사 태깅한 결과를 시각화하였다.
<img src="https://velog.velcdn.com/images/young_ryeol/post/d530b6ed-83b9-469b-9fd2-609d1aa2f29b/image.png" alt="">
<img src="https://velog.velcdn.com/images/young_ryeol/post/cc83685b-7ed2-4ce2-a792-1748c3f2edc7/image.png" alt="">
<img src="https://velog.velcdn.com/images/young_ryeol/post/040e287b-2b41-40a2-9f40-852536e93160/image.png" alt=""></p>
<p>** ✔️데이터 전처리**</p>
<pre><code>label_dict = {
    &#39;코드1&#39;: 0,
    &#39;코드2&#39;: 0,
    &#39;웹&#39;: 1,
    &#39;이론&#39;: 2,
    &#39;시스템 운영&#39;: 3,
    &#39;원격&#39;: 4
}
preprocessed_df = train_df.replace({&#39;label&#39;: label_dict}).copy()
</code></pre><p>각 레이블를 숫자로 매핑시켜주었다.</p>
<pre><code>import re
import string
#removal_list =  &quot;‘, ’, ◇, ‘, ”,  ’, &#39;, ·, \“, ·, △, ●,  , ■, (, ), \&quot;, &gt;&gt;, `, /, -,∼,=,ㆍ&lt;,&gt;, .,?, !,【,】, …, ◆,%&quot;
removal_list =  &quot;‘’◇‘”’&#39;·\“·△●■()\&quot;&gt;&gt;`/-∼=ㆍ&lt;&gt;.?!【】…◆%&quot;
removal_list += string.punctuation
def cleansing_special(sentence: str = None) -&gt; str:
    &quot;&quot;&quot;
    특수문자를 전처리를 하는 함수
    :param sentence: 전처리 대상 문장
    :return: 전처리 완료된 문장
    &quot;&quot;&quot;
    #sentence = re.sub(&quot;[.,\&#39;\&quot;’‘”“!?]&quot;, &quot;&quot;, sentence)
    sentence = re.sub(&quot;[^가-힣0-9a-zA-Z\\s]&quot;, &quot; &quot;, sentence)
    sentence = re.sub(&quot;\s+&quot;, &quot; &quot;, sentence)

    sentence = sentence.translate(str.maketrans(removal_list, &#39; &#39;*len(removal_list)))
    sentence = sentence.strip()
    return sentence</code></pre><p>특수문자 제거를 해주었다.</p>
<pre><code>from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.feature_extraction.text import TfidfTransformer

mecab_cv = CountVectorizer(tokenizer=mecab_tokenizer)
okt_cv = CountVectorizer(tokenizer=okt_tokenizer)
# 내부적으로 transformer 클래스로 l2 방식으로 벡터 정규화하여 tf-idf 값 계산
okf_tv = TfidfVectorizer(tokenizer=okt_tokenizer, norm=&#39;l2&#39;)

x_tr_mecab_cv = mecab_cv.fit_transform(x_train)
x_te_mecab_cv = mecab_cv.transform(x_test)

x_tr_okt_cv = okt_cv.fit_transform(x_train)
x_te_okt_cv = okt_cv.transform(x_test)

x_tr_okt_tv = okf_tv.fit_transform(x_train)
x_te_okt_tv = okf_tv.transform(x_test)

tf_transformer = TfidfTransformer()

x_tr_me_tf = tf_transformer.fit_transform(x_tr_mecab_cv)
x_te_me_tf = tf_transformer.transform(x_te_mecab_cv)

x_tr_okt_tf = tf_transformer.fit_transform(x_tr_okt_cv)

</code></pre><p>N-grams처리를 해주었다. okt, mecab등을 통해 형태소 분석을 진행하고, tf-idf가중치를 통해 표현해주었다.</p>
<pre><code>%%time
import tensorflow as tf
import numpy as np
import tensorflow.keras as keras
from keras.preprocessing import sequence
from keras.preprocessing import text
TOP_K = 5000
MAX_SEQUENCE_LENGTH = 500
X_mor_tr_str = X_tr.apply(lambda x:&#39; &#39;.join(mecab_tokenizer(x)))
X_mor_val_str = X_val.apply(lambda x:&#39; &#39;.join(mecab_tokenizer(x)))

X_mor_tr = X_tr.apply(lambda x:mecab_tokenizer(x))
X_mor_val = X_val.apply(lambda x:mecab_tokenizer(x))

tokenizer_str = text.Tokenizer(num_words=TOP_K, char_level=False)
tokenizer_str.fit_on_texts(X_mor_tr_str)
X_mor_tr_seq_str = tokenizer_str.texts_to_sequences(X_mor_tr_str)
X_mor_val_seq_str = tokenizer_str.texts_to_sequences(X_mor_val_str)

max_length = len(max(X_mor_tr_seq_str, key=len))
if max_length &gt; MAX_SEQUENCE_LENGTH:
    max_length = MAX_SEQUENCE_LENGTH

print(max_length)
X_mor_tr_seq_str = sequence.pad_sequences(X_mor_tr_seq_str, maxlen=max_length)
X_mor_val_seq_str = sequence.pad_sequences(X_mor_val_seq_str, maxlen=max_length)

tokenizer = text.Tokenizer(num_words=TOP_K, char_level=False)
tokenizer.fit_on_texts(X_mor_tr)
X_mor_tr_seq = tokenizer.texts_to_sequences(X_mor_tr)
X_mor_val_seq = tokenizer.texts_to_sequences(X_mor_val)


max_length = len(max(X_mor_tr_seq, key=len))
if max_length &gt; MAX_SEQUENCE_LENGTH:
    max_length = MAX_SEQUENCE_LENGTH

print(max_length)
X_mor_tr_seq = sequence.pad_sequences(X_mor_tr_seq, maxlen=max_length)
X_mor_val_seq = sequence.pad_sequences(X_mor_val_seq, maxlen=max_length)

</code></pre><p>sequence 처리를 해주었다. 문장 길이 분포를 파악하고 설정한 길이로 맞춰준 후 텍스트 데이터를 정수 시퀀스로 변환해준다.</p>
<p>** ✔️모델링**
<img src="https://velog.velcdn.com/images/young_ryeol/post/4ef921bb-fb96-4cb1-b600-0d02ee0af006/image.png" alt=""></p>
<p>구글에서 제공한 가이드를 보면  Number of Samples / Number of words per sample 값에 따라 모델링을 다르게 하라고 말해준다. 
🔗구글 가이드: <a href="https://developers.google.com/machine-learning/guides/text-classification/step-2-5?hl=ko">https://developers.google.com/machine-learning/guides/text-classification/step-2-5?hl=ko</a></p>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/9077ba37-9760-4874-aa45-37230a999a25/image.png" alt="">
이번 데이터에서는 46정도의 숫자가 나왔고, 이 때 N-grams를 통한 머신러닝 모델링을 했을 때 성능이 좋을 것이라고 예측했다.</p>
<p>🚩 Model 1 (SVC)</p>
<pre><code># Hyperparameter
param_grid = {
    &#39;C&#39;: [0.1, 1, 10],
    &#39;kernel&#39;: [&#39;linear&#39;, &#39;rbf&#39;,&#39;sigmoid&#39;],
    &#39;gamma&#39;: [0.1, 1, &#39;scale&#39;]
}

# 교차 검증
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

# GridSearchCV 객체를 생성
grid_search = GridSearchCV(SVC(), param_grid, cv=skf, scoring=&#39;f1_macro&#39;)
grid_search.fit(x_train, y_train)

best_params = grid_search.best_params_
best_model = grid_search.best_estimator_

</code></pre><p>나는 서포트 벡터 머신의 분류기를 사용하였고, 하이퍼 파라미터 튜닝 및 교차검증을 적용하였다. 전처리할 때 코드 레이블에는 특수문자를 제거하지않았다. 코드 문의는 기호가 많을 것이라고 생각했기 때문이다. 그 결과<del>~</del> 0.94!!!!!!!!!!
<img src="https://velog.velcdn.com/images/young_ryeol/post/56222ea6-afa9-4417-b72d-49361f84d915/image.png" alt="">
하지만 테스트 데이터에도 전처리를 동일하게 적용해줘야 하는데 테스트 데이터에는 레이블이 없잖니... 고로 코드 레이블 제외한 특수문자 제거는 불가능... 따라서 모든 데이터에 특수문자를 제거했더니 결과는 0.84정도로 떨어졌다. 그래도 준수한 정확도이다. 이 후 높은 성능을 위해 MLP, XGB등을 사용해보고 앙상블도 시도했지만 0.84에서 오르지않았다. 이 때 나의 선택은 <strong>pre-trained mode</strong>l을 가져오는 것이였다.</p>
<p>🚩 Model 2 (klue/bert-base)</p>
<p><strong>허깅페이스</strong>를 통해 모델들을 찾아보다가 klue/bert-base을 발견하고 바로 적용해보았다. 하지만 모델마다 데이터 입력 형식을 맞춰줘야하기에 어려움을 겪었다. 하지만 여러 자료들을 찾아보며 해결했다. </p>
<pre><code>
from transformers import BertTokenizerFast

# Load Tokenizer
tokenizer = BertTokenizerFast.from_pretrained(HUGGINGFACE_MODEL_PATH)

# Tokenizing
train_encodings = tokenizer(train_texts, truncation=True, padding=True)
val_encodings = tokenizer(val_texts, truncation=True, padding=True)
test_encodings = tokenizer(test_texts, truncation=True, padding=True)
import tensorflow as tf

# trainset-set
train_dataset = tf.data.Dataset.from_tensor_slices((
    dict(train_encodings),
    train_labels
))

# validation-set
val_dataset = tf.data.Dataset.from_tensor_slices((
    dict(val_encodings),
    val_labels
))

from transformers import TFBertForSequenceClassification

model = TFBertForSequenceClassification.from_pretrained(HUGGINGFACE_MODEL_PATH, num_labels=5, from_pt=True)

optimizer = tf.keras.optimizers.Adam(learning_rate=1e-5, weight_decay=0.1)
model.compile(optimizer=optimizer, loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=[&#39;accuracy&#39;])


callback_earlystop = EarlyStopping(
    monitor=&quot;val_accuracy&quot;,
    min_delta=0.001, # the threshold that triggers the termination (acc should at least improve 0.001)
    patience=5)

history =model.fit(
    train_dataset.shuffle(1000).batch(8), epochs=3, batch_size=8,
    validation_data=val_dataset.shuffle(1000).batch(8),
    callbacks = [callback_earlystop])
# Save the ensemble model
import joblib
joblib.dump(model, &#39;best_pre_model.pkl&#39;)</code></pre><p>먼저 결과는 F1-score 0.85!!!!! 이 결과를 얻어내는데 정말 오래 걸렸다. epochs, learning late를 조절하며 학습을 진행하느라 많은 시간을 썼다🫠 그래도 의미있는 시간이였다. 허깅페이스를 통해 pretrained model을 사용해보았고, bert를 사용해보았기에 유익한 시간이였다. 
참고 링크: <a href="https://velog.io/@jaehyeong/Fine-tuning-Bert-using-Transformers-and-TensorFlow">https://velog.io/@jaehyeong/Fine-tuning-Bert-using-Transformers-and-TensorFlow</a></p>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/f21ee945-3f81-436a-815e-51ac0728caa6/image.png" alt=""></p>
<p>상위10등이 <strong>A</strong>인데, 8등으로 마무리! 아쉬운 것도 있지만 만족한다! </p>
<blockquote>
<p>🚩4차 미니 프로젝트를 마치며
이번 프로젝트는 가장 재밌었다!! 자연어 처리는 거리감이 있었는데 재밌어서 의외?였다. 데이터를 분석하고 이에 따라 <strong>알맞은 전처리</strong>를 진행하는 것이 가장 중요하다는 것을 느꼈다. 하지만 결과적으로 가장 중요한 것은 성능 좋은 모델을 만들어내는 것이다. 이것이 가능하려면? pre-trained model을 잘 활용하는 것이다. 직접 모델링을 해보며 기본적인 이론은 숙지해야하는 것은 당연하다. 하지만 <strong>요즘은 많은 모델들이 이미 나와있기에 이것으로 빠른 일처리를 하는 능력</strong>이 요구된다. 강사님도 이 부분을 강조하셨다! 물론 구현에만 집중하는 것이 아닌 이론적인 부분도 잘 알아야하는 것이 전제조건이라고 생각한다. 이번 프로젝트를 마치며 아쉬운 점은 SVC와 bert를 앙상블해보면 더 좋은 모델이 나왔을 것이라고 생각한다. 하지만 프로젝트 진행중에는 시간이 촉박했기에 이제 생각이 들었다🤣 상위 3개조의 발표를 들어보았는 데 GPT API를 사용하거나 전처리를 더 세밀하게 진행하였다. 역시 같은 주제로 프로젝트를 진행해도 방법이 다르고, 결과도 다른 것을 보며 많이 배울 수 있었다. 발표는 정말 싫지만 다음에는 더 상위권에 진입해보고싶다. 에이블스쿨을 진행하며 많은 사람들과 프로젝트를 진행해볼 수 있다는 것이 정말 좋다. 여러 생각을 공유할 수 있고, 이를 취합하는 경험을 하는 것이 귀하다고 생각한다. 남은 기간도 뿌셔보자👊</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Ready-For-Developer]_03]]></title>
            <link>https://velog.io/@young_ryeol/Ready-For-Tech-Interview03</link>
            <guid>https://velog.io/@young_ryeol/Ready-For-Tech-Interview03</guid>
            <pubDate>Sun, 15 Oct 2023 12:23:52 GMT</pubDate>
            <description><![CDATA[<h2 id="추천-시스템">추천 시스템</h2>
<blockquote>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/50de04a9-d491-43da-ba7b-c5e71aaa4756/image.png" alt="">
요즘 기업들의 추천 시스템 알고리즘은 완전히 공개되지는 않았지만, 어찌보면 나 자신보다 추천 알고리즘이 내 취향을 잘 알고있다는 생각이 든다.
그래서 미니 프로젝트의 주제로 추천 시스템을 선정했다. 추천시스템에 대한 공부 내용과 프로젝트 진행 결과를 적어봐야겠다:)</p>
</blockquote>
<h3 id="추천-시스템의-개념">추천 시스템의 개념</h3>
<p>📌 추천시스템의 중요 용어: 사용자(User)와 상품(Item)</p>
<p>📌 특정 사용자가 좋아할 상품을 추천 or 비슷한 상품을 좋아할 사용자를 추천</p>
<p>📌 추천시스템은 User가 좋아하는 것을 정확히 모르지만 좋아할 것 같은 Item을 추천해줌</p>
<h3 id="컨텐츠-기반-필터링">컨텐츠 기반 필터링</h3>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/2cc929bc-96bd-423f-a7e5-04646d337047/image.png" alt=""></p>
<p>📌 기본적으로 생각하는 수집된 데이터를 기반으로 유사도를 계산해서 추천하는 알고리즘. 이때, 책이라면 책의 제목, 장르, 출판일등의 속성과 사용자의 과거 이력등의 프로필 정보등을 활용.</p>
<p>한마디로 정리하자면 <em>&quot; <strong>사용자 A가 아이템 c에 관심이 있었다면 미래에도 이 아이템에 관심이 있을 테니, c와 비슷한 다른 아이템을 추천하자!</strong>&quot;</em> 이다.</p>
<p>내가 &lt;언어의 온도&gt;라는 책을 읽었다면, 이 책과 비슷한 책 소개, 저자, 장르를 가진 책을 추천해주는 것이다. 이 때 사용하는 방법이 유사도를 구하는 것이다. &lt;언어의 온도&gt;와 유사도가 높은 책을 추천해주는 것이다. 이 때 유사도를 구하는 방법은? 정말 많다.</p>
<p>컨텐츠 기반 필터링은 TF-IDF, Word2Vec(NLP에서만 사용 되는 방법)와 같은 Feature Extraction 방법론이 사용된다.
추출 된 Feature를 통해 아이템 간의 유사도는 <strong>코사인 유사도</strong>, 유클리어드 유사도, 자카드 유사도, 피어슨 상관관계를 통해 측정된다.
유사도 함수들을 통해 각각 순위를 매긴 후 정렬을 한다. 보통 많이 쓰는 것은 코사인유사도이다. </p>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/33db1e49-3101-4c6d-ad0b-d2ff687cbf05/image.png" alt=""></p>
<ul>
<li>-1은 서로 완전히 반대되는 경우</li>
<li>0은 서로 독립적인 경우</li>
<li>1은 서로 완전히 같은 경우</li>
</ul>
<h3 id="협업-필터링">협업 필터링</h3>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/c1e4ec41-29c9-476d-831c-c9dfa8dca3cc/image.png" alt=""></p>
<p>비슷한 성향/취향을 가진 다른 유저가 좋아한 아이템을 현재 유저에게 추천하는 것!</p>
<p>유저 A와 유저 B 모두 같은 아이템에 대해 비슷한/같은 평가를 했다
이때, 유저 A는 다른 아이템에도 비슷한 호감 나타냄
따라서 유저 A, B의 성향은 비슷할 것이므로 다른 아이템을 유저 B에게도 추천</p>
<h4 id="협업-필터링의-한계">협업 필터링의 한계</h4>
<ul>
<li>콜드 스타트(Cold start)
협업 필터링을 사용하기 위해서는 기존 데이터를 활용해야 합니다. 사용자 기반 추천방식에서는 
신규 사용자의 행동이 기록되지 않으면, 어떤 아이템도 추천하지 못한다는 문제가 발생합니다. 
아이템 기반 추천방식에서도, 신규 상품이 출시되더라도 이를 추천할 수 있는 정보가 쌓일 때까지 
추천을 할 수 없다는 의미입니다. 즉, 시스템이 아직 충분한 정보를 모으지 못하면 사용자에 대한 추론을 이끌어 내지 못해 추천을 할 수 없는 한계가 있습니다.</li>
<li>계산 효율 저하
협업 필터링은 계산량이 많은 알고리즘이기 때문에 사용자가 많아질수록 계산 시간 증가하게 
됩니다. 사용자가 많아야 정확한 추천 결과를 도출할 수 있지만, 동시에 계산 시간도 증가하기 때문에 길게는 며칠이 걸리기도 합니다. 이렇게 알고리즘의 정확도와 걸리는 시간이라는 상충되는 문제점은 협업 필터링의 딜레마입니다.</li>
<li>롱테일(Long-Tail) 문제
파레토 법칙(전체 결과의 80%가 전체 원인의 20%에서 일어나는 현상)을 그래프로 나타내었을 때 
꼬리처럼 긴 부분을 형성하는 80%의 부분을 롱테일이라고 합니다. 이는 사용자들이 관심을 많이 
보이는 소수의 인기 있는 콘텐츠를 주로 추천하여 ‘비대칭적 쏠림 현상&#39;이 발생한다는 의미입니다. 
사용자들은 소수의 인기 있는 항목에만 관심을 보이고 관심이 저조한 아이템은 정보가 부족하여 
추천되지 못하여, 다양성이 떨어지는 문제가 발생합니다.</li>
</ul>
<h3 id="하이브리드-시스템">하이브리드 시스템</h3>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/9a053823-2a42-4ab4-83b4-8ea13d409061/image.png" alt=""></p>
<p>컨텐츠 기반 필터링, 협업 필터링 모두 장단점을 가지고있다. 이 때 두가지 방법을 모두 이용한 하이브리드 시스템을 이용한다. 두 가지 알고리즘을 모두 적용하여 아이템마다 가중평균을 구해 랭킹을 매기는 방법, 점 데이터와 아이템 프로필을 조합해 사용자 프로필을 만들어 추천하는 방법 등 다양한 기법이 있다. 실제로 넷플릭스는 협업 필터링을 사용해 유사한 사용자간의 시청/검색 기록을 비교할 뿐만 아니라, 컨텐츠 기반 필터링을 사용해 사용자가 높게 평가한 영화의 특징을 공유하는 영화를 제공한다고 알려져 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[코테 준비 : day21]]]></title>
            <link>https://velog.io/@young_ryeol/%EC%BD%94%ED%85%8C-%EC%A4%80%EB%B9%84-day21</link>
            <guid>https://velog.io/@young_ryeol/%EC%BD%94%ED%85%8C-%EC%A4%80%EB%B9%84-day21</guid>
            <pubDate>Sat, 14 Oct 2023 04:50:47 GMT</pubDate>
            <description><![CDATA[<h3 id="재밌는데-재밌다고-생각해야겠는데">재밌는데? 재밌다고 생각해야겠는데?</h3>
<p>요즘은 에이블스쿨에서 진행하는 코딩마스터스가 끝나고 백준 문제를 푸는 중이다🔥코딩마스터스 2차도 있다고하여 그 때는 80문제 이상을 풀기위해! 멀리 보면 취업을 위한 코테를 위해! 코테준비? 재밌다고 생각해야겠는데?😝</p>
<blockquote>
<ol>
<li>DFS와 BFS
<a href="https://www.acmicpc.net/problem/1260">https://www.acmicpc.net/problem/1260</a>
<img src="https://velog.velcdn.com/images/young_ryeol/post/1093bcc7-5ca0-41b1-9d11-d3e910c26974/image.png" alt="">
이 문제는 DFS, BFS의 특성을 이해하고, 비교하기에 좋았다!</li>
</ol>
</blockquote>
<pre><code>
rdef bfs(V):
    q = deque([V])  # pop메서드의 시간복잡도가 낮은 덱 내장 메서드를 이용한다
    visited2[V] = True  # 해당 V 값을 방문처리
    while q:  # q가 빌때까지 돈다.
        V = q.popleft()  # 큐에 있는 첫번째 값 꺼낸다.
        print(V, end=&quot; &quot;)  # 해당 값 출력
        for i in range(1, N + 1):  # 1부터 N까지 돈다
            if not visited2[i] and graph[V][i]:  # 만약 해당 i값을 방문하지 않았고 V와 연결이 되어 있다면
                q.append(i)  # 그 i 값을 추가
                visited2[i] = True  # i 값을 방문처리

def dfs(V):
    visited1[V] = True  # 해당 V값 방문처리
    print(V, end=&quot; &quot;)
    for i in range(1, N + 1):
        if not visited1[i] and graph[V][i]:  # 만약 i값을 방문하지 않았고 V와 연결이 되어 있다면
            dfs(i)  # 해당 i 값으로 dfs를 돈다.(더 깊이 탐색)


from collections import deque

N, M, V = map(int, input().split())

graph = [[False] * (N + 1) for _ in range(N + 1)]

for _ in range(M):
    a, b = map(int, input().split())
    graph[a][b] = True
    graph[b][a] = True

visited1 = [False] * (N + 1)  # dfs의 방문기록
visited2 = [False] * (N + 1)  # bfs의 방문기록

dfs(V)
print()
bfs(V)
</code></pre><blockquote>
<ol start="2">
<li>MooTube (Silver)
<a href="https://www.acmicpc.net/problem/15591">https://www.acmicpc.net/problem/15591</a>
<img src="https://velog.velcdn.com/images/young_ryeol/post/4a785b2c-4a0e-4b0a-b09e-770fe840054e/image.png" alt="">
이 문제는 DFS, BFS의 특성을 이해하고 적용시키기에 좋았던 문제다!</li>
</ol>
</blockquote>
<pre><code>
from sys import stdin
from collections import deque, defaultdict
input = stdin.readline

def bfs(k, v):
    num = 0
    q = deque([v])
    vi = [0] * (N + 1)
    vi[v] = 1 

    while q:
        v= q.popleft()
        for nv, nw in graph[v]:
            if vi[nv] == 0 and nw &gt;= k:
                vi[nv] = 1
                q.append(nv)
                num += 1
    return num

N, Q = map(int, input().split())

graph = defaultdict(list)

for _ in range(N-1):
    p,q,r = map(int, input().split())
    graph[p].append([q,r])
    graph[q].append([p,r])

for _ in range(Q):
    k, v = map(int ,input().split())
    print(bfs(k, v))
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[KT 에이블스쿨] 4차 미니프로젝트_01]]></title>
            <link>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-4%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-4%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Sat, 14 Oct 2023 04:08:21 GMT</pubDate>
            <description><![CDATA[<h2 id="👨👩👧👦-4차-미니-프로젝트">👨‍👩‍👧‍👦 4차 미니 프로젝트</h2>
<p>*<em>미션: 서울시 공공 데이터 기반 생활인구 예측 *</em></p>
<p><strong>활용 데이터셋</strong> </p>
<p>Train data set - 17년도 ~ 21년도 생활인구 데이터
Test data set  -  22년도 생활인구 데이터</p>
<p><strong>도메인 이해</strong></p>
<p>상주인구 - 통계청에서는 인구 센서스를 통해 거주인구를 조사하는데 이를 상주인구 또는 야간인구라 함
유인인구 - 인구 센서스에서는 통근/통학인구를 조사하는데, 통근/통학을 통해 해당지역에 유입되는 인구를 말함
유츌인구 - 인구 센서스에서는 통근/통학인구를 조사하는데, 통근/통학을 통해 해당지역에서 타지역으로 유출되는 인구를 말함
주간인구 - 상주인구에서 유입인구를 더하고 유출인구를 뺀 인구를 말함
등록인구 - 행정기관(주민센터)에 등록하는 주민등록인구를 말함
경제활동인구 - 만 15세 이상의 생산가능 연령 인구 중에서 구직활동이 가능한 취업자 및 실업자를 말함
생활인구 - 특정시점에 특정지역에 존재하는 모든 인구이며, 현주인구(de factoPopulation) 또는 현재인구, 서비스 인구라고도 함</p>
<p>❗서울 생활 인구의 정의 : 서울시가 보유한 빅데이터와 KT의 통신데이터로 측정한 특정 시점에 서울의 특정 지역에 존재하는 인구</p>
<p>📌 즉, 거주가 아닌 특정 시점에 서울에 있다면 생활 인구로 측정되므로 서울로 출퇴근하는 시간을 주의깊게 봐야겠다.</p>
<p>** ✔️데이터 분석**</p>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/af91899c-de27-4e5e-aa88-ea5eb4c56c0c/image.png" alt="">
역시 예상대로 <strong>근무시간에 생활인구가 높게 측정</strong>된다. 현재 하나의 행정동을 분석한 것인데 이 지역은 근무지가 몰려있는 지역인 것이다. 따라서 근무시간에 생활인구가 높고, 새벽이나 밤에는 생활인구가 낮아지는 것을 볼 수 있다. 이것으로 더 생각해보면 <strong>20대~60대</strong>가 회사에 다니는 나이이므로 이 나이 구간도 주의 깊게 볼 필요가 있을듯하다.</p>
<p>이 데이터는 시계열데이터이기에 정상성을 따져볼 필요가 있다. 여기서 정상성을 띈다는 것은 시계열 데이터의 평균과 분산이 일정하다는 것이다.</p>
<pre><code>from statsmodels.tsa.stattools import adfuller

def adf_test(y):
    dftest = adfuller(y, autolag=&#39;AIC&#39;)
    # autolag &#39;AIC&#39; : 검정 AR 모형의 차수를 자동으로 결정
    dfoutput = pd.Series(dftest[0:4], index=[&#39;test statistic&#39;, &#39;p-value&#39;, &#39;# of lags&#39;, &#39;# of observations&#39;])
    for key, value in dftest[4].items():
        dfoutput[&#39;Critical Value ({})&#39;.format(key)] = value
    print(dfoutput)
adf_test(df_total[&#39;총생활인구수&#39;])

test statistic         -8.946524e+00
p-value                 8.957713e-15
# of lags               5.500000e+01
# of observations       4.345600e+04
Critical Value (1%)    -3.430500e+00
Critical Value (5%)    -2.861607e+00
Critical Value (10%)   -2.566805e+00
dtype: float64</code></pre><p>이어서 정규성을 띄는지 확인해보고자 했다. 여기서 정규성이란 데이터의 분포가 정규분포를 이룬다는 것이다.</p>
<pre><code>from scipy import stats
from scipy.stats import shapiro
shapiro_test = stats.shapiro(df_total[&#39;총생활인구수&#39;])
shapiro_test

from scipy.stats import anderson
anderson(df_total[&#39;총생활인구수&#39;])</code></pre><p>** ✔️데이터 전처리**</p>
<p>깔끔한 데이터라서 이상치, 결측치등을 처리할 것이 거의 없다. 따라서 기존 데이터에서 필요한 데이터를 추출해보고자 날짜에서 연,월,일 열을 만들어서 사용할 것이다. 그리고 필요한 데이터들만 뽑아서 hour, 총생활인구수, 연, 월, 일, 이동평균 열만 사용하기로 결정했다.</p>
<pre><code>
# 데이터의 형식 변환
train_set[&#39;기준일ID&#39;] = train_set[&#39;기준일ID&#39;].apply(lambda x: x.replace(&#39;-&#39;, &#39;&#39;)[0:8])

# &#39;기준일ID&#39; 열을 datetime 형식으로 변경
train_set[&#39;기준일ID&#39;] = pd.to_datetime(train_set[&#39;기준일ID&#39;], format=&#39;%Y%m%d&#39;)

# &#39;연&#39; 정보를 새로운 열로 추가
train_set[&#39;연&#39;] = train_set[&#39;기준일ID&#39;].dt.year

# &#39;월&#39; 정보를 새로운 열로 추가
train_set[&#39;월&#39;] = train_set[&#39;기준일ID&#39;].dt.month

# &#39;일&#39; 정보를 새로운 열로 추가
train_set[&#39;일&#39;] = train_set[&#39;기준일ID&#39;].dt.day

# 결과를 확인
print(train_set[[&#39;기준일ID&#39;, &#39;연&#39;, &#39;월&#39;, &#39;일&#39;]])
</code></pre><p>훈련, 테스트 데이터 나누기
훈련 데이터셋 : 17년도 ~ 21년도
테스트 데이터 셋 : 22년도(01월~06월)</p>
<pre><code># 아래에 실습코드를 작성하고 결과를 확인합니다.

# 훈련 데이터 (train_set) 나누기
train_x = train_set.drop([&#39;target&#39;], axis=1)  # &#39;target&#39; 열을 제외한 나머지 열을 훈련 데이터로 사용
train_y = train_set[&#39;target&#39;]  # &#39;target&#39; 열을 훈련 데이터의 목표값으로 사용

# 테스트 데이터 (test_set) 나누기
test_x = test_set.drop([&#39;target&#39;], axis=1)  # &#39;target&#39; 열을 제외한 나머지 열을 테스트 데이터로 사용
test_y = test_set[&#39;target&#39;]  # &#39;target&#39; 열을 테스트 데이터의 목표값으로 사용

# 인덱스 리셋
train_x.reset_index(drop=True, inplace=True)
train_y.reset_index(drop=True, inplace=True)
test_x.reset_index(drop=True, inplace=True)
test_y.reset_index(drop=True, inplace=True)
</code></pre><p>** ✔️모델링**</p>
<p>&lt; linear &gt;
RMSE: 842.52
R-squared Score: 0.94</p>
<pre><code>from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error,r2_score
import numpy as np

model=LinearRegression()

model.fit(train_x, train_y)

# 모델을 사용하여 테스트 데이터에 대한 예측 수행
predictions = model.predict(test_x)

# RMSE 계산
rmse = np.sqrt(mean_squared_error(test_y, predictions))

# R-squared Score 계산
r2 = r2_score(test_y, predictions)

# 결과 출력
print(&quot;RMSE: {:.2f}&quot;.format(rmse))
print(&quot;R-squared Score: {:.2f}&quot;.format(r2))
</code></pre><p>&lt; RandomForestRegressor&gt; 
RMSE: 704.57
R-squared Score: 0.96</p>
<pre><code>from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error,r2_score
import numpy as np

rf_model=RandomForestRegressor(n_estimators=100, random_state=42)

rf_model.fit(train_x, train_y)

# 모델을 사용하여 테스트 데이터에 대한 예측 수행
predictions = rf_model.predict(test_x)

# RMSE 계산
rmse = np.sqrt(mean_squared_error(test_y, predictions))

# R-squared Score 계산
r2 = r2_score(test_y, predictions)

# 결과 출력
print(&quot;RMSE: {:.2f}&quot;.format(rmse))
print(&quot;R-squared Score: {:.2f}&quot;.format(r2))</code></pre><p>&lt; GradientBoostingRegressor &gt;
RMSE: 644.4736257455878
R-squared Score: 0.9670418438482387</p>
<pre><code>from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_absolute_error,r2_score

gb_model = GradientBoostingRegressor()

gb_model.fit(train_x,train_y)

gb_predictions = gb_model.predict(test_x)

# 평가 - RMSE
gb_rmse = mean_squared_error(test_y, gb_predictions, squared=False)
print(&quot;RMSE:&quot;, gb_rmse)

# 평가 - R-squared Score
gb_r2 = r2_score(test_y, gb_predictions)
print(&quot;R-squared Score:&quot;, gb_r2)</code></pre><p>&lt; Deeplearning &gt;</p>
<pre><code>import numpy as np
import tensorflow as tf

np.random.seed(0)
tf.random.set_seed(0)

X = tf.keras.Input(shape=[6])

H = tf.keras.layers.Dense(64)(X)
H = tf.keras.layers.BatchNormalization()(H)
H = tf.keras.layers.Activation(&#39;swish&#39;)(H)

H = tf.keras.layers.Dropout(0.6)(H)
H = tf.keras.layers.Dense(64)(H)
H = tf.keras.layers.BatchNormalization()(H)
H = tf.keras.layers.Activation(&#39;swish&#39;)(H)

H = tf.keras.layers.Dropout(0.5)(H)
H = tf.keras.layers.Dense(16)(H)
H = tf.keras.layers.BatchNormalization()(H)
H = tf.keras.layers.Activation(&#39;swish&#39;)(H)

H = tf.keras.layers.Dropout(0.5)(H)
H = tf.keras.layers.Dense(8)(H)
H = tf.keras.layers.BatchNormalization()(H)
H = tf.keras.layers.Activation(&#39;swish&#39;)(H)

H = tf.keras.layers.Dropout(0.3)(H)
Y = tf.keras.layers.Dense(1)(H)

model1 = tf.keras.Model(X, Y)
model1.compile(loss=&#39;mse&#39;)
# model1.summary()

model1.fit(train_x, train_y, epochs=30, batch_size=128,
          validation_split=0.2, verbose=0)
model1.fit(train_x, train_y, epochs=10,  batch_size=128, validation_split=0.2)</code></pre><blockquote>
<p>🚩4차 미니 프로젝트를 마치며
생활인구 예측 미니 프로젝트가 끝났다. 기본적으로 데이터가 깔끔했고, 전처리할 것이 많지않았다. 의도적으로 데이터를 만들어낼 수 있었지만 최소화해서 깔끔한 데이터로 모델링을 해보고싶었다. 결과적으로 GradientBoostingRegressor가 r2_score 0.967로 가장 좋은 결과를 나타내었다. 딥러닝 모델은 성능이 좋지 않았다. 이 전 프로젝트에서도 딥러닝 모델이 큰 성과를 내지못했는데 내가 모델링을 잘했더라면 높았을까라는 의문이 있지만 이런 결과가 계속 되니 딥러닝 모델에 대한 의문이 늘어갔다. 성능을 높일 수 있는 다향한 방법을 더 공부해봐야겠다!</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Ready-For-Developer]_02]]></title>
            <link>https://velog.io/@young_ryeol/Ready-For-Tech-Interview02</link>
            <guid>https://velog.io/@young_ryeol/Ready-For-Tech-Interview02</guid>
            <pubDate>Fri, 13 Oct 2023 06:49:56 GMT</pubDate>
            <description><![CDATA[<h2 id="그래프-탐색-기법">그래프 탐색 기법</h2>
<h3 id="📌그래프-탐색-알고리즘">📌그래프 탐색 알고리즘</h3>
<p>탐색(Search)이란, 많은 양의 데이터 중에서 원하는 데이터를 찾는 과정이다. 대표적인 그래프 탐색 알고리즘으로는 DFS와 BFS가 있다. DFS와 BFS는 코딩 테스트에서 매우 자주 등장하는 유형이므로 반드시 숙지해야 한다. 나도 이 글을 정리하며 개념을 확실히 하고자 이 포스팅을 작성한다😊</p>
<blockquote>
<h3 id="📌dfs-depth-first-search">📌DFS (Depth-First Search)</h3>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/fb8116e9-bffb-422d-a7cb-407ad9d88b58/image.gif" alt="">
DFS는 Depth - First Search, 깊이 우선 탐색이라고도 부르며, 그래프와 트리의 깊은 부분을 우선적으로 탐색하는 알고리즘이다. 
그림에서와 같이 갈 수 있는 한 끝까지 탐색해 리프 노드를 방문하고, 이전 갈림길로 돌아와 선택하지 않았던 노드를 방문하는 식으로 탐색한다. DFS는 스택(Stack) 자료구조를 이용하며 구체적인 동작 과정은 다음과 같다.
<em>탐색 시작 노드를 스택에 삽입하고 방문 처리를 한다.
스택의 최상단 노드에 방문하지 않은 인접 노드가 있으면 그 인접 노드를 스택에 넣고 방문 처리를 한다. 그리고 방문하지 않은 인접 노드가 없으면 스택에서 최상단 노드를 꺼낸다.
두 번째 과정을 더 이상 수행할 수 없을 때까지 반복한다.</em></p>
</blockquote>
<blockquote>
<h3 id="📌bfs-breadth---first-search">📌BFS (Breadth - First Search)</h3>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/69f85ba6-2a4a-4a70-8fc4-54ad733db704/image.gif" alt="">
BFS는 Breadth - First Search, 너비 우선 탐색이라고도 부르며, 그래프와 트리의 가까운 노드부터 탐색하는 알고리즘이다.
그림에서와 같이 루트 노드와 같은 거리에 있는 노드를 우선으로 방문하며 탐색한다.
BFS는 큐(Queue) 자료구조를 이용하며 구체적인 동작 과정은 다음과 같다.
<em>탐색 시작 노드를 큐에 삽입하고 방문 처리를 한다.
큐에서 노드를 꺼내 해당 노드의 인접 노드 중에서 방문하지 않은 노드를 모두 큐에 삽입하고 방문 처리를 한다.
두 번째 과정을 더 이상 수행할 수 없을 때까지 반복한다.</em></p>
</blockquote>
<h3 id="❗dfs와-bfs-비교">❗DFS와 BFS 비교</h3>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/3d828d04-d32c-450a-b91f-c5319f9b5f84/image.png" alt=""></p>
<ul>
<li>두 방식 모두 조건 내의 모든 노드를 검색한다는 점에서 시간 복잡도는 동일하지만 일반적으로 DFS를 재귀 함수로 구현한다는 점에서 DFS보다 BFS가 조금 더 빠르게 동작한다고 기억하면 된다.</li>
</ul>
<p>❗문제의 특징 별 DFS / BFS 활용</p>
<ol>
<li>그래프의 모든 정점을 방문하는 것이 주요한 문제</li>
</ol>
<p>단순히 모든 정점을 방문하는 것이 중요한 문제의 경우 DFS, BFS 두 가지 방법 중 어느 것을 사용해도 상관이 없다. </p>
<ol start="2">
<li>경로의 특징을 저장해둬야 하는 문제</li>
</ol>
<p>예를 들어 각 정점에 숫자가 적혀있고 a부터 b까지 가는 경로를 구하는데 경로에 같은 숫자가 있으면 안 된다는 문제 등, 각각의 경로마다 특징을 저장해둬야 할 때는 DFS를 사용한다. (BFS는 경로의 특징을 가지지 못한다)</p>
<ol start="3">
<li>최단거리를 구하는 문제</li>
</ol>
<p>미로 찾기 등 최단 거리를 구해야 할 경우, BFS가 유리하다.</p>
<p>왜냐하면 DFS로 경로를 검색할 경우 처음으로 발견되는 해답이 최단거리가 아닐 수 있지만, BFS는 현재 노드부터 가까운 곳부터 찾기 때문에 경로 탐색 시 먼저 찾아지는 해답이 곧 최단거리이기 때문이다.</p>
<p>이외에도 검색 대상 그래프가 정말 크다면 DFS를 고려하고 검색 대상의 규모가 크지 않고, 검색 시작 지점으로부터 원하는 대상이 별로 멀지 않다면 BFS를 고려하는 등으로 더 생각해볼 수 있다. </p>
<p>🚩추천 문제 - &gt; (백준 DFS와 BFS) <a href="https://www.acmicpc.net/problem/1260">https://www.acmicpc.net/problem/1260</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Ready-For-Developer]_01]]></title>
            <link>https://velog.io/@young_ryeol/Ready-For-Tech-Interview10%EC%9B%94-2%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@young_ryeol/Ready-For-Tech-Interview10%EC%9B%94-2%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Thu, 12 Oct 2023 00:36:33 GMT</pubDate>
            <description><![CDATA[<h2 id="정렬의-개념">정렬의 개념</h2>
<h3 id="📌버블-정렬bubble-sort">📌버블 정렬(Bubble Sort)</h3>
<pre><code>서로 인접한 두 원소를 검사하여 정렬하는 알고리즘이다.
인접한 2개의 원소를 비교해 크기가 순서대로 되어 있지 않으면 서로 교환한다.
선택 정렬과 기본 개념이 유사하다.</code></pre><h4 id="로직">로직</h4>
<p>1회전에 첫 번째 원소와 두 번째 원소를, 두 번째 원소와 세 번째 원소를, 세 번째 원소와 네 번째 원소를, ... 이런 식으로 마지막 - 1 번째 원소와 마지막 원소를 비교하여 조건에 맞지 않으면 서로 교환한다.
1회전을 수행하고 나면 가장 큰 원소가 맨 뒤로 이동하므로 2회전에서는 맨 끝에 있는 원소는 정렬에서 제외되고, 2회전을 수행하고 나면 끝에서 두번째 원소까지는 정렬에서 제외된다. 이렇게 정렬을 1회전 수행할 때마다 정렬에서 제외되는 데이터가 하나씩 늘어난다.</p>
<pre><code>private static void sort(int[] arr) {
        for (int i = 0; i &lt; arr.length; i++) { // 1
            for (int j = 0; j &lt; arr.length - i - 1; j++) { // 2
                if (arr[j] &gt; arr[j + 1]) { // 3
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }

            System.out.print((i + 1) + &quot;단계 : &quot;);
            print(arr);
        }
    }

private static void print(int[] arr) {
        for (int i = 0; i &lt; arr.length; i++) {
            System.out.print(arr[i] + &quot; &quot;);
        }
        System.out.println();
    }

// 단계별 결과.
1단계 : 6 2 4 3 7 1 9 
2단계 : 2 4 3 6 1 7 9 
3단계 : 2 3 4 1 6 7 9 
4단계 : 2 3 1 4 6 7 9 
5단계 : 2 1 3 4 6 7 9 
6단계 : 1 2 3 4 6 7 9 
7단계 : 1 2 3 4 6 7 9 </code></pre><h4 id="장점">장점</h4>
<p>구현이 간단하고 소스코드가 직관적이다.
이미 정렬된 데이터를 정렬할 때, 가장 빠르다.
정렬하고자 하는 배열 안에서 정렬하는 방식이므로, 다른 메모리 공간을 필요로 하지 않는다.
안정 정렬이다.</p>
<h4 id="단점">단점</h4>
<p>시간 복잡도가 최악, 최선, 평균 모두 O(N^2)이므로 비효율적이다.
다른 정렬에 비해 정렬 속도가 느리다.
교환 횟수가 많다.
역순배열을 정렬할 때, 가장 느리다.</p>
<h3 id="📌병합-정렬merge-sort">📌병합 정렬(Merge Sort)</h3>
<pre><code>빠른 정렬로 분류되며, Quick Sort와 함께 많이 언급되는 정렬 방식이다.
Quick Sort와는 반대로 안정 정렬에 속한다.</code></pre><h4 id="로직-1">로직</h4>
<p>1회전에 첫 번째 원소와 두 번째 원소를, 두 번째 원소와 세 번째 원소를, 세 번째 원소와 네 번째 원소를, ... 이런 식으로 마지막 - 1 번째 원소와 마지막 원소를 비교하여 조건에 맞지 않으면 서로 교환한다.
1회전을 수행하고 나면 가장 큰 원소가 맨 뒤로 이동하므로 2회전에서는 맨 끝에 있는 원소는 정렬에서 제외되고, 2회전을 수행하고 나면 끝에서 두번째 원소까지는 정렬에서 제외된다. 이렇게 정렬을 1회전 수행할 때마다 정렬에서 제외되는 데이터가 하나씩 늘어난다.</p>
<pre><code>private static void mergeSort(int[] a, int left, int right) {
        if (left &lt; right) {
            int mid = (left + right) / 2;

            mergeSort(a, left, mid); // 왼쪽 부분 배열을 나눈다.
            mergeSort(a, mid + 1, right); // 오른쪽 부분 배열을 나눈다.
            merge(a, left, mid, right);
            // 나눈 부분 배열을 합친다.
            // 핵심 로직이다.
        }
    }

/*
    * i : 왼쪽 부분 배열을 관리하는 인덱스
    * j : 오른쪽 부분 배열을 관리하는 인덱스
    * */
    private static void merge(int[] a, int left, int mid, int right) {
        int i, j, k, l;
        i = left;
        j = (mid + 1);
        k = left;

        // 왼쪽 부분 배열과 오른쪽 부분 배열을 비교하면서
        // 각각의 원소 중에서 작은 원소가 sorted 배열에 들어간다.
        // 왼쪽 혹은 오른쪽의 부분 배열 중 하나의 배열이라도 모든 원소가 sorted 배열에 들어간다면
        // 아래의 반복문은 조건을 만족하지 하지 않기 때문에 빠져 나온다.
        // sorted 배열에 들어가지 못한 부분 배열은 아래 쪽에서 채워진다.
        while (i &lt;= mid &amp;&amp; j &lt;= right) {
            if (a[i] &lt; a[j]) sorted[k++] = a[i++];
            else sorted[k++] = a[j++];
        }

        // mid &lt; i 인 순간, i는 왼쪽 부분 배열의 인덱스를 관리하므로
        // 즉, 왼쪽 부분 배열이 sorted 에 모두 채워졌음을 의미한다.
        // 따라서 남아 있는 오른쪽 부분 배열의 값을 일괄 복사한다.
        if (mid &lt; i) {
            for (l = j; l &lt;= right; l++) sorted[k++] = a[l];
        } else {
            // mid &gt; i 인 것은 오른쪽 부분 배열이 sorted 배열에 정렬된 상태로 모두 채워졌음을 의미한다.
            // 따라서, 왼쪽 부분 배열은 아직 남아 있는 상태이다.
            // 즉, 남아 있는 왼쪽 부분 배열의 값을 일괄 복사한다.
            for (l = i; l &lt;= mid; l++) sorted[k++] = a[l];
        }

        // sorted 배열에 들어간 부분 배열을 합하여 정렬한 배열은
        // 원본 배열인 a 배열로 다시 복사한다.
        for (l = left; l &lt;= right; l++) a[l] = sorted[l];
    }</code></pre><h4 id="장점-1">장점</h4>
<p>데이터의 분포에 영향을 덜 받는다. 즉, 입력 데이터가 무엇이든 간에 정렬되는 시간은 동일하다. -&gt; O(N logN)
크기가 큰 레코드를 정렬한 경우, LinkedList를 사용한다면 병합 정렬은 퀵 정렬을 포함한 다른 어떤 정렬 방법보다 효율적이다.
안정 정렬에 속한다.</p>
<h4 id="단점-1">단점</h4>
<p>레코드를 배열로 구성한다면, 임시 배열이 필요하다.
메모리 낭비를 초래한다.
제자리 정렬이 아니다.
레코드의 크기가 큰 경우에는 이동 횟수가 많으므로 매우 큰 시간적 낭비를 초래한다.</p>
<h3 id="📌삽입-정렬intersection-sort">📌삽입 정렬(Intersection Sort)</h3>
<pre><code>손 안의 카드를 정렬하는 방법과 유사하다.
새로운 카드를 기존의 정렬된 카드 사이에 올바른 자리를 찾아 삽입한다.
2번째 원소부터 시작하여 그 앞(왼쪽)의 원소들과 비교하여 삽입할 위치를 지정한 후, 원소를 뒤로 옮기고 지정된 자리에 자료를 삽입하여 정렬하는 알고리즘이다.
최선의 경우, O(N)이라는 엄청나게 빠른 효율성을 가지고 있어, 다른 정렬 알고리즘의 일부로 사용될만큼 좋은 정렬 알고리즘이다.</code></pre><h4 id="로직-2">로직</h4>
<p>정렬은 2번째 위치(index)의 값을 standard에 저장한다
standard와 이전에 있는 원소들과 비교하여 자리를 바꾸며 삽입해 나간다.
1번으로 돌아가서 다음 위치(index)의 값을 standard에 저장하고 이 과정을 반복한다.</p>
<pre><code>private static void sort(int[] arr) {
        for (int i = 1; i &lt; arr.length; i++) { // 1
            int standard = arr[i];
            int index = i - 1;

            while ((0 &lt;= index) &amp;&amp; standard &lt; arr[index]) {//2
                arr[index + 1] = arr[index];
                index--;
            }
            arr[index + 1] = standard; // 3

            print(arr, i);
        }
    }

    private static void print(int[] arr, int step) {
        System.out.print(step + &quot;단계 : &quot;);
        for (int i = 0; i &lt; arr.length; i++) {
            System.out.print(arr[i] + &quot; &quot;);
        }

        System.out.println();
    }
// 단계별 결과.
1단계 : 6 7 2 4 3 9 1 
2단계 : 2 6 7 4 3 9 1 
3단계 : 2 4 6 7 3 9 1 
4단계 : 2 3 4 6 7 9 1 
5단계 : 2 3 4 6 7 9 1 
6단계 : 1 2 3 4 6 7 9</code></pre><h4 id="장점-2">장점</h4>
<p>알고리즘이 단순하다.
대부분의 원소가 이미 정렬되어 있는 경우, 매우 효율적일 수 있다.
정렬하고자 하는 배열 안에서 교환하는 방식이므로, 다른 메모리 공간을 필요로 하지 않는다.
선택 정렬이나 버블 정렬에 비하여 상대적으로 빠르다.</p>
<h4 id="단점-2">단점</h4>
<p>비교적 많은 수들의 이동을 포함한다.
비교할 수가 많고 크기가 클 경우에 적합하지 않다.(배열의 길이가 길어질수록 비효율적)
평균과 최악의 시간 복잡도가 O(N^2)이므로 비효율적이다.</p>
<h3 id="📌선택-정렬selection-sort">📌선택 정렬(Selection Sort)</h3>
<pre><code>해당 순서에 원소를 넣을 위치는 이미 정해져있고, 어떤 원소를 넣을지 선택하는 알고리즘이다.
현재 위치에 저장될 값의 크기가 작냐, 크냐에 따라서 최소 선택 정렬(오름차순 정렬)과 최대 선택 정렬(내림차순 정렬)로 나뉜다.</code></pre><h4 id="로직-3">로직</h4>
<p>주어진 배열에서 첫번째 인덱스를 기준으로 잡는다. 기준은 처음부터 시작한다.
주어진 배열에서 기준 이후의 값 중 최소값을 찾는다.
최소값과 그 기준의 값을 교체한다.
기준 이후의 나머지 배열을 같은 방법으로 교체한다.</p>
<pre><code>int[] arr = {7, 6, 2, 4, 3, 9, 1};

private static void sort(int[] arr) {
        for (int i = 0; i &lt; arr.length; i++) { // 1
            int standard = i;
            for (int j = i + 1; j &lt; arr.length; j++) { // 2
                if (arr[j] &lt; arr[standard]) standard = j; // 3
            }

              // 4
            int temp = arr[standard];
            arr[standard] = arr[i];
            arr[i] = temp;

            print(arr);
        }
    }

private static void print(int[] arr) {
        for (int i = 0; i &lt; arr.length; i++) {
            System.out.print(arr[i] + &quot; &quot;);
        }
        System.out.println();
    }

// 단계별 결과.
1단계 : 1 6 2 4 3 9 7 
2단계 : 1 2 6 4 3 9 7 
3단계 : 1 2 3 4 6 9 7 
4단계 : 1 2 3 4 6 9 7 
5단계 : 1 2 3 4 6 9 7 
6단계 : 1 2 3 4 6 7 9 
7단계 : 1 2 3 4 6 7 9 </code></pre><h4 id="장점-3">장점</h4>
<p>알고리즘이 단순하다.
정렬을 위한 비교는 여러번 수행되지만, 실제로 교환 횟수는 적기 때문에 많은 교환이 일어나야 하는 자료 상태에서 비교적 효율적인 면이 있다.
정렬하고자 하는 배열 안에서 교환하는 방식이므로, 다른 메모리 공간을 필요로 하지 않는다.</p>
<h4 id="단점-3">단점</h4>
<p>시간 복잡도가 O(N^2)이므로 비효율적이다.
불안정 정렬(Unstable Sort)이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Ready-For-Developer]_00]]></title>
            <link>https://velog.io/@young_ryeol/ReadyForTechInterview</link>
            <guid>https://velog.io/@young_ryeol/ReadyForTechInterview</guid>
            <pubDate>Wed, 11 Oct 2023 06:01:36 GMT</pubDate>
            <description><![CDATA[<h3 id="새로운-시리즈의-시작">새로운 시리즈의 시작!</h3>
<p>이제부터 내가 시작할 시리즈의 주제는 기술면접 대비 기록 일지이다!</p>
<p>IT 관련 기사, 이슈등에 대한 정리와 함께 나의 생각도 조금씩 적어보려한다.
이 시리즈를 계속 이어나간다면 트렌드를 빠르게 따라갈 수 있을것이다!
평소 IT뉴스를 자주 보고, 이슈들도 찾아서 보는데 이것을 면접에서 어필하거나, 나의 기술로 습득하려면 기록이 필요하다는 생각이 들었다.</p>
<p>앞으로 IT기사, 신기술, 이슈 등 가리지않고 내가 관심있는 내용에 대해 정리해보자!
기사, 기술 리뷰를 통해 어떤 개발자가 되고싶은지 적어봐야겠다!</p>
<blockquote>
<p>📌매주 하나씩 포스팅할 것
   Ready-For-Tech-Interview start! _ 2023.10.11</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[코테 준비 : day20]]]></title>
            <link>https://velog.io/@young_ryeol/%EC%BD%94%ED%85%8C-%EC%A4%80%EB%B9%84-day20</link>
            <guid>https://velog.io/@young_ryeol/%EC%BD%94%ED%85%8C-%EC%A4%80%EB%B9%84-day20</guid>
            <pubDate>Wed, 11 Oct 2023 03:24:04 GMT</pubDate>
            <description><![CDATA[<h3 id="기록은-없지만-열심히-했습니다">기록은 없지만 열심히 했습니다..</h3>
<p>이번 포스팅은 내 근황 + 코테 준비에 관한 이야기이다!
평일 하루에 8시간은 <strong>에이블스쿨</strong>에 전념하고있다. 힘이 쭉 빠지지만 쉴 틈을 주지 않는 ..ㅎ 바로 한 달동안 <strong>코딩마스터스</strong>라는 이름으로 100문제를 푸는 대회가 열렸다. 나는 10등안에 드는 것을 목표로 정말 열심히 풀었지만 100문제 중 74문제를 풀어서 27등으로 마무리했다🫠. 70문제 풀면 마스터라고 칭해준다..ㅎ 살짝 유치하지만 기분은 좋다! 후회없이 열심히 했고, 많은 알고리즘에 대한 이해를 할 수 있었기에 미련은 없다. 하지만 외부로 유출을 할 수 없으니 내가 푼 문제들을 기록할 수 없다는 점이 조금 슬프다. 74문제를 풀며 자기객관화가 확실히 됐다. <em><strong>난 아직 많이 부족하고 매일 한 문제씩이라도 풀어야 감을 잃지않는다. 오늘부터 백준 문제들로 다시 GO.</strong></em>
<img src="https://velog.velcdn.com/images/young_ryeol/post/6a3afde8-0b53-449e-b751-38f04ee42743/image.png" alt=""></p>
<blockquote>
<ol>
<li>봄버맨
<a href="https://www.acmicpc.net/problem/16918">https://www.acmicpc.net/problem/16918</a>
<img src="https://velog.velcdn.com/images/young_ryeol/post/2366a6db-0e71-4142-89e3-d955c4dc4134/image.png" alt="">
이 문제는 구현문제로 매 초마다 달라지는 격자판에 대해 출력을 해야한다. 홀수, 짝수 초마다 다르고 격자판이 계속 바뀌기에 트래킹을 하며 업데이트를 해야한다. 함수로 각 기능을 나누어서 가독성이 좋도록 했다!</li>
</ol>
</blockquote>
<p>```</p>
<p>r, c, n = map(int, input().split()) # 입력
arr = [list(input()) for _ in range(r)] # 격자판 초기상태 입력
d = [(-1, 0), (1, 0), (0, -1), (0, 1)] # 폭탄 인접 칸 지정
bombs = [] # 폭탄 위치
find_bomb = lambda li: [(i, j) for j in range(c) for i in range(r) if li[i][j] == &#39;O&#39;]  # 현재 폭탄 위치 좌표로 기억</p>
<p>def pung(): # 폭탄 펑!
    global arr, bombs
    for bx, by in bombs:
        arr[bx][by] = &#39;.&#39; # 폭탄 위치 폭파
        for i in range(4):
            nx, ny = bx + d[i][0], by + d[i][1]
            if nx in range(r) and ny in range(c):
                arr[nx][ny] = &#39;.&#39; # 폭탄 인접 위치 폭파</p>
<p>def fill_bombs(): # 폭탄으로 채우기. 모두 0으로
    global arr
    arr = [[&#39;O&#39;] * c for _ in range(r)]</p>
<p>def print_answer(li): # 결과 출력
    for line in li:
        print(&#39;&#39;.join(line))</p>
<p>for second in range(1, n): # 홀수: 폭탄 위치 기억, 모두 폭탄으로 채우기 / 짝수: 폭탄 펑!
    if second % 2 == 1:
        bombs = find_bomb(arr) # 폭탄 위치 찾고
        fill_bombs() # 폭탄 채우기
    else:
        pung() # 폭탄 펑!</p>
<p>print_answer(arr)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[KT 에이블스쿨] 3차 미니프로젝트]]></title>
            <link>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-3%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-3%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Tue, 10 Oct 2023 06:50:23 GMT</pubDate>
            <description><![CDATA[<h2 id="💲-3차-미니-프로젝트">💲 3차 미니 프로젝트</h2>
<p><strong>미션: 저시력자들을 위한 원화 화폐  분류</strong></p>
<p><strong>활용 데이터셋</strong> </p>
<p>화폐정보 데이터(이미지, 메타정보)</p>
<p><strong>활용 기술</strong> </p>
<p>Object Detection- YOLOv5</p>
<p><strong>도메인 이해</strong></p>
<p>리나라 국민 약 200명 중 1명은 시각장애</p>
<p>시각장애인 76%가 후천적 요인으로 시력을 잃음</p>
<p>시각장애인 90%가 점자 해독 불가능</p>
<p>📌 저시력자들은 빠르게 화폐를 구별할 수 있는 도구가 필요함!</p>
<p><strong>데이터 전처리 및 구조 만들기</strong></p>
<pre><code>import os
import glob
import shutil
import random

# 데이터 분할 및 이동
def split_and_move_data(data_path, split_ratio=0.8):
    won_list = [&#39;10&#39;, &#39;50&#39;, &#39;100&#39;, &#39;500&#39;, &#39;1000&#39;, &#39;5000&#39;, &#39;10000&#39;, &#39;50000&#39;]

    for won in won_list:
        image_files = glob.glob(os.path.join(data_path, won, &#39;*.jpg&#39;))
        random.shuffle(image_files)  # 데이터 순서를 랜덤하게 섞음

        num_train = int(len(image_files) * split_ratio)

        for i, image_file in enumerate(image_files):
            if i &lt; num_train:
                split = &#39;train&#39;
            else:
                split = &#39;val&#39;

            # 이미지 데이터 이동
            dest_image_path = os.path.join(data_path, &#39;images&#39;, split, os.path.basename(image_file))
            shutil.move(image_file, dest_image_path)

            # 레이블 데이터 파일명을 맞춰서 이동
            label_file = os.path.splitext(image_file)[0] + &#39;.json&#39;
            dest_label_path = os.path.join(data_path, &#39;labels&#39;, split, os.path.basename(label_file))
            shutil.move(label_file, dest_label_path)

if __name__ == &#39;__main__&#39;:
    data_path = &#39;/content/drive/MyDrive/Dataset/&#39;

    split_and_move_data(data_path</code></pre><p><strong>JSON 파일 정보 추출 및 변경</strong></p>
<pre><code>import os
import json
won_dict = {0:&#39;Ten&#39;, 1:&#39;Fifty&#39;, 2:&#39;Hundred&#39;, 3:&#39;Five_Hundred&#39;, 4:&#39;Thousand&#39;, 5:&#39;Five_Thousand&#39;, 6:&#39;Ten_Thousand&#39;, 7:&#39;Fifty_Thousand&#39;}
# JSON 파일에서 정보 추출 및 YOLO 형식으로 변환하는 함수
def convert_json_to_yolo(json_file_path):
    with open(json_file_path, &#39;r&#39;) as json_file:
        data = json.load(json_file)

        # 클래스 정보에서 앞뒷면 구분 없애기
        # label = data[&#39;shapes&#39;][0][&#39;label&#39;].split(&#39;_&#39;)[0]
        label = data[&#39;shapes&#39;][0][&#39;label&#39;].rsplit(&#39;_&#39;, 1)[0]

        # 클래스 이름을 매핑된 이름으로 변경
        label =list(won_dict.keys())[list(won_dict.values()).index(label)]
        # JSON 파일 내의 이미지 크기 가져오기
        original_image_width = data[&#39;imageWidth&#39;]
        original_image_height = data[&#39;imageHeight&#39;]

        # 이미지 크기 (원본 크기의 1/5)
        image_width = original_image_width / 5.0
        image_height = original_image_height / 5.0

        # 위치 정보 추출 및 YOLO 형식에 맞게 변환
        x1, y1 = data[&#39;shapes&#39;][0][&#39;points&#39;][0]
        x2, y2 = data[&#39;shapes&#39;][0][&#39;points&#39;][1]
        x1 = x1 / 5.0
        y1 = y1 / 5.0
        x2 = x2 / 5.0
        y2 = y2 / 5.0

        # YOLO 형식으로 변환
        x_center = (x1 + x2) / 2.0
        y_center = (y1 + y2) / 2.0
        width = x2 - x1
        height = y2 - y1

        # Normalize된 값으로 변환
        x_center_norm = x_center / image_width
        y_center_norm = y_center / image_height
        width_norm = width / image_width
        height_norm = height / image_height

        # YOLO 형식의 문자열 생성
        yolo_label = f&quot;{label} {x_center_norm} {y_center_norm} {width_norm} {height_norm}&quot;

        return yolo_label

# JSON 파일들이 있는 디렉토리 경로
base_json_dir = &#39;/content/drive/MyDrive/Dataset/labels&#39;
subdirs = [&#39;train&#39;, &#39;val&#39;]

# JSON 파일을 YOLO 형식으로 변환하여 TXT 파일로 저장
for subdir in subdirs:
    json_dir = os.path.join(base_json_dir, subdir)
    for json_file in os.listdir(json_dir):
        if json_file.endswith(&#39;.json&#39;):
            json_file_path = os.path.join(json_dir, json_file)
            yolo_label = convert_json_to_yolo(json_file_path)

            # TXT 파일로 저장
            txt_file_path = os.path.splitext(json_file_path)[0] + &#39;.txt&#39;
            with open(txt_file_path, &#39;w+&#39;) as txt_file:
                txt_file.write(yolo_label)

            # 변환된 레이블과 TXT 파일 경로 출력
            print(f&#39;변환된 레이블: {yolo_label}&#39;)
            print(f&#39;TXT 파일 경로: {txt_file_path}&#39;)</code></pre><p><strong>가중치 파일 다운로드 및 학습</strong></p>
<pre><code>
#가중치 파일
!mkdir /content/drive/MyDrive/Dataset/weights  # 가중치 파일을 저장할 폴더 생성
!wget https://github.com/ultralytics/yolov5/releases/download/v5.0/yolov5s.pt -O /content/drive/MyDrive/Dataset/weights/yolov5s.pt

#학습
!python /content/yolov5/train.py --img-size 416 --batch-size 16 --epochs 50 --data /content/drive/MyDrive/Dataset/money.yaml --cfg yolov5/models/yolov5s.yaml --weights yolov5/weights/yolov5s.pt --name my_experiment

#탐지
!python yolov5/detect.py --weights /content/yolov5/runs/train/my_experiment/weights/best.pt --img-size 416 --conf 0.75 --iou-thres 0.25 --source  /content/drive/MyDrive/minipro_03/Dataset/test_money2.jpg
</code></pre><p>✔train.py를 통해 학습을 진행하기 위해 YOLOv5 데이터 구조 만들어주기</p>
<p>✔이미지 크기는 416, batch는 16, epochs는 50으로 설정</p>
<p>✔data에는 위에서 만든 yaml 파일 경로를 지정</p>
<p>✔weights와 cfg에는 위에서 다운한 yolov5s의 파일을 가져온다</p>
<p>✔마지막으로 결과를 저장할 이름을 설정하고 학습을 진행한다.</p>
<p>✔️학습을 마친 후에는 최적의 가중치가 담긴 best.pt가 생성되므로 학습 이 후에는 best.pt를 이용하여 detect를 진행한다.
<img src="https://velog.velcdn.com/images/young_ryeol/post/07f022d7-5882-4aed-949d-c0851acd9b2e/image.png" alt=""></p>
<p><a href="https://youtube.com/shorts/LSIVn96ULs8?si=Rm4sHaPzjmjrrY3V">화폐 분류 인식 결과 영상</a></p>
<blockquote>
<p>🚩3차 미니 프로젝트를 마치며
<img src="https://velog.velcdn.com/images/young_ryeol/post/cc898f59-b156-477c-bbdf-49f705cab537/image.png" alt="">
일단 학습 데이터가  iconic했기에 여러 동전이 겹쳐있는 경우는 인식이 어려웠다. 하지만 화폐 전체가 잘 보인다면 인식률은 상당히 높았다!
YOLOv5는 캡스톤 디자인 때 많이 다뤄봤기에 에이블스쿨에서도 만나니 반가웠다. 이 얘기는 시각 지능을 얘기할 때 YOLO는 빠질 수 없는 기술이라는 것이다. 어떤 서비스를 기획할 때 카메라를 통한 연계 기술을 하고자 한다면 다시 찾을 YOLO.. 다음엔 YOLOv8을 사용해볼 것이다😊</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[KT 에이블스쿨] 2차 미니프로젝트]]></title>
            <link>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-2%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-2%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Tue, 10 Oct 2023 06:08:29 GMT</pubDate>
            <description><![CDATA[<h2 id="🚖-2차-미니-프로젝트">🚖 2차 미니 프로젝트</h2>
<p><strong>미션: 장애인 이동권 개선을 위한 장애인 콜택시 대기시간 예측</strong></p>
<p><strong>활용 데이터셋</strong> </p>
<p>1.장애인 콜택시 운행정보
2.날씨 정보</p>
<p><strong>도메인 이해</strong></p>
<p>장애인 외출 시 자주 이용하는 교통수단 1위 → 장애인 콜택시
콜접수 - 배차 - 운행
이용 고객 만족도가 낮음</p>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/c3aa556c-888e-413e-bc0b-cf53714fbe44/image.png" alt="">
📌이용 고객들에게 정확한 대기 시간을 제공해주자!</p>
<p><strong>데이터 전처리 및 분석</strong></p>
<pre><code># 시각화 (lineplot 사용)
plt.figure(figsize=(10, 6))
plt.plot(daily_car_count.index, daily_car_count.values, marker=&#39;o&#39;, linestyle=&#39;-&#39;, color=&#39;b&#39;)
plt.title(&#39;일별 차량 운행수&#39;)
plt.xlabel(&#39;날짜&#39;)
plt.ylabel(&#39;차량 운행수&#39;)
plt.xticks(rotation=45)  # x축 라벨 회전
plt.grid(True)
plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/young_ryeol/post/fc45512e-a1df-41ce-a79d-20bf1e65a7d7/image.png" alt=""></p>
<pre><code># 시각화 (lineplot 사용)
plt.figure(figsize=(10, 6))
plt.plot(daily_request_count.index, daily_request_count.values, marker=&#39;o&#39;, linestyle=&#39;-&#39;, color=&#39;b&#39;, label=&#39;접수건&#39;)
plt.plot(daily_ride_count.index, daily_ride_count.values, marker=&#39;o&#39;, linestyle=&#39;-&#39;, color=&#39;g&#39;, label=&#39;탑승건&#39;)
plt.title(&#39;일별 접수건 및 탑승건&#39;)
plt.xlabel(&#39;날짜&#39;)
plt.ylabel(&#39;건 수&#39;)
plt.xticks(rotation=45)  # x축 라벨 회전
plt.legend()  # 범례 표시
plt.grid(True)
plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/young_ryeol/post/c555b0d2-6f67-496f-a913-7cb315107076/image.png" alt=""></p>
<pre><code># 시각화 (boxplot 사용)
plt.figure(figsize=(10, 6))
plt.boxplot(weekday_car_counts, labels=[&#39;월&#39;, &#39;화&#39;, &#39;수&#39;, &#39;목&#39;, &#39;금&#39;, &#39;토&#39;, &#39;일&#39;])
plt.title(&#39;요일별 차량 운행수&#39;)
plt.xlabel(&#39;요일&#39;)
plt.ylabel(&#39;차량 운행수&#39;)
plt.grid(True)
plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/young_ryeol/post/dc933d6d-b80f-48dc-a5a2-408add7d89dc/image.png" alt=""></p>
<pre><code># 시각화 (boxplot 사용)
plt.figure(figsize=(10, 6))
plt.boxplot(month_waiting_time, labels=[&#39;1월&#39;, &#39;2월&#39;, &#39;3월&#39;, &#39;4월&#39;, &#39;5월&#39;, &#39;6월&#39;, &#39;7월&#39;,&#39;8월&#39;, &#39;9월&#39;, &#39;10월&#39;, &#39;11월&#39;,&#39;12월&#39;])
plt.title(&#39;월별 차량운행수&#39;)
plt.xlabel(&#39;월&#39;)
plt.ylabel(&#39;차량운행수&#39;)
plt.grid(True)
plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/young_ryeol/post/aa708e42-f6d5-42d1-be36-48247d6170c7/image.png" alt=""></p>
<p>** 데이터 구조 만들기**</p>
<pre><code># 날짜를 하루씩 미루어서 다음날 예보 데이터로 사용
weather[&#39;Date&#39;] = pd.to_datetime(weather[&#39;Date&#39;]) - pd.DateOffset(days=1)
weather[&#39;Date&#39;] = pd.to_datetime(weather[&#39;Date&#39;])
# 장애인 이동 데이터와 날씨 데이터를 날짜를 기준으로 병합
combined_data = pd.merge(open_data, weather,on=&#39;Date&#39;,how=&#39;inner&#39;)


# 결과 데이터를 저장하거나 분석에 활용할 수 있습니다.
combined_data.to_csv(&quot;merge.csv&quot;, index=False)  # 저장 파일 경로에 맞게 변경


# 익일의 대기시간(waiting time)을 오늘의 데이터를 활용하여 예측 해야하는 대상(target)으로 설정
# waiting_time 열을 시프트하여 익일 대기시간을 예측 대상으로 만듭니다.
merged_data[&#39;target&#39;] = merged_data[&#39;Waiting_Time&#39;].shift(-1)

# 마지막 행을 제거하여 NaN 값을 제거합니다. (마지막 행은 익일 대기시간이 없으므로)
merged_data = merged_data.dropna(subset=[&#39;target&#39;])

# 예측 대상인 next_day_waiting_time을 설정합니다.
target = merged_data[&#39;target&#39;]</code></pre><pre><code># 숫자형 feature와 Target 간의 상관계수 계산
correlation_matrix = data1.corr()

# 상관계수 히트맵 그리기
plt.figure(figsize=(12, 8))
sns.heatmap(correlation_matrix, annot=True, cmap=&#39;coolwarm&#39;, fmt=&quot;.2f&quot;, linewidths=0.5)
plt.title(&quot;숫자 feature와 Target 간의 상관계수 히트맵&quot;)
plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/young_ryeol/post/3acade05-7bc9-43f0-b26e-37671f7b9dec/image.png" alt=""></p>
<p><strong>모델링</strong></p>
<ul>
<li>가변수화<pre><code># 범주형 변수 리스트
categorical_columns = [&#39;weekday&#39;, &#39;month&#39;, &#39;year&#39;, &#39;season&#39;,&#39;holiday_yn&#39;,&#39;rain_yn&#39;]
</code></pre></li>
</ul>
<h1 id="범주형-변수를-가변수로-변환">범주형 변수를 가변수로 변환</h1>
<p>data2 = pd.get_dummies(data2, columns=categorical_columns)</p>
<h1 id="결과-확인">결과 확인</h1>
<p>print(data2.head())</p>
<pre><code>- 데이터 분할</code></pre><h1 id="데이터프레임을-날짜date-열을-기준으로-정렬합니다">데이터프레임을 날짜(Date) 열을 기준으로 정렬합니다.</h1>
<p>data2.sort_values(by=&#39;Date&#39;, inplace=True)</p>
<h1 id="2022-10-01부터-마지막-날짜까지의-데이터를-검증-셋으로-분리합니다">2022-10-01부터 마지막 날짜까지의 데이터를 검증 셋으로 분리합니다.</h1>
<p>validation_start_date = &#39;2022-10-01&#39;
validation_set = data2[data2[&#39;Date&#39;] &gt;= validation_start_date]</p>
<h1 id="검증-셋을-저장할-때-사용할-날짜-리스트를-추출합니다">검증 셋을 저장할 때 사용할 날짜 리스트를 추출합니다.</h1>
<p>validation_dates = validation_set[&#39;Date&#39;].unique()</p>
<h1 id="검증-셋을-저장할-파일-경로를-지정합니다-필요에-따라-수정하세요">검증 셋을 저장할 파일 경로를 지정합니다. 필요에 따라 수정하세요.</h1>
<p>validation_set.to_csv(&#39;validation_set.csv&#39;, index=False)</p>
<h1 id="결과-확인-1">결과 확인</h1>
<p>print(f&quot;검증 셋 크기: {len(validation_set)}&quot;)
print(f&quot;검증 셋 날짜 리스트: {validation_dates}&quot;)</p>
<h1 id="x와-y를-나누기">x와 y를 나누기</h1>
<p>x = train_test_data.drop(columns=[&#39;target&#39;])  # &#39;target&#39; 열을 제외한 모든 열을 x로 선택
y = train_test_data[&#39;target&#39;]  # &#39;target&#39; 열을 y로 선택</p>
<p>from sklearn.model_selection import train_test_split</p>
<h1 id="데이터를-훈련-세트와-검증-세트로-나누기">데이터를 훈련 세트와 검증 세트로 나누기</h1>
<p>x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, shuffle=False)</p>
<pre><code>- 머신러닝 모델1</code></pre><h1 id="1단계-불러오기">1단계: 불러오기</h1>
<p>from sklearn.linear_model import LinearRegression
from sklearn.metrics import *</p>
<p>model=LinearRegression()</p>
<p>model.fit(x_train, y_train)</p>
<p>y_pred = model.predict(x_test)
y_pred</p>
<p>from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error(y_test, y_pred)
print(&quot;MAE:&quot;, mae)</p>
<p>print(&#39;MAPE: &#39;, mean_absolute_percentage_error(y_test, y_pred))</p>
<p>#MAE: 5.146222160026497
#MAPE:  0.18669192807780016</p>
<h1 id="시각화를-위해-데이터프레임-생성">시각화를 위해 데이터프레임 생성</h1>
<p>result_df = pd.DataFrame({&#39;Actual&#39;: y_test, &#39;Predicted&#39;: y_pred})</p>
<h1 id="라인-차트로-실제값과-예측값-시각화">라인 차트로 실제값과 예측값 시각화</h1>
<p>plt.figure(figsize=(12, 6))
plt.plot(result_df.index, result_df[&#39;Actual&#39;], label=&#39;Actual&#39;, marker=&#39;o&#39;)
plt.plot(result_df.index, result_df[&#39;Predicted&#39;], label=&#39;Predicted&#39;, marker=&#39;x&#39;)
plt.title(&#39;Actual vs. Predicted&#39;)
plt.xlabel(&#39;Sample Index&#39;)
plt.ylabel(&#39;Value&#39;)
plt.legend()
plt.grid(True)
plt.show()</p>
<pre><code>![](https://velog.velcdn.com/images/young_ryeol/post/7695fe08-7ea7-4373-ad0f-994ca550b630/image.png)

- 머신러닝 모델2</code></pre><h1 id="1단계-불러오기-1">1단계: 불러오기</h1>
<p>from sklearn.neighbors import KNeighborsRegressor</p>
<h1 id="2단계-선언하기">2단계: 선언하기</h1>
<p>model = KNeighborsRegressor()</p>
<h1 id="3단계-학습하기">3단계: 학습하기</h1>
<p>model.fit(x_train_scaler, y_train)</p>
<h1 id="4단계-예측하기">4단계: 예측하기</h1>
<p>y_pred = model.predict(x_test_scaler)</p>
<h1 id="5단계-평가하기">5단계: 평가하기</h1>
<h1 id="mae-계산">MAE 계산</h1>
<p>mae = mean_absolute_error(y_test, y_pred)
print(&quot;MAE:&quot;, mae)</p>
<h1 id="mape-계산">MAPE 계산</h1>
<p>print(&#39;MAPE: &#39;, mean_absolute_percentage_error(y_test, y_pred))</p>
<p>#MAE: 13.559294117647058
#MAPE:  0.4844556722610472</p>
<h1 id="시각화를-위해-데이터프레임-생성-1">시각화를 위해 데이터프레임 생성</h1>
<p>result_df = pd.DataFrame({&#39;Actual&#39;: y_test, &#39;Predicted&#39;: y_pred})</p>
<h1 id="라인-차트로-실제값과-예측값-시각화-1">라인 차트로 실제값과 예측값 시각화</h1>
<p>plt.figure(figsize=(12, 6))
plt.plot(result_df.index, result_df[&#39;Actual&#39;], label=&#39;Actual&#39;, marker=&#39;o&#39;)
plt.plot(result_df.index, result_df[&#39;Predicted&#39;], label=&#39;Predicted&#39;, marker=&#39;x&#39;)
plt.title(&#39;Actual vs. Predicted&#39;)
plt.xlabel(&#39;Sample Index&#39;)
plt.ylabel(&#39;Value&#39;)
plt.legend()
plt.grid(True)
plt.show()</p>
<pre><code>
![](https://velog.velcdn.com/images/young_ryeol/post/f98cb0a7-a8e2-4595-bd84-c37c0ee9e42b/image.png)


- 딥러닝 모델</code></pre><p>import tensorflow as tf</p>
<p>X = tf.keras.Input(shape=x_train.shape[1])
H = tf.keras.layers.Flatten()(X)</p>
<p>H = tf.keras.layers.Dense(64)(H)
H = tf.keras.layers.BatchNormalization()(H)
H = tf.keras.layers.Activation(&#39;swish&#39;)(H)</p>
<p>for i in range(16):
    H1 = tf.keras.layers.Dense(64)(H)
    H1 = tf.keras.layers.BatchNormalization()(H1)
    H1 = tf.keras.layers.Activation(&#39;swish&#39;)(H1)
    H = tf.keras.layers.Add()([H, H1])</p>
<p>Y = tf.keras.layers.Dense(1)(H)
model2 = tf.keras.Model(X, Y)
model2.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
             loss=&#39;mae&#39;)</p>
<h1 id="modelsummary">model.summary()</h1>
<p>early = tf.keras.callbacks.EarlyStopping(patience=10, restore_best_weights=True)
result = model2.fit(x_train, y_train, epochs=10000000, batch_size=128,
                   validation_split=0.2, # validation_data=(x_val, y_val)
                   callbacks=[early])</p>
<p>model2.evaluate(x_test, y_test)</p>
<p>#4.886806011199951</p>
<pre><code></code></pre><h1 id="모델-1번-시각화">모델 1번 시각화</h1>
<p>final_model = model1</p>
<p>y_pred = final_model.predict(x_test)
plt.plot(y_test.values, label=&#39;Actual&#39;)
plt.plot(y_pred, label=&#39;Predicted&#39;)
plt.legend()
plt.title(&#39;Waiting Time&#39;)
plt.show()</p>
<p>mae = mean_absolute_error(y_test, y_pred)
print(f&#39;MAE : {round(mae,3)}&#39;)</p>
<pre><code>![](https://velog.velcdn.com/images/young_ryeol/post/694de607-db2f-4496-9cdf-01640924035d/image.png)


&gt; 🚩2차 미니 프로젝트를 마치며
- 모델링에서 어떤 변수를 이용하냐에 따라 성능이 달라지는 것을 확인하고 어떤 변수를 제거할지 고민을 많이 해야한다. 조별 회의 때 변수를 어떻게 선정했는지 이야기를 많이 했는데 대부분 팀원들이 상관 분석을 통해 상관계수가 작은 변수를 제거하는 쪽을 택했다. 하지만 여기서도 나뉜 것이 계수로만 보고 판단해서 과감하게 다 제거하거나 아니면 계수는 작지만 개인적으로 생각했는데 필요하다고 생각하는 변수는 넣자와 머신 러닝 자체가 학습을 하면서 관계가 적은 변수의 가중치를 줄여 학습을 하는데 굳이 생각하지 않고 모든 변수를 다 이용한 팀원 분도 계셨다.
- 2020년에 콜택시 이용자 수가 크게 감소했다. 그 이유는? 코로나일 것이다. 데이터를 분석하며 그저 보이는대로 분석하기 보단 이상치 혹은 이벤트도 고려하여 분석해야한다.


</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[KT 에이블스쿨] 1차 미니프로젝트]]></title>
            <link>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-1%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-1%EC%B0%A8-%EB%AF%B8%EB%8B%88%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Tue, 10 Oct 2023 05:20:46 GMT</pubDate>
            <description><![CDATA[<h2 id="🚌1차-미니-프로젝트">🚌1차 미니 프로젝트</h2>
<p><strong>미션: 버스노선 추가가 필요한 서울시 내 자치구 선정</strong></p>
<p><strong>활용 데이터셋</strong> </p>
<ol>
<li>서울시 구별 버스 승하차 이용 데이터</li>
<li>서울시 버스 데이터</li>
<li>서울시 구별 유동 인구 데이터</li>
<li>서울시 구별 주민 등록 인구 데이터</li>
<li>서울시 구별 업종 등록 데이터</li>
</ol>
<p><strong>도메인 이해</strong></p>
<ol>
<li>서울은 몇 개의 구로 이루어져 있을까?</li>
<li>인구가 가장 많은 구는? 가장 적은 구는?</li>
<li>면적이 가장 큰 구는? 가장 작은 구는?</li>
<li>도로 길이 합이 제일 긴 구는?</li>
<li>도로 면적 합이 제일 큰 구는?</li>
</ol>
<p><strong>가설 설정</strong>
승차 총 승객 수, 택시 사업자수, 용달 사업자수, 구별 이동 시간이 노선 수 결정에  영향을 준다.</p>
<p><strong>데이터 분석</strong></p>
<pre><code>import matplotlib.pyplot as plt
import seaborn as sns

# 그래프 그리기
plt.figure(figsize=(12, 8))

# 구 별 버스 노선 개수 그래프
sns.barplot(x=&#39;자치구&#39;, y=&#39;버스정류장개수&#39;, data=seoul_bus_station)
plt.xticks(rotation=90)
plt.title(&#39;구 별 버스 정류장 개수&#39;)

plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/young_ryeol/post/3d7afc20-df31-42c8-84a3-d6e0dcfb25f2/image.png" alt=""></p>
<pre><code># 그래프 크기 설정
plt.figure(figsize=(10, 6))

# 막대 그래프 그리기
sns.barplot(data=seoul_bus_station, x=&quot;자치구&quot;, y=&quot;승차평균승객수&quot;, color=&quot;blue&quot;, label=&quot;승차&quot;)
sns.barplot(data=seoul_bus_station, x=&quot;자치구&quot;, y=&quot;하차평균승객수&quot;, color=&quot;orange&quot;, label=&quot;하차&quot;)

# 범례 표시
plt.legend()

# 그래프 제목과 라벨 설정
plt.title(&quot;자치구별 승차/하차 평균 승객수&quot;)
plt.xlabel(&quot;자치구&quot;)
plt.ylabel(&quot;평균 승객수&quot;)
plt.xticks(rotation=90)
# 그래프 출력
plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/young_ryeol/post/0a45060a-168e-456e-bb75-6ab526ef39bb/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/ca1f3d9f-1dca-4b7c-92d8-8784efb1c3dc/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/850c630a-200d-41e2-a850-946b27ba854e/image.png" alt=""></p>
<p><strong>가설 검증</strong>
해당 변수들이 전부 노선 증설 결정에 포함해야 한다고 생각하여 다음과 같은 공식 수립
<strong>승차총승객수역순위</strong> <strong>* 0.67 + 택시역순위</strong> <strong>* -0.60 + 용달역순위</strong> <strong>* -0.58 +</strong> <strong>이동시간평균역순위</strong> <strong>* -0.68</strong>
❗r값을 가중치로 설정</p>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/12a68570-6e4f-4a6f-819d-c7f202b69e6b/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/2748a19b-7da4-4134-a768-bf1a96fe6b48/image.png" alt=""></p>
<p>*<em>솔루션 도출 *</em>
데이터 전처리 후 변수들 간 관계를 따져보았다.</p>
<p>강한 상관관계를 보이는 변수들을 고려하여 r값을 가중치로 지정하여 노선 증설 순위를 매겼다.</p>
<p><strong>결론적으로 강동구, 강서구, 도봉구 순으로 노선 증설이 필요하다고 생각한다.</strong></p>
<blockquote>
<p>🚩<strong>1차 미니 프로젝트를 마치며</strong>
1차 미니 프로젝트를 진행하며 너무 많은 것들을 느꼈다. </p>
</blockquote>
<ul>
<li>일반적으로 맞다고 생각한 것이 데이터를 분석해보면 상반되는 경우가 정말 많다.
예를 들어 버스 정류장이 적고, 버스 이용자 수가 많다면 당연하게 노선을 추가해야한다고 생각했다. 하지만 택시 운행 수가 많은 곳은 버스 노선 추가가 필요 없을 확률이 높다. 버스 보다 택시, 지하철이 편한 지역일 경우일 수 있다.<ul>
<li>사람마다 데이터를 바라보는 관점이 다르기에 팀 동료들과 많은 얘기를 해봐야한다.
나는 이번 주제에서 용달종사자의 수 데이터는 필요없다고 생각했다. 하지만 팀원이 말하길 용달 종사자라면 버스를 타지 않을 것이고, 이는 노선  추가 제외 대상이지 않냐는 의견이였다. 머리를 한 대 맞은 느낌...! 데이터를 필터링하는 것은 중요하지만, 한 번 더 생각해볼 필요가 있다는 것을 느꼈다.</li>
<li>실제 데이터를 이용한 미니 프로젝트
이번 프로젝트를 진행하며 실제 데이터를 다뤄보는 것이 가장 좋았다. 실제로 서울시에 어느 곳이 어떤 특성을 띄는지 알 수 있었고, 내가 알던 도메인 지식도 추가하여 프로젝트를 진행할 수  있었다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[KT 에이블스쿨] 교육 시작]]></title>
            <link>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-%EA%B5%90%EC%9C%A1-1%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-%EA%B5%90%EC%9C%A1-1%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Fri, 18 Aug 2023 03:08:11 GMT</pubDate>
            <description><![CDATA[<h3 id="kt-에이블스쿨-교육-1주차-_--back-to-19">KT 에이블스쿨 교육 1주차 _ ( back to 19..)</h3>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/46f9fc17-b7b2-4a64-9320-88121d82795e/image.png" alt=""></p>
<p>드디어 교육 시작..! 요즘 나의 하루는 05:50 기상- 헬스 - 9<del>6 수업 - 7</del>9 개인공부...
고3으로 돌아간 기분이다. 근데 나쁘지않다? 사실 난 이런 체계가 잡히면 잘 따라가는편🫠
기상시간은 몇 년째 똑같으니 힘들지않고, 수업을 들을 때 허리가 아플뿐..!
하루 리듬을 몸에 익히는 중이다. 흐름에 몸을 맡겨🏄‍♂️</p>
<p><strong>1주차 교육은 git 사용법, 파이썬 기본 문법을 배웠다.</strong>
파이썬 문법은 평소에 잘 알고있었기에 복습하는 느낌으로 가볍게 들었다.
git 사용은 정말 유용했다..! 유명하신 이고잉 강사님...익숙한 목소리여서 너무 좋았다.
사실 시작할 때 풀- 변경하고 커밋-푸쉬만을 알고 있었는데 여러 관계를 따져보니 복잡했다.</p>
<p><strong>pull-작업-commit-pull-push  =&gt; 퇴근이 빨라진다😝</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[KT 에이블스쿨] 노트북 수령 후기]]></title>
            <link>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-%EB%85%B8%ED%8A%B8%EB%B6%81-%EC%88%98%EB%A0%B9-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@young_ryeol/KT-%EC%97%90%EC%9D%B4%EB%B8%94%EC%8A%A4%EC%BF%A8-%EB%85%B8%ED%8A%B8%EB%B6%81-%EC%88%98%EB%A0%B9-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Mon, 14 Aug 2023 00:50:40 GMT</pubDate>
            <description><![CDATA[<h3 id="내년에는-사원증으로💪">내년에는 사원증으로💪</h3>
<h4 id="내배카-발급-및-hrd-net-수강신청">&lt;내배카 발급 및 HRD-net 수강신청&gt;</h4>
<p>지난번 합격후기에 이어서 수강신청, 노트북 수령 후기로 돌아왔다!
먼저 수업을 듣기 전에 내배카 발급, 수강신청을 진행했다. 
<strong>오픈톡방</strong>으로 궁금한 점을 바로 해소할 수 있어서 수월하게 진행했다👻
국취제 관련해서 복잡한 절차가 있는 듯했다. 그래서 수강신청 후 국취제 신청하는 것을 권장한다고 하셨다! 난 이미 합격과 동시에 신청에 들어가서, 수강신청에서 문제가 생기는게 아닌지 걱정했지만 다행히 문제는 없었다.</p>
<p>이 세가지만 확인한다면 수월할 것이라고 생각한다~</p>
<p><strong>1. 내배카 미리 발급
2. 국취제는 미리 신청해서 상담 3회차까지 끝내는 것이 베스트
3. 수강신청 잘하기</strong></p>
<h4 id="노트북-수령-후기">&lt;노트북 수령 후기&gt;</h4>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/b6c5a108-c905-4ad0-961b-d31c84711cd4/image.png" alt=""></p>
<p>노트북 수령하러 kt 분당 본사에 다녀왔다. 분당선으로 정자역까지만 가면 금방 갈 수 있어서 편하게 갔다.
하지만 여름인걸.. 폭염인걸.. 생각하지 않고 20분 걸어갔다가 그냥 티셔츠가 다 젖었다.<br><strong>땀? 흐를게~ 회색티? 젖을게~</strong>  뽀송하게 가고싶었지만 <strong>내 첫인상은 농부</strong>일듯하다...ㅎ 뽀송은 포기하고 빠르게 받고 나오자라는 생각으로 들어갔다! 건물은 정말 크고 깨끗해보였다. 나도 취업을 한다면 이 곳에서 일하고 싶다는 생각이 들었다. 출입증을 받고 출입증을 찍으며 들어갔는데 정말 기분이 묘했다. <strong>이 출입증이 사원증으로 바뀌는 상상을 하며..!</strong>
노트북은 LG그램을 수령했고 모두 다 친절하게 대해주셔서 기분이 좋았다~
노트북을 받으러 갔다오니 동기부여가 됐다. 이 건물에 사원증을 찍고 들어갈 것이다!
그래서 <strong>앞으로의 6개월이 중요하다는 것을 잘 알고있다. 가보자고</strong>👊</p>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/72772ac3-c738-4c57-8844-6ecf2b3fe7e4/image.png" alt=""></p>
<blockquote>
<p><em><strong>다음엔 출입증이 아닌 사원증으로!</strong></em></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[코테 준비 : day19]]]></title>
            <link>https://velog.io/@young_ryeol/%EC%BD%94%ED%85%8C-%EC%A4%80%EB%B9%84-day19</link>
            <guid>https://velog.io/@young_ryeol/%EC%BD%94%ED%85%8C-%EC%A4%80%EB%B9%84-day19</guid>
            <pubDate>Thu, 20 Jul 2023 06:49:56 GMT</pubDate>
            <description><![CDATA[<h3 id="돌고돌아-단게별로-풀어보기로">돌고돌아 단게별로 풀어보기로</h3>
<p>예전에 백준을 처음 시작할 때 단계별로 풀어보기를 풀다가 다른 커리큘럼을 떠돌았다. 하지만 돌고 돌아 순정..! 
단계별로 풀어보기 정진할 예정이다. 쉬운 부분도 있지만 올라가는 맛이 있으니 차근차근 올라가보자구요😋</p>
<p><img src="https://velog.velcdn.com/images/young_ryeol/post/7d732ffa-591f-4cef-a68c-2f7e20fdb47f/image.png" alt=""></p>
<blockquote>
<ol>
<li>약수들의합
<a href="https://www.acmicpc.net/problem/9506">https://www.acmicpc.net/problem/9506</a>
<img src="https://velog.velcdn.com/images/young_ryeol/post/02992459-e3f5-4584-9c17-1b4db1575dc7/image.png" alt=""></li>
</ol>
</blockquote>
<pre><code>while True:
    n=int(input())
    num=[]
    sum=0
    if n==-1:
        break
    for i in range(1,n):
        if n%i==0:
            num.append(i)
    for j in num:
        sum+=j
    if sum==n:
        print(n,&quot;=&quot;,end=&quot; &quot;)
        print(*num,sep=&quot; + &quot;)

    else:
        print(&#39;%d is NOT perfect.&#39; %n)

</code></pre><blockquote>
<ol start="2">
<li>소수
<a href="https://www.acmicpc.net/problem/2581">https://www.acmicpc.net/problem/2581</a>
<img src="https://velog.velcdn.com/images/young_ryeol/post/ce359e9c-c459-4e9f-b808-dea9428ce7dc/image.png" alt=""></li>
</ol>
</blockquote>
<pre><code>n=int(input())
m=int(input())
num=[]
for i in range(n,m+1):
    flag=True
    if i&gt;1:
        for j in range(2,i):
            if i%j==0:
                flag=False
        if flag:
            num.append(i)
if len(num)&gt;0:
    print(sum(num))
    print(min(num))
else:
    print(-1)
</code></pre><blockquote>
<ol start="3">
<li>중앙 이동 알고리즘
<a href="https://www.acmicpc.net/problem/2903">https://www.acmicpc.net/problem/2903</a>
<img src="https://velog.velcdn.com/images/young_ryeol/post/08f768ee-6bca-4852-a819-e58efc4bf499/image.png" alt=""></li>
</ol>
</blockquote>
<pre><code>print((2**int(input())+1)**2)</code></pre><blockquote>
<ol start="4">
<li>대푯값2
<a href="https://www.acmicpc.net/problem/2587">https://www.acmicpc.net/problem/2587</a>
<img src="https://velog.velcdn.com/images/young_ryeol/post/7d1f7585-48b9-424b-a497-7c5b4955169b/image.png" alt=""></li>
</ol>
</blockquote>
<pre><code>num=[]
for i in range(5):
    num.append(int(input()))
num.sort()
print(int(sum(num)//len(num)))
print(num[-3])</code></pre><blockquote>
<ol start="5">
<li>좌표 정렬하기 2
<a href="https://www.acmicpc.net/problem/11651">https://www.acmicpc.net/problem/11651</a>
<img src="https://velog.velcdn.com/images/young_ryeol/post/e287a956-e767-4da8-a745-e1e2a4cd867e/image.png" alt=""></li>
</ol>
</blockquote>
<pre><code>n=int(input())
num=[]
for i in range(n):
    x,y=map(int,input().split())
    num.append((x,y))
num.sort(key=lambda x: (x[1],x[0]))
for j in num:
    print(j[0],j[1])</code></pre>]]></description>
        </item>
    </channel>
</rss>