<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ko">
		<id>https://capstone.uos.ac.kr/cdc/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Com237</id>
		<title>cdc wiki - 사용자 기여 [ko]</title>
		<link rel="self" type="application/atom+xml" href="https://capstone.uos.ac.kr/cdc/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Com237"/>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php/%ED%8A%B9%EC%88%98:%EA%B8%B0%EC%97%AC/Com237"/>
		<updated>2026-05-01T22:42:03Z</updated>
		<subtitle>사용자 기여</subtitle>
		<generator>MediaWiki 1.28.2</generator>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=12013</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=12013"/>
				<updated>2025-06-19T14:07:27Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 사용자 만족도 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:Dos-등산사고-발생-요인.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_1&amp;quot;&amp;gt;'''그림 1.''' 등산사고 발생 요인 (산림청 제공)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::최근 산림청의 조사[[#ref1|[1]]]에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다([[#그림_1|그림 1]]). 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터([[#그림_2|그림 2]])를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-산림청제공데이터.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_2&amp;quot;&amp;gt;'''그림 2.''' 산림청 제공 데이터 예시&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[[#ref1|[1]]].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_3&amp;quot;&amp;gt;'''그림 3.''' 22개 산 데이터의 정점 수(왼쪽), 간선 수(오른쪽). 빨간색 점선은 평균값에 해당한다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. [[#그림_3|그림 3]]은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. &lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표 1&amp;quot;&amp;gt;표 1. 한 번에 10명의 사용자가 동시에 요청을 보냈을 때 소요 시간&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-자원사용률.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_4&amp;quot;&amp;gt;'''그림 4.''' 실제 서버에서 등산로 추천 요청을 100개 정도 받았을 때 걸리는 서버 부하&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다([[#표_1|표 1]]). 시뮬레이션 결과, 서버에 걸리는 부하는 [[#그림_4|그림 4]]와 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표 2&amp;quot;&amp;gt;표 2. 라즈베리파이 5 사양 명세&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다([[#표_2|표 2]]). 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
 소프트웨어 실행 흐름도&lt;br /&gt;
:개략적인 우리 시스템의 실행 흐름은 다음과 같다([[#그림_5|그림 5]]).&lt;br /&gt;
[[파일:소프트웨어흐름도.png|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_5&amp;quot;&amp;gt;'''그림 5.''' 시스템의 실행 흐름도&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동사진.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_6&amp;quot;&amp;gt;'''그림 6.''' 프로토타입 메인 화면 및 등산로 추천 기능&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
아래의 링크를 클릭하거나 인터넷 탐색기에 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:dos-실행방법.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_7&amp;quot;&amp;gt;'''그림 7.''' 셰르파(Sherpa) 실행 방법&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:::[[파일:dos-ASQ-tesk.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도 (SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
:::[[파일:Dos-sus.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[[#ref5|[5]]]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시나리오 후 설문 (ASQ)'''&lt;br /&gt;
[[파일:dos-asq-result.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_10&amp;quot;&amp;gt;'''그림 10.''' 시나리오 후 설문(ASQ)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시나리오 후 설문([[#그림_10|[그림 10]]]은 각 Task를 수행하는 것이 얼마나 어려운지 확인하는 사용성 평가 방법이다[[#ref6|[6]]]. 우리는 우리 시스템에서 제공하는 주요 기능(개인 맞춤형 등산 목적지 추천, 개인 맞춤형 등산로 생성, 생성한 등산로 안내)을 쉽게 사용할 수 있는 지 확인하기 위하여 우리의 기능에 대응되는 Task를 만든 시나리오 후 설문을 진행했다. 설문 진행 결과, 우리가 제공하는 주요 기능이 모두 사용자가 쓰기 편하다는 것을 확인했다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''반구조화 인터뷰'''&lt;br /&gt;
우리는 추후 우리 앱을 개선하기 위하여, 앞선 두 개의 설문을 진행한 이후 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 묻는 반구조화 인터뷰를 진행했다. 주요한 내용은 다음과 같았다.&lt;br /&gt;
&lt;br /&gt;
:'''좋았던 점'''&lt;br /&gt;
 ''기존에 등산로 방향을 찾을 때 사진이 올라와 있는 블로그들을 많이 참조했는데, 직접적으로 방향을 알려주는 점이 좋았다.             -P7-''&lt;br /&gt;
&lt;br /&gt;
 ''아직 개인의 운동 수준과 등산로 난이도 스케일이 정확히 맞지는 않는 것 같지만, 어려운 등산로일수록 등산로 난이도가 어렵게 나오는 건 맞는 것 같다. 등산을 진행할 때 어느 정도 참고가 가능할 것 같다.      -P10- ''&lt;br /&gt;
&lt;br /&gt;
:'''개선할 점'''&lt;br /&gt;
 ''등산 목적지에 쉬운 코스가 없을 경우, 난이도를 쉽게 설정해도 어려운 코스가 나오는 문제점이 있다.   -P4-''  (해결됨)&lt;br /&gt;
&lt;br /&gt;
 ''위시리스트 담기라는 표현 자체가 잘 이해되지 않았다.      -P8-''&lt;br /&gt;
&lt;br /&gt;
 ''Navi 페이지에서 진행바가 새로고침할 때마다 리셋되는 것이 아쉬웠다.  -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''목적지 추천 부분에서 산 이름이 영어로 나오는 점이 아쉬웠다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
:'''UI 관련'''&lt;br /&gt;
 ''프로토타입 UI는 개인적으론 별 다른 것 없이 깔끔해서 좋았다.     -P2, P7-''&lt;br /&gt;
&lt;br /&gt;
 ''잡다한 기능이 없어서 사용법을 금방 익힐 수 있었다. -P9-''&lt;br /&gt;
&lt;br /&gt;
:'''추가되었으면 하는 기능'''&lt;br /&gt;
 ''코스 예상시간이 표기되면 좋을 것 같다.   -P1-''&lt;br /&gt;
&lt;br /&gt;
 ''더 많은 산들에 대해서도 정보를 제공하면 좋을 것 같다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
 ''나와 비슷한 사용자들을 매칭해주는 기능이 있으면 좋을 것 같다.   -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''등산했던 등산로들을 모아서 저장하고 공유할 수 있는 기능이 있으면 좋을 것 같다.      -P12-''&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
서비스를 운영하는 데에 드는 비용은 도메인 유지 비용(10달러/1년), 라즈베리파이를 유지하기 위한 전기료 정도를 고려할 수 있다. 이는 페이지 내 배너 광고를 하나만 추가해도 상회할 수 있으며, 운영 비용 자체가 적기 때문에 수익을 계속 유지할 수 있으며, 유지보수 및 지속적인 개발 또한 가능할 것으로 보인다.&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
====어려웠던 내용들====&lt;br /&gt;
:- 산림청에서 제공하는 geojson 데이터를 시스템에서 사용하기 위한 형태로 가공하는 과정에서 많은 시행착오가 있었다.&lt;br /&gt;
&lt;br /&gt;
:- 기존에는 클라우드 서비스를 이용하는 형태로 설계했는데, 클라우드 비용 문제 및 교내망에서는 서버에 접속할 수 없는 문제가 발생하였다.&lt;br /&gt;
&lt;br /&gt;
:- 설문조사 및 인터뷰 대상을 모집하는 과정에서 어려움이 있었다.&lt;br /&gt;
 &lt;br /&gt;
:- 추천 알고리즘을 만들기 위한 사람들의 등산 데이터가 너무 적었다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====차후 구현할 내용====&lt;br /&gt;
주로 반구조화 인터뷰 중 아쉬웠던 점, 추가되었으면 하는 기능들 중 구현 난이도가 쉬운 항목부터 진행할 예정이다. 구체적으로 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
:- “위시리스트 담기”와 같이 사용자가 한 번에 이해되지 않을만한 표현, 불필요하게 작성된 영어 표현이 있는지 확인하고 수정한다.&lt;br /&gt;
&lt;br /&gt;
:- Navi 페이지의 진행 바의 진행 상황을 새로고침 되더라도 유지한다.&lt;br /&gt;
&lt;br /&gt;
:- 코스 예상시간 표기 기능을 추가한다.&lt;br /&gt;
&lt;br /&gt;
:- 시스템에서 지원하는 산의 개수를 더 늘린다.&lt;br /&gt;
&lt;br /&gt;
:- 더 많은 사용자들의 검색 데이터들을 참고하여 추천 알고리즘을 개선한다.&lt;br /&gt;
&lt;br /&gt;
:- 등산했던 등산로들을 모아서 저장하고 공유하는 기능을 개발한다.&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
===구성원 및 추진체계===&lt;br /&gt;
[[파일명|사진들어갈자리]]&lt;br /&gt;
===자재소요서===&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
&lt;br /&gt;
===개발사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-asq-result.jpg&amp;diff=12012</id>
		<title>파일:Dos-asq-result.jpg</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-asq-result.jpg&amp;diff=12012"/>
				<updated>2025-06-19T14:07:08Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: dos-asq-result.jpg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;dos-asq-result.jpg&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=12010</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=12010"/>
				<updated>2025-06-19T14:05:30Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 사용자 만족도 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:Dos-등산사고-발생-요인.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_1&amp;quot;&amp;gt;'''그림 1.''' 등산사고 발생 요인 (산림청 제공)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::최근 산림청의 조사[[#ref1|[1]]]에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다([[#그림_1|그림 1]]). 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터([[#그림_2|그림 2]])를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-산림청제공데이터.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_2&amp;quot;&amp;gt;'''그림 2.''' 산림청 제공 데이터 예시&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[[#ref1|[1]]].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_3&amp;quot;&amp;gt;'''그림 3.''' 22개 산 데이터의 정점 수(왼쪽), 간선 수(오른쪽). 빨간색 점선은 평균값에 해당한다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. [[#그림_3|그림 3]]은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. &lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표 1&amp;quot;&amp;gt;표 1. 한 번에 10명의 사용자가 동시에 요청을 보냈을 때 소요 시간&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-자원사용률.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_4&amp;quot;&amp;gt;'''그림 4.''' 실제 서버에서 등산로 추천 요청을 100개 정도 받았을 때 걸리는 서버 부하&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다([[#표_1|표 1]]). 시뮬레이션 결과, 서버에 걸리는 부하는 [[#그림_4|그림 4]]와 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표 2&amp;quot;&amp;gt;표 2. 라즈베리파이 5 사양 명세&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다([[#표_2|표 2]]). 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
 소프트웨어 실행 흐름도&lt;br /&gt;
:개략적인 우리 시스템의 실행 흐름은 다음과 같다([[#그림_5|그림 5]]).&lt;br /&gt;
[[파일:소프트웨어흐름도.png|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_5&amp;quot;&amp;gt;'''그림 5.''' 시스템의 실행 흐름도&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동사진.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_6&amp;quot;&amp;gt;'''그림 6.''' 프로토타입 메인 화면 및 등산로 추천 기능&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
아래의 링크를 클릭하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:dos-실행방법.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_7&amp;quot;&amp;gt;'''그림 7.''' 셰르파(Sherpa) 실행 방법&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:::[[파일:dos-ASQ-tesk.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도 (SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
:::[[파일:Dos-sus.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[[#ref5|[5]]]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시나리오 후 설문 (ASQ)'''&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_10&amp;quot;&amp;gt;'''그림 10.''' 시나리오 후 설문(ASQ)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시나리오 후 설문([[#그림_10|[그림 10]]]은 각 Task를 수행하는 것이 얼마나 어려운지 확인하는 사용성 평가 방법이다[[#ref6|[6]]]. 우리는 우리 시스템에서 제공하는 주요 기능(개인 맞춤형 등산 목적지 추천, 개인 맞춤형 등산로 생성, 생성한 등산로 안내)을 쉽게 사용할 수 있는 지 확인하기 위하여 우리의 기능에 대응되는 Task를 만든 시나리오 후 설문을 진행했다. 설문 진행 결과, 우리가 제공하는 주요 기능이 모두 사용자가 쓰기 편하다는 것을 확인했다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''반구조화 인터뷰'''&lt;br /&gt;
우리는 추후 우리 앱을 개선하기 위하여, 앞선 두 개의 설문을 진행한 이후 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 묻는 반구조화 인터뷰를 진행했다. 주요한 내용은 다음과 같았다.&lt;br /&gt;
&lt;br /&gt;
:'''좋았던 점'''&lt;br /&gt;
 ''기존에 등산로 방향을 찾을 때 사진이 올라와 있는 블로그들을 많이 참조했는데, 직접적으로 방향을 알려주는 점이 좋았다.             -P7-''&lt;br /&gt;
&lt;br /&gt;
 ''아직 개인의 운동 수준과 등산로 난이도 스케일이 정확히 맞지는 않는 것 같지만, 어려운 등산로일수록 등산로 난이도가 어렵게 나오는 건 맞는 것 같다. 등산을 진행할 때 어느 정도 참고가 가능할 것 같다.      -P10- ''&lt;br /&gt;
&lt;br /&gt;
:'''개선할 점'''&lt;br /&gt;
 ''등산 목적지에 쉬운 코스가 없을 경우, 난이도를 쉽게 설정해도 어려운 코스가 나오는 문제점이 있다.   -P4-''  (해결됨)&lt;br /&gt;
&lt;br /&gt;
 ''위시리스트 담기라는 표현 자체가 잘 이해되지 않았다.      -P8-''&lt;br /&gt;
&lt;br /&gt;
 ''Navi 페이지에서 진행바가 새로고침할 때마다 리셋되는 것이 아쉬웠다.  -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''목적지 추천 부분에서 산 이름이 영어로 나오는 점이 아쉬웠다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
:'''UI 관련'''&lt;br /&gt;
 ''프로토타입 UI는 개인적으론 별 다른 것 없이 깔끔해서 좋았다.     -P2, P7-''&lt;br /&gt;
&lt;br /&gt;
 ''잡다한 기능이 없어서 사용법을 금방 익힐 수 있었다. -P9-''&lt;br /&gt;
&lt;br /&gt;
:'''추가되었으면 하는 기능'''&lt;br /&gt;
 ''코스 예상시간이 표기되면 좋을 것 같다.   -P1-''&lt;br /&gt;
&lt;br /&gt;
 ''더 많은 산들에 대해서도 정보를 제공하면 좋을 것 같다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
 ''나와 비슷한 사용자들을 매칭해주는 기능이 있으면 좋을 것 같다.   -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''등산했던 등산로들을 모아서 저장하고 공유할 수 있는 기능이 있으면 좋을 것 같다.      -P12-''&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
서비스를 운영하는 데에 드는 비용은 도메인 유지 비용(10달러/1년), 라즈베리파이를 유지하기 위한 전기료 정도를 고려할 수 있다. 이는 페이지 내 배너 광고를 하나만 추가해도 상회할 수 있으며, 운영 비용 자체가 적기 때문에 수익을 계속 유지할 수 있으며, 유지보수 및 지속적인 개발 또한 가능할 것으로 보인다.&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
====어려웠던 내용들====&lt;br /&gt;
:- 산림청에서 제공하는 geojson 데이터를 시스템에서 사용하기 위한 형태로 가공하는 과정에서 많은 시행착오가 있었다.&lt;br /&gt;
&lt;br /&gt;
:- 기존에는 클라우드 서비스를 이용하는 형태로 설계했는데, 클라우드 비용 문제 및 교내망에서는 서버에 접속할 수 없는 문제가 발생하였다.&lt;br /&gt;
&lt;br /&gt;
:- 설문조사 및 인터뷰 대상을 모집하는 과정에서 어려움이 있었다.&lt;br /&gt;
 &lt;br /&gt;
:- 추천 알고리즘을 만들기 위한 사람들의 등산 데이터가 너무 적었다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====차후 구현할 내용====&lt;br /&gt;
주로 반구조화 인터뷰 중 아쉬웠던 점, 추가되었으면 하는 기능들 중 구현 난이도가 쉬운 항목부터 진행할 예정이다. 구체적으로 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
:- “위시리스트 담기”와 같이 사용자가 한 번에 이해되지 않을만한 표현, 불필요하게 작성된 영어 표현이 있는지 확인하고 수정한다.&lt;br /&gt;
&lt;br /&gt;
:- Navi 페이지의 진행 바의 진행 상황을 새로고침 되더라도 유지한다.&lt;br /&gt;
&lt;br /&gt;
:- 코스 예상시간 표기 기능을 추가한다.&lt;br /&gt;
&lt;br /&gt;
:- 시스템에서 지원하는 산의 개수를 더 늘린다.&lt;br /&gt;
&lt;br /&gt;
:- 더 많은 사용자들의 검색 데이터들을 참고하여 추천 알고리즘을 개선한다.&lt;br /&gt;
&lt;br /&gt;
:- 등산했던 등산로들을 모아서 저장하고 공유하는 기능을 개발한다.&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
===구성원 및 추진체계===&lt;br /&gt;
[[파일명|사진들어갈자리]]&lt;br /&gt;
===자재소요서===&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
&lt;br /&gt;
===개발사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-ASQ-tesk.jpg&amp;diff=12008</id>
		<title>파일:Dos-ASQ-tesk.jpg</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-ASQ-tesk.jpg&amp;diff=12008"/>
				<updated>2025-06-19T14:05:04Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: dos-ASQ-tesk.jpg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;dos-ASQ-tesk.jpg&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=12005</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=12005"/>
				<updated>2025-06-19T14:03:41Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 실행 방법 (Run) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:Dos-등산사고-발생-요인.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_1&amp;quot;&amp;gt;'''그림 1.''' 등산사고 발생 요인 (산림청 제공)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::최근 산림청의 조사[[#ref1|[1]]]에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다([[#그림_1|그림 1]]). 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터([[#그림_2|그림 2]])를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-산림청제공데이터.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_2&amp;quot;&amp;gt;'''그림 2.''' 산림청 제공 데이터 예시&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[[#ref1|[1]]].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
[[내용]]&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_3&amp;quot;&amp;gt;'''그림 3.''' 22개 산 데이터의 정점 수(왼쪽), 간선 수(오른쪽). 빨간색 점선은 평균값에 해당한다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. [[#그림_3|그림 3]]은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. &lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표 1&amp;quot;&amp;gt;표 1. 한 번에 10명의 사용자가 동시에 요청을 보냈을 때 소요 시간&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-자원사용률.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_4&amp;quot;&amp;gt;'''그림 4.''' 실제 서버에서 등산로 추천 요청을 100개 정도 받았을 때 걸리는 서버 부하&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다([[#표_1|표 1]]). 시뮬레이션 결과, 서버에 걸리는 부하는 [[#그림_4|그림 4]]와 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표 2&amp;quot;&amp;gt;표 2. 라즈베리파이 5 사양 명세&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다([[#표_2|표 2]]). 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
 소프트웨어 실행 흐름도&lt;br /&gt;
:개략적인 우리 시스템의 실행 흐름은 다음과 같다([[#그림_5|그림 5]]).&lt;br /&gt;
[[파일:소프트웨어흐름도.png|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_5&amp;quot;&amp;gt;'''그림 5.''' 시스템의 실행 흐름도&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동사진.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_6&amp;quot;&amp;gt;'''그림 6.''' 프로토타입 메인 화면 및 등산로 추천 기능&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
인터넷 탐색기에서 다음 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:dos-실행방법.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_7&amp;quot;&amp;gt;'''그림 7.''' 셰르파(Sherpa) 실행 방법&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:::[[파일:사진명.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도 (SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
:::[[파일:Dos-sus.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[[#ref5|[5]]]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시나리오 후 설문 (ASQ)'''&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_10&amp;quot;&amp;gt;'''그림 10.''' 시나리오 후 설문(ASQ)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시나리오 후 설문([[#그림_10|[그림 10]]]은 각 Task를 수행하는 것이 얼마나 어려운지 확인하는 사용성 평가 방법이다[[#ref6|[6]]]. 우리는 우리 시스템에서 제공하는 주요 기능(개인 맞춤형 등산 목적지 추천, 개인 맞춤형 등산로 생성, 생성한 등산로 안내)을 쉽게 사용할 수 있는 지 확인하기 위하여 우리의 기능에 대응되는 Task를 만든 시나리오 후 설문을 진행했다. 설문 진행 결과, 우리가 제공하는 주요 기능이 모두 사용자가 쓰기 편하다는 것을 확인했다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''반구조화 인터뷰'''&lt;br /&gt;
우리는 추후 우리 앱을 개선하기 위하여, 앞선 두 개의 설문을 진행한 이후 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 묻는 반구조화 인터뷰를 진행했다. 주요한 내용은 다음과 같았다.&lt;br /&gt;
&lt;br /&gt;
:'''좋았던 점'''&lt;br /&gt;
 ''기존에 등산로 방향을 찾을 때 사진이 올라와 있는 블로그들을 많이 참조했는데, 직접적으로 방향을 알려주는 점이 좋았다.             -P7-''&lt;br /&gt;
&lt;br /&gt;
 ''아직 개인의 운동 수준과 등산로 난이도 스케일이 정확히 맞지는 않는 것 같지만, 어려운 등산로일수록 등산로 난이도가 어렵게 나오는 건 맞는 것 같다. 등산을 진행할 때 어느 정도 참고가 가능할 것 같다.      -P10- ''&lt;br /&gt;
&lt;br /&gt;
:'''개선할 점'''&lt;br /&gt;
 ''등산 목적지에 쉬운 코스가 없을 경우, 난이도를 쉽게 설정해도 어려운 코스가 나오는 문제점이 있다.   -P4-''  (해결됨)&lt;br /&gt;
&lt;br /&gt;
 ''위시리스트 담기라는 표현 자체가 잘 이해되지 않았다.      -P8-''&lt;br /&gt;
&lt;br /&gt;
 ''Navi 페이지에서 진행바가 새로고침할 때마다 리셋되는 것이 아쉬웠다.  -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''목적지 추천 부분에서 산 이름이 영어로 나오는 점이 아쉬웠다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
:'''UI 관련'''&lt;br /&gt;
 ''프로토타입 UI는 개인적으론 별 다른 것 없이 깔끔해서 좋았다.     -P2, P7-''&lt;br /&gt;
&lt;br /&gt;
 ''잡다한 기능이 없어서 사용법을 금방 익힐 수 있었다. -P9-''&lt;br /&gt;
&lt;br /&gt;
:'''추가되었으면 하는 기능'''&lt;br /&gt;
 ''코스 예상시간이 표기되면 좋을 것 같다.   -P1-''&lt;br /&gt;
&lt;br /&gt;
 ''더 많은 산들에 대해서도 정보를 제공하면 좋을 것 같다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
 ''나와 비슷한 사용자들을 매칭해주는 기능이 있으면 좋을 것 같다.   -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''등산했던 등산로들을 모아서 저장하고 공유할 수 있는 기능이 있으면 좋을 것 같다.      -P12-''&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
서비스를 운영하는 데에 드는 비용은 도메인 유지 비용(10달러/1년), 라즈베리파이를 유지하기 위한 전기료 정도를 고려할 수 있다. 이는 페이지 내 배너 광고를 하나만 추가해도 상회할 수 있으며, 운영 비용 자체가 적기 때문에 수익을 계속 유지할 수 있으며, 유지보수 및 지속적인 개발 또한 가능할 것으로 보인다.&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
====어려웠던 내용들====&lt;br /&gt;
:- 산림청에서 제공하는 geojson 데이터를 시스템에서 사용하기 위한 형태로 가공하는 과정에서 많은 시행착오가 있었다.&lt;br /&gt;
&lt;br /&gt;
:- 기존에는 클라우드 서비스를 이용하는 형태로 설계했는데, 클라우드 비용 문제 및 교내망에서는 서버에 접속할 수 없는 문제가 발생하였다.&lt;br /&gt;
&lt;br /&gt;
:- 설문조사 및 인터뷰 대상을 모집하는 과정에서 어려움이 있었다.&lt;br /&gt;
 &lt;br /&gt;
:- 추천 알고리즘을 만들기 위한 사람들의 등산 데이터가 너무 적었다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====차후 구현할 내용====&lt;br /&gt;
주로 반구조화 인터뷰 중 아쉬웠던 점, 추가되었으면 하는 기능들 중 구현 난이도가 쉬운 항목부터 진행할 예정이다. 구체적으로 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
:- “위시리스트 담기”와 같이 사용자가 한 번에 이해되지 않을만한 표현, 불필요하게 작성된 영어 표현이 있는지 확인하고 수정한다.&lt;br /&gt;
&lt;br /&gt;
:- Navi 페이지의 진행 바의 진행 상황을 새로고침 되더라도 유지한다.&lt;br /&gt;
&lt;br /&gt;
:- 코스 예상시간 표기 기능을 추가한다.&lt;br /&gt;
&lt;br /&gt;
:- 시스템에서 지원하는 산의 개수를 더 늘린다.&lt;br /&gt;
&lt;br /&gt;
:- 더 많은 사용자들의 검색 데이터들을 참고하여 추천 알고리즘을 개선한다.&lt;br /&gt;
&lt;br /&gt;
:- 등산했던 등산로들을 모아서 저장하고 공유하는 기능을 개발한다.&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
===구성원 및 추진체계===&lt;br /&gt;
[[파일명|사진들어갈자리]]&lt;br /&gt;
===자재소요서===&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
&lt;br /&gt;
===개발사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EC%8B%A4%ED%96%89%EB%B0%A9%EB%B2%95.jpg&amp;diff=12004</id>
		<title>파일:Dos-실행방법.jpg</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EC%8B%A4%ED%96%89%EB%B0%A9%EB%B2%95.jpg&amp;diff=12004"/>
				<updated>2025-06-19T14:03:33Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: dos-실행방법.jpg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;dos-실행방법.jpg&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11971</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11971"/>
				<updated>2025-06-19T13:46:55Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 실행 방법 (Run) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:Dos-등산사고-발생-요인.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_1&amp;quot;&amp;gt;'''그림 1.''' 등산사고 발생 요인 (산림청 제공)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::최근 산림청의 조사[[#ref1|[1]]]에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다([[#그림_1|그림 1]]). 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터([[#그림_2|그림 2]])를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-산림청제공데이터.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_2&amp;quot;&amp;gt;'''그림 2.''' 산림청 제공 데이터 예시&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[[#ref1|[1]]].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
[[내용]]&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_3&amp;quot;&amp;gt;'''그림 3.''' 22개 산 데이터의 정점 수(왼쪽), 간선 수(오른쪽). 빨간색 점선은 평균값에 해당한다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. [[#그림_3|그림 3]]은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. &lt;br /&gt;
&lt;br /&gt;
[[파일:dos-자원사용률.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다. 시뮬레이션 결과, 서버에 걸리는 부하는 그림 4와 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다. 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:소프트웨어흐름도.png]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동사진.jpg|1000픽셀]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
인터넷 탐색기에서 다음 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:::[[파일:사진명.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도 (SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
:::[[파일:Dos-sus.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[[#ref5|[5]]]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시나리오 후 설문 (ASQ)'''&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_10&amp;quot;&amp;gt;'''그림 10.''' 시나리오 후 설문(ASQ)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시나리오 후 설문([[#그림_10|[그림 10]]]은 각 Task를 수행하는 것이 얼마나 어려운지 확인하는 사용성 평가 방법이다[[#ref6|[6]]]. 우리는 우리 시스템에서 제공하는 주요 기능(개인 맞춤형 등산 목적지 추천, 개인 맞춤형 등산로 생성, 생성한 등산로 안내)을 쉽게 사용할 수 있는 지 확인하기 위하여 우리의 기능에 대응되는 Task를 만든 시나리오 후 설문을 진행했다. 설문 진행 결과, 우리가 제공하는 주요 기능이 모두 사용자가 쓰기 편하다는 것을 확인했다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''반구조화 인터뷰'''&lt;br /&gt;
우리는 추후 우리 앱을 개선하기 위하여, 앞선 두 개의 설문을 진행한 이후 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 묻는 반구조화 인터뷰를 진행했다. 주요한 내용은 다음과 같았다.&lt;br /&gt;
&lt;br /&gt;
:'''좋았던 점'''&lt;br /&gt;
 ''기존에 등산로 방향을 찾을 때 사진이 올라와 있는 블로그들을 많이 참조했는데, 직접적으로 방향을 알려주는 점이 좋았다.             -P7-''&lt;br /&gt;
&lt;br /&gt;
 ''아직 개인의 운동 수준과 등산로 난이도 스케일이 정확히 맞지는 않는 것 같지만, 어려운 등산로일수록 등산로 난이도가 어렵게 나오는 건 맞는 것 같다. 등산을 진행할 때 어느 정도 참고가 가능할 것 같다.      -P10- ''&lt;br /&gt;
&lt;br /&gt;
:'''개선할 점'''&lt;br /&gt;
 ''등산 목적지에 쉬운 코스가 없을 경우, 난이도를 쉽게 설정해도 어려운 코스가 나오는 문제점이 있다.   -P4-''  (해결됨)&lt;br /&gt;
&lt;br /&gt;
 ''위시리스트 담기라는 표현 자체가 잘 이해되지 않았다.      -P8-''&lt;br /&gt;
&lt;br /&gt;
 ''Navi 페이지에서 진행바가 새로고침할 때마다 리셋되는 것이 아쉬웠다.  -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''목적지 추천 부분에서 산 이름이 영어로 나오는 점이 아쉬웠다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
:'''UI 관련'''&lt;br /&gt;
 ''프로토타입 UI는 개인적으론 별 다른 것 없이 깔끔해서 좋았다.     -P2, P7-''&lt;br /&gt;
&lt;br /&gt;
 ''잡다한 기능이 없어서 사용법을 금방 익힐 수 있었다. -P9-''&lt;br /&gt;
&lt;br /&gt;
:'''추가되었으면 하는 기능'''&lt;br /&gt;
 ''코스 예상시간이 표기되면 좋을 것 같다.   -P1-''&lt;br /&gt;
&lt;br /&gt;
 ''더 많은 산들에 대해서도 정보를 제공하면 좋을 것 같다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
 ''나와 비슷한 사용자들을 매칭해주는 기능이 있으면 좋을 것 같다.   -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''등산했던 등산로들을 모아서 저장하고 공유할 수 있는 기능이 있으면 좋을 것 같다.      -P12-''&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
서비스를 운영하는 데에 드는 비용은 도메인 유지 비용(10달러/1년), 라즈베리파이를 유지하기 위한 전기료 정도를 고려할 수 있다. 이는 페이지 내 배너 광고를 하나만 추가해도 상회할 수 있으며, 운영 비용 자체가 적기 때문에 수익을 계속 유지할 수 있으며, 유지보수 및 지속적인 개발 또한 가능할 것으로 보인다.&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
====어려웠던 내용들====&lt;br /&gt;
:- 산림청에서 제공하는 geojson 데이터를 시스템에서 사용하기 위한 형태로 가공하는 과정에서 많은 시행착오가 있었다.&lt;br /&gt;
&lt;br /&gt;
:- 기존에는 클라우드 서비스를 이용하는 형태로 설계했는데, 클라우드 비용 문제 및 교내망에서는 서버에 접속할 수 없는 문제가 발생하였다.&lt;br /&gt;
&lt;br /&gt;
:- 설문조사 및 인터뷰 대상을 모집하는 과정에서 어려움이 있었다.&lt;br /&gt;
 &lt;br /&gt;
:- 추천 알고리즘을 만들기 위한 사람들의 등산 데이터가 너무 적었다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====차후 구현할 내용====&lt;br /&gt;
주로 반구조화 인터뷰 중 아쉬웠던 점, 추가되었으면 하는 기능들 중 구현 난이도가 쉬운 항목부터 진행할 예정이다. 구체적으로 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
:- “위시리스트 담기”와 같이 사용자가 한 번에 이해되지 않을만한 표현, 불필요하게 작성된 영어 표현이 있는지 확인하고 수정한다.&lt;br /&gt;
&lt;br /&gt;
:- Navi 페이지의 진행 바의 진행 상황을 새로고침 되더라도 유지한다.&lt;br /&gt;
&lt;br /&gt;
:- 코스 예상시간 표기 기능을 추가한다.&lt;br /&gt;
&lt;br /&gt;
:- 시스템에서 지원하는 산의 개수를 더 늘린다.&lt;br /&gt;
&lt;br /&gt;
:- 더 많은 사용자들의 검색 데이터들을 참고하여 추천 알고리즘을 개선한다.&lt;br /&gt;
&lt;br /&gt;
:- 등산했던 등산로들을 모아서 저장하고 공유하는 기능을 개발한다.&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
===구성원 및 추진체계===&lt;br /&gt;
[[파일명|사진들어갈자리]]&lt;br /&gt;
===자재소요서===&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
&lt;br /&gt;
===개발사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11969</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11969"/>
				<updated>2025-06-19T13:46:29Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 이론적 계산 및 시뮬레이션 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:Dos-등산사고-발생-요인.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_1&amp;quot;&amp;gt;'''그림 1.''' 등산사고 발생 요인 (산림청 제공)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::최근 산림청의 조사[[#ref1|[1]]]에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다([[#그림_1|그림 1]]). 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터([[#그림_2|그림 2]])를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-산림청제공데이터.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_2&amp;quot;&amp;gt;'''그림 2.''' 산림청 제공 데이터 예시&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[[#ref1|[1]]].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
[[내용]]&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_3&amp;quot;&amp;gt;'''그림 3.''' 22개 산 데이터의 정점 수(왼쪽), 간선 수(오른쪽). 빨간색 점선은 평균값에 해당한다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. 그림 #은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. (테스트 환경: 라즈베리파이 5)&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-자원사용률.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다. 시뮬레이션 결과, 서버에 걸리는 부하는 그림 4와 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다. 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:소프트웨어흐름도.png]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동사진.jpg|1000픽셀]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
인터넷 탐색기에서 다음 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:사진명|섬네일|가운데|'''그림 7.''' 셰르파(Sherpa) 실행 방법]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:::[[파일:사진명.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도 (SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
:::[[파일:Dos-sus.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[[#ref5|[5]]]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시나리오 후 설문 (ASQ)'''&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_10&amp;quot;&amp;gt;'''그림 10.''' 시나리오 후 설문(ASQ)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시나리오 후 설문([[#그림_10|[그림 10]]]은 각 Task를 수행하는 것이 얼마나 어려운지 확인하는 사용성 평가 방법이다[[#ref6|[6]]]. 우리는 우리 시스템에서 제공하는 주요 기능(개인 맞춤형 등산 목적지 추천, 개인 맞춤형 등산로 생성, 생성한 등산로 안내)을 쉽게 사용할 수 있는 지 확인하기 위하여 우리의 기능에 대응되는 Task를 만든 시나리오 후 설문을 진행했다. 설문 진행 결과, 우리가 제공하는 주요 기능이 모두 사용자가 쓰기 편하다는 것을 확인했다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''반구조화 인터뷰'''&lt;br /&gt;
우리는 추후 우리 앱을 개선하기 위하여, 앞선 두 개의 설문을 진행한 이후 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 묻는 반구조화 인터뷰를 진행했다. 주요한 내용은 다음과 같았다.&lt;br /&gt;
&lt;br /&gt;
:'''좋았던 점'''&lt;br /&gt;
 ''기존에 등산로 방향을 찾을 때 사진이 올라와 있는 블로그들을 많이 참조했는데, 직접적으로 방향을 알려주는 점이 좋았다.             -P7-''&lt;br /&gt;
&lt;br /&gt;
 ''아직 개인의 운동 수준과 등산로 난이도 스케일이 정확히 맞지는 않는 것 같지만, 어려운 등산로일수록 등산로 난이도가 어렵게 나오는 건 맞는 것 같다. 등산을 진행할 때 어느 정도 참고가 가능할 것 같다.      -P10- ''&lt;br /&gt;
&lt;br /&gt;
:'''개선할 점'''&lt;br /&gt;
 ''등산 목적지에 쉬운 코스가 없을 경우, 난이도를 쉽게 설정해도 어려운 코스가 나오는 문제점이 있다.   -P4-''  (해결됨)&lt;br /&gt;
&lt;br /&gt;
 ''위시리스트 담기라는 표현 자체가 잘 이해되지 않았다.      -P8-''&lt;br /&gt;
&lt;br /&gt;
 ''Navi 페이지에서 진행바가 새로고침할 때마다 리셋되는 것이 아쉬웠다.  -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''목적지 추천 부분에서 산 이름이 영어로 나오는 점이 아쉬웠다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
:'''UI 관련'''&lt;br /&gt;
 ''프로토타입 UI는 개인적으론 별 다른 것 없이 깔끔해서 좋았다.     -P2, P7-''&lt;br /&gt;
&lt;br /&gt;
 ''잡다한 기능이 없어서 사용법을 금방 익힐 수 있었다. -P9-''&lt;br /&gt;
&lt;br /&gt;
:'''추가되었으면 하는 기능'''&lt;br /&gt;
 ''코스 예상시간이 표기되면 좋을 것 같다.   -P1-''&lt;br /&gt;
&lt;br /&gt;
 ''더 많은 산들에 대해서도 정보를 제공하면 좋을 것 같다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
 ''나와 비슷한 사용자들을 매칭해주는 기능이 있으면 좋을 것 같다.   -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''등산했던 등산로들을 모아서 저장하고 공유할 수 있는 기능이 있으면 좋을 것 같다.      -P12-''&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
서비스를 운영하는 데에 드는 비용은 도메인 유지 비용(10달러/1년), 라즈베리파이를 유지하기 위한 전기료 정도를 고려할 수 있다. 이는 페이지 내 배너 광고를 하나만 추가해도 상회할 수 있으며, 운영 비용 자체가 적기 때문에 수익을 계속 유지할 수 있으며, 유지보수 및 지속적인 개발 또한 가능할 것으로 보인다.&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
====어려웠던 내용들====&lt;br /&gt;
:- 산림청에서 제공하는 geojson 데이터를 시스템에서 사용하기 위한 형태로 가공하는 과정에서 많은 시행착오가 있었다.&lt;br /&gt;
&lt;br /&gt;
:- 기존에는 클라우드 서비스를 이용하는 형태로 설계했는데, 클라우드 비용 문제 및 교내망에서는 서버에 접속할 수 없는 문제가 발생하였다.&lt;br /&gt;
&lt;br /&gt;
:- 설문조사 및 인터뷰 대상을 모집하는 과정에서 어려움이 있었다.&lt;br /&gt;
 &lt;br /&gt;
:- 추천 알고리즘을 만들기 위한 사람들의 등산 데이터가 너무 적었다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====차후 구현할 내용====&lt;br /&gt;
주로 반구조화 인터뷰 중 아쉬웠던 점, 추가되었으면 하는 기능들 중 구현 난이도가 쉬운 항목부터 진행할 예정이다. 구체적으로 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
:- “위시리스트 담기”와 같이 사용자가 한 번에 이해되지 않을만한 표현, 불필요하게 작성된 영어 표현이 있는지 확인하고 수정한다.&lt;br /&gt;
&lt;br /&gt;
:- Navi 페이지의 진행 바의 진행 상황을 새로고침 되더라도 유지한다.&lt;br /&gt;
&lt;br /&gt;
:- 코스 예상시간 표기 기능을 추가한다.&lt;br /&gt;
&lt;br /&gt;
:- 시스템에서 지원하는 산의 개수를 더 늘린다.&lt;br /&gt;
&lt;br /&gt;
:- 더 많은 사용자들의 검색 데이터들을 참고하여 추천 알고리즘을 개선한다.&lt;br /&gt;
&lt;br /&gt;
:- 등산했던 등산로들을 모아서 저장하고 공유하는 기능을 개발한다.&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
===구성원 및 추진체계===&lt;br /&gt;
[[파일명|사진들어갈자리]]&lt;br /&gt;
===자재소요서===&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
&lt;br /&gt;
===개발사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11968</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11968"/>
				<updated>2025-06-19T13:46:05Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 하드웨어 설계 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:Dos-등산사고-발생-요인.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_1&amp;quot;&amp;gt;'''그림 1.''' 등산사고 발생 요인 (산림청 제공)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::최근 산림청의 조사[[#ref1|[1]]]에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다([[#그림_1|그림 1]]). 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터([[#그림_2|그림 2]])를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-산림청제공데이터.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_2&amp;quot;&amp;gt;'''그림 2.''' 산림청 제공 데이터 예시&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[[#ref1|[1]]].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
[[내용]]&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_3&amp;quot;&amp;gt;'''그림 3.''' 22개 산 데이터의 정점 수(왼쪽), 간선 수(오른쪽). 빨간색 점선은 평균값에 해당한다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. 그림 #은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. (테스트 환경: 라즈베리파이 5)&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-자원사용률.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 자리]]&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다(그림#). 시뮬레이션 결과, 서버에 걸리는 부하는 그림 #과 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다. 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:소프트웨어흐름도.png]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동사진.jpg|1000픽셀]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
인터넷 탐색기에서 다음 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:사진명|섬네일|가운데|'''그림 7.''' 셰르파(Sherpa) 실행 방법]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:::[[파일:사진명.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도 (SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
:::[[파일:Dos-sus.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[[#ref5|[5]]]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시나리오 후 설문 (ASQ)'''&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_10&amp;quot;&amp;gt;'''그림 10.''' 시나리오 후 설문(ASQ)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시나리오 후 설문([[#그림_10|[그림 10]]]은 각 Task를 수행하는 것이 얼마나 어려운지 확인하는 사용성 평가 방법이다[[#ref6|[6]]]. 우리는 우리 시스템에서 제공하는 주요 기능(개인 맞춤형 등산 목적지 추천, 개인 맞춤형 등산로 생성, 생성한 등산로 안내)을 쉽게 사용할 수 있는 지 확인하기 위하여 우리의 기능에 대응되는 Task를 만든 시나리오 후 설문을 진행했다. 설문 진행 결과, 우리가 제공하는 주요 기능이 모두 사용자가 쓰기 편하다는 것을 확인했다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''반구조화 인터뷰'''&lt;br /&gt;
우리는 추후 우리 앱을 개선하기 위하여, 앞선 두 개의 설문을 진행한 이후 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 묻는 반구조화 인터뷰를 진행했다. 주요한 내용은 다음과 같았다.&lt;br /&gt;
&lt;br /&gt;
:'''좋았던 점'''&lt;br /&gt;
 ''기존에 등산로 방향을 찾을 때 사진이 올라와 있는 블로그들을 많이 참조했는데, 직접적으로 방향을 알려주는 점이 좋았다.             -P7-''&lt;br /&gt;
&lt;br /&gt;
 ''아직 개인의 운동 수준과 등산로 난이도 스케일이 정확히 맞지는 않는 것 같지만, 어려운 등산로일수록 등산로 난이도가 어렵게 나오는 건 맞는 것 같다. 등산을 진행할 때 어느 정도 참고가 가능할 것 같다.      -P10- ''&lt;br /&gt;
&lt;br /&gt;
:'''개선할 점'''&lt;br /&gt;
 ''등산 목적지에 쉬운 코스가 없을 경우, 난이도를 쉽게 설정해도 어려운 코스가 나오는 문제점이 있다.   -P4-''  (해결됨)&lt;br /&gt;
&lt;br /&gt;
 ''위시리스트 담기라는 표현 자체가 잘 이해되지 않았다.      -P8-''&lt;br /&gt;
&lt;br /&gt;
 ''Navi 페이지에서 진행바가 새로고침할 때마다 리셋되는 것이 아쉬웠다.  -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''목적지 추천 부분에서 산 이름이 영어로 나오는 점이 아쉬웠다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
:'''UI 관련'''&lt;br /&gt;
 ''프로토타입 UI는 개인적으론 별 다른 것 없이 깔끔해서 좋았다.     -P2, P7-''&lt;br /&gt;
&lt;br /&gt;
 ''잡다한 기능이 없어서 사용법을 금방 익힐 수 있었다. -P9-''&lt;br /&gt;
&lt;br /&gt;
:'''추가되었으면 하는 기능'''&lt;br /&gt;
 ''코스 예상시간이 표기되면 좋을 것 같다.   -P1-''&lt;br /&gt;
&lt;br /&gt;
 ''더 많은 산들에 대해서도 정보를 제공하면 좋을 것 같다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
 ''나와 비슷한 사용자들을 매칭해주는 기능이 있으면 좋을 것 같다.   -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''등산했던 등산로들을 모아서 저장하고 공유할 수 있는 기능이 있으면 좋을 것 같다.      -P12-''&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
서비스를 운영하는 데에 드는 비용은 도메인 유지 비용(10달러/1년), 라즈베리파이를 유지하기 위한 전기료 정도를 고려할 수 있다. 이는 페이지 내 배너 광고를 하나만 추가해도 상회할 수 있으며, 운영 비용 자체가 적기 때문에 수익을 계속 유지할 수 있으며, 유지보수 및 지속적인 개발 또한 가능할 것으로 보인다.&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
====어려웠던 내용들====&lt;br /&gt;
:- 산림청에서 제공하는 geojson 데이터를 시스템에서 사용하기 위한 형태로 가공하는 과정에서 많은 시행착오가 있었다.&lt;br /&gt;
&lt;br /&gt;
:- 기존에는 클라우드 서비스를 이용하는 형태로 설계했는데, 클라우드 비용 문제 및 교내망에서는 서버에 접속할 수 없는 문제가 발생하였다.&lt;br /&gt;
&lt;br /&gt;
:- 설문조사 및 인터뷰 대상을 모집하는 과정에서 어려움이 있었다.&lt;br /&gt;
 &lt;br /&gt;
:- 추천 알고리즘을 만들기 위한 사람들의 등산 데이터가 너무 적었다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====차후 구현할 내용====&lt;br /&gt;
주로 반구조화 인터뷰 중 아쉬웠던 점, 추가되었으면 하는 기능들 중 구현 난이도가 쉬운 항목부터 진행할 예정이다. 구체적으로 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
:- “위시리스트 담기”와 같이 사용자가 한 번에 이해되지 않을만한 표현, 불필요하게 작성된 영어 표현이 있는지 확인하고 수정한다.&lt;br /&gt;
&lt;br /&gt;
:- Navi 페이지의 진행 바의 진행 상황을 새로고침 되더라도 유지한다.&lt;br /&gt;
&lt;br /&gt;
:- 코스 예상시간 표기 기능을 추가한다.&lt;br /&gt;
&lt;br /&gt;
:- 시스템에서 지원하는 산의 개수를 더 늘린다.&lt;br /&gt;
&lt;br /&gt;
:- 더 많은 사용자들의 검색 데이터들을 참고하여 추천 알고리즘을 개선한다.&lt;br /&gt;
&lt;br /&gt;
:- 등산했던 등산로들을 모아서 저장하고 공유하는 기능을 개발한다.&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
===구성원 및 추진체계===&lt;br /&gt;
[[파일명|사진들어갈자리]]&lt;br /&gt;
===자재소요서===&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
&lt;br /&gt;
===개발사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11966</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11966"/>
				<updated>2025-06-19T13:45:52Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 하드웨어 설계 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:Dos-등산사고-발생-요인.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_1&amp;quot;&amp;gt;'''그림 1.''' 등산사고 발생 요인 (산림청 제공)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::최근 산림청의 조사[[#ref1|[1]]]에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다([[#그림_1|그림 1]]). 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터([[#그림_2|그림 2]])를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-산림청제공데이터.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_2&amp;quot;&amp;gt;'''그림 2.''' 산림청 제공 데이터 예시&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[[#ref1|[1]]].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
[[내용]]&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. 그림 #은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. (테스트 환경: 라즈베리파이 5)&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-자원사용률.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 자리]]&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다(그림#). 시뮬레이션 결과, 서버에 걸리는 부하는 그림 #과 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 부분]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다. 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:소프트웨어흐름도.png]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동사진.jpg|1000픽셀]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
인터넷 탐색기에서 다음 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:사진명|섬네일|가운데|'''그림 7.''' 셰르파(Sherpa) 실행 방법]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:::[[파일:사진명.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도 (SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
:::[[파일:Dos-sus.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[[#ref5|[5]]]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시나리오 후 설문 (ASQ)'''&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_10&amp;quot;&amp;gt;'''그림 10.''' 시나리오 후 설문(ASQ)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시나리오 후 설문([[#그림_10|[그림 10]]]은 각 Task를 수행하는 것이 얼마나 어려운지 확인하는 사용성 평가 방법이다[[#ref6|[6]]]. 우리는 우리 시스템에서 제공하는 주요 기능(개인 맞춤형 등산 목적지 추천, 개인 맞춤형 등산로 생성, 생성한 등산로 안내)을 쉽게 사용할 수 있는 지 확인하기 위하여 우리의 기능에 대응되는 Task를 만든 시나리오 후 설문을 진행했다. 설문 진행 결과, 우리가 제공하는 주요 기능이 모두 사용자가 쓰기 편하다는 것을 확인했다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''반구조화 인터뷰'''&lt;br /&gt;
우리는 추후 우리 앱을 개선하기 위하여, 앞선 두 개의 설문을 진행한 이후 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 묻는 반구조화 인터뷰를 진행했다. 주요한 내용은 다음과 같았다.&lt;br /&gt;
&lt;br /&gt;
:'''좋았던 점'''&lt;br /&gt;
 ''기존에 등산로 방향을 찾을 때 사진이 올라와 있는 블로그들을 많이 참조했는데, 직접적으로 방향을 알려주는 점이 좋았다.             -P7-''&lt;br /&gt;
&lt;br /&gt;
 ''아직 개인의 운동 수준과 등산로 난이도 스케일이 정확히 맞지는 않는 것 같지만, 어려운 등산로일수록 등산로 난이도가 어렵게 나오는 건 맞는 것 같다. 등산을 진행할 때 어느 정도 참고가 가능할 것 같다.      -P10- ''&lt;br /&gt;
&lt;br /&gt;
:'''개선할 점'''&lt;br /&gt;
 ''등산 목적지에 쉬운 코스가 없을 경우, 난이도를 쉽게 설정해도 어려운 코스가 나오는 문제점이 있다.   -P4-''  (해결됨)&lt;br /&gt;
&lt;br /&gt;
 ''위시리스트 담기라는 표현 자체가 잘 이해되지 않았다.      -P8-''&lt;br /&gt;
&lt;br /&gt;
 ''Navi 페이지에서 진행바가 새로고침할 때마다 리셋되는 것이 아쉬웠다.  -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''목적지 추천 부분에서 산 이름이 영어로 나오는 점이 아쉬웠다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
:'''UI 관련'''&lt;br /&gt;
 ''프로토타입 UI는 개인적으론 별 다른 것 없이 깔끔해서 좋았다.     -P2, P7-''&lt;br /&gt;
&lt;br /&gt;
 ''잡다한 기능이 없어서 사용법을 금방 익힐 수 있었다. -P9-''&lt;br /&gt;
&lt;br /&gt;
:'''추가되었으면 하는 기능'''&lt;br /&gt;
 ''코스 예상시간이 표기되면 좋을 것 같다.   -P1-''&lt;br /&gt;
&lt;br /&gt;
 ''더 많은 산들에 대해서도 정보를 제공하면 좋을 것 같다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
 ''나와 비슷한 사용자들을 매칭해주는 기능이 있으면 좋을 것 같다.   -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''등산했던 등산로들을 모아서 저장하고 공유할 수 있는 기능이 있으면 좋을 것 같다.      -P12-''&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
서비스를 운영하는 데에 드는 비용은 도메인 유지 비용(10달러/1년), 라즈베리파이를 유지하기 위한 전기료 정도를 고려할 수 있다. 이는 페이지 내 배너 광고를 하나만 추가해도 상회할 수 있으며, 운영 비용 자체가 적기 때문에 수익을 계속 유지할 수 있으며, 유지보수 및 지속적인 개발 또한 가능할 것으로 보인다.&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
====어려웠던 내용들====&lt;br /&gt;
:- 산림청에서 제공하는 geojson 데이터를 시스템에서 사용하기 위한 형태로 가공하는 과정에서 많은 시행착오가 있었다.&lt;br /&gt;
&lt;br /&gt;
:- 기존에는 클라우드 서비스를 이용하는 형태로 설계했는데, 클라우드 비용 문제 및 교내망에서는 서버에 접속할 수 없는 문제가 발생하였다.&lt;br /&gt;
&lt;br /&gt;
:- 설문조사 및 인터뷰 대상을 모집하는 과정에서 어려움이 있었다.&lt;br /&gt;
 &lt;br /&gt;
:- 추천 알고리즘을 만들기 위한 사람들의 등산 데이터가 너무 적었다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====차후 구현할 내용====&lt;br /&gt;
주로 반구조화 인터뷰 중 아쉬웠던 점, 추가되었으면 하는 기능들 중 구현 난이도가 쉬운 항목부터 진행할 예정이다. 구체적으로 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
:- “위시리스트 담기”와 같이 사용자가 한 번에 이해되지 않을만한 표현, 불필요하게 작성된 영어 표현이 있는지 확인하고 수정한다.&lt;br /&gt;
&lt;br /&gt;
:- Navi 페이지의 진행 바의 진행 상황을 새로고침 되더라도 유지한다.&lt;br /&gt;
&lt;br /&gt;
:- 코스 예상시간 표기 기능을 추가한다.&lt;br /&gt;
&lt;br /&gt;
:- 시스템에서 지원하는 산의 개수를 더 늘린다.&lt;br /&gt;
&lt;br /&gt;
:- 더 많은 사용자들의 검색 데이터들을 참고하여 추천 알고리즘을 개선한다.&lt;br /&gt;
&lt;br /&gt;
:- 등산했던 등산로들을 모아서 저장하고 공유하는 기능을 개발한다.&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
===구성원 및 추진체계===&lt;br /&gt;
[[파일명|사진들어갈자리]]&lt;br /&gt;
===자재소요서===&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
&lt;br /&gt;
===개발사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11964</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11964"/>
				<updated>2025-06-19T13:44:58Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 이론적 계산 및 시뮬레이션 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:Dos-등산사고-발생-요인.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_1&amp;quot;&amp;gt;'''그림 1.''' 등산사고 발생 요인 (산림청 제공)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::최근 산림청의 조사[[#ref1|[1]]]에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다([[#그림_1|그림 1]]). 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터([[#그림_2|그림 2]])를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-산림청제공데이터.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_2&amp;quot;&amp;gt;'''그림 2.''' 산림청 제공 데이터 예시&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[[#ref1|[1]]].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
[[내용]]&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. 그림 #은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. (테스트 환경: 라즈베리파이 5)&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-자원사용률.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 자리]]&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다(그림#). 시뮬레이션 결과, 서버에 걸리는 부하는 그림 #과 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 부분]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다(See 그림x). 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:소프트웨어흐름도.png]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동사진.jpg|1000픽셀]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
인터넷 탐색기에서 다음 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:사진명|섬네일|가운데|'''그림 7.''' 셰르파(Sherpa) 실행 방법]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:::[[파일:사진명.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도 (SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
:::[[파일:Dos-sus.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[[#ref5|[5]]]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시나리오 후 설문 (ASQ)'''&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_10&amp;quot;&amp;gt;'''그림 10.''' 시나리오 후 설문(ASQ)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시나리오 후 설문([[#그림_10|[그림 10]]]은 각 Task를 수행하는 것이 얼마나 어려운지 확인하는 사용성 평가 방법이다[[#ref6|[6]]]. 우리는 우리 시스템에서 제공하는 주요 기능(개인 맞춤형 등산 목적지 추천, 개인 맞춤형 등산로 생성, 생성한 등산로 안내)을 쉽게 사용할 수 있는 지 확인하기 위하여 우리의 기능에 대응되는 Task를 만든 시나리오 후 설문을 진행했다. 설문 진행 결과, 우리가 제공하는 주요 기능이 모두 사용자가 쓰기 편하다는 것을 확인했다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''반구조화 인터뷰'''&lt;br /&gt;
우리는 추후 우리 앱을 개선하기 위하여, 앞선 두 개의 설문을 진행한 이후 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 묻는 반구조화 인터뷰를 진행했다. 주요한 내용은 다음과 같았다.&lt;br /&gt;
&lt;br /&gt;
:'''좋았던 점'''&lt;br /&gt;
 ''기존에 등산로 방향을 찾을 때 사진이 올라와 있는 블로그들을 많이 참조했는데, 직접적으로 방향을 알려주는 점이 좋았다.             -P7-''&lt;br /&gt;
&lt;br /&gt;
 ''아직 개인의 운동 수준과 등산로 난이도 스케일이 정확히 맞지는 않는 것 같지만, 어려운 등산로일수록 등산로 난이도가 어렵게 나오는 건 맞는 것 같다. 등산을 진행할 때 어느 정도 참고가 가능할 것 같다.      -P10- ''&lt;br /&gt;
&lt;br /&gt;
:'''개선할 점'''&lt;br /&gt;
 ''등산 목적지에 쉬운 코스가 없을 경우, 난이도를 쉽게 설정해도 어려운 코스가 나오는 문제점이 있다.   -P4-''  (해결됨)&lt;br /&gt;
&lt;br /&gt;
 ''위시리스트 담기라는 표현 자체가 잘 이해되지 않았다.      -P8-''&lt;br /&gt;
&lt;br /&gt;
 ''Navi 페이지에서 진행바가 새로고침할 때마다 리셋되는 것이 아쉬웠다.  -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''목적지 추천 부분에서 산 이름이 영어로 나오는 점이 아쉬웠다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
:'''UI 관련'''&lt;br /&gt;
 ''프로토타입 UI는 개인적으론 별 다른 것 없이 깔끔해서 좋았다.     -P2, P7-''&lt;br /&gt;
&lt;br /&gt;
 ''잡다한 기능이 없어서 사용법을 금방 익힐 수 있었다. -P9-''&lt;br /&gt;
&lt;br /&gt;
:'''추가되었으면 하는 기능'''&lt;br /&gt;
 ''코스 예상시간이 표기되면 좋을 것 같다.   -P1-''&lt;br /&gt;
&lt;br /&gt;
 ''더 많은 산들에 대해서도 정보를 제공하면 좋을 것 같다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
 ''나와 비슷한 사용자들을 매칭해주는 기능이 있으면 좋을 것 같다.   -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''등산했던 등산로들을 모아서 저장하고 공유할 수 있는 기능이 있으면 좋을 것 같다.      -P12-''&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
서비스를 운영하는 데에 드는 비용은 도메인 유지 비용(10달러/1년), 라즈베리파이를 유지하기 위한 전기료 정도를 고려할 수 있다. 이는 페이지 내 배너 광고를 하나만 추가해도 상회할 수 있으며, 운영 비용 자체가 적기 때문에 수익을 계속 유지할 수 있으며, 유지보수 및 지속적인 개발 또한 가능할 것으로 보인다.&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
====어려웠던 내용들====&lt;br /&gt;
:- 산림청에서 제공하는 geojson 데이터를 시스템에서 사용하기 위한 형태로 가공하는 과정에서 많은 시행착오가 있었다.&lt;br /&gt;
&lt;br /&gt;
:- 기존에는 클라우드 서비스를 이용하는 형태로 설계했는데, 클라우드 비용 문제 및 교내망에서는 서버에 접속할 수 없는 문제가 발생하였다.&lt;br /&gt;
&lt;br /&gt;
:- 설문조사 및 인터뷰 대상을 모집하는 과정에서 어려움이 있었다.&lt;br /&gt;
 &lt;br /&gt;
:- 추천 알고리즘을 만들기 위한 사람들의 등산 데이터가 너무 적었다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====차후 구현할 내용====&lt;br /&gt;
주로 반구조화 인터뷰 중 아쉬웠던 점, 추가되었으면 하는 기능들 중 구현 난이도가 쉬운 항목부터 진행할 예정이다. 구체적으로 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
:- “위시리스트 담기”와 같이 사용자가 한 번에 이해되지 않을만한 표현, 불필요하게 작성된 영어 표현이 있는지 확인하고 수정한다.&lt;br /&gt;
&lt;br /&gt;
:- Navi 페이지의 진행 바의 진행 상황을 새로고침 되더라도 유지한다.&lt;br /&gt;
&lt;br /&gt;
:- 코스 예상시간 표기 기능을 추가한다.&lt;br /&gt;
&lt;br /&gt;
:- 시스템에서 지원하는 산의 개수를 더 늘린다.&lt;br /&gt;
&lt;br /&gt;
:- 더 많은 사용자들의 검색 데이터들을 참고하여 추천 알고리즘을 개선한다.&lt;br /&gt;
&lt;br /&gt;
:- 등산했던 등산로들을 모아서 저장하고 공유하는 기능을 개발한다.&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
===구성원 및 추진체계===&lt;br /&gt;
[[파일명|사진들어갈자리]]&lt;br /&gt;
===자재소요서===&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
&lt;br /&gt;
===개발사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EC%9E%90%EC%9B%90%EC%82%AC%EC%9A%A9%EB%A5%A0.jpg&amp;diff=11963</id>
		<title>파일:Dos-자원사용률.jpg</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EC%9E%90%EC%9B%90%EC%82%AC%EC%9A%A9%EB%A5%A0.jpg&amp;diff=11963"/>
				<updated>2025-06-19T13:44:34Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: dos-자원사용률.jpg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;dos-자원사용률.jpg&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EB%B6%81%ED%95%9C%EC%82%B0%ED%83%90%EB%B0%A9%EC%95%88%EB%82%B4%EB%8F%84.jpg&amp;diff=11960</id>
		<title>파일:Dos-북한산탐방안내도.jpg</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EB%B6%81%ED%95%9C%EC%82%B0%ED%83%90%EB%B0%A9%EC%95%88%EB%82%B4%EB%8F%84.jpg&amp;diff=11960"/>
				<updated>2025-06-19T13:42:17Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11955</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11955"/>
				<updated>2025-06-19T13:39:13Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 개발 과제의 배경 및 효과 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:Dos-등산사고-발생-요인.jpg|1200픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_1&amp;quot;&amp;gt;'''그림 1.''' 등산사고 발생 요인 (산림청 제공)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
최근 산림청의 조사[[#ref1|[1]]]에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다([[#그림_1|그림 1]]). 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터([[#그림_2|그림 2]])를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
[[파일:dos-산림청제공데이터.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_2&amp;quot;&amp;gt;'''그림 2.''' 산림청 제공 데이터 예시&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
[[파일:북한산탐방안내도.jpg|400픽셀]] [[파일:국립공원날씨_1672.jpg|500픽셀]]&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[1].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
[[내용]]&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. 그림 #은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. (테스트 환경: 라즈베리파이 5)&lt;br /&gt;
&lt;br /&gt;
[[사진들어갈자리1]]&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 자리]]&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다(그림#). 시뮬레이션 결과, 서버에 걸리는 부하는 그림 #과 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 부분]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다(See 그림x). 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:소프트웨어흐름도.png]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동사진.jpg|1000픽셀]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
인터넷 탐색기에서 다음 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:사진명|섬네일|가운데|'''그림 7.''' 셰르파(Sherpa) 실행 방법]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:::[[파일:사진명.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도 (SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
:::[[파일:Dos-sus.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[[#ref5|[5]]]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시나리오 후 설문 (ASQ)'''&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_10&amp;quot;&amp;gt;'''그림 10.''' 시나리오 후 설문(ASQ)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시나리오 후 설문([[#그림_10|[그림 10]]]은 각 Task를 수행하는 것이 얼마나 어려운지 확인하는 사용성 평가 방법이다[[#ref6|[6]]]. 우리는 우리 시스템에서 제공하는 주요 기능(개인 맞춤형 등산 목적지 추천, 개인 맞춤형 등산로 생성, 생성한 등산로 안내)을 쉽게 사용할 수 있는 지 확인하기 위하여 우리의 기능에 대응되는 Task를 만든 시나리오 후 설문을 진행했다. 설문 진행 결과, 우리가 제공하는 주요 기능이 모두 사용자가 쓰기 편하다는 것을 확인했다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''반구조화 인터뷰'''&lt;br /&gt;
우리는 추후 우리 앱을 개선하기 위하여, 앞선 두 개의 설문을 진행한 이후 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 묻는 반구조화 인터뷰를 진행했다. 주요한 내용은 다음과 같았다.&lt;br /&gt;
&lt;br /&gt;
:'''좋았던 점'''&lt;br /&gt;
 ''기존에 등산로 방향을 찾을 때 사진이 올라와 있는 블로그들을 많이 참조했는데, 직접적으로 방향을 알려주는 점이 좋았다.             -P7-''&lt;br /&gt;
&lt;br /&gt;
 ''아직 개인의 운동 수준과 등산로 난이도 스케일이 정확히 맞지는 않는 것 같지만, 어려운 등산로일수록 등산로 난이도가 어렵게 나오는 건 맞는 것 같다. 등산을 진행할 때 어느 정도 참고가 가능할 것 같다.      -P10- ''&lt;br /&gt;
&lt;br /&gt;
:'''개선할 점'''&lt;br /&gt;
 ''등산 목적지에 쉬운 코스가 없을 경우, 난이도를 쉽게 설정해도 어려운 코스가 나오는 문제점이 있다.   -P4-''  (해결됨)&lt;br /&gt;
&lt;br /&gt;
 ''위시리스트 담기라는 표현 자체가 잘 이해되지 않았다.      -P8-''&lt;br /&gt;
&lt;br /&gt;
 ''Navi 페이지에서 진행바가 새로고침할 때마다 리셋되는 것이 아쉬웠다.  -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''목적지 추천 부분에서 산 이름이 영어로 나오는 점이 아쉬웠다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
:'''UI 관련'''&lt;br /&gt;
 ''프로토타입 UI는 개인적으론 별 다른 것 없이 깔끔해서 좋았다.     -P2, P7-''&lt;br /&gt;
&lt;br /&gt;
 ''잡다한 기능이 없어서 사용법을 금방 익힐 수 있었다. -P9-''&lt;br /&gt;
&lt;br /&gt;
:'''추가되었으면 하는 기능'''&lt;br /&gt;
 ''코스 예상시간이 표기되면 좋을 것 같다.   -P1-''&lt;br /&gt;
&lt;br /&gt;
 ''더 많은 산들에 대해서도 정보를 제공하면 좋을 것 같다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
 ''나와 비슷한 사용자들을 매칭해주는 기능이 있으면 좋을 것 같다.   -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''등산했던 등산로들을 모아서 저장하고 공유할 수 있는 기능이 있으면 좋을 것 같다.      -P12-''&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
서비스를 운영하는 데에 드는 비용은 도메인 유지 비용(10달러/1년), 라즈베리파이를 유지하기 위한 전기료 정도를 고려할 수 있다. 이는 페이지 내 배너 광고를 하나만 추가해도 상회할 수 있으며, 운영 비용 자체가 적기 때문에 수익을 계속 유지할 수 있으며, 유지보수 및 지속적인 개발 또한 가능할 것으로 보인다.&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
====어려웠던 내용들====&lt;br /&gt;
:- 산림청에서 제공하는 geojson 데이터를 시스템에서 사용하기 위한 형태로 가공하는 과정에서 많은 시행착오가 있었다.&lt;br /&gt;
&lt;br /&gt;
:- 기존에는 클라우드 서비스를 이용하는 형태로 설계했는데, 클라우드 비용 문제 및 교내망에서는 서버에 접속할 수 없는 문제가 발생하였다.&lt;br /&gt;
&lt;br /&gt;
:- 설문조사 및 인터뷰 대상을 모집하는 과정에서 어려움이 있었다.&lt;br /&gt;
 &lt;br /&gt;
:- 추천 알고리즘을 만들기 위한 사람들의 등산 데이터가 너무 적었다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====차후 구현할 내용====&lt;br /&gt;
주로 반구조화 인터뷰 중 아쉬웠던 점, 추가되었으면 하는 기능들 중 구현 난이도가 쉬운 항목부터 진행할 예정이다. 구체적으로 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
:- “위시리스트 담기”와 같이 사용자가 한 번에 이해되지 않을만한 표현, 불필요하게 작성된 영어 표현이 있는지 확인하고 수정한다.&lt;br /&gt;
&lt;br /&gt;
:- Navi 페이지의 진행 바의 진행 상황을 새로고침 되더라도 유지한다.&lt;br /&gt;
&lt;br /&gt;
:- 코스 예상시간 표기 기능을 추가한다.&lt;br /&gt;
&lt;br /&gt;
:- 시스템에서 지원하는 산의 개수를 더 늘린다.&lt;br /&gt;
&lt;br /&gt;
:- 더 많은 사용자들의 검색 데이터들을 참고하여 추천 알고리즘을 개선한다.&lt;br /&gt;
&lt;br /&gt;
:- 등산했던 등산로들을 모아서 저장하고 공유하는 기능을 개발한다.&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
===구성원 및 추진체계===&lt;br /&gt;
[[파일명|사진들어갈자리]]&lt;br /&gt;
===자재소요서===&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
&lt;br /&gt;
===개발사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EC%82%B0%EB%A6%BC%EC%B2%AD%EC%A0%9C%EA%B3%B5%EB%8D%B0%EC%9D%B4%ED%84%B0.jpg&amp;diff=11953</id>
		<title>파일:Dos-산림청제공데이터.jpg</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EC%82%B0%EB%A6%BC%EC%B2%AD%EC%A0%9C%EA%B3%B5%EB%8D%B0%EC%9D%B4%ED%84%B0.jpg&amp;diff=11953"/>
				<updated>2025-06-19T13:38:43Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: dos-산림청제공데이터.jpg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;dos-산림청제공데이터.jpg&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11949</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11949"/>
				<updated>2025-06-19T13:36:49Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 개발 과제의 배경 및 효과 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:Dos-등산사고-발생-요인.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_1&amp;quot;&amp;gt;'''그림 1.''' 등산사고 발생 요인 (산림청 제공)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
[[파일:월별등산사고.png]] [[파일:원인별등산사고.png]]&lt;br /&gt;
&lt;br /&gt;
최근 산림청의 조사[[#ref1|[1]]]에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다([[#그림_1]|[그림 1]]]). 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터([[#그림_2]|[그림 2]]])를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
[[파일:파일명|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_2&amp;quot;&amp;gt;'''그림 2.''' 산림청 제공 데이터 예시&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
[[파일:북한산탐방안내도.jpg|400픽셀]] [[파일:국립공원날씨_1672.jpg|500픽셀]]&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[1].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
[[내용]]&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. 그림 #은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. (테스트 환경: 라즈베리파이 5)&lt;br /&gt;
&lt;br /&gt;
[[사진들어갈자리1]]&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 자리]]&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다(그림#). 시뮬레이션 결과, 서버에 걸리는 부하는 그림 #과 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 부분]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다(See 그림x). 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:소프트웨어흐름도.png]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동사진.jpg|1000픽셀]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
인터넷 탐색기에서 다음 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:사진명|섬네일|가운데|'''그림 7.''' 셰르파(Sherpa) 실행 방법]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:::[[파일:사진명.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도 (SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
:::[[파일:Dos-sus.jpg|1000픽셀|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[[#ref5|[5]]]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시나리오 후 설문 (ASQ)'''&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_10&amp;quot;&amp;gt;'''그림 10.''' 시나리오 후 설문(ASQ)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시나리오 후 설문([[#그림_10|[그림 10]]]은 각 Task를 수행하는 것이 얼마나 어려운지 확인하는 사용성 평가 방법이다[[#ref6|[6]]]. 우리는 우리 시스템에서 제공하는 주요 기능(개인 맞춤형 등산 목적지 추천, 개인 맞춤형 등산로 생성, 생성한 등산로 안내)을 쉽게 사용할 수 있는 지 확인하기 위하여 우리의 기능에 대응되는 Task를 만든 시나리오 후 설문을 진행했다. 설문 진행 결과, 우리가 제공하는 주요 기능이 모두 사용자가 쓰기 편하다는 것을 확인했다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''반구조화 인터뷰'''&lt;br /&gt;
우리는 추후 우리 앱을 개선하기 위하여, 앞선 두 개의 설문을 진행한 이후 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 묻는 반구조화 인터뷰를 진행했다. 주요한 내용은 다음과 같았다.&lt;br /&gt;
&lt;br /&gt;
:'''좋았던 점'''&lt;br /&gt;
 ''기존에 등산로 방향을 찾을 때 사진이 올라와 있는 블로그들을 많이 참조했는데, 직접적으로 방향을 알려주는 점이 좋았다.             -P7-''&lt;br /&gt;
&lt;br /&gt;
 ''아직 개인의 운동 수준과 등산로 난이도 스케일이 정확히 맞지는 않는 것 같지만, 어려운 등산로일수록 등산로 난이도가 어렵게 나오는 건 맞는 것 같다. 등산을 진행할 때 어느 정도 참고가 가능할 것 같다.      -P10- ''&lt;br /&gt;
&lt;br /&gt;
:'''개선할 점'''&lt;br /&gt;
 ''등산 목적지에 쉬운 코스가 없을 경우, 난이도를 쉽게 설정해도 어려운 코스가 나오는 문제점이 있다.   -P4-''  (해결됨)&lt;br /&gt;
&lt;br /&gt;
 ''위시리스트 담기라는 표현 자체가 잘 이해되지 않았다.      -P8-''&lt;br /&gt;
&lt;br /&gt;
 ''Navi 페이지에서 진행바가 새로고침할 때마다 리셋되는 것이 아쉬웠다.  -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''목적지 추천 부분에서 산 이름이 영어로 나오는 점이 아쉬웠다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
:'''UI 관련'''&lt;br /&gt;
 ''프로토타입 UI는 개인적으론 별 다른 것 없이 깔끔해서 좋았다.     -P2, P7-''&lt;br /&gt;
&lt;br /&gt;
 ''잡다한 기능이 없어서 사용법을 금방 익힐 수 있었다. -P9-''&lt;br /&gt;
&lt;br /&gt;
:'''추가되었으면 하는 기능'''&lt;br /&gt;
 ''코스 예상시간이 표기되면 좋을 것 같다.   -P1-''&lt;br /&gt;
&lt;br /&gt;
 ''더 많은 산들에 대해서도 정보를 제공하면 좋을 것 같다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
 ''나와 비슷한 사용자들을 매칭해주는 기능이 있으면 좋을 것 같다.   -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''등산했던 등산로들을 모아서 저장하고 공유할 수 있는 기능이 있으면 좋을 것 같다.      -P12-''&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
서비스를 운영하는 데에 드는 비용은 도메인 유지 비용(10달러/1년), 라즈베리파이를 유지하기 위한 전기료 정도를 고려할 수 있다. 이는 페이지 내 배너 광고를 하나만 추가해도 상회할 수 있으며, 운영 비용 자체가 적기 때문에 수익을 계속 유지할 수 있으며, 유지보수 및 지속적인 개발 또한 가능할 것으로 보인다.&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
====어려웠던 내용들====&lt;br /&gt;
:- 산림청에서 제공하는 geojson 데이터를 시스템에서 사용하기 위한 형태로 가공하는 과정에서 많은 시행착오가 있었다.&lt;br /&gt;
&lt;br /&gt;
:- 기존에는 클라우드 서비스를 이용하는 형태로 설계했는데, 클라우드 비용 문제 및 교내망에서는 서버에 접속할 수 없는 문제가 발생하였다.&lt;br /&gt;
&lt;br /&gt;
:- 설문조사 및 인터뷰 대상을 모집하는 과정에서 어려움이 있었다.&lt;br /&gt;
 &lt;br /&gt;
:- 추천 알고리즘을 만들기 위한 사람들의 등산 데이터가 너무 적었다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====차후 구현할 내용====&lt;br /&gt;
주로 반구조화 인터뷰 중 아쉬웠던 점, 추가되었으면 하는 기능들 중 구현 난이도가 쉬운 항목부터 진행할 예정이다. 구체적으로 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
:- “위시리스트 담기”와 같이 사용자가 한 번에 이해되지 않을만한 표현, 불필요하게 작성된 영어 표현이 있는지 확인하고 수정한다.&lt;br /&gt;
&lt;br /&gt;
:- Navi 페이지의 진행 바의 진행 상황을 새로고침 되더라도 유지한다.&lt;br /&gt;
&lt;br /&gt;
:- 코스 예상시간 표기 기능을 추가한다.&lt;br /&gt;
&lt;br /&gt;
:- 시스템에서 지원하는 산의 개수를 더 늘린다.&lt;br /&gt;
&lt;br /&gt;
:- 더 많은 사용자들의 검색 데이터들을 참고하여 추천 알고리즘을 개선한다.&lt;br /&gt;
&lt;br /&gt;
:- 등산했던 등산로들을 모아서 저장하고 공유하는 기능을 개발한다.&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
===구성원 및 추진체계===&lt;br /&gt;
[[파일명|사진들어갈자리]]&lt;br /&gt;
===자재소요서===&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
&lt;br /&gt;
===개발사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EB%93%B1%EC%82%B0%EC%82%AC%EA%B3%A0-%EB%B0%9C%EC%83%9D-%EC%9A%94%EC%9D%B8.jpg&amp;diff=11948</id>
		<title>파일:Dos-등산사고-발생-요인.jpg</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EB%93%B1%EC%82%B0%EC%82%AC%EA%B3%A0-%EB%B0%9C%EC%83%9D-%EC%9A%94%EC%9D%B8.jpg&amp;diff=11948"/>
				<updated>2025-06-19T13:36:25Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: 등산사고 발생 요인&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;등산사고 발생 요인&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-asq.jpg&amp;diff=11921</id>
		<title>파일:Dos-asq.jpg</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-asq.jpg&amp;diff=11921"/>
				<updated>2025-06-19T13:23:38Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: Com237님이 파일:Dos-asq.jpg의 새 판을 올렸습니다&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-asq.jpg&amp;diff=11918</id>
		<title>파일:Dos-asq.jpg</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-asq.jpg&amp;diff=11918"/>
				<updated>2025-06-19T13:22:46Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11915</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11915"/>
				<updated>2025-06-19T13:21:09Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 사용자 만족도 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:월별등산사고.png]] [[파일:원인별등산사고.png]]&lt;br /&gt;
&lt;br /&gt;
최근 산림청의 조사에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다. 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
[[파일:북한산탐방안내도.jpg|400픽셀]] [[파일:국립공원날씨_1672.jpg|500픽셀]]&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[1].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
[[내용]]&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. 그림 #은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. (테스트 환경: 라즈베리파이 5)&lt;br /&gt;
&lt;br /&gt;
[[사진들어갈자리1]]&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 자리]]&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다(그림#). 시뮬레이션 결과, 서버에 걸리는 부하는 그림 #과 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 부분]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다(See 그림x). 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:소프트웨어흐름도.png]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동사진.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
인터넷 탐색기에서 다음 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:사진명|섬네일|가운데|'''그림 7.''' 셰르파(Sherpa) 실행 방법]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도 (SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
[[파일:Dos-sus.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[5]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시나리오 후 설문 (ASQ)'''&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_10&amp;quot;&amp;gt;'''그림 10.''' 시나리오 후 설문(ASQ)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시나리오 후 설문([[#그림_10|[그림 10]]]은 각 Task를 수행하는 것이 얼마나 어려운지 확인하는 사용성 평가 방법이다[[#ref6|[6]]]. 우리는 우리 시스템에서 제공하는 주요 기능(개인 맞춤형 등산 목적지 추천, 개인 맞춤형 등산로 생성, 생성한 등산로 안내)을 쉽게 사용할 수 있는 지 확인하기 위하여 우리의 기능에 대응되는 Task를 만든 시나리오 후 설문을 진행했다. 설문 진행 결과, 우리가 제공하는 주요 기능이 모두 사용자가 쓰기 편하다는 것을 확인했다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''반구조화 인터뷰'''&lt;br /&gt;
우리는 추후 우리 앱을 개선하기 위하여, 앞선 두 개의 설문을 진행한 이후 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 묻는 반구조화 인터뷰를 진행했다. 주요한 내용은 다음과 같았다.&lt;br /&gt;
&lt;br /&gt;
:'''좋았던 점'''&lt;br /&gt;
 ''기존에 등산로 방향을 찾을 때 사진이 올라와 있는 블로그들을 많이 참조했는데, 직접적으로 방향을 알려주는 점이 좋았다.             -P7-''&lt;br /&gt;
&lt;br /&gt;
 ''아직 개인의 운동 수준과 등산로 난이도 스케일이 정확히 맞지는 않는 것 같지만, 어려운 등산로일수록 등산로 난이도가 어렵게 나오는 건 맞는 것 같다. 등산을 진행할 때 어느 정도 참고가 가능할 것 같다.      -P10- ''&lt;br /&gt;
&lt;br /&gt;
:'''개선할 점'''&lt;br /&gt;
 ''등산 목적지에 쉬운 코스가 없을 경우, 난이도를 쉽게 설정해도 어려운 코스가 나오는 문제점이 있다.   -P4-''  (해결됨)&lt;br /&gt;
&lt;br /&gt;
 ''위시리스트 담기라는 표현 자체가 잘 이해되지 않았다.      -P8-''&lt;br /&gt;
&lt;br /&gt;
 ''Navi 페이지에서 진행바가 새로고침할 때마다 리셋되는 것이 아쉬웠다.  -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''목적지 추천 부분에서 산 이름이 영어로 나오는 점이 아쉬웠다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
:'''UI 관련'''&lt;br /&gt;
 ''프로토타입 UI는 개인적으론 별 다른 것 없이 깔끔해서 좋았다.     -P2, P7-''&lt;br /&gt;
&lt;br /&gt;
 ''잡다한 기능이 없어서 사용법을 금방 익힐 수 있었다. -P9-''&lt;br /&gt;
&lt;br /&gt;
:'''추가되었으면 하는 기능'''&lt;br /&gt;
 ''코스 예상시간이 표기되면 좋을 것 같다.   -P1-''&lt;br /&gt;
&lt;br /&gt;
 ''더 많은 산들에 대해서도 정보를 제공하면 좋을 것 같다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
 ''나와 비슷한 사용자들을 매칭해주는 기능이 있으면 좋을 것 같다.   -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''등산했던 등산로들을 모아서 저장하고 공유할 수 있는 기능이 있으면 좋을 것 같다.      -P12-''&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
서비스를 운영하는 데에 드는 비용은 도메인 유지 비용(10달러/1년), 라즈베리파이를 유지하기 위한 전기료 정도를 고려할 수 있다. 이는 페이지 내 배너 광고를 하나만 추가해도 상회할 수 있으며, 운영 비용 자체가 적기 때문에 수익을 계속 유지할 수 있으며, 유지보수 및 지속적인 개발 또한 가능할 것으로 보인다.&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
====어려웠던 내용들====&lt;br /&gt;
:- 산림청에서 제공하는 geojson 데이터를 시스템에서 사용하기 위한 형태로 가공하는 과정에서 많은 시행착오가 있었다.&lt;br /&gt;
&lt;br /&gt;
:- 기존에는 클라우드 서비스를 이용하는 형태로 설계했는데, 클라우드 비용 문제 및 교내망에서는 서버에 접속할 수 없는 문제가 발생하였다.&lt;br /&gt;
&lt;br /&gt;
:- 설문조사 및 인터뷰 대상을 모집하는 과정에서 어려움이 있었다.&lt;br /&gt;
 &lt;br /&gt;
:- 추천 알고리즘을 만들기 위한 사람들의 등산 데이터가 너무 적었다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====차후 구현할 내용====&lt;br /&gt;
주로 반구조화 인터뷰 중 아쉬웠던 점, 추가되었으면 하는 기능들 중 구현 난이도가 쉬운 항목부터 진행할 예정이다. 구체적으로 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
:- “위시리스트 담기”와 같이 사용자가 한 번에 이해되지 않을만한 표현, 불필요하게 작성된 영어 표현이 있는지 확인하고 수정한다.&lt;br /&gt;
&lt;br /&gt;
:- Navi 페이지의 진행 바의 진행 상황을 새로고침 되더라도 유지한다.&lt;br /&gt;
&lt;br /&gt;
:- 코스 예상시간 표기 기능을 추가한다.&lt;br /&gt;
&lt;br /&gt;
:- 시스템에서 지원하는 산의 개수를 더 늘린다.&lt;br /&gt;
&lt;br /&gt;
:- 더 많은 사용자들의 검색 데이터들을 참고하여 추천 알고리즘을 개선한다.&lt;br /&gt;
&lt;br /&gt;
:- 등산했던 등산로들을 모아서 저장하고 공유하는 기능을 개발한다.&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
===구성원 및 추진체계===&lt;br /&gt;
[[파일명|사진들어갈자리]]&lt;br /&gt;
===자재소요서===&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
&lt;br /&gt;
===개발사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==개발사업비 내역서==&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-sus.jpg&amp;diff=11912</id>
		<title>파일:Dos-sus.jpg</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-sus.jpg&amp;diff=11912"/>
				<updated>2025-06-19T13:20:30Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11907</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11907"/>
				<updated>2025-06-19T13:16:46Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 완료 작품의 소개 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:월별등산사고.png]] [[파일:원인별등산사고.png]]&lt;br /&gt;
&lt;br /&gt;
최근 산림청의 조사에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다. 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
[[파일:북한산탐방안내도.jpg|400픽셀]] [[파일:국립공원날씨_1672.jpg|500픽셀]]&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[1].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
[[내용]]&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. 그림 #은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. (테스트 환경: 라즈베리파이 5)&lt;br /&gt;
&lt;br /&gt;
[[사진들어갈자리1]]&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 자리]]&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다(그림#). 시뮬레이션 결과, 서버에 걸리는 부하는 그림 #과 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 부분]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다(See 그림x). 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:소프트웨어흐름도.png]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동사진.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
인터넷 탐색기에서 다음 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:사진명|섬네일|가운데|'''그림 7.''' 셰르파(Sherpa) 실행 방법]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도 (SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
[[파일:사진명|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[5]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시나리오 후 설문 (ASQ)'''&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_10&amp;quot;&amp;gt;'''그림 10.''' 시나리오 후 설문(ASQ)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시나리오 후 설문([[#그림_10|[그림 10]]]은 각 Task를 수행하는 것이 얼마나 어려운지 확인하는 사용성 평가 방법이다[[#ref6|[6]]]. 우리는 우리 시스템에서 제공하는 주요 기능(개인 맞춤형 등산 목적지 추천, 개인 맞춤형 등산로 생성, 생성한 등산로 안내)을 쉽게 사용할 수 있는 지 확인하기 위하여 우리의 기능에 대응되는 Task를 만든 시나리오 후 설문을 진행했다. 설문 진행 결과, 우리가 제공하는 주요 기능이 모두 사용자가 쓰기 편하다는 것을 확인했다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''반구조화 인터뷰'''&lt;br /&gt;
우리는 추후 우리 앱을 개선하기 위하여, 앞선 두 개의 설문을 진행한 이후 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 묻는 반구조화 인터뷰를 진행했다. 주요한 내용은 다음과 같았다.&lt;br /&gt;
&lt;br /&gt;
:'''좋았던 점'''&lt;br /&gt;
 ''기존에 등산로 방향을 찾을 때 사진이 올라와 있는 블로그들을 많이 참조했는데, 직접적으로 방향을 알려주는 점이 좋았다.             -P7-''&lt;br /&gt;
&lt;br /&gt;
 ''아직 개인의 운동 수준과 등산로 난이도 스케일이 정확히 맞지는 않는 것 같지만, 어려운 등산로일수록 등산로 난이도가 어렵게 나오는 건 맞는 것 같다. 등산을 진행할 때 어느 정도 참고가 가능할 것 같다.      -P10- ''&lt;br /&gt;
&lt;br /&gt;
:'''개선할 점'''&lt;br /&gt;
 ''등산 목적지에 쉬운 코스가 없을 경우, 난이도를 쉽게 설정해도 어려운 코스가 나오는 문제점이 있다.   -P4-''  (해결됨)&lt;br /&gt;
&lt;br /&gt;
 ''위시리스트 담기라는 표현 자체가 잘 이해되지 않았다.      -P8-''&lt;br /&gt;
&lt;br /&gt;
 ''Navi 페이지에서 진행바가 새로고침할 때마다 리셋되는 것이 아쉬웠다.  -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''목적지 추천 부분에서 산 이름이 영어로 나오는 점이 아쉬웠다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
:'''UI 관련'''&lt;br /&gt;
 ''프로토타입 UI는 개인적으론 별 다른 것 없이 깔끔해서 좋았다.     -P2, P7-''&lt;br /&gt;
&lt;br /&gt;
 ''잡다한 기능이 없어서 사용법을 금방 익힐 수 있었다. -P9-''&lt;br /&gt;
&lt;br /&gt;
:'''추가되었으면 하는 기능'''&lt;br /&gt;
 ''코스 예상시간이 표기되면 좋을 것 같다.   -P1-''&lt;br /&gt;
&lt;br /&gt;
 ''더 많은 산들에 대해서도 정보를 제공하면 좋을 것 같다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
 ''나와 비슷한 사용자들을 매칭해주는 기능이 있으면 좋을 것 같다.   -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''등산했던 등산로들을 모아서 저장하고 공유할 수 있는 기능이 있으면 좋을 것 같다.      -P12-''&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
서비스를 운영하는 데에 드는 비용은 도메인 유지 비용(10달러/1년), 라즈베리파이를 유지하기 위한 전기료 정도를 고려할 수 있다. 이는 페이지 내 배너 광고를 하나만 추가해도 상회할 수 있으며, 운영 비용 자체가 적기 때문에 수익을 계속 유지할 수 있으며, 유지보수 및 지속적인 개발 또한 가능할 것으로 보인다.&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
====어려웠던 내용들====&lt;br /&gt;
:- 산림청에서 제공하는 geojson 데이터를 시스템에서 사용하기 위한 형태로 가공하는 과정에서 많은 시행착오가 있었다.&lt;br /&gt;
&lt;br /&gt;
:- 기존에는 클라우드 서비스를 이용하는 형태로 설계했는데, 클라우드 비용 문제 및 교내망에서는 서버에 접속할 수 없는 문제가 발생하였다.&lt;br /&gt;
&lt;br /&gt;
:- 설문조사 및 인터뷰 대상을 모집하는 과정에서 어려움이 있었다.&lt;br /&gt;
 &lt;br /&gt;
:- 추천 알고리즘을 만들기 위한 사람들의 등산 데이터가 너무 적었다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====차후 구현할 내용====&lt;br /&gt;
주로 반구조화 인터뷰 중 아쉬웠던 점, 추가되었으면 하는 기능들 중 구현 난이도가 쉬운 항목부터 진행할 예정이다. 구체적으로 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
:- “위시리스트 담기”와 같이 사용자가 한 번에 이해되지 않을만한 표현, 불필요하게 작성된 영어 표현이 있는지 확인하고 수정한다.&lt;br /&gt;
&lt;br /&gt;
:- Navi 페이지의 진행 바의 진행 상황을 새로고침 되더라도 유지한다.&lt;br /&gt;
&lt;br /&gt;
:- 코스 예상시간 표기 기능을 추가한다.&lt;br /&gt;
&lt;br /&gt;
:- 시스템에서 지원하는 산의 개수를 더 늘린다.&lt;br /&gt;
&lt;br /&gt;
:- 더 많은 사용자들의 검색 데이터들을 참고하여 추천 알고리즘을 개선한다.&lt;br /&gt;
&lt;br /&gt;
:- 등산했던 등산로들을 모아서 저장하고 공유하는 기능을 개발한다.&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
[[사진들어갈자리]]&lt;br /&gt;
&lt;br /&gt;
==자재소요서==&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
==개발사업비 내역서==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EC%9E%91%EB%8F%99%EC%82%AC%EC%A7%84.jpg&amp;diff=11906</id>
		<title>파일:Dos-작동사진.jpg</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EC%9E%91%EB%8F%99%EC%82%AC%EC%A7%84.jpg&amp;diff=11906"/>
				<updated>2025-06-19T13:16:31Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EC%9E%91%EB%8F%99%ED%99%94%EB%A9%B4.png&amp;diff=11904</id>
		<title>파일:Dos-작동화면.png</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EC%9E%91%EB%8F%99%ED%99%94%EB%A9%B4.png&amp;diff=11904"/>
				<updated>2025-06-19T13:14:42Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: Com237님이 파일:Dos-작동화면.png의 새 판을 올렸습니다&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11903</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11903"/>
				<updated>2025-06-19T13:13:38Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 완료 작품의 소개 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:월별등산사고.png]] [[파일:원인별등산사고.png]]&lt;br /&gt;
&lt;br /&gt;
최근 산림청의 조사에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다. 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
[[파일:북한산탐방안내도.jpg|400픽셀]] [[파일:국립공원날씨_1672.jpg|500픽셀]]&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[1].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
[[내용]]&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. 그림 #은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. (테스트 환경: 라즈베리파이 5)&lt;br /&gt;
&lt;br /&gt;
[[사진들어갈자리1]]&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 자리]]&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다(그림#). 시뮬레이션 결과, 서버에 걸리는 부하는 그림 #과 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 부분]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다(See 그림x). 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:소프트웨어흐름도.png]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동화면.png|800픽셀]]&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
인터넷 탐색기에서 다음 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:사진명|섬네일|가운데|'''그림 7.''' 셰르파(Sherpa) 실행 방법]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도 (SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
[[파일:사진명|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[5]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시나리오 후 설문 (ASQ)'''&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_10&amp;quot;&amp;gt;'''그림 10.''' 시나리오 후 설문(ASQ)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시나리오 후 설문([[#그림_10|[그림 10]]]은 각 Task를 수행하는 것이 얼마나 어려운지 확인하는 사용성 평가 방법이다[[#ref6|[6]]]. 우리는 우리 시스템에서 제공하는 주요 기능(개인 맞춤형 등산 목적지 추천, 개인 맞춤형 등산로 생성, 생성한 등산로 안내)을 쉽게 사용할 수 있는 지 확인하기 위하여 우리의 기능에 대응되는 Task를 만든 시나리오 후 설문을 진행했다. 설문 진행 결과, 우리가 제공하는 주요 기능이 모두 사용자가 쓰기 편하다는 것을 확인했다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''반구조화 인터뷰'''&lt;br /&gt;
우리는 추후 우리 앱을 개선하기 위하여, 앞선 두 개의 설문을 진행한 이후 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 묻는 반구조화 인터뷰를 진행했다. 주요한 내용은 다음과 같았다.&lt;br /&gt;
&lt;br /&gt;
:'''좋았던 점'''&lt;br /&gt;
 ''기존에 등산로 방향을 찾을 때 사진이 올라와 있는 블로그들을 많이 참조했는데, 직접적으로 방향을 알려주는 점이 좋았다.             -P7-''&lt;br /&gt;
&lt;br /&gt;
 ''아직 개인의 운동 수준과 등산로 난이도 스케일이 정확히 맞지는 않는 것 같지만, 어려운 등산로일수록 등산로 난이도가 어렵게 나오는 건 맞는 것 같다. 등산을 진행할 때 어느 정도 참고가 가능할 것 같다.      -P10- ''&lt;br /&gt;
&lt;br /&gt;
:'''개선할 점'''&lt;br /&gt;
 ''등산 목적지에 쉬운 코스가 없을 경우, 난이도를 쉽게 설정해도 어려운 코스가 나오는 문제점이 있다.   -P4-''  (해결됨)&lt;br /&gt;
&lt;br /&gt;
 ''위시리스트 담기라는 표현 자체가 잘 이해되지 않았다.      -P8-''&lt;br /&gt;
&lt;br /&gt;
 ''Navi 페이지에서 진행바가 새로고침할 때마다 리셋되는 것이 아쉬웠다.  -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''목적지 추천 부분에서 산 이름이 영어로 나오는 점이 아쉬웠다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
:'''UI 관련'''&lt;br /&gt;
 ''프로토타입 UI는 개인적으론 별 다른 것 없이 깔끔해서 좋았다.     -P2, P7-''&lt;br /&gt;
&lt;br /&gt;
 ''잡다한 기능이 없어서 사용법을 금방 익힐 수 있었다. -P9-''&lt;br /&gt;
&lt;br /&gt;
:'''추가되었으면 하는 기능'''&lt;br /&gt;
 ''코스 예상시간이 표기되면 좋을 것 같다.   -P1-''&lt;br /&gt;
&lt;br /&gt;
 ''더 많은 산들에 대해서도 정보를 제공하면 좋을 것 같다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
 ''나와 비슷한 사용자들을 매칭해주는 기능이 있으면 좋을 것 같다.   -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''등산했던 등산로들을 모아서 저장하고 공유할 수 있는 기능이 있으면 좋을 것 같다.      -P12-''&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
서비스를 운영하는 데에 드는 비용은 도메인 유지 비용(10달러/1년), 라즈베리파이를 유지하기 위한 전기료 정도를 고려할 수 있다. 이는 페이지 내 배너 광고를 하나만 추가해도 상회할 수 있으며, 운영 비용 자체가 적기 때문에 수익을 계속 유지할 수 있으며, 유지보수 및 지속적인 개발 또한 가능할 것으로 보인다.&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
[[사진들어갈자리]]&lt;br /&gt;
&lt;br /&gt;
==자재소요서==&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
==개발사업비 내역서==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11901</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11901"/>
				<updated>2025-06-19T13:12:45Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 완료 작품의 소개 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:월별등산사고.png]] [[파일:원인별등산사고.png]]&lt;br /&gt;
&lt;br /&gt;
최근 산림청의 조사에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다. 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
[[파일:북한산탐방안내도.jpg|400픽셀]] [[파일:국립공원날씨_1672.jpg|500픽셀]]&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[1].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
[[내용]]&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. 그림 #은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. (테스트 환경: 라즈베리파이 5)&lt;br /&gt;
&lt;br /&gt;
[[사진들어갈자리1]]&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 자리]]&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다(그림#). 시뮬레이션 결과, 서버에 걸리는 부하는 그림 #과 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 부분]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다(See 그림x). 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:소프트웨어흐름도.png]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동화면.png|x200px]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
인터넷 탐색기에서 다음 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:사진명|섬네일|가운데|'''그림 7.''' 셰르파(Sherpa) 실행 방법]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도 (SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
[[파일:사진명|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[5]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시나리오 후 설문 (ASQ)'''&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_10&amp;quot;&amp;gt;'''그림 10.''' 시나리오 후 설문(ASQ)&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시나리오 후 설문([[#그림_10|[그림 10]]]은 각 Task를 수행하는 것이 얼마나 어려운지 확인하는 사용성 평가 방법이다[[#ref6|[6]]]. 우리는 우리 시스템에서 제공하는 주요 기능(개인 맞춤형 등산 목적지 추천, 개인 맞춤형 등산로 생성, 생성한 등산로 안내)을 쉽게 사용할 수 있는 지 확인하기 위하여 우리의 기능에 대응되는 Task를 만든 시나리오 후 설문을 진행했다. 설문 진행 결과, 우리가 제공하는 주요 기능이 모두 사용자가 쓰기 편하다는 것을 확인했다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''반구조화 인터뷰'''&lt;br /&gt;
우리는 추후 우리 앱을 개선하기 위하여, 앞선 두 개의 설문을 진행한 이후 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 묻는 반구조화 인터뷰를 진행했다. 주요한 내용은 다음과 같았다.&lt;br /&gt;
&lt;br /&gt;
:'''좋았던 점'''&lt;br /&gt;
 ''기존에 등산로 방향을 찾을 때 사진이 올라와 있는 블로그들을 많이 참조했는데, 직접적으로 방향을 알려주는 점이 좋았다.             -P7-''&lt;br /&gt;
&lt;br /&gt;
 ''아직 개인의 운동 수준과 등산로 난이도 스케일이 정확히 맞지는 않는 것 같지만, 어려운 등산로일수록 등산로 난이도가 어렵게 나오는 건 맞는 것 같다. 등산을 진행할 때 어느 정도 참고가 가능할 것 같다.      -P10- ''&lt;br /&gt;
&lt;br /&gt;
:'''개선할 점'''&lt;br /&gt;
 ''등산 목적지에 쉬운 코스가 없을 경우, 난이도를 쉽게 설정해도 어려운 코스가 나오는 문제점이 있다.   -P4-''  (해결됨)&lt;br /&gt;
&lt;br /&gt;
 ''위시리스트 담기라는 표현 자체가 잘 이해되지 않았다.      -P8-''&lt;br /&gt;
&lt;br /&gt;
 ''Navi 페이지에서 진행바가 새로고침할 때마다 리셋되는 것이 아쉬웠다.  -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''목적지 추천 부분에서 산 이름이 영어로 나오는 점이 아쉬웠다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
:'''UI 관련'''&lt;br /&gt;
 ''프로토타입 UI는 개인적으론 별 다른 것 없이 깔끔해서 좋았다.     -P2, P7-''&lt;br /&gt;
&lt;br /&gt;
 ''잡다한 기능이 없어서 사용법을 금방 익힐 수 있었다. -P9-''&lt;br /&gt;
&lt;br /&gt;
:'''추가되었으면 하는 기능'''&lt;br /&gt;
 ''코스 예상시간이 표기되면 좋을 것 같다.   -P1-''&lt;br /&gt;
&lt;br /&gt;
 ''더 많은 산들에 대해서도 정보를 제공하면 좋을 것 같다.   -P11-''&lt;br /&gt;
&lt;br /&gt;
 ''나와 비슷한 사용자들을 매칭해주는 기능이 있으면 좋을 것 같다.   -P12-''&lt;br /&gt;
&lt;br /&gt;
 ''등산했던 등산로들을 모아서 저장하고 공유할 수 있는 기능이 있으면 좋을 것 같다.      -P12-''&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
[[사진들어갈자리]]&lt;br /&gt;
&lt;br /&gt;
==자재소요서==&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
==개발사업비 내역서==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11899</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11899"/>
				<updated>2025-06-19T13:11:59Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 완료 작품의 소개 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:월별등산사고.png]] [[파일:원인별등산사고.png]]&lt;br /&gt;
&lt;br /&gt;
최근 산림청의 조사에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다. 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
[[파일:북한산탐방안내도.jpg|400픽셀]] [[파일:국립공원날씨_1672.jpg|500픽셀]]&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[1].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
[[내용]]&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. 그림 #은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. (테스트 환경: 라즈베리파이 5)&lt;br /&gt;
&lt;br /&gt;
[[사진들어갈자리1]]&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 자리]]&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다(그림#). 시뮬레이션 결과, 서버에 걸리는 부하는 그림 #과 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 부분]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다(See 그림x). 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:소프트웨어흐름도.png]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동화면.png|300px]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
인터넷 탐색기에서 다음 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:사진명|섬네일|가운데|'''그림 7.''' 셰르파(Sherpa) 실행 방법]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도(SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
[[파일:사진명|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[5]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
[[사진들어갈자리]]&lt;br /&gt;
&lt;br /&gt;
==자재소요서==&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
==개발사업비 내역서==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11898</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11898"/>
				<updated>2025-06-19T13:11:12Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 완료 작품의 소개 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:월별등산사고.png]] [[파일:원인별등산사고.png]]&lt;br /&gt;
&lt;br /&gt;
최근 산림청의 조사에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다. 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
[[파일:북한산탐방안내도.jpg|400픽셀]] [[파일:국립공원날씨_1672.jpg|500픽셀]]&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[1].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
[[내용]]&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. 그림 #은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. (테스트 환경: 라즈베리파이 5)&lt;br /&gt;
&lt;br /&gt;
[[사진들어갈자리1]]&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 자리]]&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다(그림#). 시뮬레이션 결과, 서버에 걸리는 부하는 그림 #과 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 부분]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다(See 그림x). 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:소프트웨어흐름도.png]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
[[파일:Dos-작동화면.png]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
인터넷 탐색기에서 다음 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:사진명|섬네일|가운데|'''그림 7.''' 셰르파(Sherpa) 실행 방법]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도(SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
[[파일:사진명|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[5]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
[[사진들어갈자리]]&lt;br /&gt;
&lt;br /&gt;
==자재소요서==&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
==개발사업비 내역서==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11896</id>
		<title>1분반-DOS</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=1%EB%B6%84%EB%B0%98-DOS&amp;diff=11896"/>
				<updated>2025-06-19T13:09:53Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 완료 작품의 소개 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==프로젝트 개요==&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' AI 기반 개인 맞춤형 등산로 추천 시스템&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' AI-based Personalized Hiking Trail Recommendation System&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
DOS&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
김성환 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2025년 3월 ~ 2025년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 이*영(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 문*서&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20209200** 장*빈&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
본 과제는 산림청 및 국립공원관리공단이 제공하는 신뢰도 높은 탐방로 데이터를 기반으로, 인공지능 기술을 활용하여 개인의 체력, 취향, 등산 경험에 최적화된 등산 목적지 및 코스를 추천하고 안내하는 시스템을 개발하는 것을 목표로 한다.&lt;br /&gt;
&lt;br /&gt;
초기 추천 시스템 구축을 위해 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)를 대상으로, 설문조사를 통해 등산객 106명의 사용자 개개인의 신체 능력과 등산 경험 등을 포함한 설문조사를 실시했다. 설문조사를 통해 수집한 신체 능력 및 등산 경험에 기반하여 사용자의 적정 난이도를 계산하는 알고리즘을 회귀분석으로 구현하였으며, 비슷한 성향을 가진 사람들이 자주 방문한 목적지를 추천하는 알고리즘을 인공지능 분류 모델을 이용하여 구현했다. &lt;br /&gt;
&lt;br /&gt;
또한, 사용자 맞춤형 등산로의 경우 경로 난이도를 우선으로 고려해 다익스트라 알고리즘으로 희망하는 등산로를 생성하는 기능을 구현했다. 등산로의 난이도는 등산로 정보(예: 등산로의 기울기)를 이용해 Tobler’s hiking function을 응용하여 계산하였다. 이를 바탕으로 사용자에게 적절한 난이도와 추천한 목적지, 사용자의 입산 위치와 퇴산 위치를 바탕으로 개인에 최적화된 등산로를 생성하고, 사용자의 위치에 기반하여 등산로를 안내하는 기능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
현재 개발 과제는 서울 지역 주요 산 4개소(북한산, 도봉산, 수락산, 관악산)에 대해서는 목적지 추천 기능까지 모두 제공하며, 대한민국의 주요 산 20여 개에 대해서는 등산로 추천 기능만 제공한다. 추후 각 산에 따른 사용자 데이터를 추가로 수집하여 범위를 확장할 계획이다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경 및 효과====&lt;br /&gt;
[[파일:월별등산사고.png]] [[파일:원인별등산사고.png]]&lt;br /&gt;
&lt;br /&gt;
최근 산림청의 조사에 따르면, 대한민국 전체 성인 남녀 중 약 78%가 한 달에 한 번 이상 등산을 즐기고 있다. 이처럼 등산은 국민 여가 활동의 중요한 부분을 차지하고 있다. 그러나 기존 등산 정보 제공 서비스들은 탐방로 정보의 신뢰성, 가독성, 그리고 사용자 맞춤형 추천 기능 등에서 한계를 보인다. 특히, 산림청과 같은 공공기관의 공식 데이터를 활용한 고품질 정보는 부족한 상황이며, 개인의 체력이나 운동 부하를 고려한 추천 시스템이 부재하여 사용자는 자신에게 적합한 코스를 찾기 어려운 실정이다.&lt;br /&gt;
&lt;br /&gt;
본 과제는 이러한 문제점을 해결하고자 산림청, 국립공원관리공단의 정밀한 탐방로 데이터를 기반으로 사용자가 손쉽게 접근할 수 있는 인터페이스를 제공하며, 인공지능 기술을 통해 개인 맞춤형 등산 코스를 추천하는 시스템을 개발하는 것이다. 이 시스템을 통해 등산객들은 보다 안전하고 효율적인 코스 선택이 가능해지며, 이로 인해 개인의 안전사고 예방 효과가 기대된다.&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
 정확하고 신뢰성 있는 탐방로 정보 제공&lt;br /&gt;
:산림청과 국립공원관리공단이 제공하는 공식 탐방로 데이터를 바탕으로, 사용자에게 명확하고 신뢰성 높은 정보를 제공하고자 한다. 이를 위해 사용자 인터페이스와 정보 구조를 재정비하고, 효과적인 데이터 시각화 기법을 도입하여 정보 접근성을 향상할 계획이다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 추천 시스템 구현&lt;br /&gt;
&lt;br /&gt;
:사용자의 기본 정보, 체력 상태, 운동 부하, 선호도 등 다양한 요소를 종합적으로 분석하여 개인에게 최적화된 등산 코스를 추천하는 AI 기반 알고리즘을 개발한다. 이를 위해 머신러닝 및 딥러닝 모델을 적용하고, 사용자의 피드백을 신속하게 반영할 수 있는 동적 학습 기능을 포함할 예정이다.&lt;br /&gt;
&lt;br /&gt;
 지속적 시스템 개선 및 사용자 만족도 증대&lt;br /&gt;
&lt;br /&gt;
:시스템 개발 완료 후에도 사용자 피드백과 평가를 지속적으로 수집·분석하여 정기적인 업데이트를 수행한다. 이를 통해 최신 정보와 최적의 추천 서비스를 제공하며, 사용자의 만족도를 지속적으로 향상하고자 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구체적인 개발 단계는 우선 탐방로 데이터의 정제 및 가공을 통해 데이터베이스를 구축하는 것으로 시작된다. 이후 사용자 프로파일링과 데이터 분석을 기반으로, 등산로와 사용자의 특성을 매칭하는 AI 알고리즘을 개발하고, 이를 챗봇 및 웹 기반 서비스로 개발할 것이다. 최종적으로 사용자 테스트와 파일럿 운영을 거쳐 상용화에 필요한 기술적, 기능적 보완을 진행하여, 실제 등산객들이 안정적으로 사용할 수 있는 완성도 높은 시스템을 구현할 예정이다.&lt;br /&gt;
&lt;br /&gt;
[[파일:북한산탐방안내도.jpg|400픽셀]] [[파일:국립공원날씨_1672.jpg|500픽셀]]&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
 등산로의 난이도 측정 알고리즘&lt;br /&gt;
:- 지형 데이터를 수치화하여 난이도를 정량적으로 산출하는 알고리즘이 활발히 연구되고 있음. &lt;br /&gt;
&lt;br /&gt;
:- Naismith의 법칙을 기반으로 하면 상승 고도와 수평 거리의 시간적 등가성을 계산할 수 있음[2].&lt;br /&gt;
&lt;br /&gt;
:- Tobler 함수는 경사에 따른 보행 속도를 지수 함수로 모델링해, 경로 탐색과 최적화에 활용됨[3].&lt;br /&gt;
&lt;br /&gt;
 추천 시스템&lt;br /&gt;
:- 추천 시스템은 다양한 응용 서비스 분야에서 활발히 사용되고 있다.&lt;br /&gt;
&lt;br /&gt;
:- 최근 연구들은 콘텐츠 기반 필터링, 협업 필터링 등 다양한 추천 모델을 활용하고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
:- 특히, 설문조사나 사용자 행동 데이터를 기반으로 한 개인화 추천 시스템이 각광받고 있음 [4].&lt;br /&gt;
&lt;br /&gt;
 사용자 위치 기반 경로 안내 기술&lt;br /&gt;
:- GPS, 고도계 등의 복합 센서를 활용해 실시간 사용자 위치를 추적하는 기술이 개발됨.&lt;br /&gt;
&lt;br /&gt;
:- 그러나, 실제 등산로와 사용자 방향을 실시간으로 분석해 비교하는 기술은 아직 존재하지 않음.&lt;br /&gt;
&lt;br /&gt;
 등산로 데이터 가공 및 시각화 기술&lt;br /&gt;
&lt;br /&gt;
:- 산림청에서는 등산로 데이터를 개방데이터로 공개하고 있음&lt;br /&gt;
&lt;br /&gt;
===기술 로드맵===&lt;br /&gt;
 1단계: 데이터 수집 및 구조화&lt;br /&gt;
:- 산림청 데이터를 정제하고, 필요 정보(경도, 위도, 경로 특성 등)를 추출하여 구조화된 DB 구축&lt;br /&gt;
:- 사용자 정보를 수집하기 위한 설문 시스템 기획 및 구축&lt;br /&gt;
 2단계: 기초 알고리즘 개발&lt;br /&gt;
:- Naismith 및 Tobler과 같은 실제 등산로 기반 난이도 산정 알고리즘 구현&lt;br /&gt;
:- 기본적인 목적지 및 경로 추천 알고리즘 프로토타입 개발&lt;br /&gt;
:- geojson 기반 등산로 시각화 모듈 제작&lt;br /&gt;
 3단계: 개인화 및 실시간 시스템 통합&lt;br /&gt;
:- 사용자 운동 경험, 연령, 희망 난이도 등 특성 기반 추천 시스템 고도화 (머신러닝 적용)&lt;br /&gt;
:- 난이도 예측 알고리즘과 사용자 선호도 매칭을 통한 개인 맞춤형 경로 추천 기능 구현&lt;br /&gt;
:- 실시간 경로 안내 알고리즘 구현&lt;br /&gt;
   &lt;br /&gt;
===특허 조사===&lt;br /&gt;
 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법&lt;br /&gt;
:- GPS 수신기와 산악 전자지도 DB를 내장한 휴대용 등산 내비게이션 단말기를 이용해 안내&lt;br /&gt;
 산림 빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법&lt;br /&gt;
:- 트레킹부터 시작하여 산림 빅데이터를 사용할 때 시스템의 구성에 관한 특허&lt;br /&gt;
&lt;br /&gt;
===특허 전략===&lt;br /&gt;
 사용자 맞춤의 구체적인 방식에 대한 차별화 전략&lt;br /&gt;
:- 기존 특허가 포괄적으로 ‘산림 빅데이터’와 ‘사용자 맞춤 서비스’까지 청구항으로 포함하고 있어, 동작 과정의 구체적인 방식에 주목해 차별화를 시도할 예정임&lt;br /&gt;
&lt;br /&gt;
 구체적인 청구 전략&lt;br /&gt;
:- Naismith, Tobler 등 복수의 등산 시간/속도 모델을 활용해 등산로의 난이도를 산정할 수 있음&lt;br /&gt;
:- 운동 경험, 연령, 성별, 선호 강도를 통해 사용자의 희망 난이도를 산정할 수 있음&lt;br /&gt;
:- 등산로의 난이도와 사용자의 희망 난이도를 매칭하여 경로를 추천할 수 있음&lt;br /&gt;
&lt;br /&gt;
===관련 시장에 대한 분석===&lt;br /&gt;
====경쟁제품 조사 비교====&lt;br /&gt;
 네이버 지도&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 서비스의 인터페이스가 사용자 친화적이다.&lt;br /&gt;
::- 사용자의 리뷰를 볼 수 있다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 경사도, 통제 등의 상세한 등산로 정보를 제공하지 않는다.&lt;br /&gt;
::- 코스 정보가 구간 단위로 파편화되어 있어 사용자가 전체 등산로에 대한 정보를 알기 어렵다.&lt;br /&gt;
&lt;br /&gt;
 국립공원공단 홈페이지&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 상세한 등산로 정보를 제공한다.&lt;br /&gt;
::- 정확한 등산로 정보를 제공한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- UI의 가독성이 떨어진다.&lt;br /&gt;
::- 같은 등산로에 대한 정보가 여러 페이지에 흩어져 있어 사용자가 등산로 정보를 한눈에 알아보기 힘들다.&lt;br /&gt;
 트랭글&lt;br /&gt;
:'''장점'''&lt;br /&gt;
::- 실제 사용자 데이터를 기반으로 등산로 데이터를 제공한다.&lt;br /&gt;
::- Gamification을 통해 사용자에게 등산에 대한 동기를 부여한다.&lt;br /&gt;
:'''단점'''&lt;br /&gt;
::- 등산로 데이터를 사용자가 직접 입력하기 때문에 정보의 신뢰성이 부족하다.&lt;br /&gt;
::- 비인기 코스에 대한 등산로 정보가 부족하다.&lt;br /&gt;
::- 핵심 기능(예: Gamification)을 유료로 제공하고 있다.&lt;br /&gt;
   &lt;br /&gt;
====마케팅 전략====&lt;br /&gt;
 좋은 사용성을 유지하면서도 정확하고 자세한 등산 경로를 추천하는 서비스를 제공한다.&lt;br /&gt;
:- 네이버 지도의 경우는 좋은 사용성을 가졌으나 전체 등산로 정보를 알기 어렵다.&lt;br /&gt;
:- 국립공원공단 홈페이지는 정확하고 자세한 등산 경로를 제공하나, 사용성이 나쁘다.&lt;br /&gt;
:- 트랭글은 사용성이 좋으나, 정보의 신뢰성이 부족하다.&lt;br /&gt;
:- 우리 서비스는 선행 서비스를 따라잡기 위하여 좋은 사용성에 대한 점검을 철저히 할 계획이다.&lt;br /&gt;
 사용자 개개인의 특성 및 난이도에 맞추어 정보를 제공한다.&lt;br /&gt;
:- 사용자 개개인의 특성에 기반하여 등산 목적지를 추천한다.&lt;br /&gt;
:- 사용자의 운동 수준 및 희망 수준, 등산 목적지를 고려하여 등산로를 생성하여 제공한다.&lt;br /&gt;
:- 이는 선행 서비스에서 제공하지 않는 부분이다.&lt;br /&gt;
 등산로에 대한 정확한 정보를 적절하게 제공한다.&lt;br /&gt;
:- 산림청에 따르면 많은 산악사고가 등산로에 대한 정보 부족 때문에 발생한다[1].&lt;br /&gt;
:- 잠재적 사용자(예: 등산객)를 대상으로 조사해본 결과, 블로그 등의 신뢰성을 보장할 수 없는 출처에서 등산로 정보를 얻는다는 점을 발견했다.&lt;br /&gt;
:- 또한, 등산로 내 표지판 부족으로 다른 등산객들이 직접 표지판을 만드는 경우도 많다.&lt;br /&gt;
:- 산악구조대 소속 전문가 인터뷰 결과, 등산로의 방향을 적절한 때에 제공하면 등산 중 사고가 줄어들 것이라는 의견을 받았다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:위의 마케팅 전략을 바탕으로, 우리는 다음과 같은 기능을 제공한다.&lt;br /&gt;
::- 사용자 정보 입력 기능&lt;br /&gt;
::- 사용자 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
::- 사용자 맞춤형 등산로 생성 기능&lt;br /&gt;
::- 등산로 안내 기능&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
 등산로 데이터 가공 및 구조화 기술 확보&lt;br /&gt;
:산림청에서 제공하는 등산로 geojson 데이터를 기반으로, 향후 다양한 등산 관련 서비스의 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 난이도 분석 알고리즘 개발&lt;br /&gt;
:등산로의 길이, 고도차, 경사, 재질 등의 데이터를 종합하여 산행 난이도를 정량화하여, 사용자에게 맞춤형으로 제공할 수 있는 기술적 기반을 마련할 수 있다.&lt;br /&gt;
 등산 경로 안내 기술 확보&lt;br /&gt;
:가공한 등산로 데이터를 사용자에게 내비게이션과 유사한 방식으로 사용자에게 제공하여 등산로  정보를 가독성 있게 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
[[내용]]&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
[[내용]]&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===사용자 요구사항===&lt;br /&gt;
====기능적 요구사항====&lt;br /&gt;
 R1: 개인 정보 입력 기능&lt;br /&gt;
:- 사용자는 등산 목적지 추천 및 경로 생성을 위해 키, 체중, 성별, 등산 빈도, 선호 목적(예: 운동, 경치, 휴식) 등의 정보를 입력할 수 있어야 한다.&lt;br /&gt;
 R2: 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:- 시스템은 사용자가 입력한 신체 정보와 등산 경험 데이터를 바탕으로, 유사한 사용자들이 선호한 등산 목적지를 추천할 수 있어야 한다.&lt;br /&gt;
 R3: 출발 및 도착 지점 선택 기능&lt;br /&gt;
:- 사용자는 지도상에서 자신이 원하는 입산 지점과 하산 지점을 선택할 수 있어야 한다.&lt;br /&gt;
 R4: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:- 시스템은 사용자의 체력 수준 및 희망 난이도와 등산로의 기울기, 고도, 재질 등의 정보를 고려하여 최적의 등산 경로를 생성해야 한다.&lt;br /&gt;
 R5: 실시간 등산로 안내 기능&lt;br /&gt;
:- 시스템은 GPS를 기반으로 사용자의 현재 위치를 표시하고, 등산 도중 갈림길이나 분기점에서 방향을 알려주는 기능을 제공해야 한다.&lt;br /&gt;
&lt;br /&gt;
====비기능적 요구사항====&lt;br /&gt;
 R6: 사용성 (Usability)&lt;br /&gt;
:- 사용자 인터페이스는 직관적이고 사용자가 각 기능을 쉽게 사용할 수 있어야 한다.&lt;br /&gt;
 R7: 응답 속도 (Performance)&lt;br /&gt;
:- 등산 목적지 추천 기능 및 등산로 생성 기능은 각각 2초 이내에 처리되어야 한다.&lt;br /&gt;
 R8: 신뢰성 (Reliability)&lt;br /&gt;
:- 시스템은 산림청에서 제공한 등산로 데이터에 기반하여 정확한 정보를 제공해야 한다.&lt;br /&gt;
 R9: 확장성 (Scalability)&lt;br /&gt;
:- 추후 더 많은 산과 사용자 데이터를 추가할 수 있도록 시스템 구조는 확장 가능해야 한다.&lt;br /&gt;
&lt;br /&gt;
===사용자 요구사항 만족을 위한 기능 정의 및 기능별 정량목표 ===&lt;br /&gt;
 F1: 개인 맞춤형 등산 목적지 추천 기능&lt;br /&gt;
:'''기능 정의''' &lt;br /&gt;
::사용자가 입력한 키, 체중, 등산 빈도, 선호 목적 등 개인 정보를 바탕으로, 유사 사용자군이 선호한 목적지를 인공지능 모델을 통해 추천한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 추천 결과 정확도: 95% 이상 (실제 등산 목적지 도달 성공률 기준)&lt;br /&gt;
::- 평균 응답 시간: 2초 이내&lt;br /&gt;
::- 사용자 만족도: SUS 점수 상위 5%&lt;br /&gt;
 F2: 개인 맞춤형 등산로 생성 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자의 희망 목적지와 입산/퇴산 지점 정보를 바탕으로, 산림청 등산로 데이터를 활용하여 사용자 난이도에 맞는 최적 경로를 생성한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 경로 생성 시간: 2초 이내&lt;br /&gt;
::- 개인 맞춤형 등산로 생성 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F3: 실시간 등산 경로 안내 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::GPS 위치 정보를 기반으로, 사용자가 현재 위치에서 어떤 방향으로 이동해야 하는지를 이미지로 안내한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 사용자 위치와 GPS 표기 위치 간 차이 15m 이내&lt;br /&gt;
::- 안내 정확도: 99% 이상 (등산로 갈림길 방향 일치 여부)&lt;br /&gt;
 F4: 사용자 정보 입력 기능&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::사용자가 자신의 정보를 손쉽게 입력할 수 있는 입력 양식을 제공한다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 입력 완료 소요 시간: 2분 이내&lt;br /&gt;
::- 사용자 정보 입력 기능에 대한 ASQ 평가 결과 6점 이상&lt;br /&gt;
 F5: 시스템 성능 및 신뢰성 목표&lt;br /&gt;
:'''기능 정의'''&lt;br /&gt;
::전체 시스템이 모바일 환경에서 원활히 작동하고, 여러 사용자가 동시에 요청하더라도 서버 부하 없이 빠르게 응답하도록 구성된다.&lt;br /&gt;
:'''정량 목표'''&lt;br /&gt;
::- 동시 요청 처리량: 10명 기준 초당 5건 이상&lt;br /&gt;
::- 평균 응답 시간: 2초&lt;br /&gt;
::- 시스템 실패율: 0% (100회 요청 기준)&lt;br /&gt;
&lt;br /&gt;
===기능 구현을 위한 세부기술 선택사항 (디자인) ===&lt;br /&gt;
 서버 및 클라이언트 프레임워크&lt;br /&gt;
:프론트엔드는 React를 활용하여 사용자 인터페이스를 구성하였다. 백엔드는 Python의 FastAPI를 사용하여 경량화된 RESTful API 서버를 구현하였다. FastAPI는 비동기 처리와 빠른 응답 속도를 제공한다. 컴포넌트 기반의 설계로 유지보수와 확장성이 뛰어나며, 사용자 경험(UX)을 고려한 동적 페이지 처리가 용이하다.&lt;br /&gt;
&lt;br /&gt;
 하드웨어 인프라 구성&lt;br /&gt;
:라즈베리파이 5를 서버로 사용하여 저전력 환경에서도 동작할 수 있도록 구성하였다. 서버의 부하를 분산시키기 위해 파일 서버, 프론트엔드, 백엔드 각각 1개씩 총 3개의 라즈베리파이를 사용하였으며, 이를 통해 트래픽 분산과 장애 시 대체 가능성 확보 등 관리 용이성을 강화하였다.&lt;br /&gt;
&lt;br /&gt;
 경로 탐색 알고리즘 설계&lt;br /&gt;
:등산로 생성 기능에서는 Tobler’s hiking function을 활용하여 등산로의 난이도를 산출한다. 산출된 난이도를 바탕으로 다익스트라(Dijkstra) 알고리즘을 사용하였다. 이를 통해 등산로 특성을 고려한 사용자 맞춤형 최적 경로를 생성할 수 있도록 설계하였다.&lt;br /&gt;
&lt;br /&gt;
 지도 시각화 도구&lt;br /&gt;
:등산 경로의 시각화 및 지도 기능 구현에는 Leaflet.js와 OpenStreetMap을 사용하였다. 이를 통해 사용자에게 직관적이고 반응성이 뛰어난 지도 UI를 제공한다. 또한, 지도상에 경로 및 분기점을 효과적으로 표시할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===시스템 설계===&lt;br /&gt;
 클라이언트 (프론트엔드)&lt;br /&gt;
:'''구현 기술: React'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 정보 입력&lt;br /&gt;
::- 지도 기반의 등산 경로 표시 (Leaflet.js + OpenStreetMap)&lt;br /&gt;
::- 추천 경로 결과 시각화 및 반응형 UI 구성&lt;br /&gt;
 API 서버 (백엔드)&lt;br /&gt;
:'''구현 기술: FastAPI'''&lt;br /&gt;
:'''주요 역할'''&lt;br /&gt;
::- 사용자 요청 처리 (등산로 추천, 등산 경로 요청 등)&lt;br /&gt;
::- 경로 탐색 알고리즘 실행 (Dijkstra 기반)&lt;br /&gt;
::- 서버는 RESTful API 형태로 구현되어 있으며, 데이터는 JSON 형식으로 주고받는다.&lt;br /&gt;
 데이터베이스 및 경로 데이터 처리&lt;br /&gt;
::- 사용자 정보 및 등산로 데이터를 저장 및 관리한다.&lt;br /&gt;
::- 산 데이터에는 등산로 전체 경로, 분기점 등의 속성이 포함되어 있다.&lt;br /&gt;
::- 등산로는 좌표 데이터를 기반으로 Leaflet 상에 Polyline 객체로 변환되어 시각화된다.&lt;br /&gt;
::- 좌표, 난이도 등의 속성이 포함되어 있으며, 알고리즘 수행 시 가중치로 사용된다.&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
[[파일:산_데이터_통계_1672.jpg|800픽셀]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템의 등산로 생성 기능에는 다익스트라(Dijkstra) 알고리즘이 사용되었으며, 알고리즘의 이론적 시간 복잡도 (: 정점 수, : 간선 수)이다. 그림 #은 각 산에 존재하는 등산로의 정점과 간선을 나타내는데, 각 산의 데이터가 크지 않음을 확인할 수 있다. 정점과 간선 개수가 많을수록 등산로 생성이 오래 걸리는데, 정점과 간선 개수가 가장 많은 팔공산 비로봉(정점 334개, 간선 405개를 기준으로 최장 거리 구간 탐색을 수행해도 소요 시간은 약 0.0005초에 불과했다. (테스트 환경: 라즈베리파이 5)&lt;br /&gt;
&lt;br /&gt;
[[사진들어갈자리1]]&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 지표 !! 동시 사용자 10명 (100회 평균)&lt;br /&gt;
|-&lt;br /&gt;
| 처리량(요청/초) || 9.24개/초&lt;br /&gt;
|-&lt;br /&gt;
| 평균 응답 시간 || 1,081.9 ms (약 1.08초)&lt;br /&gt;
|-&lt;br /&gt;
| 연결 설정 시간 || 7.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 서버 대기 시간 || 982.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 처리 완료 시간 || 1019.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| 총 소요 시간 || 1025.0 ms&lt;br /&gt;
|-&lt;br /&gt;
| P50 (상위50%) || 1066 ms&lt;br /&gt;
|-&lt;br /&gt;
| P90 (상위90%) || 1482 ms&lt;br /&gt;
|-&lt;br /&gt;
| P95 (상위95%) || 1512 ms&lt;br /&gt;
|-&lt;br /&gt;
| P100 (상위100%) || 1517 ms&lt;br /&gt;
|-&lt;br /&gt;
| 실패율 || 0%&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 자리]]&lt;br /&gt;
&lt;br /&gt;
:실제 서비스를 위하여, 한 번에 많은 등산로 추천 요청을 받는 경우를 테스트했다(그림#). 시뮬레이션 결과, 서버에 걸리는 부하는 그림 #과 같았다. 1초에 약 9개 정도의 요청을 처리할 수 있는 것을 확인했으며, 평균 응답 시간은 1.08초였고, 최대 응답 시간은 1.52초였다. 우리가 제시했던 최대 응답 시간은 2초 이내로, 실제 부하가 있는 환경에서도 개발한 서비스가 제시했던 기준을 충족함을 확인했다.&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
====하드웨어 설계====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 구분 !! 사양&lt;br /&gt;
|-&lt;br /&gt;
| 모델 || Raspberry Pi 5 (8GB RAM)&lt;br /&gt;
|-&lt;br /&gt;
| CPU || Quad-core Cortex-A76 @ 2.4GHz&lt;br /&gt;
|-&lt;br /&gt;
| GPU || VideoCore VII (800 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| RAM || 8GB LPDDR4X&lt;br /&gt;
|-&lt;br /&gt;
| Storage || 64GB microSD&lt;br /&gt;
|-&lt;br /&gt;
| Network || 1Gbps Ethernet, Wi-Fi 802.11ac, Bluetooth 5.0&lt;br /&gt;
|-&lt;br /&gt;
| I/O || USB 3.0 x 2, USB 2.0 x 2, GPIO, HDMI × 2&lt;br /&gt;
|-&lt;br /&gt;
| 전원 || USB-C (5V 5A), 평균 소비 전력 약 15W&lt;br /&gt;
|}&lt;br /&gt;
[[설명 들어갈 부분]]&lt;br /&gt;
&lt;br /&gt;
:본 시스템에 사용한 라즈베리파이 5의 성능은 다음과 같았다(See 그림x). 총 라즈베리파이 5 (8GB 모델) 3대를 활용하였으며, 프론트엔드 서버(React 앱 서빙 및 정적 자원 제공), 백엔드 API 서버(FastAPI, 경로 추천, 사용자 데이터 처리), 데이터 서버(등산로 데이터, 이미지 저장 및 처리)로 역할을 분리한 구조로 설계되었다. 각 장비는 물리적으로 독립된 하드웨어로 구성되며, 동일 네트워크상의 라우터를 통해 상호 연결되어 있다. &lt;br /&gt;
&lt;br /&gt;
:이러한 구조는 저전력으로 운용할 수 있다는 장점을 가질 뿐만 아니라, 마이크로서비스 형태로의 확장이 용이하며, 장애 분리 및 병렬 처리가 가능하다는 장점이 있다. 각 장비는 SSH 접속을 통해 원격에서 제어 및 유지관리가 가능하도록 설정되어 있다.&lt;br /&gt;
&lt;br /&gt;
====소프트웨어 설계====&lt;br /&gt;
본 시스템은 사용자 맞춤형 등산로 추천 기능을 중심으로 한 웹 기반 등산로 내비게이션 시스템으로, 다양한 소프트웨어(예: 프론트엔드 등)으로 이루어진다.&lt;br /&gt;
&lt;br /&gt;
 전체 아키텍처 설계&lt;br /&gt;
:시스템은 클라이언트-서버 구조를 기반으로 하며, 주요 구성은 다음과 같다.&lt;br /&gt;
::- 클라이언트 서버(프론트엔드): React 기반으로 구현되어 사용자 정보 입력, 등산로 시각화, 경로 추천 결과 출력, 등산로 안내 기능을 제공한다.&lt;br /&gt;
::- API 서버(백엔드): FastAPI를 사용하여 사용자 입력 정보를 처리하고, 등산로 경로 생성 및 경로 안내를 수행한다.&lt;br /&gt;
::- 데이터베이스 서버: 산림청 제공 데이터 및 2차 가공 데이터(예: 등산로 데이터) 등이 저장된다.&lt;br /&gt;
::- 서버 인프라: 라즈베리파이 5 장비 3대를 병렬 구성하여 백엔드, 프론트엔드, 데이터 서버로 분리 운영하며, 저전력 기반에서도 충분한 성능을 제공한다.&lt;br /&gt;
&lt;br /&gt;
 주요 기능별 설계&lt;br /&gt;
:'''개인 맞춤형 목적지 추천'''&lt;br /&gt;
::- 사용자로부터 성별, 키, 체중, 등산 빈도, 등산 목적 등의 정보를 입력받는다.&lt;br /&gt;
::- 회귀분석 기반의 운동 수준 계산 알고리즘과 인공지능 분류 모델을 사용하여 유사한 사용자들이 선호했던 목적지를 추천한다.&lt;br /&gt;
:'''개인 맞춤형 등산로 생성'''&lt;br /&gt;
::- 사용자의 체력 지수 및 희망 난이도, 시작 지점과 종료 지점을 바탕으로 등산로를 선택한다.&lt;br /&gt;
::- 등산로의 난이도는 Tobler’s Hiking Function을 응용하여, 기울기와 고도차 등의 정보를 기반으로 계산한다.&lt;br /&gt;
::- Dijkstra 알고리즘을 이용하여 난이도 기반 가중치를 고려한 최적 경로를 탐색한다.&lt;br /&gt;
:'''실시간 등산로 안내 기능'''&lt;br /&gt;
::- 사용자의 GPS 위치를 기반으로 등산로 진행 방향을 시각적 이미지로 제공한다.&lt;br /&gt;
::- 산 내부 갈림길에서의 방향 정보를 제공하여, 표지판이 부족한 지역에서도 올바른 경로를 안내한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:소프트웨어흐름도.png]]&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
&lt;br /&gt;
[[File:Dos-작동화면.png|thumb|설명]]&lt;br /&gt;
&lt;br /&gt;
 개인 정보 입력&lt;br /&gt;
:사용자는 자신의 키, 체중 및 등산 빈도, 등산 목적과 같은 정보를 입력한다. &lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산 목적지 추천&lt;br /&gt;
:앞서 입력된 개인 정보를 바탕으로 과거 유사한 사용자들이 선호했던 목적지들을 추천한다. &lt;br /&gt;
:사용자는 추천된 목적지들을 저장하고 이를 바탕으로 개인 맞춤형 등산로 생성 기능에서 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
 개인 맞춤형 등산로 생성&lt;br /&gt;
:사용자는 개인 맞춤형 등산 목적지 추천 기능에서 선택한 등산 목적지들의 등산 시작 지점, 등산 종료 지점을 확인할 수 있다. &lt;br /&gt;
:이후 등산 시작 지점, 등산 종료 지점을 선택하고, 희망 난이도(매우 쉽게- 매우 어렵게)를 선택한다. &lt;br /&gt;
:시스템은 등산 목적지, 사용자 운동 수준 및 사용자의 희망 난이도, 그리고 입력받은 등산 시작 지점 및 등산 종료 지점을 바탕으로 개인 맞춤형 등산로를 생성한다. &lt;br /&gt;
&lt;br /&gt;
 생성한 등산로 안내&lt;br /&gt;
:앞서 개인 맞춤형 등산로 생성 과정에서 생성한 등산로에 대해 사용자에게 안내하는 기능을 제공한다. &lt;br /&gt;
:산 내부의 갈림길에서 표지판이 없는 경우가 있어 해당 기능을 제공하게 되었으며, 각 갈림길에서 진행해야 할 방향을 사용자에게 안내한다. &lt;br /&gt;
:사용자는 자신의 현재 위치에 기반하여 정보를 받을 수 있고, 길을 잘못 들었을 경우 GPS를 통해 이를 확인하고 되돌아갈 수 있다.&lt;br /&gt;
&lt;br /&gt;
===실행 방법 (Run)===&lt;br /&gt;
인터넷 탐색기에서 다음 주소를 입력하여 바로 실행할 수 있다. &lt;br /&gt;
모바일 환경에 최적화되어 있다.&lt;br /&gt;
&lt;br /&gt;
[https://uos-dos.shop/ 셰르파(Sherpa)]&lt;br /&gt;
[[파일:사진명|섬네일|가운데|'''그림 7.''' 셰르파(Sherpa) 실행 방법]]&lt;br /&gt;
&lt;br /&gt;
===완료 작품의 평가===&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ 표 3. 완료 작품 평가 항목 및 결과&lt;br /&gt;
|-&lt;br /&gt;
! 평가 항목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발 목표치&lt;br /&gt;
! 비중 (%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 정보의 정확성&lt;br /&gt;
| 평가용 질문 &amp;amp; 답변&amp;lt;br&amp;gt;실제 등산을 통한 확인&lt;br /&gt;
| 정확도 (100%)&lt;br /&gt;
| 99%&lt;br /&gt;
| 50&lt;br /&gt;
| 97.2%&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 만족도&lt;br /&gt;
| 시스템 사용성 척도(SUS)&amp;lt;br&amp;gt;시나리오 후 설문(ASQ)&lt;br /&gt;
| 만족도 (5점)&amp;lt;br&amp;gt;점수 (7점)&lt;br /&gt;
| SUS 4점&amp;lt;br&amp;gt;ASQ 5.5점&lt;br /&gt;
| 30&lt;br /&gt;
| SUS 상위 5%&amp;lt;br&amp;gt;ASQ 6.67점&lt;br /&gt;
|-&lt;br /&gt;
| 3. 유지보수 가능성&lt;br /&gt;
| 서비스를 운용하는 데&amp;lt;br&amp;gt;들어가는 비용 &amp;amp; 수익 비교&lt;br /&gt;
| -&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
| 20&lt;br /&gt;
| 수익&amp;gt;비용&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====정보의 정확성====&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|+ &amp;lt;span id=&amp;quot;표_4&amp;quot;&amp;gt;표 4. 생성한 등산로의 각 목적지별 정확도&amp;lt;/span&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! 목적지&lt;br /&gt;
! 정확도&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 정상&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 내원암&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 수락산 도정봉&lt;br /&gt;
| 100%&lt;br /&gt;
|-&lt;br /&gt;
| 북한산 사모바위&lt;br /&gt;
| 97%&lt;br /&gt;
|-&lt;br /&gt;
| 노고산 정상&lt;br /&gt;
| 89%&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
실제 등산로 안내 기능을 활용해 등산을 진행하며, 서비스에서 표시되는 화살표의 방향이 실제 진행해야 할 방향과 일치하는지를 확인하였다([[#표_4|표 4]]). 수락산에서는 기능이 정상적으로 동작하여 100%의 정확도를 보였다. &lt;br /&gt;
&lt;br /&gt;
북한산 사모바위의 경우 97%의 정확도를 보였는데 33개의 갈림길에 대해 생성된 33개의 화살표 이미지 중 한 개의 화살표에 문제가 있었다. 실제 상황은 사거리에서 직진해야 하는 구조였으나, 좌측 8시 방향 탐방로가 표시되지 않아, 시스템상에서는 삼거리에서 직진하는 이미지가 생성되었다. 8시 방향 탐방로가 반영되지 않은 이유는 해당 구간이 이용이 금지된 비법정 탐방로로, 산림청 제공 데이터에 포함되어 있지 않았기 때문이다. 사거리가 삼거리로 표시되어 사용자에게 혼란을 줄 가능성은 있으나, 진행 방향은 정상적으로 안내되었고, 제공되지 않은 비법정 탐방로로 인해 실제 등산 과정에서 문제는 발생하지 않았다.&lt;br /&gt;
&lt;br /&gt;
노고산 정상의 경우, 89%의 정확도를 보였다. 27개의 갈림길 중 초반 24개의 갈림길에 대해서는 화살표 이미지가 전부 정확하게 생성되었으나 후반 3개의 갈림에 대한 화살표 이미지가 생성되지 않았다. 이미지가 생성되지 않은 이유는, 산림청 제공 데이터에서 24번째 갈림길 이후의 등산로 데이터가 누락되어 있었기 때문이다. 다만, 24번째 갈림길까지는 정확한 길을 제시하였기 때문에 정상까지의 모든 길을 안내해 주지는 못하였으나, 잘못된 길로 안내하지도 않았다.&lt;br /&gt;
&lt;br /&gt;
정보 누락의 원인으로는 두 가지 가능성을 고려할 수 있다. &lt;br /&gt;
&lt;br /&gt;
 첫째, 노고산은 국립공원에 속하지 않는 양주시 관할 등산로이기 때문에, 산림청과 기초지방자치단체(양주시) 간의 정보 공유 및 연계가 원활하지 않았을 가능성이 있다. &lt;br /&gt;
 둘째, 노고산은 상대적으로 탐방객 수가 적은 저명도 산지로, 양주시에서 등산로를 체계적으로 조사하거나 디지털화하여 외부 기관에 제공하는 데에 적극적이지 않았을 가능성도 존재한다.&lt;br /&gt;
&lt;br /&gt;
실제 평가 결과 다섯 개의 평균은 97.2%로, 기존 개발 목표치였던 99%보다 떨어졌으나, 실제 등산 과정에서 사용자에게 치명적인 혼란이나 위험을 유발하지는 않았다는 점에서 기능의 기본적인 유효성은 확보되었음을 확인할 수 있다. 특히, 수락산과 같은 정비된 등산로에서는 화살표 이미지와 실제 경로가 완전히 일치하였고, 북한산도 단일 예외 사례를 제외하면 전반적으로 신뢰할 수 있는 결과를 보였다.&lt;br /&gt;
&lt;br /&gt;
====사용자 만족도====&lt;br /&gt;
우리는 프로토타입의 추천 시스템의 초기 데이터로 사용하기 위해 106명의 등산객을 대상으로 설문조사를 진행하였다. 평가 인원을 모집하기 위하여 설문조사에 참여했던 등산객들에게 이메일, 전화번호를 이용해 사용자 평가 인원을 모집했다. 모집한 사용자들을 대상으로 사용자 만족도를 평가하고, 개발한 시스템을 개선하기 위하여 12명의 사용자를 대상으로 노고산(4명), 수락산(8명)에서 두 번의 평가를 진행했다. 사용자들은 실제로 등산 전에 3분 이내로 우리 시스템을 사용할 시간을 제공받고, 우리 시스템을 사용해 다음 Task를 수행했다([[#그림_8|그림 8]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[파일:사진명.jpg|섬네일|가운데|&amp;lt;span id=&amp;quot;그림_8&amp;quot;&amp;gt;'''그림 8.''' ASQ(시나리오 후 설문)에서 각 기능을 평가하기 위한 Task들&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Task를 수행한 이후, 각 Task와 시스템의 사용성에 대해 질문한 후, 등산을 진행하면서 반구조화된 인터뷰를 수행하여 우리 앱의 좋았던 점, 개선할 점, UI, 추가되었으면 하는 기능을 전달받았다. 인터뷰 내용은 녹음을 통해 확인하였으며, 대본으로 바꾼 이후 즉시 녹음 파일을 삭제하였다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''시스템 사용성 척도(SUS) [[#ref5|[5]]]'''&lt;br /&gt;
&lt;br /&gt;
[[파일:사진명|섬네일|가운데|&amp;lt;span id=&amp;quot;그림 9&amp;quot;&amp;gt;'''그림 9.''' System Usability Scale(SUS) 10개 문항(1점 : 매우 동의하지 않는다, 5점 : 매우 동의한다). 오른쪽의 환산 점수가 각 문항별 우리 시스템의 사용성 점수이다.&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도([[#그림_9|그림 9]])는 시스템의 사용성을 빠르게 평가하기 위해 고안된 설문지이다. &lt;br /&gt;
&lt;br /&gt;
시스템 사용성 척도는 10개의 Likert-scale 문항으로 구성되어 있으며, 홀수 문항은 점수가 높을수록, 짝수 항목은 점수가 낮을수록 높은 사용성을 의미한다[5]. 짝수 문항은 (6 – 점수)를 통해 환산 점수를 산출하며, 을 통해 시스템의 사용성 점수를 도출할 수 있다. 사용성은 84.1점 이상일 경우, 상위 5%의 사용성(Best imaginable)을 가진다. 실제 사용성 평가 결과 우리 시스템의 사용성은 91.8점이 나왔으며, 좋은 사용성을 가졌다는 것을 확인하였다.&lt;br /&gt;
&lt;br /&gt;
====유지보수 가능성====&lt;br /&gt;
&lt;br /&gt;
===향후 평가===&lt;br /&gt;
&lt;br /&gt;
==개발 사업비 정산==&lt;br /&gt;
[[사진들어갈자리]]&lt;br /&gt;
&lt;br /&gt;
==자재소요서==&lt;br /&gt;
 서비스를 제공할 도메인&lt;br /&gt;
:10달러/1년의 비용이 발생하며, 서비스를 하기 위하여 항상 필요하다. (현재 사비로 지출)&lt;br /&gt;
&lt;br /&gt;
 라즈베리 파이 5  &lt;br /&gt;
:백엔드, 프론트엔드, 데이터 각각의 서버를 구동하기 위하여 총 3개가 사용되었으며, 마찬가지로 없으면 서비스가 불가능하다.&lt;br /&gt;
==개발사업비 내역서==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;text-align:right&amp;quot; | (단위 : 천원)&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 항목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! 수량&lt;br /&gt;
! 단가&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | 금액&lt;br /&gt;
! 비고&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 직접 개발비&lt;br /&gt;
| 라즈베리 파이 5 || 3 || 130 || 390 || 390 || &lt;br /&gt;
|-&lt;br /&gt;
| 합계 || || || 390 || 390 || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 부록 ==&lt;br /&gt;
&lt;br /&gt;
=== A-1 참고문헌 및 참고사이트 ===&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref1&amp;quot;&amp;gt;[1]&amp;lt;/span&amp;gt; 산림청. (2022년 8월 2일). 우리나라 성인 78% 한 달에 한 번 이상 산에 간다. 대한민국 정책 브리핑. https://www.korea.kr/news/policyNewsView.do?newsId=148911465  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref2&amp;quot;&amp;gt;[2]&amp;lt;/span&amp;gt; Scarf, P. (2007). Route choice in mountain navigation, Naismith's rule, and the equivalence of distance and climb. ''Journal of Sports Sciences, 25''(6), 719–726.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref3&amp;quot;&amp;gt;[3]&amp;lt;/span&amp;gt; Goodwin, A., Hammett, M., &amp;amp; Harris, M. (2025). The application of Tobler's hiking function in data-driven traverse modelling for planetary exploration. ''Acta Astronautica, 228,'' 265–273.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref4&amp;quot;&amp;gt;[4]&amp;lt;/span&amp;gt; Ko, H., Lee, S., Park, Y., &amp;amp; Choi, A. (2022). A survey of recommendation systems: recommendation models, techniques, and application fields. ''Electronics, 11''(1), 141.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref5&amp;quot;&amp;gt;[5]&amp;lt;/span&amp;gt; Brooke, J. (2013). SUS: a retrospective. ''Journal of usability studies, 8''(2).  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ref6&amp;quot;&amp;gt;[6]&amp;lt;/span&amp;gt; Qualaroo. How to create an after-scenario questionnaire (ASQ). Retrieved June 10, 2025, from https://help.qualaroo.com/after-scenario-questionnaire&lt;br /&gt;
&lt;br /&gt;
=== A-2 관련 특허 ===&lt;br /&gt;
[1] 등산 내비게이션 단말 시스템 및 이를 이용한 등산 코스 안내 운영 방법  &lt;br /&gt;
[2] 산림빅데이터 플랫폼에 기반하여 데이터 상품을 제공하는 장치 및 방법  &lt;br /&gt;
&lt;br /&gt;
=== A-3 소프트웨어 프로그램 소스 ===&lt;br /&gt;
(소스코드 내용이 이곳에 들어감. 필요 시 별도 첨부)&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EC%9E%91%EB%8F%99%ED%99%94%EB%A9%B4.png&amp;diff=11894</id>
		<title>파일:Dos-작동화면.png</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EC%9E%91%EB%8F%99%ED%99%94%EB%A9%B4.png&amp;diff=11894"/>
				<updated>2025-06-19T13:08:05Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EC%9E%90%EC%9B%90%EC%82%AC%EC%9A%A9%EB%A5%A0.png&amp;diff=11879</id>
		<title>파일:Dos-자원사용률.png</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Dos-%EC%9E%90%EC%9B%90%EC%82%AC%EC%9A%A9%EB%A5%A0.png&amp;diff=11879"/>
				<updated>2025-06-19T12:41:04Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9173</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9173"/>
				<updated>2023-06-24T11:30:30Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 관련사업비 내역서 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation service&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
:- 알고리즘 문제풀이는 알고리즘 유형파악과 코드구현 부분으로 나누어 볼 수 있다.&lt;br /&gt;
:- 현존하는 온라인 알고리즘 문제풀이 사이트는 대부분 코드구현 부분에 포커스가 맞춰져 있다.&lt;br /&gt;
:- 본 Vision은 알고리즘 유형파악에 포커스를 맞춘 서비스를 개발한다.&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:- (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천 기능 구현&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준 &amp;amp; 김형철)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  모델 평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  인프라 세팅&lt;br /&gt;
  웹서버 배포(서버, DB)&lt;br /&gt;
  CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀 수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달 받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 프로젝트 코드의 갱신을 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을 때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해 언어가 한국어가 아니거나 태그분류가 없을 경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일 때는 싱글스레드로 크롤링 해왔지만 ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답 태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
포스터 제작한 바 없음&lt;br /&gt;
&lt;br /&gt;
===관련사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; colspan=&amp;quot;2&amp;quot; | 항     목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 수 량&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 단 가&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | 금    액&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 비 고&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| 계&lt;br /&gt;
| 현금&lt;br /&gt;
| 비고&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;직&amp;lt;br&amp;gt;접&amp;lt;br&amp;gt;개&amp;lt;br&amp;gt;발&amp;lt;br&amp;gt;비&lt;br /&gt;
| AWS EC2 Server 사용비&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 합  계&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에 해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
◇ 어드민 페이지 화면 구현&amp;lt;br&amp;gt;&lt;br /&gt;
:* 퀴즈 문제 검수&lt;br /&gt;
:* 퀴즈 문제 등록 &lt;br /&gt;
:* 사용자 신고/차단/강제 탈퇴&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
특허 출허한 바 없음&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9172</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9172"/>
				<updated>2023-06-24T11:30:10Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 완료작품의 평가 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation service&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
:- 알고리즘 문제풀이는 알고리즘 유형파악과 코드구현 부분으로 나누어 볼 수 있다.&lt;br /&gt;
:- 현존하는 온라인 알고리즘 문제풀이 사이트는 대부분 코드구현 부분에 포커스가 맞춰져 있다.&lt;br /&gt;
:- 본 Vision은 알고리즘 유형파악에 포커스를 맞춘 서비스를 개발한다.&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:- (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천 기능 구현&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준 &amp;amp; 김형철)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  모델 평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  인프라 세팅&lt;br /&gt;
  웹서버 배포(서버, DB)&lt;br /&gt;
  CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀 수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달 받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 프로젝트 코드의 갱신을 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을 때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해 언어가 한국어가 아니거나 태그분류가 없을 경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일 때는 싱글스레드로 크롤링 해왔지만 ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답 태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
포스터 제작한 바 없음&lt;br /&gt;
&lt;br /&gt;
===관련사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; colspan=&amp;quot;2&amp;quot; | 항     목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 수 량&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 단 가&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | 금    액&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 비 고&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;계&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;현금&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;비고&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;직&amp;lt;br&amp;gt;접&amp;lt;br&amp;gt;개&amp;lt;br&amp;gt;발&amp;lt;br&amp;gt;비&lt;br /&gt;
| AWS EC2 Server 사용비&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 합  계&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에 해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
◇ 어드민 페이지 화면 구현&amp;lt;br&amp;gt;&lt;br /&gt;
:* 퀴즈 문제 검수&lt;br /&gt;
:* 퀴즈 문제 등록 &lt;br /&gt;
:* 사용자 신고/차단/강제 탈퇴&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
특허 출허한 바 없음&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9171</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9171"/>
				<updated>2023-06-24T11:07:52Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 포스터 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation service&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
:- 알고리즘 문제풀이는 알고리즘 유형파악과 코드구현 부분으로 나누어 볼 수 있다.&lt;br /&gt;
:- 현존하는 온라인 알고리즘 문제풀이 사이트는 대부분 코드구현 부분에 포커스가 맞춰져 있다.&lt;br /&gt;
:- 본 Vision은 알고리즘 유형파악에 포커스를 맞춘 서비스를 개발한다.&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:- (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천 기능 구현&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준 &amp;amp; 김형철)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  모델 평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  인프라 세팅&lt;br /&gt;
  웹서버 배포(서버, DB)&lt;br /&gt;
  CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀 수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달 받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 프로젝트 코드의 갱신을 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을 때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해 언어가 한국어가 아니거나 태그분류가 없을 경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일 때는 싱글스레드로 크롤링 해왔지만 ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답 태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
포스터 제작한 바 없음&lt;br /&gt;
&lt;br /&gt;
===관련사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; colspan=&amp;quot;2&amp;quot; | 항     목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 수 량&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 단 가&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | 금    액&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 비 고&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;계&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;현금&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;비고&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;직&amp;lt;br&amp;gt;접&amp;lt;br&amp;gt;개&amp;lt;br&amp;gt;발&amp;lt;br&amp;gt;비&lt;br /&gt;
| AWS EC2 Server 사용비&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 합  계&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개  발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
◇ 어드민 페이지 화면 구현&amp;lt;br&amp;gt;&lt;br /&gt;
:* 퀴즈 문제 검수&lt;br /&gt;
:* 퀴즈 문제 등록 &lt;br /&gt;
:* 사용자 신고/차단/강제 탈퇴&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
특허 출허한 바 없음&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9170</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9170"/>
				<updated>2023-06-24T10:06:50Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation service&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
:- 알고리즘 문제풀이는 알고리즘 유형파악과 코드구현 부분으로 나누어 볼 수 있다.&lt;br /&gt;
:- 현존하는 온라인 알고리즘 문제풀이 사이트는 대부분 코드구현 부분에 포커스가 맞춰져 있다.&lt;br /&gt;
:- 본 Vision은 알고리즘 유형파악에 포커스를 맞춘 서비스를 개발한다.&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:- (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천 기능 구현&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준 &amp;amp; 김형철)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  모델 평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  인프라 세팅&lt;br /&gt;
  웹서버 배포(서버, DB)&lt;br /&gt;
  CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀 수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달 받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 프로젝트 코드의 갱신을 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을 때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해 언어가 한국어가 아니거나 태그분류가 없을 경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일 때는 싱글스레드로 크롤링 해왔지만 ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답 태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
포스터 재작한 바 없음&lt;br /&gt;
&lt;br /&gt;
===관련사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; colspan=&amp;quot;2&amp;quot; | 항     목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 수 량&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 단 가&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | 금    액&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 비 고&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;계&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;현금&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;비고&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;직&amp;lt;br&amp;gt;접&amp;lt;br&amp;gt;개&amp;lt;br&amp;gt;발&amp;lt;br&amp;gt;비&lt;br /&gt;
| AWS EC2 Server 사용비&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 합  계&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개  발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
◇ 어드민 페이지 화면 구현&amp;lt;br&amp;gt;&lt;br /&gt;
:* 퀴즈 문제 검수&lt;br /&gt;
:* 퀴즈 문제 등록 &lt;br /&gt;
:* 사용자 신고/차단/강제 탈퇴&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
특허 출허한 바 없음&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9169</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9169"/>
				<updated>2023-06-24T10:01:36Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation sevice&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
:- 알고리즘 문제풀이는 알고리즘 유형파악과 코드구현 부분으로 나누어 볼 수 있다.&lt;br /&gt;
:- 현존하는 온라인 알고리즘 문제풀이 사이트는 대부분 코드구현 부분에 포커스가 맞춰져 있다.&lt;br /&gt;
:- 본 Vision은 알고리즘 유형파악에 포커스를 맞춘 서비스를 개발한다.&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:- (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점   을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준, 김형철 공통)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  main 머지 시 자동 배포 (CI/CD)&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 현재 Dockerfile, docker-compose.yaml의 내용이 변경된 것은 쉽게 적용이 가능하지만, 프로젝트의 내용이 바뀐 경우도 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE(Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해. 언어가 한국어가 아니거나 태그분류가 없을경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일때는 싱글스레드로 크롤링 해왔지만. ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은, 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
포스터 제작한 바 없음&lt;br /&gt;
&lt;br /&gt;
===관련사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; colspan=&amp;quot;2&amp;quot; | 항     목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 수 량&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 단 가&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | 금    액&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 비 고&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;계&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;현금&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;비고&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;직&amp;lt;br&amp;gt;접&amp;lt;br&amp;gt;개&amp;lt;br&amp;gt;발&amp;lt;br&amp;gt;비&lt;br /&gt;
| AWS EC2 Server 사용비&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 합  계&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개  발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
◇ 어드민 페이지 화면 구현&amp;lt;br&amp;gt;&lt;br /&gt;
:* 퀴즈 문제 검수&lt;br /&gt;
:* 퀴즈 문제 등록 &lt;br /&gt;
:* 사용자 신고/차단/강제 탈퇴&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
특허 출허한 바 없음&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9168</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9168"/>
				<updated>2023-06-24T10:01:04Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 포스터 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation sevice&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
:- 알고리즘 문제풀이는 알고리즘 유형파악과 코드구현 부분으로 나누어 볼 수 있다.&lt;br /&gt;
:- 현존하는 온라인 알고리즘 문제풀이 사이트는 대부분 코드구현 부분에 포커스가 맞춰져 있다.&lt;br /&gt;
:- 본 Vision은 알고리즘 유형파악에 포커스를 맞춘 서비스를 개발한다.&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:- (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점   을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준, 김형철 공통)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  main 머지 시 자동 배포 (CI/CD)&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 현재 Dockerfile, docker-compose.yaml의 내용이 변경된 것은 쉽게 적용이 가능하지만, 프로젝트의 내용이 바뀐 경우도 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해. 언어가 한국어가 아니거나 태그분류가 없을경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일때는 싱글스레드로 크롤링 해왔지만. ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은, 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
포스터 제작한 바 없음&lt;br /&gt;
&lt;br /&gt;
===관련사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; colspan=&amp;quot;2&amp;quot; | 항     목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 수 량&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 단 가&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | 금    액&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 비 고&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;계&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;현금&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;비고&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;직&amp;lt;br&amp;gt;접&amp;lt;br&amp;gt;개&amp;lt;br&amp;gt;발&amp;lt;br&amp;gt;비&lt;br /&gt;
| AWS EC2 Server 사용비&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 합  계&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개  발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
◇ 어드민 페이지 화면 구현&amp;lt;br&amp;gt;&lt;br /&gt;
:* 퀴즈 문제 검수&lt;br /&gt;
:* 퀴즈 문제 등록 &lt;br /&gt;
:* 사용자 신고/차단/강제 탈퇴&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
특허 출허한 바 없음&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9167</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9167"/>
				<updated>2023-06-24T09:58:21Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 유저 취약 TAG 기반 Problem 추천 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation sevice&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
:- 알고리즘 문제풀이는 알고리즘 유형파악과 코드구현 부분으로 나누어 볼 수 있다.&lt;br /&gt;
:- 현존하는 온라인 알고리즘 문제풀이 사이트는 대부분 코드구현 부분에 포커스가 맞춰져 있다.&lt;br /&gt;
:- 본 Vision은 알고리즘 유형파악에 포커스를 맞춘 서비스를 개발한다.&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:- (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점   을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준, 김형철 공통)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  main 머지 시 자동 배포 (CI/CD)&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 현재 Dockerfile, docker-compose.yaml의 내용이 변경된 것은 쉽게 적용이 가능하지만, 프로젝트의 내용이 바뀐 경우도 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해. 언어가 한국어가 아니거나 태그분류가 없을경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일때는 싱글스레드로 크롤링 해왔지만. ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은, 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
포스터 재작한 바 없음&lt;br /&gt;
&lt;br /&gt;
===관련사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; colspan=&amp;quot;2&amp;quot; | 항     목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 수 량&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 단 가&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | 금    액&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 비 고&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;계&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;현금&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;비고&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;직&amp;lt;br&amp;gt;접&amp;lt;br&amp;gt;개&amp;lt;br&amp;gt;발&amp;lt;br&amp;gt;비&lt;br /&gt;
| AWS EC2 Server 사용비&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 합  계&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개  발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
◇ 어드민 페이지 화면 구현&amp;lt;br&amp;gt;&lt;br /&gt;
:* 퀴즈 문제 검수&lt;br /&gt;
:* 퀴즈 문제 등록 &lt;br /&gt;
:* 사용자 신고/차단/강제 탈퇴&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
특허 출허한 바 없음&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9166</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9166"/>
				<updated>2023-06-24T09:54:16Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* JWT 사용자 인증 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation sevice&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
:- 알고리즘 문제풀이는 알고리즘 유형파악과 코드구현 부분으로 나누어 볼 수 있다.&lt;br /&gt;
:- 현존하는 온라인 알고리즘 문제풀이 사이트는 대부분 코드구현 부분에 포커스가 맞춰져 있다.&lt;br /&gt;
:- 본 Vision은 알고리즘 유형파악에 포커스를 맞춘 서비스를 개발한다.&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:- (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점   을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준, 김형철 공통)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  main 머지 시 자동 배포 (CI/CD)&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 현재 Dockerfile, docker-compose.yaml의 내용이 변경된 것은 쉽게 적용이 가능하지만, 프로젝트의 내용이 바뀐 경우도 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해. 언어가 한국어가 아니거나 태그분류가 없을경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일때는 싱글스레드로 크롤링 해왔지만. ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은, 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
 이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
포스터 재작한 바 없음&lt;br /&gt;
&lt;br /&gt;
===관련사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; colspan=&amp;quot;2&amp;quot; | 항     목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 수 량&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 단 가&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | 금    액&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 비 고&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;계&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;현금&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;비고&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;직&amp;lt;br&amp;gt;접&amp;lt;br&amp;gt;개&amp;lt;br&amp;gt;발&amp;lt;br&amp;gt;비&lt;br /&gt;
| AWS EC2 Server 사용비&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 합  계&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개  발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
◇ 어드민 페이지 화면 구현&amp;lt;br&amp;gt;&lt;br /&gt;
:* 퀴즈 문제 검수&lt;br /&gt;
:* 퀴즈 문제 등록 &lt;br /&gt;
:* 사용자 신고/차단/강제 탈퇴&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
특허 출허한 바 없음&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9165</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9165"/>
				<updated>2023-06-24T09:53:08Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 관련 기술의 현황 및 분석(State of art) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation sevice&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
:- 알고리즘 문제풀이는 알고리즘 유형파악과 코드구현 부분으로 나누어 볼 수 있다.&lt;br /&gt;
:- 현존하는 온라인 알고리즘 문제풀이 사이트는 대부분 코드구현 부분에 포커스가 맞춰져 있다.&lt;br /&gt;
:- 본 Vision은 알고리즘 유형파악에 포커스를 맞춘 서비스를 개발한다.&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:- (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:- (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점   을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준, 김형철 공통)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  main 머지 시 자동 배포 (CI/CD)&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 현재 Dockerfile, docker-compose.yaml의 내용이 변경된 것은 쉽게 적용이 가능하지만, 프로젝트의 내용이 바뀐 경우도 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해. 언어가 한국어가 아니거나 태그분류가 없을경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일때는 싱글스레드로 크롤링 해왔지만. ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은, 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
 이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
포스터 재작한 바 없음&lt;br /&gt;
&lt;br /&gt;
===관련사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; colspan=&amp;quot;2&amp;quot; | 항     목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 수 량&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 단 가&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | 금    액&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 비 고&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;계&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;현금&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;비고&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;직&amp;lt;br&amp;gt;접&amp;lt;br&amp;gt;개&amp;lt;br&amp;gt;발&amp;lt;br&amp;gt;비&lt;br /&gt;
| AWS EC2 Server 사용비&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 합  계&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개  발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
◇ 어드민 페이지 화면 구현&amp;lt;br&amp;gt;&lt;br /&gt;
:* 퀴즈 문제 검수&lt;br /&gt;
:* 퀴즈 문제 등록 &lt;br /&gt;
:* 사용자 신고/차단/강제 탈퇴&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
특허 출허한 바 없음&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9164</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9164"/>
				<updated>2023-06-24T09:52:53Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 관련 기술의 현황 및 분석(State of art) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation sevice&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
:- 알고리즘 문제풀이는 알고리즘 유형파악과 코드구현 부분으로 나누어 볼 수 있다.&lt;br /&gt;
:- 현존하는 온라인 알고리즘 문제풀이 사이트는 대부분 코드구현 부분에 포커스가 맞춰져 있다.&lt;br /&gt;
:- 본 Vision은 알고리즘 유형파악에 포커스를 맞춘 서비스를 개발한다.&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:◇ (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점   을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준, 김형철 공통)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  main 머지 시 자동 배포 (CI/CD)&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 현재 Dockerfile, docker-compose.yaml의 내용이 변경된 것은 쉽게 적용이 가능하지만, 프로젝트의 내용이 바뀐 경우도 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해. 언어가 한국어가 아니거나 태그분류가 없을경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일때는 싱글스레드로 크롤링 해왔지만. ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은, 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
 이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
포스터 재작한 바 없음&lt;br /&gt;
&lt;br /&gt;
===관련사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; colspan=&amp;quot;2&amp;quot; | 항     목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 수 량&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 단 가&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | 금    액&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 비 고&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;계&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;현금&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;비고&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;직&amp;lt;br&amp;gt;접&amp;lt;br&amp;gt;개&amp;lt;br&amp;gt;발&amp;lt;br&amp;gt;비&lt;br /&gt;
| AWS EC2 Server 사용비&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 합  계&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개  발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
◇ 어드민 페이지 화면 구현&amp;lt;br&amp;gt;&lt;br /&gt;
:* 퀴즈 문제 검수&lt;br /&gt;
:* 퀴즈 문제 등록 &lt;br /&gt;
:* 사용자 신고/차단/강제 탈퇴&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
특허 출허한 바 없음&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9163</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9163"/>
				<updated>2023-06-24T09:49:23Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 완료 작품의 소개 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation sevice&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
내용&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:◇ (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점   을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준, 김형철 공통)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  main 머지 시 자동 배포 (CI/CD)&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 현재 Dockerfile, docker-compose.yaml의 내용이 변경된 것은 쉽게 적용이 가능하지만, 프로젝트의 내용이 바뀐 경우도 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해. 언어가 한국어가 아니거나 태그분류가 없을경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일때는 싱글스레드로 크롤링 해왔지만. ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은, 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
 이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
포스터 재작한 바 없음&lt;br /&gt;
&lt;br /&gt;
===관련사업비 내역서===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; colspan=&amp;quot;2&amp;quot; | 항     목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 수 량&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 단 가&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | 금    액&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 비 고&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;계&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;현금&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;비고&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;직&amp;lt;br&amp;gt;접&amp;lt;br&amp;gt;개&amp;lt;br&amp;gt;발&amp;lt;br&amp;gt;비&lt;br /&gt;
| AWS EC2 Server 사용비&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 합  계&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개  발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
◇ 어드민 페이지 화면 구현&amp;lt;br&amp;gt;&lt;br /&gt;
:* 퀴즈 문제 검수&lt;br /&gt;
:* 퀴즈 문제 등록 &lt;br /&gt;
:* 사용자 신고/차단/강제 탈퇴&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
특허 출허한 바 없음&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9162</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9162"/>
				<updated>2023-06-24T09:48:36Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 포스터 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation sevice&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
내용&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:◇ (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점   을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준, 김형철 공통)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  main 머지 시 자동 배포 (CI/CD)&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 현재 Dockerfile, docker-compose.yaml의 내용이 변경된 것은 쉽게 적용이 가능하지만, 프로젝트의 내용이 바뀐 경우도 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해. 언어가 한국어가 아니거나 태그분류가 없을경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일때는 싱글스레드로 크롤링 해왔지만. ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은, 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
 이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
포스터 재작한 바 없음&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; colspan=&amp;quot;2&amp;quot; | 항     목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 수 량&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 단 가&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | 금    액&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 비 고&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;계&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;현금&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;비고&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;직&amp;lt;br&amp;gt;접&amp;lt;br&amp;gt;개&amp;lt;br&amp;gt;발&amp;lt;br&amp;gt;비&lt;br /&gt;
| AWS EC2 Server 사용비&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 합  계&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개  발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
◇ 어드민 페이지 화면 구현&amp;lt;br&amp;gt;&lt;br /&gt;
:* 퀴즈 문제 검수&lt;br /&gt;
:* 퀴즈 문제 등록 &lt;br /&gt;
:* 사용자 신고/차단/강제 탈퇴&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
특허 출허한 바 없음&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9161</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9161"/>
				<updated>2023-06-24T09:48:23Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 특허 출원 내용 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation sevice&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
내용&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:◇ (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점   을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준, 김형철 공통)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  main 머지 시 자동 배포 (CI/CD)&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 현재 Dockerfile, docker-compose.yaml의 내용이 변경된 것은 쉽게 적용이 가능하지만, 프로젝트의 내용이 바뀐 경우도 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해. 언어가 한국어가 아니거나 태그분류가 없을경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일때는 싱글스레드로 크롤링 해왔지만. ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은, 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
 이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; colspan=&amp;quot;2&amp;quot; | 항     목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 수 량&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 단 가&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | 금    액&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 비 고&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;계&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;현금&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;비고&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;직&amp;lt;br&amp;gt;접&amp;lt;br&amp;gt;개&amp;lt;br&amp;gt;발&amp;lt;br&amp;gt;비&lt;br /&gt;
| AWS EC2 Server 사용비&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 합  계&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개  발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
◇ 어드민 페이지 화면 구현&amp;lt;br&amp;gt;&lt;br /&gt;
:* 퀴즈 문제 검수&lt;br /&gt;
:* 퀴즈 문제 등록 &lt;br /&gt;
:* 사용자 신고/차단/강제 탈퇴&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
특허 출허한 바 없음&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9160</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9160"/>
				<updated>2023-06-24T09:47:51Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 관련사업비 내역서 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation sevice&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
내용&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:◇ (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점   을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준, 김형철 공통)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  main 머지 시 자동 배포 (CI/CD)&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 현재 Dockerfile, docker-compose.yaml의 내용이 변경된 것은 쉽게 적용이 가능하지만, 프로젝트의 내용이 바뀐 경우도 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해. 언어가 한국어가 아니거나 태그분류가 없을경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일때는 싱글스레드로 크롤링 해왔지만. ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은, 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
 이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; colspan=&amp;quot;2&amp;quot; | 항     목&amp;lt;br&amp;gt;(품명, 규격)&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 수 량&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 단 가&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | 금    액&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 비 고&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;계&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;현금&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;비고&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;직&amp;lt;br&amp;gt;접&amp;lt;br&amp;gt;개&amp;lt;br&amp;gt;발&amp;lt;br&amp;gt;비&lt;br /&gt;
| AWS EC2 Server 사용비&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 합  계&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| 1&lt;br /&gt;
| KRW 205,819.37&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
| &amp;lt;br /&amp;gt;   &amp;lt;br /&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개  발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
◇ 어드민 페이지 화면 구현&amp;lt;br&amp;gt;&lt;br /&gt;
:* 퀴즈 문제 검수&lt;br /&gt;
:* 퀴즈 문제 등록 &lt;br /&gt;
:* 사용자 신고/차단/강제 탈퇴&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
내용&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9159</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9159"/>
				<updated>2023-06-24T09:41:51Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 향후계획 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation sevice&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
내용&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:◇ (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점   을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준, 김형철 공통)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  main 머지 시 자동 배포 (CI/CD)&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 현재 Dockerfile, docker-compose.yaml의 내용이 변경된 것은 쉽게 적용이 가능하지만, 프로젝트의 내용이 바뀐 경우도 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해. 언어가 한국어가 아니거나 태그분류가 없을경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일때는 싱글스레드로 크롤링 해왔지만. ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은, 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
 이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===관련사업비 내역서===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개  발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
◇ 어드민 페이지 화면 구현&amp;lt;br&amp;gt;&lt;br /&gt;
:* 퀴즈 문제 검수&lt;br /&gt;
:* 퀴즈 문제 등록 &lt;br /&gt;
:* 사용자 신고/차단/강제 탈퇴&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
내용&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9158</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9158"/>
				<updated>2023-06-24T09:41:12Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 완료작품의 평가 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation sevice&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
내용&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:◇ (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점   을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준, 김형철 공통)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  main 머지 시 자동 배포 (CI/CD)&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 현재 Dockerfile, docker-compose.yaml의 내용이 변경된 것은 쉽게 적용이 가능하지만, 프로젝트의 내용이 바뀐 경우도 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해. 언어가 한국어가 아니거나 태그분류가 없을경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일때는 싱글스레드로 크롤링 해왔지만. ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은, 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
 이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===관련사업비 내역서===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! 평  가  항  목&lt;br /&gt;
! 평가방법&lt;br /&gt;
! 적용기준&lt;br /&gt;
! 개  발목표치&lt;br /&gt;
! 비중(%)&lt;br /&gt;
! 평가결과&lt;br /&gt;
|-&lt;br /&gt;
| 1. 사용자 문제 풀이 시간 향상 척도&lt;br /&gt;
|  DB에   문제푸는데 걸린 시간을 기록한다.&amp;lt;br&amp;gt;이를 이용해 문제 푸는 시간 향상 정도를 파악한다.&lt;br /&gt;
| A : 푸는 시간이 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 2. 사용자 퀴즈 정확도 향상 척도&lt;br /&gt;
| DB에 퀴즈 정확도를 기록한다.&amp;lt;br&amp;gt;이를 이용해   문제 풀이 정확도 향상 정도를 파악한다.&lt;br /&gt;
| A : 정확도가 향상된 유저가 전체 유저의 70% 이상&amp;lt;br&amp;gt;B : 향상된 유저가 50% 이상&amp;lt;br&amp;gt;C : 그 외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 30%&lt;br /&gt;
| A&lt;br /&gt;
|-&lt;br /&gt;
| 3. 서비스 유용성&lt;br /&gt;
| 사용자에게 설문조사를 실시한다.&lt;br /&gt;
| A : 전체 설문 항목의 80%이상에서 긍정적   답변을 얻는다&amp;lt;br&amp;gt;B : 그외&lt;br /&gt;
| 적용기준 A에   해당하는 효과 구현&lt;br /&gt;
| 40%&lt;br /&gt;
| A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
내용&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9157</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=Vision&amp;diff=9157"/>
				<updated>2023-06-24T09:38:05Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: /* 프로토타입 사진 혹은 작동 장면 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=프로젝트 개요=&lt;br /&gt;
=== 기술개발 과제 ===&lt;br /&gt;
''' 국문 : ''' 코테고리 서비스 - 알고리즘 유형분류 퀴즈 및 문제 추천 서비스&lt;br /&gt;
&lt;br /&gt;
''' 영문 : ''' Cotegory Service - Algorithm type classification quiz and problem recommendation sevice&lt;br /&gt;
&lt;br /&gt;
===과제 팀명===&lt;br /&gt;
Vision&lt;br /&gt;
&lt;br /&gt;
===지도교수===&lt;br /&gt;
황*수 교수님&lt;br /&gt;
&lt;br /&gt;
===개발기간===&lt;br /&gt;
2023년 3월 ~ 2023년 6월 (총 4개월)&lt;br /&gt;
&lt;br /&gt;
===구성원 소개===&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 류*욱(팀장)&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20179200** 김*&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20184300** 김*철&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 임*욱&lt;br /&gt;
&lt;br /&gt;
서울시립대학교 컴퓨터과학부 20189200** 한*한&lt;br /&gt;
&lt;br /&gt;
==서론==&lt;br /&gt;
===개발 과제의 개요===&lt;br /&gt;
====개발 과제 요약====&lt;br /&gt;
◇ 사용자 수준에 맞춘 알고리즘 문제 유형 분류 퀴즈 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 오답률이 높은 문제 유형의 알고리즘 분야 파악 및 문제 추천 기능 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 기반으로 한 프로필 요약 제공&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취업 및 자기계발이 서비스의 주 목적으로 취준생이 주요 타겟층&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 배경====&lt;br /&gt;
◇ IT 분야의 기업에 취업을 희망하는 경우, 다수의 기업이 알고리즘 코딩테스트를 기업의 전형에 포함하고있어, 알고리즘 학습에 대한 수요가 많은 상황이다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 문제를 읽고 접근방식에 대한 충분한 검토 없이 바로 풀이에 들어가는 사용자가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====개발 과제의 목표 및 내용====&lt;br /&gt;
◇ 알고리즘 대회 또는 코딩테스트를 준비하는 사용자가 쉽게 자신의 알고리즘 역량을 확인하고, 향상시킬 수 있는 웹 플랫폼을 개발한다.&amp;lt;br&amp;gt; &lt;br /&gt;
◇ 퀴즈 결과를 통해 요약 프로필을 제공하고 이를 통해 자신의 알고리즘 풀이 능력을 한 눈에 확인할 수 있게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 퀴즈 결과를 통해 취약한 알고리즘 유형의 문제를 추천하여 자연스럽게 구현까지 이어지게 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 사용자가 서비스를 활용할 수록 알고리즘 풀이에 흥미를 갖게하여 꾸준하게 Cotegory 서비스를 이용할 수 있도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===관련 기술의 현황===&lt;br /&gt;
====관련 기술의 현황 및 분석(State of art)====&lt;br /&gt;
*전 세계적인 기술현황&lt;br /&gt;
내용&lt;br /&gt;
*특허조사 및 특허 전략 분석&lt;br /&gt;
:◇ (주)뤼이드. 인공 지능 학습 기반의 학습 컨텐츠 추천 시스템 및 그것의 동작 방법. 10-2021-0014455. 2021년 2월 2일, 2022년 4월 29일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 온라인 학습에서 적응형 사용자 인터페이스를 제공하는 방법 및 장치. 10-2020-0024119. 2020년 2월 27일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ (주)뤼이드. 교육 컨텐츠를 제공하는 방법, 장치 및 컴퓨터 프로그램. 10-2019-0024272. 2019년 2월 28일, 2021년 2월 2일&amp;lt;br&amp;gt;&lt;br /&gt;
*기술 로드맵&lt;br /&gt;
[[파일:Image00001.png]]&lt;br /&gt;
&lt;br /&gt;
====시장상황에 대한 분석====&lt;br /&gt;
*경쟁제품 조사 비교&lt;br /&gt;
:◇ Baekjoon&amp;lt;br&amp;gt;&lt;br /&gt;
::* 대표적인 알고리즘 문제 해결 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 알고리즘 문제를 코드를 작성하여 직접 해결 할 수 있으나 알고리즘 문제에 대한 카테고리를 맞추는 문제는 제공하지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자에게 문제를 추천해주는 서비스는 제공해주지 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Programmers (스킬체크)&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 스스로 생각하는 레벨별로 알고리즘 문제를 제공 후 평가해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 코드의 정확성과 효율성을 판단할 수 있음&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ Solved.ac (프로필 제공 측면)&amp;lt;br&amp;gt;&lt;br /&gt;
::* Baekjoon 사이트의 기록을 기반으로 문제와 사용자의 프로필을 제공해주는 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자의 수준과 문제의 난이도를 파악할 수 있음.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 직접적인 문제를 풀 수 있는 서비스르 제공해주지는 않음.&amp;lt;br&amp;gt;&lt;br /&gt;
:◇ 산타 토익&amp;lt;br&amp;gt;&lt;br /&gt;
::* 사용자가 푼 문제 결과를 기반으로 토익 문제를 추천해주는 영어 공부 서비스&amp;lt;br&amp;gt;&lt;br /&gt;
::* 첫 12문제의 결과 값을 이용하여 사용자에게 적합한 문제를 추천해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
::* 토익 시험 응시생을 대상으로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 서비스 타겟&lt;br /&gt;
! 추천 서비스&lt;br /&gt;
! 문제 제공 서비스&lt;br /&gt;
! 프로필 제공&lt;br /&gt;
|-&lt;br /&gt;
| 백준&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| solved.ac&lt;br /&gt;
| 백준을 사용하는   사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 제공하지 않음&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| programmers&lt;br /&gt;
| 알고리즘을 해결하고자   하는 사용자&lt;br /&gt;
| 존재하지 않음.&lt;br /&gt;
| 알고리즘 문제   제공&lt;br /&gt;
| 간단한 정보 제공&lt;br /&gt;
|-&lt;br /&gt;
| 산타 토익&lt;br /&gt;
| 토익을 준비하는   사용자&lt;br /&gt;
| 사용자의 수준에   맞는 문제 추천&lt;br /&gt;
| 토익 문제 제공&lt;br /&gt;
| 사용자 맞춤형   정보 제공&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
| 코테고리&lt;br /&gt;
| 취업을 준비하는 사용자&lt;br /&gt;
| 사용자의 수준에 맞는 문제 추천&lt;br /&gt;
| 알고리즘 카테고리 문제 제공&lt;br /&gt;
| 사용자 맞춤형 정보 제공&lt;br /&gt;
|}&lt;br /&gt;
*마케팅 전략 제시&lt;br /&gt;
:◇ 코딩테스트 준비를 시작하려는 취업 준비생들에게 본인의 알고리즘 역량을 쉽게 파악할 수 있는 점   을 강조한다.&lt;br /&gt;
:◇ 기존 서비스에는 존재 하지 않던 &amp;quot;카테고리&amp;quot;를 맞추는 문제를 제공해 준다는 점을 강조한다.&lt;br /&gt;
:◇ 사용자가 어려워하는 유형의 문제를 추천하여 문제 해결에 대한 취약점 개선 가능성을 강조한다.&lt;br /&gt;
:◇ 사용자에게 설문조사를 실시한다.&lt;br /&gt;
&lt;br /&gt;
===개발과제의 기대효과===&lt;br /&gt;
====기술적 기대효과====&lt;br /&gt;
◇ 알고리즘 유형 분석 능력 증진&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 취약한 분야의 알고리즘 문제를 추천받을 수 있다&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 기업 코딩테스트 대비&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====경제적, 사회적 기대 및 파급효과====&lt;br /&gt;
◇ 알고리즘 접근 난이도 하향&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 알고리즘 풀이에 대한 흥미 유발&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 교육 자료로 활용&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===기술개발 일정 및 추진체계===&lt;br /&gt;
====개발 일정====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 기술 로드맵 구성&lt;br /&gt;
! colspan=&amp;quot;4&amp;quot; | 진행   순서 (월단위)&lt;br /&gt;
|- style=&amp;quot;background-color:#F2F2F2;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 3&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 4&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 5&lt;br /&gt;
| style=&amp;quot;width: 70px&amp;quot; | 6&lt;br /&gt;
|-&lt;br /&gt;
| 프로젝트 구상 및 구체화&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DB 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| UI 설계&lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 추천 모델 데이터 수집 및 학습&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| AI 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| API 서버 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 웹 제작&lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 설문 조사&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|-&lt;br /&gt;
| 릴리즈 버전 테스트&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| style=&amp;quot;background-color:#6182D6;&amp;quot; | &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====구성원 및 추진체계====&lt;br /&gt;
◇ Front-end (류병욱)&lt;br /&gt;
  UI/UX&lt;br /&gt;
  프론트 페이지 HTML 작성&lt;br /&gt;
  Back-end와의 통신코드 작성&lt;br /&gt;
◇ Back-end (김준)&lt;br /&gt;
  mmr시스템 로직 구현&lt;br /&gt;
  mmr시스템을 통한 Quiz 추천&lt;br /&gt;
  기업문제 추천&lt;br /&gt;
◇ Back-end (김형철)&lt;br /&gt;
  크롤링 로직 구현&lt;br /&gt;
  JWT 로그인 구현&lt;br /&gt;
  어드민 페이지 API 개발&lt;br /&gt;
  비정상적 문제 검열 로직&lt;br /&gt;
◇ Back-end (김준, 김형철 공통)&lt;br /&gt;
  서비스 로직 API 개발&lt;br /&gt;
◇ AI (한수한)&lt;br /&gt;
  모델 학습&lt;br /&gt;
  평가 &amp;amp; 비교(EASE, AUTO_ENCODER)&lt;br /&gt;
◇ 아마존 배포 (임재욱)&lt;br /&gt;
  main 머지 시 자동 배포 (CI/CD)&lt;br /&gt;
&lt;br /&gt;
==설계==&lt;br /&gt;
===설계사양===&lt;br /&gt;
====제품의 요구사항====&lt;br /&gt;
◇ R1: 알고리즘 퀴즈를 풀고 이력을 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R2: 취약한 알고리즘 분야에 대한 추천을 받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R3: 다양한 알고리즘 문제를 추천받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ R4: 요약 프로필을 제공받을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====설계 사양====&lt;br /&gt;
◇ F1:&lt;br /&gt;
:* 기능: 알고리즘 퀴즈를 하나씩 제공하고 정답 여부가 기록되어 마이페이지에서 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 알고리즘 퀴즈를 Front-end 서버에 전달하며, 정답 여부를 db에 저장한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제와 알고리즘 퀴즈 문제를 화면에 보이고 문제를 풀수 있는 UI를 제공한다. &lt;br /&gt;
◇ F2:&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: 유저가 취약한 알고리즘 분야의 문제를 추천받고자 하는 경우, AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀 수 있는 링크또한 제공한다.&lt;br /&gt;
◇ F3: 랜덤 문제, 유저가 취약한 알고리즘 분야의 문제, 기업 문제를 추천한다.&lt;br /&gt;
:* 기능: 유저로부터 전달받은 정보를 활용하여 AI 모델을 통해 적합한 문제를 추천한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- AI: AUTO_ENCODER 모델을 적용하여 추천 문제를 선별하여 Back-end 서버에 제공한다.&lt;br /&gt;
::- Back-end: 추천 문제를 Front-end 서버에 전달하며, 오늘의 추천 문제와 기업 문제 또한 Front-end 서버에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 추천 문제를 화면에 보이고 문제를 풀수 있는 링크 또한 제공한다.&lt;br /&gt;
◇ F4: 문제 히스토리와 요약 프로필을 제공한다.&lt;br /&gt;
:* 기능: 퀴즈 결과와 알고리즘 대분류별 MMR을 제공한다.&lt;br /&gt;
:* 정량 목표:&lt;br /&gt;
::- Back-end: 퀴즈 결과와 알고리즘 대분류별 MMR 점수를 Front-end에 전달한다.&lt;br /&gt;
::- Front-end: Back-end 서버로부터 전달받은 데이터를 화면에 보이고 데이터를 가공하여 100점 만점을 기준으로 점수를 보여주며 능력치를 progress bar 형태로 보여준다.&lt;br /&gt;
&lt;br /&gt;
===개념설계안===&lt;br /&gt;
[[ 파일:Image00002.png]]&lt;br /&gt;
[[ 파일:Image00003.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
1. EC2 Instance와 Docker Container: EC2 인스턴스에서 Docker를 실행하고, Docker 컨테이너를 생성하여 애플리케이션을 실행합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
2. Dockerfile과 Docker Image: Dockerfile은 Docker 이미지를 작성하는데 사용됩니다. Docker 이미지는 애플리케이션과 애플리케이션 실행에 필요한 모든 종속성을 포함하는 실행 가능한 패키지입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* Dockerfile은 총 3개로, 각각 AI, Front-end, Back-end 도메인을 의미합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Docker Compose.yml과 Docker Compose: Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 관리하는 데 사용되는 도구입니다. Docker Compose.yml 파일은 Docker Compose가 사용하는 설정 파일입니다.&amp;lt;br&amp;gt;&lt;br /&gt;
4. AWS S3와 EC2 Instance: EC2 인스턴스는 AWS S3에 접근하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 EC2 인스턴스와 S3 버킷 간에 파일 공유 또는 데이터 저장 등의 작업이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
5. AWS RDS와 EC2 Instance: EC2 인스턴스는 AWS RDS(Relational Database Service)에 접근하여 데이터베이스에 연결하고 데이터를 읽거나 쓸 수 있습니다. 이를 통해 애플리케이션과 데이터베이스 간의 상호작용이 가능합니다.&amp;lt;br&amp;gt;&lt;br /&gt;
6. 현재 Dockerfile, docker-compose.yaml의 내용이 변경된 것은 쉽게 적용이 가능하지만, 프로젝트의 내용이 바뀐 경우도 고려하여 GitHub Actions를 사용하여 CI/CD를 적용하였습니다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===이론적 계산 및 시뮬레이션===&lt;br /&gt;
====AI 추천 모델====&lt;br /&gt;
◇ 기본적으로 훈련에 쓰인 데이터외의 데이터를 통해서도 문제를 추천해줄 수 있는 모델을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ auto_encoder 모델이 위의 특성을 가지고 있어 auto_encode 기본 모델(AUTO_ENCODER)과 간단하면서도 성능이 좋은 모델(EASE)을 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
====1. AUTO_ENCODER====&lt;br /&gt;
[[파일:Image00004.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터(X)를 encoder에 넣어 잠재 벡터로 만든후 이 잠재 벡터를 다시 decoder에 넣어 입력 데이터와 비슷한 출력 데이터로 복원하는 형태를 가진다.&amp;lt;br&amp;gt;&lt;br /&gt;
입력 데이터를 원래의 입력데이터의 압축된 지식표현으로 만드는 것이 목적이지만 이는 추천에도 활용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
훈련을 너무 오래 돌리면 auto encoder의 weight의 곱이 단위 행렬과 비슷해질 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉, 대각 값이 가장 높아져 자기 자신이 자기 자신을 추천해버리는 경우가 생긴다. (overfitting)&amp;lt;br&amp;gt;&lt;br /&gt;
그러므로 훈련을 적당한 선에서 멈추고 대각 값에 제약을 추가하는 방법을 사용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
본 프로젝트에서는 hidden layer를 2개(Encoder, Decoder)만 사용했다.&lt;br /&gt;
&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 0과 1로 이루어짐&lt;br /&gt;
&lt;br /&gt;
◇ 파라미터 &lt;br /&gt;
:* E = 아이템(I) * 잠재벡터차원(Z) Matrix&lt;br /&gt;
::- 입력 데이터를 잠재 벡터로 encoding하는 작업을 수행&lt;br /&gt;
:* D = 잠재벡터차원(Z) * 아이템(I) Matrix&lt;br /&gt;
::- 잠재 벡터를 입력 데이터처럼 decoding하는 작업을 수행&lt;br /&gt;
&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * E * D&lt;br /&gt;
:* 유저(u)에 대한 아이템(j)의 ranking 점수&lt;br /&gt;
&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 손실함수 L을 auto_encoder에 흔히 쓰이는 mse(mean squared error)로 설정했다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00005.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00006.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
훈련 루프를 돌며 L을 최소화하도록 훈련한다.&amp;lt;br&amp;gt;&lt;br /&gt;
단, 위에서 언급한 것처럼 L을 최소화하다보면 train data의 정확도는 높아지고 test data의 정확도는 낮아지는overfitting이 발생하므로  est data의 정확도가 최대일 때의 모델(가중치)를 저장한다.&lt;br /&gt;
&lt;br /&gt;
====2. EASE (Embarrassingly Shallow Autoencoders for Sparse Data)====&lt;br /&gt;
《특징》&amp;lt;br&amp;gt;&lt;br /&gt;
2019년에 나온 추천 모델로 hidden layer가 없는 shallow한 모델이다.&amp;lt;br&amp;gt;&lt;br /&gt;
다른 딥러닝 모델과 달리 학습 파라미터(매트릭스)가 1개밖에 존재하지 않고 이 학습 파라미터의 대각 성분을 0으로 함으로써 목적함수를 closed form sulution로 만들 수 있어 최적의 해를 구할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
《학습 방법》&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터 (X)&lt;br /&gt;
:* X = 유저(U) * 아이템(I) Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &lt;br /&gt;
! 문제 1&lt;br /&gt;
! 문제 2&lt;br /&gt;
! 문제 3&lt;br /&gt;
! 문제 4&lt;br /&gt;
|-&lt;br /&gt;
| 유저 A&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 유저 B&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 유저 C&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
|}&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00007.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 파라미터 (B)&lt;br /&gt;
:* I * I Matrix&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00008.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 출력 (S)&lt;br /&gt;
:* S = X * B&lt;br /&gt;
:* 예시&lt;br /&gt;
::[[파일:Image00009.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
《목적함수 (손실함수)》&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00010.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ X와 XB 의 차이를 가장 작게 하는 B를 구하는 항에 과적합을 예방하기 위한 L2-norm정규화 항을 추가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 위에서 볼 수 있듯이 EASE 모델에서는 하이퍼파라미터(hyperparamter)는 밖에 없다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ B의 값을 구하기 위해 대각 성분을 0으로 한다는 조건을 사용하여 라그랑주 승수법을 이용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 라그랑주 승수법을 통해 생성된 최종 목적함수는 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00012.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
◇ L이 최소가 되는 B를 구하는 중간 과정이 논문에 존재하지 않아 간단히 증명하면 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식에서 L2-norm 제곱 항을 다음과 같이 변경할 수 있다.&lt;br /&gt;
::[[파일:Image00013.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
::[[파일:Image00014.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 위 식을 사용한 최종 손실함수 L은 다음과 같다.&lt;br /&gt;
::[[파일:Image00015.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L을 미분하여 L의 도함수가 0이 되는 B를 구하는 과정은 다음과 같다.&lt;br /&gt;
::[[파일:Image00016.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 각 항에 대해 미분을 진행하면 다음과 같은 식이 나온다.&lt;br /&gt;
::[[파일:Image00017.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* L의 도함수를 0으로 하여 B에 대해 정리하면 논문에서 나온 B의 항등식이 나온다.&lt;br /&gt;
::[[파일:Image00018.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 다음부터는 논문에 있는 내용이다.먼저 식을 간추리기 위해 다음과 같이 P를 정의한다.&lt;br /&gt;
::[[파일:Image00019.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* B에 P를 대입하여 정리하면 다음과 같다.&lt;br /&gt;
::[[파일:Image00020.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 마지막으로 γ̃을 구하고&lt;br /&gt;
::[[파일:Image00022.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* γ̃을 B식에 대입하면&lt;br /&gt;
::[[파일:Image00024.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:* 즉, 이 과정으로 구한 B가 L이 최소가 되는 최적의 해가 된다.B의 요소를 표현해보면&lt;br /&gt;
::[[파일:Image00025.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 대각 값은 전부 0이고 그렇지 않으면 P에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: P은 위 식에서 볼 수 있듯이 X^TX에 영향을 받는다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 이때, X^TX는 $라고 표현하는데 이는 Gram Matrix라고 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G는 item-item matrix로 co-occurrence matrix(동시 발생 행렬)라고도 불리운다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: G를 본 프로젝트에 적용하자면 어떤 문제를 선택했을 때, 다른 문제도 선택될 빈도를 나타낼 수 있는 지표이다.&amp;lt;br&amp;gt;&lt;br /&gt;
:: 즉, 문제와 문제의 유사성을 띄는 matrix로 추천에 용이하게 쓰인다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====데이터셋====&lt;br /&gt;
◇ 데이터는 백준 유저 랭킹 31~280 페이지에서 10명씩 총 2500명을 sampling하여 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 데이터를 얻은 2023/05/03 기준 280페이지는 한 유저가 최소 162문제를 풀었다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ train data와 test data를 7:3으로 나누고 topk를 50까지 하기 위해서 위와 같이 sampling하였다.&lt;br /&gt;
:* 162*0.3 ~= 49이므로 대부분의 유저가 test data에 들어갈 수 있다.&lt;br /&gt;
◇ train data와 test data를 나누는 방법은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  ex) 유저 3명, 문제 5개&lt;br /&gt;
* 유저 - 문제 matrix&lt;br /&gt;
 [[1,0,1,1,1], &lt;br /&gt;
 [0,0,1,1,1], &lt;br /&gt;
 [1,1,1,0,0]] shape = (3,5) &lt;br /&gt;
&lt;br /&gt;
* test_ratio = 0.2&lt;br /&gt;
:각 유저별로 1인 값을 3개 sampling ((3*5) * 0.2 = 3)&lt;br /&gt;
&lt;br /&gt;
* split 결과&lt;br /&gt;
:test data&lt;br /&gt;
 [(0,4), (1,2), (2,0)]&lt;br /&gt;
:train data&lt;br /&gt;
 [[1,0,1,1,0], &lt;br /&gt;
 [0,0,0,1,1], &lt;br /&gt;
 [0,1,1,0,0]]&lt;br /&gt;
&lt;br /&gt;
* topk=1&lt;br /&gt;
train data를 모델에 넣어 train data에서 이미 1인 data를 제외하고 rating을 매긴 후 유저별로 가장 높은 1개의 문제를 고른다. 이때, 이 문제가 test data에 속한다면 true로 판정한다.&lt;br /&gt;
&lt;br /&gt;
ex) &lt;br /&gt;
* train data를 모델에 넣은 출력 값&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
* train data에서 1인 data 제외후 유저별로 가장 높은 1개의 문제를 고른다.&lt;br /&gt;
 [[0.8, 0.1, 0.9, 0.3, 0.15], &lt;br /&gt;
 [0.1,0.05 , 0.09, 0.6, 0.4], &lt;br /&gt;
 [0.2, 0.3, 0.7, 0.1, 0.12]]&lt;br /&gt;
&lt;br /&gt;
(0,4), (1,0), (2,0) // rating 결과 index&amp;lt;br&amp;gt;&lt;br /&gt;
(0,4), (1,2), (2,0) // test data&amp;lt;br&amp;gt;&lt;br /&gt;
정확도는 2/3가 된다&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====평가지표====&lt;br /&gt;
◇ precision&amp;lt;br&amp;gt;&lt;br /&gt;
◇ recall&amp;lt;br&amp;gt;&lt;br /&gt;
◇ ndcg&amp;lt;br&amp;gt;&lt;br /&gt;
총 3가지로 평가한다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* topks&lt;br /&gt;
:높은 점수를 받은 상위 k개를 추천해줄 때 사용되는 k 리스트&lt;br /&gt;
:ex) topks = [10, 20, 50]&lt;br /&gt;
&lt;br /&gt;
* precision &lt;br /&gt;
:true인 문제 개수 / k 여기서 true란 추천된 문제가 훈련에 쓰이지 않은 유저가 푼 문제에 해당한 경우 &lt;br /&gt;
&lt;br /&gt;
* recall&lt;br /&gt;
:true인 문제 개수 / 유저가 푼 모든 문제 개수&lt;br /&gt;
&lt;br /&gt;
* ndcg (Normalized Discounted Cumulative Gain)&lt;br /&gt;
:relevance score(rating)의 할인된 합의 정규화&amp;lt;br&amp;gt;&lt;br /&gt;
:높은 점수일수록 가중치를 훨씬 많이 제공&lt;br /&gt;
&lt;br /&gt;
ex)&lt;br /&gt;
&lt;br /&gt;
문제 총 개수 = 10&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
어느 유저가 푼 문제 matrix&amp;lt;br&amp;gt;&lt;br /&gt;
[1, 0, 1, 1, 1, 0, 0, 0, 1, 0] &lt;br /&gt;
&lt;br /&gt;
test_ratio = 0.3&amp;lt;br&amp;gt;&lt;br /&gt;
test_data = [2, 3, 4] &amp;lt;br&amp;gt;&lt;br /&gt;
train_maxtix = [1, 0, 0, 0, 0, 0, 0, 0, 1, 0] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
topk = 3&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저에 대한 rating = [0.9, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, 0.8, 0.1]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
train_maxtix 에서 1인 index는 rating에서 -INF으로 변경 (훈련에 쓰인 문제는 추천 X) &amp;lt;br&amp;gt;&lt;br /&gt;
rating = [-INF, 0.1, 0.2, 0.4, 0.6, 0.3, 0.2, 0.1, -INF, 0.1] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이제 rating에서 상위 3개 index를 뽑으면 [0.6, 0.4, 0.3]의 index인 [4, 3, 5]가 된다. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
test_data에 속한 rating의 개수는 3,4 총 2개이므로 &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
precision = 2/3 = 0.67, &amp;lt;br&amp;gt;&lt;br /&gt;
recall = 2/5 = 0.4, &amp;lt;br&amp;gt;&lt;br /&gt;
ndcg = 1.63 / 2.13 = 0.765 &amp;lt;br&amp;gt;&lt;br /&gt;
(dcg = 1/lg(2) + 1/lg(3) = 1 + 0.63 = 1.63 &amp;lt;br&amp;gt;&lt;br /&gt;
idcg = 1/lg(2) + 1/lg(3) + 1/lg(4) = 1 + 0.63 + 0.5 = 2.13)&amp;lt;br&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
====모델별 정확도 비교====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9614&lt;br /&gt;
| 0.1255&lt;br /&gt;
| 0.9691&lt;br /&gt;
|- &lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9595&lt;br /&gt;
| 0.1252&lt;br /&gt;
| 0.9670&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9647&lt;br /&gt;
| 0.1259&lt;br /&gt;
| 0.9712&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@20&lt;br /&gt;
! Recall@20&lt;br /&gt;
! nDCG@20&lt;br /&gt;
|-&lt;br /&gt;
| EASE&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2404&lt;br /&gt;
| 0.9418&lt;br /&gt;
|-&lt;br /&gt;
| AUTO_ENCODER&lt;br /&gt;
| 0.9259&lt;br /&gt;
| 0.2403&lt;br /&gt;
| 0.9410&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-decoration:underline;&amp;quot;&lt;br /&gt;
| AUTO_ENCODER_CONST&lt;br /&gt;
| 0.9292&lt;br /&gt;
| 0.2413&lt;br /&gt;
| 0.9443&lt;br /&gt;
|}&lt;br /&gt;
◇ EASE 모델은 대각선을 제한하지 않은 AUTO_ENCODER 모델보다 성능은 좋지만 대각 성분을 제한한 모델인 AUTO_ENCODER_CONST보다는 정확도가 낮다.&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 모든 부분을 보았을 때 AUTO_ENCODER_CONST가 가장 성능이 좋아 본 프로젝트에서는 대각 성분을 제한한 &amp;lt;b&amp;gt;AUTO_ENCODER_CONST 모델을 추천에 사용하기로 결정하였다.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
◇ 참고로 랜덤추천의 정확도는 아래와 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Model&lt;br /&gt;
! Precision@10&lt;br /&gt;
! Recall@10&lt;br /&gt;
! nDCG@10&lt;br /&gt;
|-&lt;br /&gt;
| RANDOM&lt;br /&gt;
| 0.0025&lt;br /&gt;
| 0.0003&lt;br /&gt;
| 0.0027&lt;br /&gt;
|}&lt;br /&gt;
위 결과에서 볼 수 있듯이 랜덤 추천의 정확도는 본 추천 모델보다 성능이 비약하다. 이는 전체 문제 수에 비해 유저가 푼 문제 수가 매우 적어서 나타나는 현상이고 유저가 문제를 푸는 성향이 서로 비슷하기 때문이다. 즉, 실제 유저가 문제를 푸는 성향이 비슷하다는 것은 서로 그 문제들을 풀 가능성이 높다는 것이기에 추천 정확도가 높은 본 추천 모델을 사용하는 것은 추천의 타당성이 있다고 볼 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====태그 그룹 선정====&lt;br /&gt;
본 프로젝트에서 태그 유형 분류 퀴즈에 쓰일 태그로 다음과 같은 총 10개의 태그를 선정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 그리디 알고리즘(탐욕 알고리즘)&lt;br /&gt;
:* 다이나믹 프로그래밍&lt;br /&gt;
:* 브루트포스 알고리즘(완전 탐색)&lt;br /&gt;
:* 이분 탐색&lt;br /&gt;
:* 너비 우선 탐색(bfs)&lt;br /&gt;
:* 깊이 우선 탐색(dfs)&lt;br /&gt;
:* 데이크스트라&lt;br /&gt;
:* 플로이드-워셜&lt;br /&gt;
:* 비트마스킹&lt;br /&gt;
:* 분리 집합(유니온 파인드)&lt;br /&gt;
퀴즈를 제공할 때 유저가 헷갈릴만한 태그 그룹을 보기로 제시하기 위해 태그간 유사성을 판별하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
아래 그림은 문제별 태그 matrix를 통해 GramMatrix를 구한 것이다.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00026.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위 matrix  태그와 태그의 교집합 개수를 표현하므로는Jaccard방식을 써서 유사성을 판단하면&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00027.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위와 같은 결과가 나온다.&amp;lt;br&amp;gt;&lt;br /&gt;
각 결과를 자기 자신을 제외한 내림차순으로 정리하면 다음과 같다.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
'그리디 알고리즘': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '이분 탐색', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'다이나믹 프로그래밍': ['비트마스킹', '그리디 알고리즘', '브루트포스 알고리즘', '이분 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'브루트포스 알고리즘': ['다이나믹 프로그래밍', '비트마스킹', '그리디 알고리즘', '깊이 우선 탐색']&amp;lt;br&amp;gt;&lt;br /&gt;
'이분 탐색': ['다이나믹 프로그래밍', '그리디 알고리즘', '브루트포스 알고리즘', '분리 집합']&amp;lt;br&amp;gt;&lt;br /&gt;
'너비 우선 탐색': ['깊이 우선 탐색', '브루트포스 알고리즘', '데이크스트라', '다이나믹 프로그래밍']&amp;lt;br&amp;gt;&lt;br /&gt;
'깊이 우선 탐색': ['너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'데이크스트라': ['너비 우선 탐색', '다이나믹 프로그래밍', '이분 탐색', '플로이드–워셜']&amp;lt;br&amp;gt;&lt;br /&gt;
'플로이드–워셜': ['데이크스트라', '너비 우선 탐색', '다이나믹 프로그래밍', '브루트포스 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'비트마스킹': ['다이나믹 프로그래밍', '브루트포스 알고리즘', '너비 우선 탐색', '그리디 알고리즘']&amp;lt;br&amp;gt;&lt;br /&gt;
'분리 집합': ['깊이 우선 탐색', '이분 탐색', '그리디 알고리즘', '다이나믹 프로그래밍']&lt;br /&gt;
|}&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
위 결과를 참고하여 어떤 태그가 서로 관련이 있는지 파악하였고 총 3개의 그룹으로 나누었다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 A : [그리디 알고리즘, 다이나믹 프로그래밍, 브루트포스 알고리즘, 이분 탐색]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 B : [너비 우선 탐색, 깊이 우선 탐색, 브루트포스 알고리즘, 다이나믹 프로그래밍]&amp;lt;br&amp;gt;&lt;br /&gt;
그룹 C : [다익스트라, 플루이드 워셜, 비트마스킹, 유니온 파인드]&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
그룹별 포함된 태그의 개수는 4개로 사용자에게 4지선다형 퀴즈를 제공한다.&lt;br /&gt;
&lt;br /&gt;
====JWT 사용자 인증====&lt;br /&gt;
백엔드 WAS(Web Application Server)에서 사용하는 인증 방법중, 널리 사용되는 2개의 방법으로 Session과 JWT가 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00028.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
Session방식은 인증 정보를 서버가 가지고 있다(서버는 Stateful)&amp;lt;br&amp;gt;&lt;br /&gt;
이 방식은 API 방식으로 BACK과 FRONT가 통신하는 본 프로젝트에는 다소 어울리지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00029.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
JWT방식은 인증 정보를 유저가 가지고있다(서버는 Stateless)&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트는 이 방식을 채용하여 유저 인증을 진행하기로 결정하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
유저가 로그인 정보를 JSON형식으로 HTTP BODY에 담아 서버에 전달하면, 서버는 토큰을 발행해준다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00030.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
유저는 이 토큰을 보관한다. 백서버에 요청할때, 이 토큰을 헤더에 포함시켜 요청한다.&amp;lt;br&amp;gt;&lt;br /&gt;
백서버는 토큰을 파싱하여 인증을 진행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00031.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
토큰을 파싱하면, JWT의 HEADER, PAYLOAD, SIGNATURE. 3가지 타입의 정보를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
HEADER에는 암호화에 사용된 타입, 기법등이 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PAYLOAD에는 토큰 발행자가 포함시킨 개인정보가 포함된다. 본 프로젝트에는 loginId와 백에서 사용하는 memberId가 포함된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SIGNATURE에는 앞서나온 HEADER와 PAYLOAD. 그리고 토큰발행자의 비밀키까지 3가지를 조합하여 생성된 SIGNATURE key값이 온다. 토큰 인증자는 이 부분을 자신이 발행할때 사용한 비밀키를 이용해 암호를 VERIFY한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
다음은 VERIFY에 실패했을 경우다. 비밀키에 토큰발행시 사용하지 않는 임의의 키를 넣었다.&lt;br /&gt;
[[파일:Image00032.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 VERIFY에 성공했을 경우다. 비밀키에 토큰발행시 사용한 키를 넣었다.&lt;br /&gt;
[[파일:Image00033.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 상기한 과정을 통해 사용자를 인증하도록 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
인증이 완료되면, 백엔드 서버는 payload에 포함된 memberId를 이용해 business 로직을 수행한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====백준 문제 크롤링 로직====&lt;br /&gt;
상기한 10개의 태그를 포함한 모든 백준 문제를 크롤링한다.&amp;lt;br&amp;gt;&lt;br /&gt;
태그별 문제 리스트는 다음과 같은 url구조를 갖는다.&amp;lt;br&amp;gt;&lt;br /&gt;
 https://www.acmicpc.net/problemset?sort=ac_desc&amp;amp;algo={algoCode}&amp;amp;algo_if=and&amp;amp;page={page}algoCode=11page=2&lt;br /&gt;
다음은, 위와 같은 URL 주소로 접속했을때의 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00034.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
크롤링할 10개의 태그의 algoCode값은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* DP(&amp;quot;다이나믹 프로그래밍&amp;quot;, 25)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DFS(&amp;quot;깊이 우선 탐색&amp;quot;, 127)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BFS(&amp;quot;너비 우선 탐색&amp;quot;, 126)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BRUTE_FORCE(&amp;quot;브루트포스 알고리즘&amp;quot;, 125)&amp;lt;br&amp;gt;&lt;br /&gt;
:* GREEDY(&amp;quot;그리디 알고리즘&amp;quot;, 33)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BINARY_SEARCH(&amp;quot;이분 탐색&amp;quot;, 12)&amp;lt;br&amp;gt;&lt;br /&gt;
:* BIT_MASKING(&amp;quot;비트마스킹&amp;quot;, 14)&amp;lt;br&amp;gt;&lt;br /&gt;
:* DIJKSTRA(&amp;quot;데이크스트라&amp;quot;, 22)&amp;lt;br&amp;gt;&lt;br /&gt;
:* FLOYD_WARSHALL(&amp;quot;플로이드-워셜&amp;quot;, 31)&amp;lt;br&amp;gt;&lt;br /&gt;
:* UNION_FIND(&amp;quot;분리 집합&amp;quot;, 81)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 url에서, {algoCode}값을 바꿔가며 태그별 문제 리스트에 접근할 수 있고. {page}값을 바꿔가며 첫번째 page부터 마지막 page까지 순회할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
각 page에 있는 문제에 접근하여 문제 컨텐츠를 크롤링 해온다. 문제를 크롤링 할때, jsoup프레임워크를 이용해 정적 html을 적절히 파싱한다. 다음은 1000번 문제를 접근했을때 볼 수 있는 화면이다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00035.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
이 화면에서 다음과 같은 항목을 크롤링한다. 각 항목을 화살표 우측의 java 변수값으로 변환한다.&amp;lt;br&amp;gt;&lt;br /&gt;
:* 시간제한 -&amp;gt; timeLimit&lt;br /&gt;
:* 메모리 제한 -&amp;gt; memoyLimit&lt;br /&gt;
:* 문제 -&amp;gt; problemBody&lt;br /&gt;
:* 입력 -&amp;gt; problemInput&lt;br /&gt;
:* 출력 -&amp;gt; problemOutput&lt;br /&gt;
:* 예제입력 -&amp;gt; sampleInput&lt;br /&gt;
:* 예제출력 -&amp;gt; sampleOutput&lt;br /&gt;
위 화면에는 문제의 태그분류(=알고리즘분류)가 빠져있는데, 이는 백준의 태그분류는 로그인 했을 경우만 접근할 수 있기 때문이다. 즉 비로그인 상태에서는 다음과 같은 항목이 나타나지 않는다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00036.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
태그분류를 보기위해서 로그인한뒤, 동적 html을 파싱하는 코드를 짤 수 도 있으나. 정적 파싱에 비해 고려해야할 사항도 많고 성능도 떨어진다. 여기서는, 알고리즘 분류를 얻기 위해 solvedac API라는 대안이 있으니. 이를 사용하기로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
solvedac는 백준에 있는 문제들의 난이도를 유저들이 매겨보는 사이트이다. 즉, 알고리즘 문제들의 난이도를 집단지성을 이용해 결정해보자는 취지의 서비스이다. solvedac에선 난이도를 포함한 문제의 메타z이터를 API형태로 제공하는데, 이 API를 통해 로그인해야만 얻을 수 있던 태그분류(=알고리즘분류)데이터를 얻을 수 있다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 solvedac api서버에 문제를 요청한다.&lt;br /&gt;
 curl--request GET \&lt;br /&gt;
 --url https://solved.ac/api/v3/problem/show \&lt;br /&gt;
 --header 'Accept: application/json'&lt;br /&gt;
이에대한 HHTP요청에 대한 응답으로, 이와 같은 json을 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;problemId&amp;quot;: 13705,&lt;br /&gt;
  &amp;quot;titleKo&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
  &amp;quot;titles&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;languageDisplayName&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Ax+Bsin(x)=C&amp;quot;,&lt;br /&gt;
      &amp;quot;isOriginal&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  ...(생략)&lt;br /&gt;
  &amp;quot;tags&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;key&amp;quot;: &amp;quot;arbitrary_precision&amp;quot;,&lt;br /&gt;
      &amp;quot;isMeta&amp;quot;: false,&lt;br /&gt;
      &amp;quot;bojTagId&amp;quot;: 117,&lt;br /&gt;
      &amp;quot;problemCount&amp;quot;: 113,&lt;br /&gt;
      &amp;quot;displayNames&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;language&amp;quot;: &amp;quot;ko&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;,&lt;br /&gt;
          &amp;quot;short&amp;quot;: &amp;quot;임의 정밀도 / 큰 수 연산&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
  ...(생략)&lt;br /&gt;
 }&lt;br /&gt;
json의 tags를 이용해 원하는 문제 번호의 태그분류를 얻을 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
추가로, titles의 language를 보면 &amp;quot;ko&amp;quot;라고 되어있는데. 문제가 한국어로 서술되어 있다는 뜻이다.&amp;lt;br&amp;gt;&lt;br /&gt;
즉 문제의 서술 언어를 확인할 수 있는데. 이 정보를 이용해 유저들에게 한국어로 된 문제만 제공한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jsoup을 이용해 정적 데이터를 크롤링 했고. API호출을 통해 태그분류와 문제서술 언어정보를 얻었다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음과 같은 java코드를 작성해, 데이터가 존재하지 않을경우 skip하도록 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (timeLimit.equals(0) //시간제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음&lt;br /&gt;
        || memoryLimit.equals(0) //메모리제한이 존재하지 않을경우 기본값 0을 갖도록 전처리되어있음        &lt;br /&gt;
        || problemBody.isBlank()&lt;br /&gt;
        || problemInput.isBlank()&lt;br /&gt;
        || problemOutput.isBlank()&lt;br /&gt;
        || sampleInput.isBlank()&lt;br /&gt;
        || sampleOutput.isBlank())&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
또한, 다음과 같은 java 코드를 작성해. 언어가 한국어가 아니거나 태그분류가 없을경우 skip한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTitles().stream().noneMatch(e -&amp;gt; e.getLanguage().equals(&amp;quot;ko&amp;quot;)))&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;if&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt; (solvedAcProblemDto.getTags().isEmpty())&lt;br /&gt;
    &amp;lt;b&amp;gt;&amp;lt;span style=&amp;quot;color: brown;&amp;quot;&amp;gt;return;&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
필터링을 통과한 데이터는 하나의 객체로 만들어 DB에 저장하는 것으로 크롤링을 끝마친다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
상기한 일련의 과정들을 코드로 구현할때, Java의 parallel stream 규격에 맞추어 구현하였다. 일반 Java stream 코드일때는 싱글스레드로 크롤링 해왔지만. ava parallel stream 코드일때는 멀티스레드로 크롤링 해온다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
동일하드웨어 환경에서 멀티스레드와 싱글스레드 크롤링 속도를 비교해보았다.&amp;lt;br&amp;gt;&lt;br /&gt;
(cpu:i5-6600 4core 4thread gpu:gtx960 ram:16gm)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 결과이다. 307.802826100초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00037.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
싱글스레드 크롤링 결과이다. 742.580477200초 걸렸다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00038.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
멀티스레드 크롤링 시간과 싱글스레드 크롤링 시간이 약 2배정도 되는걸 확인할 수 있다.&amp;lt;br&amp;gt;&lt;br /&gt;
Parallet stream은, 자동으로 모든 thread에 적절히 작업을 분배해 나눠주므로 hread수가 늘어난다면 성능차이는 더욱 커질거라 예상된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Quiz 생성 로직====&lt;br /&gt;
백준의 태그들과 상기한 3개의 태그그룹에 속한 태그들의 교집합 갯수가 1개일 경우만 Quiz를 생성한다.&amp;lt;br&amp;gt;&lt;br /&gt;
그룹에 포함된 4개의 태그를 4지선다로 사용하고. 교집합 1개를 정답태그로 한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ERD====&lt;br /&gt;
[[파일:Image00039.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
위의 ERD와 같이 DB를 구성하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
DB에 직접 SQL문을 질의하지 않았고, Java ORM기술인 JPA를 사용하여 CRUD를 수행하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====흐름도====&lt;br /&gt;
[[파일:Image00040.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====ELO 시스템====&lt;br /&gt;
기존 ELO 시스템은 다음과 같다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula1.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
다음은 기존 ELO시스템을 설명하는 도식이다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00041.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO경쟁에 참여한 모두가 동등하다.&amp;lt;br&amp;gt;&lt;br /&gt;
User의 전체 승률이 50%이다.&amp;lt;br&amp;gt;&lt;br /&gt;
user ELO 평균은 초기값 1200에 수렴한다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
기존 ELO를 본 프로젝트에 적용할 경우, user와 quiz가 동등하지 않음에 따라 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
다음 도식에 표현하였다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00042.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
ELO 경쟁에 참여한 모두가 동등하지 않다.&amp;lt;br&amp;gt;&lt;br /&gt;
만약, user승률 평균은 70%, quiz승률 평균은 30%이라 하면 quiz ELO 평균값은 지속적으로 감소하게 되고, user ELO 평균값은 지속적으로 증가하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이 경우, 다음과 같은 문제가 발생한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00043.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
문제점 : 신규 유저는 quiz중에 가장 어려운 문제를 첫 문제로 조우하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
이를 해결하기 위해 기존 ELO를 변형하여 다음과 같이 적용한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Formula2.PNG]]&amp;lt;br&amp;gt;&lt;br /&gt;
기존 K값은 사용자가 정한 임의의 고정값이었는데,&amp;lt;br&amp;gt;&lt;br /&gt;
본 프로젝트에서는 quiz와 user사이의 정답률에 의해 동적으로 변경되는 값으로 사용하도록 변경한다.&amp;lt;br&amp;gt;&lt;br /&gt;
[[파일:Image00044.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[파일:Image00045.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
변경된 ELO시스템에서는 승률평균은 50%에 수렴하지 않을지더라도, 각 그룹의 ELO평균은 1200으로 수렴하게 된다. 이에 따라 quiz ELO 평균값은 1200으로 수렴할 것이라 기대되고, user ELO 평균값은 1200으로 수렴할 것이라 기대된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====유저 취약 TAG 기반 Problem 추천====&lt;br /&gt;
위에서 상기한 QUIZ의 정답률을 기반으로 해당 유저의 TAG별 정답률을 기록하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
 이 정답률이 낮을 수록 해당 TAG에 대한 PRBLEM 추천 확률이 정비례로 높아지게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
이런 확률로 선택된 TAG는 AUTO_ENCODER_CONST 모델을 거쳐 사용자에게 PROBLEM을 추천하게 된다.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===상세설계 내용===&lt;br /&gt;
◇ AI&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* 모델 성능 비교 및 도메인을 고려하여 모델 선정&lt;br /&gt;
:* AUTO_ENCODER, EASE 모델 업로드 및 모델 적용을 통한 문제 추천&lt;br /&gt;
◇ Back-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Amazon RDS로 Maria DB 인스턴스 관리&lt;br /&gt;
:* Front-end에게 필요한 데이터 전달&lt;br /&gt;
::- Amazon S3를 활용하여 이미지 리소스 전달&lt;br /&gt;
::- Swagger를 활용하여 API 명세서 공유&lt;br /&gt;
◇ Front-end&lt;br /&gt;
:* Amazon EC2 환경에서 서버 배포&lt;br /&gt;
:* Back-end로부터 전달받은 데이터를 CLIENT에게 전달하며 구현한 화면에 포함시킴&lt;br /&gt;
◇ Infra&lt;br /&gt;
:* AI, Back-end, Front-end 서버를 Docker Compose를 활용하여 배포&lt;br /&gt;
:* GitHub Actions를 활용하여 CI/CD 적용&lt;br /&gt;
&lt;br /&gt;
==결과 및 평가==&lt;br /&gt;
===완료 작품의 소개===&lt;br /&gt;
====프로토타입 사진 혹은 작동 장면====&lt;br /&gt;
◇ 메인 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00046.png]]&lt;br /&gt;
:* 헤더에서 코테고리 풀기, 문제 추천, 코테고리 결과, 로그인(프로필) 페이지로 이동&lt;br /&gt;
:* 서비스에 대한 간단한 설명을 메인 배너 하단에 배치&lt;br /&gt;
◇ 퀴즈 풀이 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:* 답안 제출전&lt;br /&gt;
:[[파일:Image00047.png]]&lt;br /&gt;
:* 답안 제출후&lt;br /&gt;
:[[파일:Image00048.png]]&lt;br /&gt;
:* 문제 설명, 입력, 출력, 입력예제, 출력예제 및 메모리 제한, 시간 제한 정보로 코딩테스트 문제에 대한 유형 분류 퀴즈를 제공&lt;br /&gt;
:* 상단에 진행 시간을 배치하여 얼마나 이른 시간 내에 유형을 분류할 수 있는지에 대한 정보 제공  &lt;br /&gt;
:* 문제 별 4지선다를 제공하여 답안을 제출하도록 함 &lt;br /&gt;
:* 제출 후 정/오답 결과를 제공하고, 실제 문제 사이트에서 풀이할 수 있도록 링크를 제공&lt;br /&gt;
◇ 코딩테스트 문제 추천 페이지 &amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00049.png]]&lt;br /&gt;
:* 사용자 백준 풀이 정보 및 코테고리 퀴즈 결과를 기반으로한 코딩테스트 문제를 추천&lt;br /&gt;
:* 이 외에도 오늘의 추천, 실제 기업 기출 문제 추천을 제공 &lt;br /&gt;
◇ 퀴즈 풀이 결과 페이지&amp;lt;br&amp;gt;&lt;br /&gt;
:[[파일:Image00050.png]]&lt;br /&gt;
:* 사용자가 푼 퀴즈를 바탕으로 등급, mmr 점수, 알고리즘 별 정답률, 순위를 제공&lt;br /&gt;
&lt;br /&gt;
====포스터====&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===관련사업비 내역서===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===완료작품의 평가===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===향후계획===&lt;br /&gt;
내용&lt;br /&gt;
&lt;br /&gt;
===특허 출원 내용===&lt;br /&gt;
내용&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Image00050.png&amp;diff=9156</id>
		<title>파일:Image00050.png</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Image00050.png&amp;diff=9156"/>
				<updated>2023-06-24T09:37:49Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	<entry>
		<id>https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Image00049.png&amp;diff=9155</id>
		<title>파일:Image00049.png</title>
		<link rel="alternate" type="text/html" href="https://capstone.uos.ac.kr/cdc/index.php?title=%ED%8C%8C%EC%9D%BC:Image00049.png&amp;diff=9155"/>
				<updated>2023-06-24T09:36:54Z</updated>
		
		<summary type="html">&lt;p&gt;Com237: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Com237</name></author>	</entry>

	</feed>