Update app.py
Browse files
app.py
CHANGED
@@ -1,24 +1,1108 @@
|
|
1 |
-
|
|
|
|
|
|
|
|
|
|
|
2 |
from pydantic import BaseModel
|
3 |
from sentence_transformers import SentenceTransformer
|
4 |
|
5 |
-
|
|
|
|
|
6 |
app = FastAPI()
|
7 |
|
8 |
-
# 모델
|
9 |
-
model
|
|
|
|
|
10 |
|
11 |
-
#
|
12 |
-
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
-
#
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
|
21 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
@app.get("/")
|
23 |
-
|
24 |
-
return {"message": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import re
|
3 |
+
import time
|
4 |
+
import requests
|
5 |
+
import numpy as np
|
6 |
+
from fastapi import FastAPI, HTTPException
|
7 |
from pydantic import BaseModel
|
8 |
from sentence_transformers import SentenceTransformer
|
9 |
|
10 |
+
#####################################
|
11 |
+
# 1) 앱 및 모델 초기화
|
12 |
+
#####################################
|
13 |
app = FastAPI()
|
14 |
|
15 |
+
# 🟢 (A) 모델 로딩
|
16 |
+
print("Loading SentenceTransformer model... (msmarco-distilbert-base-v4)")
|
17 |
+
model_bert = SentenceTransformer('sentence-transformers/msmarco-distilbert-base-v4')
|
18 |
+
print("Model loaded.")
|
19 |
|
20 |
+
# 🟢 (B) 예시 아이템 목록
|
21 |
+
items = [
|
22 |
+
|
23 |
+
# ========= 1~12: 운동 (헬스, 요가, 필라테스, 수영, 테니스, 골프, 클라이밍, 축구, 농구, 볼링, 배드민턴, 러닝) =========
|
24 |
+
{
|
25 |
+
"item_id": 1,
|
26 |
+
"title": "헬스 퍼스널 프로젝트",
|
27 |
+
"desc": "PT 전문 코치와 함께 근력·유산소를 체계적으로 관리 (운동, 헬스)",
|
28 |
+
"personality": "외향형, 이성형"
|
29 |
+
},
|
30 |
+
{
|
31 |
+
"item_id": 2,
|
32 |
+
"title": "빈야사 요가 in 강릉",
|
33 |
+
"desc": "강릉 바다 풍경 속에서 호흡·동작을 익히는 빈야사 요가 클래스 (운동, 요가)",
|
34 |
+
"personality": "내향형, 감정형"
|
35 |
+
},
|
36 |
+
{
|
37 |
+
"item_id": 3,
|
38 |
+
"title": "매트 필라테스 집중 워크숍",
|
39 |
+
"desc": "매트 동작 위주로 기초 코어 힘을 기르는 소그룹 훈련 (운동, 필라테스)",
|
40 |
+
"personality": "내향형, 이성형"
|
41 |
+
},
|
42 |
+
{
|
43 |
+
"item_id": 4,
|
44 |
+
"title": "오픈워터 스위밍 체험",
|
45 |
+
"desc": "바다나 호수에서 수영 실력을 시험하는 자연 친화형 이벤트 (운동, 수영)",
|
46 |
+
"personality": "외향형, 감정형"
|
47 |
+
},
|
48 |
+
{
|
49 |
+
"item_id": 5,
|
50 |
+
"title": "테니스 포핸드 마스터클래스",
|
51 |
+
"desc": "포핸드 스윙·풋워크를 집중 훈련하고 미니 게임으로 실습 (운동, 테니스)",
|
52 |
+
"personality": "외향형, 감정형"
|
53 |
+
},
|
54 |
+
{
|
55 |
+
"item_id": 6,
|
56 |
+
"title": "골프 숏게임 특화 레슨",
|
57 |
+
"desc": "어프로치·퍼팅 등 숏게임 구간을 집중적으로 연습하는 프로그램 (운동, 골프)",
|
58 |
+
"personality": "내향형, 이성형"
|
59 |
+
},
|
60 |
+
{
|
61 |
+
"item_id": 7,
|
62 |
+
"title": "아웃도어 클라이밍 교실",
|
63 |
+
"desc": "실외 바위 지형에서 암벽등반 기초와 안전 수칙을 배우는 챌린지 (운동, 클라이밍)",
|
64 |
+
"personality": "외향형, 감정형"
|
65 |
+
},
|
66 |
+
{
|
67 |
+
"item_id": 8,
|
68 |
+
"title": "풋살 드리블&패스 이벤트",
|
69 |
+
"desc": "축구 소규모 버전 풋살에서 전술·팀워크를 즐기는 주말 클래스 (운동, 축구)",
|
70 |
+
"personality": "외향형, 감정형"
|
71 |
+
},
|
72 |
+
{
|
73 |
+
"item_id": 9,
|
74 |
+
"title": "스트리트 농구 대결전",
|
75 |
+
"desc": "도심 코트에서 농구 토너먼트를 열어 실력을 겨루는 액션 (운동, 농구)",
|
76 |
+
"personality": "외향형, 이성형"
|
77 |
+
},
|
78 |
+
{
|
79 |
+
"item_id": 10,
|
80 |
+
"title": "볼링 스핀&릴리스 테크닉",
|
81 |
+
"desc": "볼링장 전문 강사와 함께 볼 스핀, 릴리스 자세를 교정 (운동, 볼링)",
|
82 |
+
"personality": "내향형, 이성형"
|
83 |
+
},
|
84 |
+
{
|
85 |
+
"item_id": 11,
|
86 |
+
"title": "배드민턴 기술 업 워크숍",
|
87 |
+
"desc": "스매시·드롭샷·푸트워크를 체계적으로 배우는 배드민턴 교실 (운동, 배드민턴)",
|
88 |
+
"personality": "외향형, 감정형"
|
89 |
+
},
|
90 |
+
{
|
91 |
+
"item_id": 12,
|
92 |
+
"title": "10K 러닝 크루 레이스",
|
93 |
+
"desc": "도심 10km 달리기에 함께 도전하며 기록 향상을 목표 (운동, 러닝)",
|
94 |
+
"personality": "내향형, 감정형"
|
95 |
+
},
|
96 |
|
97 |
+
# ========= 13~20: 여행 (국내여행, 해외여행, 백패킹, 캠핑, 도시여행, 맛집탐방, 문화탐방, 힐링여행) =========
|
98 |
+
{
|
99 |
+
"item_id": 13,
|
100 |
+
"title": "부산 해안 로드트립",
|
101 |
+
"desc": "차로 부산 해안 도로를 달리며 해산물과 해변 풍경 만끽 (여행, 국내여행)",
|
102 |
+
"personality": "외향형, 감정형"
|
103 |
+
},
|
104 |
+
{
|
105 |
+
"item_id": 14,
|
106 |
+
"title": "미국 서부 배낭투어",
|
107 |
+
"desc": "LA·샌프란시스코·라스베이거스 등 미국 서부 도시에 떠나는 자유여행 (여행, 해외여행)",
|
108 |
+
"personality": "외향형, 감정형"
|
109 |
+
},
|
110 |
+
{
|
111 |
+
"item_id": 15,
|
112 |
+
"title": "설악산 백패킹 트레킹",
|
113 |
+
"desc": "설악산 국립공원에서 배낭 야영하며 산세와 계곡을 체험 (여행, 백패킹)",
|
114 |
+
"personality": "내향형, 감정형"
|
115 |
+
},
|
116 |
+
{
|
117 |
+
"item_id": 16,
|
118 |
+
"title": "모닥불 캠핑 나이트",
|
119 |
+
"desc": "텐트 피칭과 모닥불 요리로 캠핑 문화를 느끼는 하룻밤 (여행, 캠핑)",
|
120 |
+
"personality": "내향형, 감정형"
|
121 |
+
},
|
122 |
+
{
|
123 |
+
"item_id": 17,
|
124 |
+
"title": "홍콩 시티 골목탐방",
|
125 |
+
"desc": "홍콩 소호·몽콕 등 골목 시장과 길거리 음식을 즐기는 도시여행 (여행, 도시여행)",
|
126 |
+
"personality": "외향형, 이성형"
|
127 |
+
},
|
128 |
+
{
|
129 |
+
"item_id": 18,
|
130 |
+
"title": "전국 맛집 로드쇼",
|
131 |
+
"desc": "블로그·SNS 추천 맛집을 직접 찾아다니며 식도락을 즐기는 투어 (여행, 맛집탐방)",
|
132 |
+
"personality": "외향형, 감정형"
|
133 |
+
},
|
134 |
+
{
|
135 |
+
"item_id": 19,
|
136 |
+
"title": "경주 역사 문화탐방",
|
137 |
+
"desc": "신라시대 유적·박물관·전통 공연을 둘러보며 문화유산을 학습 (여행, 문화탐방)",
|
138 |
+
"personality": "내향형, 이성형"
|
139 |
+
},
|
140 |
+
{
|
141 |
+
"item_id": 20,
|
142 |
+
"title": "지중해 요가 힐링 투어",
|
143 |
+
"desc": "지중해 연안 소도시에서 요가·명상으로 몸과 마음을 재충전 (여행, 힐링여행)",
|
144 |
+
"personality": "외향형, 감정형"
|
145 |
+
},
|
146 |
|
147 |
+
# ========= 21~30: 독서 (소설, 시, 에세이, 자기계발, 인문, 역사, 과학, 경제/경영, 철학, 예술) =========
|
148 |
+
{
|
149 |
+
"item_id": 21,
|
150 |
+
"title": "이문열 '우리들의 일그러진 영웅' 독서토론",
|
151 |
+
"desc": "한국 현대소설의 학교 폭력·권력 관계를 토론하며 생각 확장 (독서, 소설)",
|
152 |
+
"personality": "내향형, 감정형"
|
153 |
+
},
|
154 |
+
{
|
155 |
+
"item_id": 22,
|
156 |
+
"title": "김소월 시 낭독 살롱",
|
157 |
+
"desc": "'진달래꽃' 등 한국적 정서가 깃든 시를 낭송하고 감상을 교류 (독서, 시)",
|
158 |
+
"personality": "내향형, 감정형"
|
159 |
+
},
|
160 |
+
{
|
161 |
+
"item_id": 23,
|
162 |
+
"title": "공지영 '즐거운 나의 집' 에세이 톡",
|
163 |
+
"desc": "가족과 일상 이야기를 담은 에세이를 함께 읽고 공감 (독서, 에세이)",
|
164 |
+
"personality": "내향형, 감정형"
|
165 |
+
},
|
166 |
+
{
|
167 |
+
"item_id": 24,
|
168 |
+
"title": "하이 퍼포먼스 습관 만들기",
|
169 |
+
"desc": "브렌든 버처드 등 자기계발서를 기반으로 아침 루틴을 실천 (독서, 자기계발)",
|
170 |
+
"personality": "내향형, 이성형"
|
171 |
+
},
|
172 |
+
{
|
173 |
+
"item_id": 25,
|
174 |
+
"title": "장하석 '온도계의 철학' 인문 스터디",
|
175 |
+
"desc": "온도·측정의 철학적 의미를 다룬 책을 통해 사고 확장 (독서, 인문)",
|
176 |
+
"personality": "내향형, 이성형"
|
177 |
+
},
|
178 |
+
{
|
179 |
+
"item_id": 26,
|
180 |
+
"title": "유홍준 '나의 문화유산답사기' 역사 독해",
|
181 |
+
"desc": "한국 문화유산 답사기를 읽고 현장 답사 욕구를 높이는 토론 (독서, 역사)",
|
182 |
+
"personality": "내향형, 이성형"
|
183 |
+
},
|
184 |
+
{
|
185 |
+
"item_id": 27,
|
186 |
+
"title": "리처드 도킨스 '이기적 유전자' 과학 세션",
|
187 |
+
"desc": "유전학 이론을 대중적으로 풀어낸 도서를 함께 읽고 토론 (독서, 과학)",
|
188 |
+
"personality": "내향형, 이성형"
|
189 |
+
},
|
190 |
+
{
|
191 |
+
"item_id": 28,
|
192 |
+
"title": "짐 콜린스 '좋은 기업을 넘어 위대한 기업으로' 세미나",
|
193 |
+
"desc": "기업 성공 사례를 분석하며 경제·경영 통찰을 얻는 과정 (독서, 경제/경영)",
|
194 |
+
"personality": "내향형, 이성형"
|
195 |
+
},
|
196 |
+
{
|
197 |
+
"item_id": 29,
|
198 |
+
"title": "장자 '소요유' 철학 살롱",
|
199 |
+
"desc": "도가 사상을 담은 장자의 글을 읽고 자유로운 삶의 가치 논의 (독서, 철학)",
|
200 |
+
"personality": "내향형, 이성형"
|
201 |
+
},
|
202 |
+
{
|
203 |
+
"item_id": 30,
|
204 |
+
"title": "에드가 드가 '발레 수업' 예술책 토크",
|
205 |
+
"desc": "인상주의 화가 드가의 발레 시리즈와 예술서를 같이 탐독 (독서, 예술)",
|
206 |
+
"personality": "내향형, 감정형"
|
207 |
+
},
|
208 |
+
|
209 |
+
# ========= 31~40: 영화 (로맨스, 코미디, 액션, 스릴러, 공포, SF, 판타지, 드라마, 애니메이션, 다큐멘터리) =========
|
210 |
+
{
|
211 |
+
"item_id": 31,
|
212 |
+
"title": "'시간 여행자의 아내' 로맨스 스크리닝",
|
213 |
+
"desc": "시간여행을 소재로 한 사랑 이야기를 함께 보고 울고 웃는 자리 (영화, 로맨스)",
|
214 |
+
"personality": "외향형, 감정형"
|
215 |
+
},
|
216 |
+
{
|
217 |
+
"item_id": 32,
|
218 |
+
"title": "코미디 '슈퍼배드' 웃음 파티",
|
219 |
+
"desc": "'슈퍼배드' 시리즈를 감상하며 유머 코드를 분석하고 떠들썩한 웃음을 공유 (영화, 코미디)",
|
220 |
+
"personality": "외향형, 감정형"
|
221 |
+
},
|
222 |
+
{
|
223 |
+
"item_id": 33,
|
224 |
+
"title": "'킹스맨' 액션씬 관전",
|
225 |
+
"desc": "'킹스맨' 시리즈의 액션 연출·스파이 코드를 짚어보는 상영회 (영화, 액션)",
|
226 |
+
"personality": "외향형, 이성형"
|
227 |
+
},
|
228 |
+
{
|
229 |
+
"item_id": 34,
|
230 |
+
"title": "'서스펙트' 스릴러 미스터리",
|
231 |
+
"desc": "긴장감 넘치는 한국 스릴러 영화를 함께 감상하고 반전 요소 해석 (영화, 스릴러)",
|
232 |
+
"personality": "외향형, 감정형"
|
233 |
+
},
|
234 |
+
{
|
235 |
+
"item_id": 35,
|
236 |
+
"title": "'에일리언' 공포 SF 밤샘",
|
237 |
+
"desc": "'에일리언' 시리즈를 몰아보며 외계 생명체 공포와 SF 설정을 토론 (영화, 공포)",
|
238 |
+
"personality": "내향형, 감정형"
|
239 |
+
},
|
240 |
+
{
|
241 |
+
"item_id": 36,
|
242 |
+
"title": "'그래비티' SF 토크",
|
243 |
+
"desc": "우주 공간 조난 스토리를 그린 '그래비티'의 과학·연출을 분석 (영화, SF)",
|
244 |
+
"personality": "외향형, 감정형"
|
245 |
+
},
|
246 |
+
{
|
247 |
+
"item_id": 37,
|
248 |
+
"title": "'해리 포터' 판타지 앤딩",
|
249 |
+
"desc": "호그와트 마법 세계관을 연속 상영하고 팬심을 나누는 스팟 (영화, 판타지)",
|
250 |
+
"personality": "외향형, 감정형"
|
251 |
+
},
|
252 |
+
{
|
253 |
+
"item_id": 38,
|
254 |
+
"title": "'인생은 아름다워' 드라마 감동",
|
255 |
+
"desc": "전쟁 속 가족사랑을 그린 이탈리아 명작으로 희망 메시지 나눔 (영화, 드라마)",
|
256 |
+
"personality": "외향형, 감정형"
|
257 |
+
},
|
258 |
+
{
|
259 |
+
"item_id": 39,
|
260 |
+
"title": "'너의 이름은' 애니메이션 스페셜",
|
261 |
+
"desc": "신카이 마코토 감독의 빛나는 작화·청춘 판타지를 감상 (영화, 애니메이션)",
|
262 |
+
"personality": "외향형, 감정형"
|
263 |
+
},
|
264 |
+
{
|
265 |
+
"item_id": 40,
|
266 |
+
"title": "'마이클 무어' 다큐 포럼",
|
267 |
+
"desc": "'화씨 9/11' 등 사회·정치적 메시지가 담긴 다큐를 보고 토론 (영화, 다큐멘터리)",
|
268 |
+
"personality": "외향형, 이성형"
|
269 |
+
},
|
270 |
+
|
271 |
+
# ========= 41~50: 게임 (RPG, FPS, 액션, 전략, 시뮬레이션, 스포츠, 퍼즐, 음악/리듬, 카드, MMORPG) =========
|
272 |
+
{
|
273 |
+
"item_id": 41,
|
274 |
+
"title": "'젤다의 전설: 야생의 숨결' RPG 탐험",
|
275 |
+
"desc": "오픈월드 명작 '젤다' 시리즈를 탐험하며 퍼즐·전투 방식을 공유 (게임, RPG)",
|
276 |
+
"personality": "내향형, 감정형"
|
277 |
+
},
|
278 |
+
{
|
279 |
+
"item_id": 42,
|
280 |
+
"title": "'콜 오브 듀티' FPS 워존 배틀",
|
281 |
+
"desc": "밀리터리 FPS에서 팀 단위 전술을 실행하고 승리를 노리는 대전 (게임, FPS)",
|
282 |
+
"personality": "외향형, 이성형"
|
283 |
+
},
|
284 |
+
{
|
285 |
+
"item_id": 43,
|
286 |
+
"title": "'갓 오브 워' 액션 앤 레이지",
|
287 |
+
"desc": "크레토스의 여정·스킬 콤보를 파고들며 액션게임의 재미 체험 (게임, 액션)",
|
288 |
+
"personality": "외향형, 감정형"
|
289 |
+
},
|
290 |
+
{
|
291 |
+
"item_id": 44,
|
292 |
+
"title": "'문명6' 전략 빌드 세션",
|
293 |
+
"desc": "턴제 전략 '문명6'에서 문명별 특성과 승리 조건을 분석 (게임, 전략)",
|
294 |
+
"personality": "내향형, 이성형"
|
295 |
+
},
|
296 |
+
{
|
297 |
+
"item_id": 45,
|
298 |
+
"title": "'플래닛 코스터' 시뮬레이션 제작소",
|
299 |
+
"desc": "놀이공원 경영 게임에서 놀이기구 배치·경영을 디자인 (게임, 시뮬레이션)",
|
300 |
+
"personality": "내향형, 감정형"
|
301 |
+
},
|
302 |
+
{
|
303 |
+
"item_id": 46,
|
304 |
+
"title": "'NBA 2K' 스포츠 매치",
|
305 |
+
"desc": "농구게임 'NBA 2K'로 온라인·오프라인 토너먼트를 개최 (게임, 스포츠)",
|
306 |
+
"personality": "외향형, 감정형"
|
307 |
+
},
|
308 |
+
{
|
309 |
+
"item_id": 47,
|
310 |
+
"title": "'폴가이즈' 퍼즐 액션 배틀",
|
311 |
+
"desc": "귀엽고 혼란스러운 장애물 코스로 다수 인원이 경쟁 (게임, 퍼즐)",
|
312 |
+
"personality": "외향형, 이성형"
|
313 |
+
},
|
314 |
+
{
|
315 |
+
"item_id": 48,
|
316 |
+
"title": "'비트세이버' 리듬 VR 체험",
|
317 |
+
"desc": "VR 기기를 착용해 박자에 맞춰 블록을 베는 리듬 대결 (게임, 음악/리듬)",
|
318 |
+
"personality": "내향형, 감정형"
|
319 |
+
},
|
320 |
+
{
|
321 |
+
"item_id": 49,
|
322 |
+
"title": "'매직: 더 개더링' 카드 덱실험",
|
323 |
+
"desc": "TCG의 원조격인 ‘매직’에서 덱 빌드와 대전 전략을 연구 (게임, 카드)",
|
324 |
+
"personality": "내향형, 이성형"
|
325 |
+
},
|
326 |
+
{
|
327 |
+
"item_id": 50,
|
328 |
+
"title": "'월드 오브 워크래프트' MMORPG 길드레이드",
|
329 |
+
"desc": "아제로스에서 길드원이 힘을 합쳐 레이드를 진행 (게임, MMORPG)",
|
330 |
+
"personality": "외향형, 이성형"
|
331 |
+
},
|
332 |
+
|
333 |
+
# ========= 51~60: 공예 (뜨개질, 자수, 도자기, 가죽공예, 목공예, 비즈공예, 캔들/디퓨저, 페이퍼크래프트, 마크라메, 레진아트) =========
|
334 |
+
{
|
335 |
+
"item_id": 51,
|
336 |
+
"title": "코바늘 뜨개질 애착인형 DIY",
|
337 |
+
"desc": "코바늘 기법으로 인형이나 소품을 만드는 초급자 대상 워크숍 (공예, 뜨개질)",
|
338 |
+
"personality": "내향형, 감정형"
|
339 |
+
},
|
340 |
+
{
|
341 |
+
"item_id": 52,
|
342 |
+
"title": "일본 자수 '사시코' 교실",
|
343 |
+
"desc": "사시코 기법으로 앞치마·티매트를 장식하는 레슨 (공예, 자수)",
|
344 |
+
"personality": "내향형, 이성형"
|
345 |
+
},
|
346 |
+
{
|
347 |
+
"item_id": 53,
|
348 |
+
"title": "도자기 핸드페인팅 체험",
|
349 |
+
"desc": "빚은 도자기에 직접 그림·문양을 그려 소성까지 경험 (공예, 도자기)",
|
350 |
+
"personality": "내향형, 이성형"
|
351 |
+
},
|
352 |
+
{
|
353 |
+
"item_id": 54,
|
354 |
+
"title": "가죽 파우치 제작 스튜디오",
|
355 |
+
"desc": "가죽 재단·바느질·마감까지 소형 파우치를 만드는 실습 (공예, 가죽공예)",
|
356 |
+
"personality": "내향형, 이성형"
|
357 |
+
},
|
358 |
+
{
|
359 |
+
"item_id": 55,
|
360 |
+
"title": "목공예 숟가락 만들기 워크숍",
|
361 |
+
"desc": "나무를 깎고 다듬어 주방용 숟가락을 만드는 기초 체험 (공예, 목공예)",
|
362 |
+
"personality": "내향형, 이성형"
|
363 |
+
},
|
364 |
+
{
|
365 |
+
"item_id": 56,
|
366 |
+
"title": "비즈공예 액세서리 디자인",
|
367 |
+
"desc": "비즈 구슬로 팔찌·목걸이를 만들고 색감 패턴을 익히는 클래스 (공예, 비즈공예)",
|
368 |
+
"personality": "내향형, 감정형"
|
369 |
+
},
|
370 |
+
{
|
371 |
+
"item_id": 57,
|
372 |
+
"title": "젤 캔들 & 디퓨저 아틀리에",
|
373 |
+
"desc": "투명 젤 왁스로 캔들과 디퓨저를 창작하며 향기를 디자인 (공예, 캔들/디퓨저)",
|
374 |
+
"personality": "내향형, 이성형"
|
375 |
+
},
|
376 |
+
{
|
377 |
+
"item_id": 58,
|
378 |
+
"title": "페이퍼크래프트 동물 피규어",
|
379 |
+
"desc": "종이로 입체 동물 모형을 만들고 채색·디테일 작업 (공예, 페이퍼크래프트)",
|
380 |
+
"personality": "내향형, 이성형"
|
381 |
+
},
|
382 |
+
{
|
383 |
+
"item_id": 59,
|
384 |
+
"title": "마크라메 해먹 의자 만들기",
|
385 |
+
"desc": "매듭 기법을 이용해 해먹 의자·월행잉 등 인테리어 소품 제작 (공예, 마크라메)",
|
386 |
+
"personality": "내향형, 이성형"
|
387 |
+
},
|
388 |
+
{
|
389 |
+
"item_id": 60,
|
390 |
+
"title": "레진아트 트레이 공방",
|
391 |
+
"desc": "레진과 색소·글리터로 컵받침이나 작은 트레이를 만드는 작업 (공예, 레진아트)",
|
392 |
+
"personality": "내향형, 이성형"
|
393 |
+
},
|
394 |
+
|
395 |
+
# ========== 61~71: 추가 11개 자유 항목 (임의 분야) ==========
|
396 |
+
{
|
397 |
+
"item_id": 61,
|
398 |
+
"title": "보드게임 '카탄' 챌린지",
|
399 |
+
"desc": "전략 보드게임 '카탄' 대회로 무역·개척 전술을 겨루는 이벤트 (기타, 보드게임)",
|
400 |
+
"personality": "외향형, 이성형"
|
401 |
+
},
|
402 |
+
{
|
403 |
+
"item_id": 62,
|
404 |
+
"title": "스페인어 기초 회화 교실",
|
405 |
+
"desc": "hola! 간단한 문장·회화를 배워 여행·일상에서 활용 (기타, 언어학습)",
|
406 |
+
"personality": "내향형, 감정형"
|
407 |
+
},
|
408 |
+
{
|
409 |
+
"item_id": 63,
|
410 |
+
"title": "홈브루잉 커피 실습",
|
411 |
+
"desc": "원두 고르기부터 핸드드립·에스프레소 추출까지 커피 제작 전과정 체험 (기타, 요리/음료)",
|
412 |
+
"personality": "내향형, 이성형"
|
413 |
+
},
|
414 |
+
{
|
415 |
+
"item_id": 64,
|
416 |
+
"title": "K-POP 댄스 커버 스튜디오",
|
417 |
+
"desc": "최신 아이돌 안무를 함께 연습·촬영해보는 퍼포먼스 프로젝트 (기타, 댄스)",
|
418 |
+
"personality": "외향형, 감정형"
|
419 |
+
},
|
420 |
+
{
|
421 |
+
"item_id": 65,
|
422 |
+
"title": "플라워 레슨 & 꽃다발 디자인",
|
423 |
+
"desc": "생화를 활용해 부케·꽃다발을 직접 만드는 교실 (기타, 플라워)",
|
424 |
+
"personality": "내향형, 감정형"
|
425 |
+
},
|
426 |
+
{
|
427 |
+
"item_id": 66,
|
428 |
+
"title": "드론 항공촬영 워크숍",
|
429 |
+
"desc": "드론 조종법·촬영 기법·영상 편집을 배우고 실습 (기타, 드론)",
|
430 |
+
"personality": "외향형, 이성형"
|
431 |
+
},
|
432 |
+
{
|
433 |
+
"item_id": 67,
|
434 |
+
"title": "비건 베이커리 클래스",
|
435 |
+
"desc": "달걀·버터 없이 쿠키·빵을 만드는 레시피와 노하우 학습 (기타, 요리/베이킹)",
|
436 |
+
"personality": "내향형, 이성형"
|
437 |
+
},
|
438 |
+
{
|
439 |
+
"item_id": 68,
|
440 |
+
"title": "애견 행동교정 & 트릭 클래스",
|
441 |
+
"desc": "반려견 기본 행동교정·산책 요령·간단한 재주를 훈련 (기타, 반려동물)",
|
442 |
+
"personality": "외향형, 감정형"
|
443 |
+
},
|
444 |
+
{
|
445 |
+
"item_id": 69,
|
446 |
+
"title": "영화 시나리오 작법 워크숍",
|
447 |
+
"desc": "시놉시스·캐릭터 구성을 배우고 단편 시나리오를 써보는 활동 (기타, 글쓰기)",
|
448 |
+
"personality": "내향형, 이성형"
|
449 |
+
},
|
450 |
+
{
|
451 |
+
"item_id": 70,
|
452 |
+
"title": "홈칵테일 믹솔로지 이벤트",
|
453 |
+
"desc": "칵테일 재료·비율을 익혀 집에서 간단히 만들 수 있는 레시피 실습 (기타, 요리/음료)",
|
454 |
+
"personality": "외향형, 감정형"
|
455 |
+
},
|
456 |
+
{
|
457 |
+
"item_id": 71,
|
458 |
+
"title": "유튜브 브이로그 크리에이팅",
|
459 |
+
"desc": "영상 기획·촬영·편집 노하우를 배우고 브이로그를 완성 (기타, 영상콘텐츠)",
|
460 |
+
"personality": "내향형, 이성형"
|
461 |
+
},
|
462 |
+
|
463 |
+
# ==== (운동 - 12개 대응, item_id 73~84) ====================================
|
464 |
+
{"item_id": 73, "title": "크로스핏 열정단", "desc": "고강도 크로스핏 운동으로 체력을 단련하는 열정적 모임 (온동, 헬스장)", "personality": "외향형, 감정형"},
|
465 |
+
{"item_id": 74, "title": "명상 요가 서클", "desc": "몸의 이완과 마음의 평화를 함께 추구하는 명상 요가 모임 (운동, 요가)", "personality": "외향형, 감정형"},
|
466 |
+
{"item_id": 75, "title": "코어 트레이닝 팸", "desc": "필라테스로 코어 근력과 유연성을 키우는 그룹 (운동, 필라테스)", "personality": "외향형, 감정형"},
|
467 |
+
{"item_id": 76, "title": "파도타기 워터팀", "desc": "수영과 워터 스포츠를 함께 즐기며 체력을 키우는 모임 (운동, 수영)", "personality": "외향형, 감정형"},
|
468 |
+
{"item_id": 77, "title": "라켓 드림클럽", "desc": "테니스를 비롯한 라켓 스포츠를 같이 배우고 즐기는 동호회 (운동, 테니스)", "personality": "외향형, 감정형"},
|
469 |
+
{"item_id": 78, "title": "필드 골프 리더스", "desc": "골프 스윙 기술과 필드 매너를 함께 익히는 라운딩 팀 (운동, 골프)", "personality": "외향형, 감정형"},
|
470 |
+
{"item_id": 79, "title": "슬링 텀블러즈", "desc": "암벽등반과 슬링 트레이닝으로 색다른 운동을 체험하는 그룹 (운동, 클라이밍)", "personality": "외향형, 감정형"},
|
471 |
+
{"item_id": 80, "title": "스포츠 골든리그", "desc": "주중·주말에 축구 경기를 주기적으로 여는 커뮤니티 (운동, 축구)", "personality": "외향형, 감정형"},
|
472 |
+
{"item_id": 81, "title": "하프코트 슈터스", "desc": "농구 코트에서 함께 뛰고 실력을 배양하는 팀 (운동, 농구)", "personality": "외향형, 감정형"},
|
473 |
+
{"item_id": 82, "title": "스트라이크 러버스", "desc": "볼링 점수를 올리기 위해 함께 연구하고 즐기는 동아리 (운동, 볼링)", "personality": "외향형, 감정형"},
|
474 |
+
{"item_id": 83, "title": "스매싱 배드민턴", "desc": "배드민턴 스매시 기술과 경기를 함께 연습하는 학습 모임 (운동, 배드민턴)", "personality": "외향형, 감정형"},
|
475 |
+
{"item_id": 84, "title": "나이트 러너스", "desc": "야간 러닝을 통해 도시를 누비며 체력을 기르는 크루 (운동, 러닝)", "personality": "외향형, 감정형"},
|
476 |
+
|
477 |
+
# ==== (여행 - 8개 대응, item_id 85~92) =====================================
|
478 |
+
{"item_id": 85, "title": "오지여행 탐험대", "desc": "국내 숨겨진 오지를 찾아 떠나며 모험심을 기르는 모임 (여행, 국내여행)", "personality": "외향형, 감정형"},
|
479 |
+
{"item_id": 86, "title": "글로벌 백팩 트립", "desc": "해외 배낭여행 루트를 함께 계획하고 실행하는 동호회 (여행, 해외여행)", "personality": "외향형, 감정형"},
|
480 |
+
{"item_id": 87, "title": "필드 캠핑 어드벤처", "desc": "백패킹과 캠핑을 결합해 자연에서 살아보는 체험 모임 (여행, 백패킹)", "personality": "외향형, 감정형"},
|
481 |
+
{"item_id": 88, "title": "패밀리 캠핑 잼", "desc": "가족 단위로 캠핑하며 자연 속 소통을 즐기는 그룹 (여행, 캠핑)", "personality": "외향형, 감정형"},
|
482 |
+
{"item_id": 89, "title": "골목길 투어 클럽", "desc": "도시 골목길과 역사적 공간을 함께 탐방하는 여행 서클 (여행, 도시여행)", "personality": "외향형, 감정형"},
|
483 |
+
{"item_id": 90, "title": "미식헌터 크루", "desc": "전국 맛집을 조사하고 직접 시식 투어를 떠나는 모임 (여행, 맛집탐방)", "personality": "외향형, 감정형"},
|
484 |
+
{"item_id": 91, "title": "문화유산 탐방기획사", "desc": "전통 문화유산과 축제를 기획·탐방하는 여행 동아리 (여행, 문화탐방)", "personality": "외향형, 감정형"},
|
485 |
+
{"item_id": 92, "title": "숲속 힐링 트래블", "desc": "자연 속에서 치유와 재충전을 목적으로 여행하는 그룹 (여행, 힐링여행)", "personality": "외향형, 감정형"},
|
486 |
+
|
487 |
+
# ==== (독서 - 10개 대응, item_id 93~102) ==================================
|
488 |
+
{"item_id": 93, "title": "문학 리뷰 서클", "desc": "소설과 문학작품을 읽고 비평하는 책동아리 (독서, 소설)", "personality": "내향형, 감정형"},
|
489 |
+
{"item_id": 94, "title": "시인 꿈나무 모임", "desc": "서로의 시를 낭독하고 공유하는 창작 시클럽 (독서, 시)", "personality": "내향형, 감정형"},
|
490 |
+
{"item_id": 95, "title": "마음글쓰기 에세이회", "desc": "에세이로 일상과 감정을 표현하며 소통하는 글모임 (독서, 에세이)", "personality": "내향형, 이성형"},
|
491 |
+
{"item_id": 96, "title": "실천형 자기계발단", "desc": "자기계발서를 읽고 즉시 실천 계획을 세우는 스터디 (독서, 자기계발)", "personality": "내향형, 이성형"},
|
492 |
+
{"item_id": 97, "title": "깊이읽기 인문소사이어티", "desc": "인문학 텍스트를 심층 토론하며 사고력을 확장하는 그룹 (독서, 인문)", "personality": "내향형, 이성형"},
|
493 |
+
{"item_id": 98, "title": "역사공부 디스커션", "desc": "시대별 역사적 사건을 공부하고 자유롭게 논의하는 모임 (독서, 역사)", "personality": "내향형, 이성형"},
|
494 |
+
{"item_id": 99, "title": "과학탐구 북클럽", "desc": "최신 과학 서적을 중심으로 아이디어를 나누는 독서회 (독서, 과학)", "personality": "내향형, 이성형"},
|
495 |
+
{"item_id": 100, "title": "경영전략 독해팀", "desc": "경제/경영 관련 서적을 함께 분석하고 사례를 연구하는 그룹 (독서, 경제/경영)", "personality": "내향형, 이성형"},
|
496 |
+
{"item_id": 101, "title": "철학강독 세미나", "desc": "철학 원전을 읽고 핵심 개념을 토론하는 학술 모임 (독서, 철학)", "personality": "내향형, 이성형"},
|
497 |
+
{"item_id": 102, "title": "아트북 인사이트회", "desc": "예술 관련 서적을 통해 예술사와 작품 세계를 탐구하는 모임 (독서, 예술)", "personality": "내향형, 감정형"},
|
498 |
+
|
499 |
+
# ==== (영화 - 10개 대응, item_id 103~112) =================================
|
500 |
+
{"item_id": 103, "title": "낭만 영화 애호가들", "desc": "감성적인 로맨스 영화를 좋아하는 사람들의 모임 (영화, 로맨스)", "personality": "외향형, 감정형"},
|
501 |
+
{"item_id": 104, "title": "폭소 코미디 페스티벌", "desc": "웃음을 주제로 코미디 영화를 함께 보는 소모임 (영화, 코미디)", "personality": "외향형, 감정형, 이성형"},
|
502 |
+
{"item_id": 105, "title": "액션매니아즈", "desc": "박진감 넘치는 액션 영화의 매력을 해부하는 그룹 (영화, 액션)", "personality": "외향형, 감정형"},
|
503 |
+
{"item_id": 106, "title": "서스펜스 시네마분석단", "desc": "스릴러 영화 속 긴장감과 스토리를 분석하는 모임 (영화, 스릴러)", "personality": "외향형, 감정형"},
|
504 |
+
{"item_id": 107, "title": "호러매틱 스터디", "desc": "공포영화의 분위기와 연출을 집중 탐구하는 팀 (영화, 공포)", "personality": "외향형, 감정형"},
|
505 |
+
{"item_id": 108, "title": "SF 월드 디스커버리", "desc": "공상과학 영화를 보고 미래 기술과 세계관을 토론하는 모임 (영화, SF)", "personality": "외향형, 감정형"},
|
506 |
+
{"item_id": 109, "title": "판타지 이매지네이션", "desc": "환상적인 판타지 영화를 감상하며 아이디어를 공유하는 서클 (영화, 판타지)", "personality": "외향형, 감정형"},
|
507 |
+
{"item_id": 110, "title": "휴먼드라마 인사이트", "desc": "감동적인 드라마 장르 영화를 함께 보고 교훈을 찾는 모임 (영화, 드라마)", "personality": "외향형, 감정형"},
|
508 |
+
{"item_id": 111, "title": "애니 애호회", "desc": "다양한 애니메이션 영화를 정기 상영하며 감상하는 팬클럽 (영화, 애니메이션)", "personality": "외향형, 감정형"},
|
509 |
+
{"item_id": 112, "title": "다큐 리뷰 포럼", "desc": "다큐멘터리 영화를 보고 사회·환경 문제를 논의하는 모임 (영화, 다큐멘터리)", "personality": "외향형, 이성형"},
|
510 |
+
|
511 |
+
# ==== (게임 - 10개 대응, item_id 113~122) =================================
|
512 |
+
{"item_id": 113, "title": "RPG 모험단", "desc": "판타지 세계에서 함께 파티를 이뤄 모험하는 RPG 팀 (게임, RPG)", "personality": "외향형, 이성형"},
|
513 |
+
{"item_id": 114, "title": "FPS 고인물 클랜", "desc": "고난도 슈팅 기술을 연습하며 대회에도 나가는 FPS 동호회 (게임, FPS)", "personality": "외향형, 이성형"},
|
514 |
+
{"item_id": 115, "title": "액션코어 전략팀", "desc": "액션 게임의 숨겨진 테크닉과 콤보를 연구하는 그룹 (게임, 액션)", "personality": "외향형, 이성형"},
|
515 |
+
{"item_id": 116, "title": "전략모드 시뮬클럽", "desc": "전략 시뮬레이션 장르를 심도 있게 플레이·분석하는 동호회 (게임, 전략)", "personality": "외향형, 이성형"},
|
516 |
+
{"item_id": 117, "title": "시뮬레이션 마니아들", "desc": "도시건설, 경영 시뮬레이션 등 다양한 시뮬 게임을 즐기는 모임 (게임, 시뮬레이션)", "personality": "외향형, 이성형, 감정형"},
|
517 |
+
{"item_id": 118, "title": "스포츠게이머 챌린지", "desc": "축구·농구 등 스포츠게임 리그를 운영하는 커뮤니티 (게임, 스포츠)", "personality": "외향형, 이성형"},
|
518 |
+
{"item_id": 119, "title": "퍼즐 브레인홀릭", "desc": "퍼��·두뇌게임을 함께 풀며 아이디어를 공유하는 팀 (게임, 퍼즐)", "personality": "외향형, 이성형"},
|
519 |
+
{"item_id": 120, "title": "리듬게임 오케스트라", "desc": "음악/리듬게임에서 합주하는 느낌으로 협력 플레이하는 모임 (게임, 음악/리듬)", "personality": "외향형, 이성형"},
|
520 |
+
{"item_id": 121, "title": "카드플레이 매니아", "desc": "포커·TCG 등 카드 기반 게임을 심도 있게 즐기는 동아리 (게임, 카드)", "personality": "외향형, 이성형"},
|
521 |
+
{"item_id": 122, "title": "MMORPG 연합길드", "desc": "대규모 온라인 RPG에서 길드원들과 함께 도전하는 팀 (게임, MMORPG)", "personality": "외향형, 이성형"},
|
522 |
+
|
523 |
+
# ==== (공예 - 10개 대응, item_id 123~132) =================================
|
524 |
+
{"item_id": 123, "title": "니트디자인 스터디오", "desc": "뜨개질로 패션 소품과 의류를 창작하는 워크숍 (공예, 뜨개질)", "personality": "내향형, 이성형"},
|
525 |
+
{"item_id": 124, "title": "자수 디테일연구회", "desc": "섬세한 자수 기법을 연구하며 작품을 완성하는 모임 (공예, 자수)", "personality": "내향형, 이성형"},
|
526 |
+
{"item_id": 125, "title": "도예 공예단", "desc": "도자기 공예로 식기·인테리어 소품을 제작해보는 그룹 (공예, 도자기)", "personality": "내향형, 이성형"},
|
527 |
+
{"item_id": 126, "title": "가죽공예 스킬랩", "desc": "가죽 재단부터 바느질까지 실습하고 디자인을 공유하는 모임 (공예, 가죽공예)", "personality": "내향형, 이성형"},
|
528 |
+
{"item_id": 127, "title": "목공 마스터스", "desc": "목재를 활용해 가구·장식품을 제작하며 기술을 배우는 모임 (공예, 목공예)", "personality": "내향형, 이성형"},
|
529 |
+
{"item_id": 128, "title": "비즈 디자인 팩토리", "desc": "비즈공예로 액세서리·장신구를 창작하는 교실 (공예, 비즈공예)", "personality": "내향형, 이성형"},
|
530 |
+
{"item_id": 129, "title": "캔들/디퓨저 크리에이티브", "desc": "향초와 디퓨저를 예술적으로 표현해보는 창작 스튜디오 (공예, 캔들/디퓨저)", "personality": "내향형, 이성형"},
|
531 |
+
{"item_id": 130, "title": "페이퍼아트 디자인랩", "desc": "종이 공예로 독특한 작품과 미니어처를 만드는 연구회 (공예, 페이퍼크래프트)", "personality": "내향형, 이성형"},
|
532 |
+
{"item_id": 131, "title": "마크라메 공예실", "desc": "마크라메 매듭 기법을 다양하게 시도해보는 작업실 (공예, 마크라메)", "personality": "내향형, 이성형"},
|
533 |
+
{"item_id": 132, "title": "레진아트 크리에이터즈", "desc": "레진을 활용해 장식품·소품을 디자인하고 공유하는 모임 (공예, 레진아트)", "personality": "내향형, 이성형"},
|
534 |
+
# ===== [133~144] 운동 (12개)
|
535 |
+
{
|
536 |
+
"item_id": 133,
|
537 |
+
"title": "나이키 헬스 피트니스 챌린지",
|
538 |
+
"desc": "헬스장에서 나이키 프로그램을 통해 웨이트 및 유산소를 마스터 (운동, 헬스)",
|
539 |
+
"personality": "외향형, 감정형"
|
540 |
+
},
|
541 |
+
{
|
542 |
+
"item_id": 134,
|
543 |
+
"title": "아쉬탕가 요가 클래스 in 발리",
|
544 |
+
"desc": "발리 자연 속에서 명상·아사나 요가를 심도 있게 체험 (운동, 요가)",
|
545 |
+
"personality": "내향형, 감정형"
|
546 |
+
},
|
547 |
+
{
|
548 |
+
"item_id": 135,
|
549 |
+
"title": "리포머 필라테스 스튜디오",
|
550 |
+
"desc": "기구 필라테스로 자세 교정과 코어 강화에 집중 (운동, 필라테스)",
|
551 |
+
"personality": "내향형, 이성형"
|
552 |
+
},
|
553 |
+
{
|
554 |
+
"item_id": 136,
|
555 |
+
"title": "아쿠아 스위밍 프로젝트",
|
556 |
+
"desc": "실내 수영장에서 영법·호흡법을 익히고 오픈워터 도전 (운동, 수영)",
|
557 |
+
"personality": "외향형, 감정형"
|
558 |
+
},
|
559 |
+
{
|
560 |
+
"item_id": 137,
|
561 |
+
"title": "윔블던 테니스 레슨",
|
562 |
+
"desc": "프로 코치와 함께 랠리·발리를 집중 훈련, 미니 매치 진행 (운동, 테니스)",
|
563 |
+
"personality": "외향형, 이성형"
|
564 |
+
},
|
565 |
+
{
|
566 |
+
"item_id": 138,
|
567 |
+
"title": "스크린 골프 라운딩",
|
568 |
+
"desc": "필드 대신 스크린 골프로 스윙 교정하고 퍼팅 실력을 키움 (운동, 골프)",
|
569 |
+
"personality": "내향형, 이성형"
|
570 |
+
},
|
571 |
+
{
|
572 |
+
"item_id": 139,
|
573 |
+
"title": "실내 클라이밍 챌린지",
|
574 |
+
"desc": "암벽등반 센터에서 다양한 코스를 공략하며 근지구력 향상 (운동, 클라이밍)",
|
575 |
+
"personality": "외향형, 감정형"
|
576 |
+
},
|
577 |
+
{
|
578 |
+
"item_id": 140,
|
579 |
+
"title": "풋볼 매치데이 이벤트",
|
580 |
+
"desc": "축구 팬들이 모여 포메이션 짜고 미니 경기를 즐기는 일정 (운동, 축구)",
|
581 |
+
"personality": "외향형, 감정형"
|
582 |
+
},
|
583 |
+
{
|
584 |
+
"item_id": 141,
|
585 |
+
"title": "NBA 농구 액션타임",
|
586 |
+
"desc": "코트에서 드리블·슛을 연습하고 3:3 스크리미지를 진행 (운동, 농구)",
|
587 |
+
"personality": "외향형, 감정형"
|
588 |
+
},
|
589 |
+
{
|
590 |
+
"item_id": 142,
|
591 |
+
"title": "락볼링 스트라이크 파티",
|
592 |
+
"desc": "볼링장에서 음악과 함께 스트라이크 확률을 높이는 교류전 (운동, 볼링)",
|
593 |
+
"personality": "내향형, 감정형"
|
594 |
+
},
|
595 |
+
{
|
596 |
+
"item_id": 143,
|
597 |
+
"title": "셔틀콕 배드민턴 교실",
|
598 |
+
"desc": "배드민턴 스매시·푸트워크 집중 연습 후 미니 토너먼트 (운동, 배드민턴)",
|
599 |
+
"personality": "외향형, 감정형"
|
600 |
+
},
|
601 |
+
{
|
602 |
+
"item_id": 144,
|
603 |
+
"title": "하프마라톤 러닝 레이스",
|
604 |
+
"desc": "도심 10km·21km 레이스에 도전하며 기록 향상을 목표 (운동, 러닝)",
|
605 |
+
"personality": "내향형, 감정형"
|
606 |
+
},
|
607 |
+
|
608 |
+
# ===== [145~152] 여행 (8개)
|
609 |
+
{
|
610 |
+
"item_id": 145,
|
611 |
+
"title": "강원도 로드트립",
|
612 |
+
"desc": "차로 강원도 해안·산골 명소를 돌아보며 자연을 만끽 (여행, 국내여행)",
|
613 |
+
"personality": "내향형, 감정형"
|
614 |
+
},
|
615 |
+
{
|
616 |
+
"item_id": 146,
|
617 |
+
"title": "유럽 배낭 자유여행",
|
618 |
+
"desc": "파리·로마·바르셀로나를 포함해 유럽 도시들을 여행 (여행, 해외여행)",
|
619 |
+
"personality": "외향형, 감정형"
|
620 |
+
},
|
621 |
+
{
|
622 |
+
"item_id": 147,
|
623 |
+
"title": "지리산 백패킹 트레일",
|
624 |
+
"desc": "배낭 하나로 지리산 둘레길을 걸으며 자연 속 야영 (여행, 백패킹)",
|
625 |
+
"personality": "내향형, 감정형"
|
626 |
+
},
|
627 |
+
{
|
628 |
+
"item_id": 148,
|
629 |
+
"title": "캠핑 파이어나이트",
|
630 |
+
"desc": "텐트 치고 모닥불을 즐기며 가족·친구와 소통하는 프로그램 (여행, 캠핑)",
|
631 |
+
"personality": "외향형, 감정형"
|
632 |
+
},
|
633 |
+
{
|
634 |
+
"item_id": 149,
|
635 |
+
"title": "서울 골목투어",
|
636 |
+
"desc": "익선동·을지로 등 오래된 골목길 카페·맛집을 탐방 (여행, 도시여행)",
|
637 |
+
"personality": "외향형, 감정형"
|
638 |
+
},
|
639 |
+
{
|
640 |
+
"item_id": 150,
|
641 |
+
"title": "전주 한옥마을 미식 탐방",
|
642 |
+
"desc": "전주의 비빔밥·막걸리·한정식을 둘러보는 식도락 여행 (여행, 맛집탐방)",
|
643 |
+
"personality": "외향형, 감정형"
|
644 |
+
},
|
645 |
+
{
|
646 |
+
"item_id": 151,
|
647 |
+
"title": "경복궁 문화탐방",
|
648 |
+
"desc": "왕궁·전통 공연·박물관을 돌며 한국 역사를 배우는 코스 (여행, 문화탐방)",
|
649 |
+
"personality": "내향형, 이성형"
|
650 |
+
},
|
651 |
+
{
|
652 |
+
"item_id": 152,
|
653 |
+
"title": "제주 오름 힐링투어",
|
654 |
+
"desc": "제주 오름·용암동굴을 걸으며 자연 속에서 재충전 (여행, 힐링여행)",
|
655 |
+
"personality": "내향형, 감정형"
|
656 |
+
},
|
657 |
+
|
658 |
+
# ===== [153~162] 독서 (10개)
|
659 |
+
{
|
660 |
+
"item_id": 153,
|
661 |
+
"title": "무라카미 '1Q84' 북클럽",
|
662 |
+
"desc": "하루키 장편소설을 함께 읽고 상징·메타포를 토론 (독서, 소설)",
|
663 |
+
"personality": "내향형, 감정형"
|
664 |
+
},
|
665 |
+
{
|
666 |
+
"item_id": 154,
|
667 |
+
"title": "윤동주 시 낭독회",
|
668 |
+
"desc": "‘하늘과 바람과 별과 시’ 등 윤동주 시를 낭송하며 문학적 감성을 공유 (독서, 시)",
|
669 |
+
"personality": "내향형, 감정형"
|
670 |
+
},
|
671 |
+
{
|
672 |
+
"item_id": 155,
|
673 |
+
"title": "김영하 '여행의 이유' 에세이 살롱",
|
674 |
+
"desc": "여행과 삶의 관계를 에세이로 탐구하고 느낀 점을 나누는 시간 (독서, 에세이)",
|
675 |
+
"personality": "내향형, 감정형"
|
676 |
+
},
|
677 |
+
{
|
678 |
+
"item_id": 156,
|
679 |
+
"title": "스티븐 코비 '성공하는 사람들의 7가지 습관'",
|
680 |
+
"desc": "자기계발서를 함께 읽고 실천 전략을 세우는 성장 프로젝트 (독서, 자기계발)",
|
681 |
+
"personality": "내향형, 이성형"
|
682 |
+
},
|
683 |
+
{
|
684 |
+
"item_id": 157,
|
685 |
+
"title": "인문학 토크: '총, 균, 쇠' & '사피엔스'",
|
686 |
+
"desc": "문명의 발전 과정을 다룬 명저를 비교·분석하는 심층 독서 (독서, 인문)",
|
687 |
+
"personality": "내향형, 이성형"
|
688 |
+
},
|
689 |
+
{
|
690 |
+
"item_id": 158,
|
691 |
+
"title": "유발 하라리 '사피엔스' 역사 세션",
|
692 |
+
"desc": "인류 역사를 조망하는 '사피엔스'를 읽고 현재 사회와 연결 (독서, 역사)",
|
693 |
+
"personality": "내향형, 이성형"
|
694 |
+
},
|
695 |
+
{
|
696 |
+
"item_id": 159,
|
697 |
+
"title": "칼 세이건 '코스모스' 과학 독서모임",
|
698 |
+
"desc": "우주와 과학적 사고를 확장해보는 '코스모스' 함께 읽기 (독서, 과학)",
|
699 |
+
"personality": "내향형, 이성형"
|
700 |
+
},
|
701 |
+
{
|
702 |
+
"item_id": 160,
|
703 |
+
"title": "애덤 스미스 '국부론' 경제포럼",
|
704 |
+
"desc": "고전 경제학을 토대로 시장경제 원리를 이해하는 세미나 (독서, 경제/경영)",
|
705 |
+
"personality": "내향형, 이성형"
|
706 |
+
},
|
707 |
+
{
|
708 |
+
"item_id": 161,
|
709 |
+
"title": "니체 '차라투스트라는 이렇게 말했다' 철학 토론",
|
710 |
+
"desc": "니체 철학을 깊이 있게 탐독하고 현대적 의미를 해석 (독서, 철학)",
|
711 |
+
"personality": "내향형, 이성형"
|
712 |
+
},
|
713 |
+
{
|
714 |
+
"item_id": 162,
|
715 |
+
"title": "빈센트 반 고흐 예술책 리뷰",
|
716 |
+
"desc": "화가 반 고흐의 작품 세계를 미술서적으로 접하고 교감 (독서, 예술)",
|
717 |
+
"personality": "내향형, 감정형"
|
718 |
+
},
|
719 |
+
|
720 |
+
# ===== [163~172] 영화 (10개)
|
721 |
+
{
|
722 |
+
"item_id": 163,
|
723 |
+
"title": "'러브 액츄얼리' 로맨스 상영회",
|
724 |
+
"desc": "여러 커플의 사랑 이야기를 담은 '러브 액츄얼리'를 감상 후 토론 (영화, 로맨스)",
|
725 |
+
"personality": "외향형, 감정형"
|
726 |
+
},
|
727 |
+
{
|
728 |
+
"item_id": 164,
|
729 |
+
"title": "코미디 '미스터 빈' 특별전",
|
730 |
+
"desc": "로완 앳킨슨의 바디 코미디를 감상하며 웃음 포인트를 분석 (영화, 코미디)",
|
731 |
+
"personality": "외향형, 감정형"
|
732 |
+
},
|
733 |
+
{
|
734 |
+
"item_id": 165,
|
735 |
+
"title": "'매드 맥스: 분노의 도로' 액션 토크",
|
736 |
+
"desc": "포스트 아포칼립스 배경의 질주 액션을 해부하는 상영회 (영화, 액션)",
|
737 |
+
"personality": "외향형, 감정형"
|
738 |
+
},
|
739 |
+
{
|
740 |
+
"item_id": 166,
|
741 |
+
"title": "스릴러 '겟 아웃' 심리분석",
|
742 |
+
"desc": "조던 필의 '겟 아웃'을 통해 공포와 사회적 메시지를 살피는 이벤트 (영화, 스릴러)",
|
743 |
+
"personality": "외향형, 감정형"
|
744 |
+
},
|
745 |
+
{
|
746 |
+
"item_id": 167,
|
747 |
+
"title": "공포 '컨저링' 오싹 체험",
|
748 |
+
"desc": "심령현상을 다룬 공포영화 '컨저링'으로 사운드·분위기 연출을 탐구 (영화, 공포)",
|
749 |
+
"personality": "외향형, 감정형"
|
750 |
+
},
|
751 |
+
{
|
752 |
+
"item_id": 168,
|
753 |
+
"title": "'인터스텔라' SF 디스커션",
|
754 |
+
"desc": "크리스토퍼 놀란의 우주·중력 이론을 담은 영화를 보고 과학적 설정 토론 (영화, SF)",
|
755 |
+
"personality": "외향형, 감정형"
|
756 |
+
},
|
757 |
+
{
|
758 |
+
"item_id": 169,
|
759 |
+
"title": "'반지의 제왕' 판타지 데이",
|
760 |
+
"desc": "톨킨 세계관을 기반으로 한 대서사시를 연속 상영·분석 (영화, 판타지)",
|
761 |
+
"personality": "외향형, 감정형"
|
762 |
+
},
|
763 |
+
{
|
764 |
+
"item_id": 170,
|
765 |
+
"title": "'쇼생크 탈출' 드라마 감동",
|
766 |
+
"desc": "인생영화 '쇼생크 탈출'을 보고 희망·인내의 메시지를 토론 (영화, 드라마)",
|
767 |
+
"personality": "외향형, 감정형"
|
768 |
+
},
|
769 |
+
{
|
770 |
+
"item_id": 171,
|
771 |
+
"title": "지브리 애니메이션 스페셜",
|
772 |
+
"desc": "'센과 치히로' 등 지브리 작품을 상영하며 판타지·동심을 느끼는 감상회 (영화, 애니메이션)",
|
773 |
+
"personality": "외향형, 감정형"
|
774 |
+
},
|
775 |
+
{
|
776 |
+
"item_id": 172,
|
777 |
+
"title": "다큐 '지구(Earth)' 환경 포럼",
|
778 |
+
"desc": "BBC 제작 다큐멘터리 '지구'를 보고 자연·환경 이슈를 논의 (영화, 다큐멘터리)",
|
779 |
+
"personality": "외향형, 이성형"
|
780 |
+
},
|
781 |
+
|
782 |
+
# ===== [173~182] 게임 (10개)
|
783 |
+
{
|
784 |
+
"item_id": 173,
|
785 |
+
"title": "'엘든 링' RPG 도전",
|
786 |
+
"desc": "프롬소프트웨어의 ‘엘든 링’에서 난이도 극복 전략과 빌드 연구 (게임, RPG)",
|
787 |
+
"personality": "외향형, 이성형"
|
788 |
+
},
|
789 |
+
{
|
790 |
+
"item_id": 174,
|
791 |
+
"title": "'오버워치2' FPS 팀플",
|
792 |
+
"desc": "‘오버워치2’에서 역할 분담·전술 플레이를 협력하는 대전 (게임, FPS)",
|
793 |
+
"personality": "외향형, 이성형"
|
794 |
+
},
|
795 |
+
{
|
796 |
+
"item_id": 175,
|
797 |
+
"title": "'데빌 메이 크라이' 액션 콤보 연구",
|
798 |
+
"desc": "콤보 액션의 정수 ‘데메크’ 시리즈를 플레이하며 기술을 익힘 (게임, 액션)",
|
799 |
+
"personality": "외향형, 이성형"
|
800 |
+
},
|
801 |
+
{
|
802 |
+
"item_id": 176,
|
803 |
+
"title": "'스타크래프트' 전략 빌드토론",
|
804 |
+
"desc": "테란·저그·프로토스 종족별 빌드 오더·리플레이 분석 (게임, 전략)",
|
805 |
+
"personality": "내향형, 이성형"
|
806 |
+
},
|
807 |
+
{
|
808 |
+
"item_id": 177,
|
809 |
+
"title": "'심시티' 시뮬레이션 건설",
|
810 |
+
"desc": "도시건설 게임 ‘심시티’로 자신만의 도시를 디자인하고 운영 (게임, 시뮬레이션)",
|
811 |
+
"personality": "내향형, 감정형"
|
812 |
+
},
|
813 |
+
{
|
814 |
+
"item_id": 178,
|
815 |
+
"title": "'피파23' 스포츠 대전",
|
816 |
+
"desc": "축구게임 ‘피파23’에서 오프라인 리그전을 열고 순위를 집계 (게임, 스포츠)",
|
817 |
+
"personality": "외향형, 이성형"
|
818 |
+
},
|
819 |
+
{
|
820 |
+
"item_id": 179,
|
821 |
+
"title": "'테트리스99' 퍼즐 배틀로얄",
|
822 |
+
"desc": "닌텐도 스위치 ‘테트리스99’로 다수 인원이 동시에 ���쟁 (게임, 퍼즐)",
|
823 |
+
"personality": "외향형, 이성형"
|
824 |
+
},
|
825 |
+
{
|
826 |
+
"item_id": 180,
|
827 |
+
"title": "'DJMAX 리스펙트 V' 리듬 페스티벌",
|
828 |
+
"desc": "국산 리듬게임 DJMAX로 콤보와 노트 패턴에 도전 (게임, 음악/리듬)",
|
829 |
+
"personality": "외향형, 이성형"
|
830 |
+
},
|
831 |
+
{
|
832 |
+
"item_id": 181,
|
833 |
+
"title": "'하스스톤' 카드 덱실험실",
|
834 |
+
"desc": "블리자드 TCG ‘하스스톤’에서 전략적 덱 구성과 토너먼트 플레이 (게임, 카드)",
|
835 |
+
"personality": "외향형, 이성형"
|
836 |
+
},
|
837 |
+
{
|
838 |
+
"item_id": 182,
|
839 |
+
"title": "'로스트아크' MMORPG 레이드",
|
840 |
+
"desc": "대규모 온라인 RPG ‘로스트아크’에서 길드원과 협동해 레이드를 공략 (게임, MMORPG)",
|
841 |
+
"personality": "외향형, 이성형"
|
842 |
+
},
|
843 |
+
|
844 |
+
# ===== [183~192] 공예 (10개)
|
845 |
+
{
|
846 |
+
"item_id": 183,
|
847 |
+
"title": "니트 코바늘 인형 만들기",
|
848 |
+
"desc": "뜨개질 기법으로 귀여운 인형이나 소품을 제작하는 워크숍 (공예, 뜨개질)",
|
849 |
+
"personality": "내향형, 이성형"
|
850 |
+
},
|
851 |
+
{
|
852 |
+
"item_id": 184,
|
853 |
+
"title": "프랑스자수 브로치 교실",
|
854 |
+
"desc": "세심한 자수로 브로치·미니 파우치를 장식하는 공예 클래스 (공예, 자수)",
|
855 |
+
"personality": "내향형, 감정형"
|
856 |
+
},
|
857 |
+
{
|
858 |
+
"item_id": 185,
|
859 |
+
"title": "도예 핸드빌딩 체험",
|
860 |
+
"desc": "흙을 손으로 빚어 머그·접시를 만드는 도자기 공예 (공예, 도자기)",
|
861 |
+
"personality": "내향형, 이성형"
|
862 |
+
},
|
863 |
+
{
|
864 |
+
"item_id": 186,
|
865 |
+
"title": "가죽공예 카드지갑 제작",
|
866 |
+
"desc": "가죽 재단·바느질·엣지 마감 실습으로 카드지갑을 완성 (공예, 가죽공예)",
|
867 |
+
"personality": "내향형, 이성형"
|
868 |
+
},
|
869 |
+
{
|
870 |
+
"item_id": 187,
|
871 |
+
"title": "나무도마 목공 교실",
|
872 |
+
"desc": "원목을 가공·샌딩하여 주방용 나무도마를 제작하는 기초 체험 (공예, 목공예)",
|
873 |
+
"personality": "내향형, 이성형"
|
874 |
+
},
|
875 |
+
{
|
876 |
+
"item_id": 188,
|
877 |
+
"title": "비즈공예 액세서리 디자인",
|
878 |
+
"desc": "비즈 구슬로 팔찌·목걸이를 만들고 색채 감각을 익히는 클래스 (공예, 비즈공예)",
|
879 |
+
"personality": "내향형, 감정형"
|
880 |
+
},
|
881 |
+
{
|
882 |
+
"item_id": 189,
|
883 |
+
"title": "소이 캔들 & 디퓨저 만들기",
|
884 |
+
"desc": "천연 소이왁스로 향초, 디퓨저를 제작해 감성 분위기를 조성 (공예, 캔들/디퓨저)",
|
885 |
+
"personality": "내향형, 이성형"
|
886 |
+
},
|
887 |
+
{
|
888 |
+
"item_id": 190,
|
889 |
+
"title": "페이퍼크래프트 3D 미니어처",
|
890 |
+
"desc": "종이 공예로 입체 구조물을 제작하고 채색·디테일을 살리는 교실 (공예, 페이퍼크래프트)",
|
891 |
+
"personality": "내향형, 이성형"
|
892 |
+
},
|
893 |
+
{
|
894 |
+
"item_id": 191,
|
895 |
+
"title": "마크라메 인테리어 월행잉",
|
896 |
+
"desc": "매듭 기법을 응용해 벽걸이·화분홀더 등 인테리어 소품을 만드는 실습 (공예, 마크라메)",
|
897 |
+
"personality": "내향형, 이성형"
|
898 |
+
},
|
899 |
+
{
|
900 |
+
"item_id": 192,
|
901 |
+
"title": "레진아트 키링 & 액세서리",
|
902 |
+
"desc": "투명 레진에 색소·글리터를 활용해 키링·반지를 만드는 창작 (공예, 레진아트)",
|
903 |
+
"personality": "내향형, 이성형"
|
904 |
+
}
|
905 |
+
|
906 |
+
]
|
907 |
+
|
908 |
+
|
909 |
+
|
910 |
+
|
911 |
+
#####################################
|
912 |
+
# 2) 아이템 임베딩 로직
|
913 |
+
#####################################
|
914 |
+
def make_item_embedding_dict(items, model):
|
915 |
+
item_embedding_dict = {}
|
916 |
+
for item in items:
|
917 |
+
text = f"{item['title']} {item['desc']}"
|
918 |
+
emb = model.encode(text, convert_to_numpy=True)
|
919 |
+
item_embedding_dict[item['item_id']] = emb
|
920 |
+
return item_embedding_dict
|
921 |
+
|
922 |
+
item_embedding_dict = make_item_embedding_dict(items, model_bert)
|
923 |
+
|
924 |
+
|
925 |
+
#####################################
|
926 |
+
# 3) 사용자 프로필 -> 문장화
|
927 |
+
#####################################
|
928 |
+
def make_user_profile_text(user_profile: dict) -> str:
|
929 |
+
ext = user_profile.get("extroversion", "")
|
930 |
+
ft = user_profile.get("feeling_thinking", "")
|
931 |
+
hobby = user_profile.get("hobby", "")
|
932 |
+
detail = user_profile.get("detail_hobby", "")
|
933 |
+
|
934 |
+
if hobby == "여행":
|
935 |
+
return (f"저는 {ext}이며 {ft}한 성향을 가진 사람입니다. "
|
936 |
+
f"여행을 정말 좋아하며, 특히 {detail}을 즐깁니다. "
|
937 |
+
"다양한 문화와 맛집을 직접 체험하고 싶어합니다.")
|
938 |
+
elif hobby == "운동":
|
939 |
+
return (f"저는 {ext}이며 {ft}한 성향을 가진 사람입니다. "
|
940 |
+
f"운동에 열정을 가지고 있으며, 특히 {detail}을 즐깁니다. "
|
941 |
+
"건강과 체력을 증진시키고자 꾸준히 활동합니다.")
|
942 |
+
elif hobby == "독서":
|
943 |
+
return (f"저는 {ext}이며 {ft}한 성향을 가진 사람입니��. "
|
944 |
+
f"독서를 사랑하며, 특히 {detail}에 깊은 관심을 가지고 있습니다. "
|
945 |
+
"새로운 지식과 다양한 관점을 배우고자 합니다.")
|
946 |
+
elif hobby == "영화":
|
947 |
+
return (f"저는 {ext}이며 {ft}한 성향을 가진 사람입니다. "
|
948 |
+
f"영화를 감상하는 것을 좋아하며, 특히 {detail} 장르에 큰 흥미를 느낍니다. "
|
949 |
+
"감동과 재미를 동시에 경험하고 싶어합니다.")
|
950 |
+
elif hobby == "게임":
|
951 |
+
return (f"저는 {ext}이며 {ft}한 성향을 가진 사람입니다. "
|
952 |
+
f"게임을 즐기며, 특히 {detail} 게임에 많은 관심을 가지고 있습니다. "
|
953 |
+
"전략적 사고와 도전을 통해 성취감을 느끼고자 합니다.")
|
954 |
+
elif hobby == "공예":
|
955 |
+
return (f"저는 {ext}이며 {ft}한 성향을 가진 사람입니다. "
|
956 |
+
f"공예 활동에 열정을 가지고 있으며, 특히 {detail}을 즐깁니다. "
|
957 |
+
"창의적인 아이디어를 실현하며 섬세한 작업을 즐깁니다.")
|
958 |
+
else:
|
959 |
+
return f"저는 {ext}이며 {ft}한 성향을 가진 사람입니다. 다양한 취미를 즐기고 있습니다."
|
960 |
+
|
961 |
+
|
962 |
+
#####################################
|
963 |
+
# 4) 사용자 임베딩 + 추천 로직
|
964 |
+
#####################################
|
965 |
+
def get_user_embedding(user_profile: dict):
|
966 |
+
user_text = make_user_profile_text(user_profile)
|
967 |
+
return model_bert.encode(user_text, convert_to_numpy=True)
|
968 |
+
|
969 |
+
def extract_hobby(desc):
|
970 |
+
match = re.search(r"\((.*?)\)", desc)
|
971 |
+
return match.group(1) if match else ""
|
972 |
+
|
973 |
+
def cosine_similarity(vec1, vec2):
|
974 |
+
norm1 = np.linalg.norm(vec1)
|
975 |
+
norm2 = np.linalg.norm(vec2)
|
976 |
+
if norm1 == 0 or norm2 == 0:
|
977 |
+
return 0
|
978 |
+
return np.dot(vec1, vec2) / (norm1 * norm2)
|
979 |
+
|
980 |
+
def recommend_content_based(user_profile, top_n=5):
|
981 |
+
user_emb = get_user_embedding(user_profile)
|
982 |
+
scored = []
|
983 |
+
|
984 |
+
user_hobby = user_profile.get("hobby", "")
|
985 |
+
user_detail_hobby = user_profile.get("detail_hobby", "")
|
986 |
+
user_extroversion = user_profile.get("extroversion", "")
|
987 |
+
user_feeling_thinking = user_profile.get("feeling_thinking", "")
|
988 |
+
|
989 |
+
for item in items:
|
990 |
+
item_id = item["item_id"]
|
991 |
+
item_emb = item_embedding_dict[item_id]
|
992 |
+
sim = cosine_similarity(user_emb, item_emb)
|
993 |
+
|
994 |
+
# 가중치
|
995 |
+
weight = 1.0
|
996 |
+
|
997 |
+
# (1) 취미
|
998 |
+
desc_hobby = extract_hobby(item["desc"]) # 예: (운동, 헬스)
|
999 |
+
if user_hobby and user_hobby in desc_hobby:
|
1000 |
+
weight *= 1.05
|
1001 |
+
if user_detail_hobby and user_detail_hobby in desc_hobby:
|
1002 |
+
weight *= 1.2
|
1003 |
+
|
1004 |
+
# (2) 성향
|
1005 |
+
personality_match_count = sum(trait in item["personality"] for trait in [user_extroversion, user_feeling_thinking])
|
1006 |
+
if personality_match_count == 1:
|
1007 |
+
weight *= 1.15
|
1008 |
+
elif personality_match_count == 2:
|
1009 |
+
weight *= 1.3
|
1010 |
+
|
1011 |
+
final_score = sim * weight
|
1012 |
+
scored.append((item, final_score))
|
1013 |
+
|
1014 |
+
scored.sort(key=lambda x: x[1], reverse=True)
|
1015 |
+
return scored[:top_n]
|
1016 |
+
|
1017 |
+
|
1018 |
+
#####################################
|
1019 |
+
# 5) 챗봇 로직
|
1020 |
+
#####################################
|
1021 |
+
HF_API_KEY = os.environ.get("HF_API_KEY", "YOUR_HF_API_KEY")
|
1022 |
+
API_URL = "https://api-inference.huggingface.co/models/Chanjeans/tfchatbot_2"
|
1023 |
+
HEADERS = {"Authorization": f"Bearer {HF_API_KEY}"}
|
1024 |
+
|
1025 |
+
def chat_response(user_input, mode="emotion", max_retries=5):
|
1026 |
+
if mode not in ["emotion", "rational"]:
|
1027 |
+
raise HTTPException(status_code=400, detail="mode는 'emotion' 또는 'rational'이어야 합니다.")
|
1028 |
+
|
1029 |
+
prompt = f"<{mode}><usr>{user_input}</usr><sys>"
|
1030 |
+
payload = {
|
1031 |
+
"inputs": prompt,
|
1032 |
+
"parameters": {
|
1033 |
+
"max_new_tokens": 128,
|
1034 |
+
"temperature": 0.7,
|
1035 |
+
"top_p": 0.9,
|
1036 |
+
"top_k": 50,
|
1037 |
+
"repetition_penalty": 1.2,
|
1038 |
+
"do_sample": True
|
1039 |
+
},
|
1040 |
+
"options": {"wait_for_model": True}
|
1041 |
+
}
|
1042 |
+
|
1043 |
+
for attempt in range(max_retries):
|
1044 |
+
response = requests.post(API_URL, headers=HEADERS, json=payload)
|
1045 |
+
if response.status_code == 200:
|
1046 |
+
try:
|
1047 |
+
result = response.json()
|
1048 |
+
if isinstance(result, list) and "generated_text" in result[0]:
|
1049 |
+
generated_text = result[0]["generated_text"]
|
1050 |
+
return generated_text.replace(prompt, "").strip()
|
1051 |
+
else:
|
1052 |
+
return "응답 형식이 예상과 다릅니다."
|
1053 |
+
except Exception as e:
|
1054 |
+
return f"JSON 파싱 오류: {e}"
|
1055 |
+
|
1056 |
+
elif response.status_code == 503:
|
1057 |
+
# 모델 로딩 중
|
1058 |
+
error_info = response.json()
|
1059 |
+
estimated_time = error_info.get("estimated_time", 15)
|
1060 |
+
time.sleep(min(estimated_time, 15))
|
1061 |
+
else:
|
1062 |
+
return f"API Error: {response.status_code}, {response.text}"
|
1063 |
+
|
1064 |
+
return "🚨 모델 로딩이 너무 오래 걸립니다. 잠시 후 다시 시도하세요."
|
1065 |
+
|
1066 |
+
|
1067 |
+
#####################################
|
1068 |
+
# 6) FastAPI Endpoint
|
1069 |
+
#####################################
|
1070 |
+
|
1071 |
+
# (1) 메인 페이지
|
1072 |
@app.get("/")
|
1073 |
+
def home():
|
1074 |
+
return {"message": "안녕하세요! 추천 & 챗봇 FastAPI 서버입니다."}
|
1075 |
+
|
1076 |
+
# (2) 추천 Endpoint
|
1077 |
+
class UserProfile(BaseModel):
|
1078 |
+
extroversion: str
|
1079 |
+
feeling_thinking: str
|
1080 |
+
hobby: str
|
1081 |
+
detail_hobby: str
|
1082 |
+
|
1083 |
+
@app.post("/recommend")
|
1084 |
+
def recommend_api(profile: UserProfile):
|
1085 |
+
# "솔루션 제공" 로직과 동일
|
1086 |
+
top_items = recommend_content_based(profile.dict(), top_n=5)
|
1087 |
+
results = []
|
1088 |
+
for (item, score) in top_items:
|
1089 |
+
results.append({
|
1090 |
+
"item_id": item["item_id"],
|
1091 |
+
"title": item["title"],
|
1092 |
+
"desc": item["desc"],
|
1093 |
+
"personality": item["personality"],
|
1094 |
+
"score": round(score, 4)
|
1095 |
+
})
|
1096 |
+
return {"recommendations": results}
|
1097 |
+
|
1098 |
+
# (3) 챗봇 Endpoint
|
1099 |
+
class ChatRequest(BaseModel):
|
1100 |
+
user_input: str
|
1101 |
+
mode: str = "emotion"
|
1102 |
+
|
1103 |
+
@app.post("/chat")
|
1104 |
+
def chat_api(req: ChatRequest):
|
1105 |
+
user_text = req.user_input
|
1106 |
+
mode = req.mode
|
1107 |
+
reply = chat_response(user_text, mode=mode)
|
1108 |
+
return {"response": reply}
|