728x90
728x90
728x90

2002년 타임지가 선정한 10대 푸드를 매일마다 챙겨먹어볼까 생각이 들었다.

각 슈퍼 푸드의 효능과 최대한 간단하게 챙겨먹는 법을 정리해봤다.

효능

귀리

귀리(영어: Oats)는 건강에 많은 이점을 제공하는 곡물 중 하나입니다. 다음은 귀리의 주요 효능과 이점 몇 가지를 설명합니다:

식이섬유 공급: 귀리는 식이섬유의 풍부한 원천 중 하나로, 소화 건강을 촉진하고 변비를 예방합니다. 높은 식이섬유 함유량은 소화를 돕고 혈당을 안정시키는 데 도움을 줄 수 있습니다.
혈당 관리: 귀리는 글루코스의 혈당 농도를 안정시키는 데 도움을 주는 베타 글루칸이라는 혈당 관리에 유용한 성분을 포함하고 있습니다. 이로 인해 당뇨병 관리에 도움을 줄 수 있습니다.
콜레스테롤 감소: 귀리에 함유된 베타 글루칸은 LDL 콜레스테롤(나쁜 콜레스테롤) 농도를 감소시키는데 도움을 줄 수 있습니다. 이것은 심혈관 질환을 예방하거나 관리하는 데 도움이 됩니다.
철분 및 비타민 공급: 귀리는 철분, 마그네슘, 인, 비타민 B1 및 비타민 B5 등의 영양소를 함유하고 있어, 영양소 섭취를 촉진하며 에너지 수준을 높일 수 있습니다.
다이어트 지원: 귀리는 다이어트에서도 인기가 있는 식품 중 하나입니다. 식이섬유 함량과 포화되지 않은 지방 함유량이 높아 포만감을 주고, 다이어트 과정에서 도움을 줄 수 있습니다.
항산화 성분: 귀리는 다양한 항산화 성분을 함유하고 있어, 세포 손상을 줄이고 노화를 방지하는 데 도움을 줄 수 있습니다.
소화 건강: 귀리는 소장 내 미생물 균형을 개선하고 소화 건강을 지원하는 프로바이오틱스를 함유하고 있을 수 있습니다.

그러나 귀리를 섭취할 때는 알러지 반응을 주의해야 하며, 의사 또는 영양사와 상담하여 개별적인 영양 상태와 건강 목표에 맞게 귀리를 포함한 식단을 계획하는 것이 좋습니다.

블루베리

블루베리는 매우 영양가가 풍부한 과일로, 여러 가지 건강에 이로운 효능을 제공합니다. 다음은 블루베리의 주요 효능과 이점을 설명합니다:

항산화 성분: 블루베리는 안토시아닌, 플라보노이드, 비타민 C, 비타민 E 등 다양한 항산화 성분을 함유하고 있습니다. 이러한 항산화 성분은 자유 라디칼의 활동을 억제하고 세포 손상을 예방하여 노화를 지연시키고 만성 질환을 예방하는 데 도움을 줄 수 있습니다.
인지 기능 향상: 일부 연구에 따르면 블루베리는 뇌 기능을 개선하고 인지 능력을 향상시킬 수 있는 것으로 알려져 있습니다. 블루베리에 함유된 항산화 성분은 뇌 건강을 지원하고 기억력을 강화할 수 있습니다.
심혈관 건강: 블루베리는 심혈관 건강을 촉진하는 데 도움을 주는 다양한 성분을 포함하고 있습니다. 항산화 성분은 혈관을 보호하고 고혈압, 혈중 콜레스테롤 수치를 개선하는 데 도움을 줄 수 있습니다.
천식 예방: 블루베리에 함유된 항염증 성분은 천식과 같은 염증성 질환을 예방하거나 증상을 완화시키는 데 도움을 줄 수 있습니다.
소화 건강: 블루베리는 식이섬유를 함유하고 있어 소화 건강을 개선하고 변비를 완화하는 데 도움을 줄 수 있습니다.
체중 관리: 블루베리는 낮은 열량을 가지고 있지만 포만감을 주는 과일로, 다이어트 중 체중 관리를 지원하는 데 도움을 줄 수 있습니다.
눈 건강: 블루베리는 눈 건강을 지키는 데 도움을 주는 루테인과 제아잔틴 같은 카로티노이드를 함유하고 있습니다. 이러한 성분은 망막 건강을 지원하고 안구 노화를 방지하는 데 도움을 줄 수 있습니다.

블루베리는 신선한 형태로 섭취하는 것뿐만 아니라, 스무디, 요거트, 시리얼, 베이킹 등 다양한 요리와 음료에 활용할 수 있습니다. 하지만 개별적인 건강 상태와 목표에 따라서 식단에 어떻게 포함할지는 전문가와 상담하실 것을 권장합니다.

녹차

녹차는 건강에 다양한 이점을 제공하는 잎차 중 하나로 잘 알려져 있습니다. 다음은 녹차의 주요 효능과 이점을 설명합니다:

항산화 성분: 녹차는 카테킨이라고 불리는 강력한 항산화 성분을 풍부하게 함유하고 있습니다. 이러한 항산화 성분은 자유 라디칼을 중화시키고 세포 손상을 예방하여 노화를 지연시키며 다양한 질병을 예방하는 데 도움을 줄 수 있습니다.
심혈관 건강: 녹차의 카테킨은 혈압을 조절하고 혈중 콜레스테롤 수치를 개선하는 데 도움을 줄 수 있습니다. 이로써 심장 질환의 위험을 감소시키고 심혈관 건강을 촉진할 수 있습니다.
체중 관리: 녹차에 함유된 카테킨은 대사를 촉진하고 체지방 연소를 돕는 데 도움을 줄 수 있습니다. 이로 인해 체중 관리와 다이어트에 도움을 줄 수 있습니다.
암 예방: 녹차에 함유된 카테킨과 다른 화학물질은 암의 발병 위험을 감소시키는 데 도움을 줄 수 있습니다. 특히 식도암, 간암, 유방암 및 폐암과 관련된 연구 결과가 있습니다.
뇌 건강: 녹차는 뇌 기능을 향상시키고 인지 기능을 개선하는 데 도움을 줄 수 있습니다. 녹차에 함유된 카테킨은 뇌세포를 보호하고 신경 질환의 위험을 감소시키는 데 기여할 수 있습니다.
구연산 및 치아 건강: 녹차는 입안 내 구연산 생성을 억제하고 치아 건강을 유지하는 데 도움을 줄 수 있습니다.
면역 체계 지원: 녹차에 함유된 다양한 성분은 면역 체계를 강화하고 감염병을 예방하는 데 도움을 줄 수 있습니다.

녹차를 섭취할 때는 가능한한 신선하고 고품질의 녹차를 선택하고, 너무 많이 마시지 않는 것이 중요합니다. 과도한 녹차 섭취는 카페인 중독과 부작용을 일으킬 수 있으므로 적당한 양으로 섭취하는 것이 좋습니다. 또한 개별적인 건강 상태와 목표에 따라 전문가와 상의하여 녹차를 포함한 식단을 계획하는 것이 좋습니다.

마늘

마늘은 역사적으로 의학과 건강에 다양한 이점을 제공하는 식재료로 사용되어온 식물입니다. 마늘의 주요 효능과 이점은 다음과 같습니다:

항균 및 항염작용: 마늘에는 알리신(allicin)이라는 화학물질이 함유되어 있어 항균과 항염 작용을 가집니다. 이러한 성분은 감염을 예방하고 염증을 완화하는데 도움을 줄 수 있습니다.
혈압 조절: 마늘은 혈압을 낮추는데 도움을 줄 수 있으며, 고혈압 예방 및 관리에 유용합니다. 마늘 추출물이 혈압을 조절하는데 특히 효과적인 것으로 알려져 있습니다.
콜레스테롤 관리: 마늘은 혈중 콜레스테롤 수치를 개선하는데 도움을 줄 수 있습니다. 특히 LDL 콜레스테롤(나쁜 콜레스테롤) 농도를 낮추고 HDL 콜레스테롤(좋은 콜레스테롤) 농도를 증가시키는데 도움을 줄 수 있습니다.
항산화 성분: 마늘에는 항산화 성분이 풍부하게 함유되어 있어, 세포 손상을 예방하고 노화를 지연시키는데 도움을 줄 수 있습니다.
면역 체계 지원: 마늘은 면역 체계를 강화하고 감염병을 예방하는데 도움을 줄 수 있습니다. 마늘은 항균 및 항염 작용을 통해 면역 체계를 지원할 수 있습니다.
항암 효과: 일부 연구에 따르면 마늘의 성분은 암 예방에 도움을 줄 수 있으며, 특히 위암과 대장암과 관련된 연구 결과가 있습니다.
소화 건강: 마늘은 소화 건강을 개선하고 소장 내 미생물 균형을 지원하는데 도움을 줄 수 있습니다.
철분 흡수 개선: 마늘은 철분 흡수를 개선하는데 도움을 줄 수 있어, 철분 부족을 예방하고 치료하는 데 도움을 줄 수 있습니다.

마늘을 섭취할 때는 신선한 마늘을 사용하거나 마늘 추출물을 고려할 수 있습니다. 그러나 과도한 마늘 섭취는 소화 불쾌감을 일으킬 수 있으므로 적당한 양으로 섭취하는 것이 중요합니다. 마늘을 음식에 추가하거나 마늘 보충제를 사용하기 전에 의사와 상의하여 개별 건강 상태와 목표에 맞게 계획하는 것이 좋습니다.

토마토

토마토는 매우 영양가가 풍부한 과일로, 건강에 다양한 이점을 제공합니다. 다음은 토마토의 주요 효능과 이점을 설명합니다:

항산화 성분: 토마토에는 린고카르디노이드와 비타민 C, 비타민 E, 베타카로틴(비타민 A의 전구체)와 같은 항산화 성분이 풍부하게 함유되어 있습니다. 이러한 항산화 성분은 자유 라디칼을 중화시켜 세포 손상을 예방하고 노화를 지연시키는 데 도움을 줄 수 있습니다.
심혈관 건강: 토마토에는 리코페인이라는 항산화 성분이 풍부하게 함유되어 있어, 혈액 순환을 촉진하고 혈압을 조절하는데 도움을 줄 수 있습니다. 이로써 심장 질환의 위험을 감소시키고 심혈관 건강을 촉진할 수 있습니다.
암 예방: 토마토에 함유된 리코페인은 암의 발병 위험을 감소시키는데 도움을 줄 수 있습니다. 특히 전립선암과 관련된 연구 결과가 있으며, 흔히 이를 위한 식품으로 사용됩니다.
뼈 건강: 토마토에 함유된 비타민 K는 뼈 건강을 유지하는 데 도움을 줄 수 있습니다.
피부 건강: 토마토에 함유된 비타민 C는 콜라겐 생산을 촉진하여 피부 건강을 개선하는데 도움을 줄 수 있습니다.
소화 건강: 토마토는 식이섬유를 함유하고 있어 소화 건강을 개선하고 변비를 예방하는데 도움을 줄 수 있습니다.
철분 흡수 개선: 토마토에 함유된 비타민 C는 철분 흡수를 개선하는데 도움을 줄 수 있습니다.
체중 관리: 토마토는 낮은 열량을 가지고 있지만 포만감을 주는 과일로, 다이어트 및 체중 관리에 도움을 줄 수 있습니다.

토마토를 섭취할 때는 신선한 형태로 먹을 수 있을뿐만 아니라 토마토 소스, 샐러드, 스프, 스무디 등 다양한 요리 및 음료에 활용할 수 있습니다. 그러나 토마토 알러지가 있는 경우나 특별한 의사 지시가 없는 한 적당한 양으로 섭취하는 것이 좋습니다. 개별적인 건강 상태와 목표에 따라 의사나 영양사와 상담하여 토마토를 포함한 식단을 계획하는 것이 좋습니다.

브로콜리

브로콜리는 건강에 많은 이점을 제공하는 식물 중 하나로, 많은 영양소와 생리적인 화학물질을 함유하고 있습니다. 다음은 브로콜리의 주요 효능과 이점을 설명합니다:

항산화 성분: 브로콜리에는 비타민 C, 카로티노이드(베타카로틴, 루테인, 제아잔틴) 및 퀘르세틴과 같은 항산화 성분이 풍부하게 함유되어 있습니다. 이러한 성분은 자유 라디칼을 제거하여 세포 손상을 예방하고 노화를 지연시키는데 도움을 줄 수 있습니다.
항염작용: 브로콜리에는 염증을 억제하는 화학물질이 있어 염증성 질환의 관리에 도움을 줄 수 있습니다.
심혈관 건강: 브로콜리는 심혈관 건강을 개선하는데 도움을 줄 수 있습니다. 비타민 K와 칼슘 함유로 뼈 건강을 지원하며, 항산화 성분은 혈관 벽의 손상을 예방하여 심혈관 질환 예방에 도움을 줄 수 있습니다.
암 예방: 브로콜리는 암 발병 위험을 감소시키는데 도움을 줄 수 있습니다. 그중에서도 고환암, 유방암, 폐암, 대장암과 관련된 연구 결과가 있으며, 이를 위해 유용한 화학물질인 글룳로신산테인과 다이멜리테인을 함유하고 있습니다.
소화 건강: 브로콜리는 식이섬유와 물을 풍부하게 함유하고 있어 소화 건강을 촉진하고 변비를 예방하는데 도움을 줄 수 있습니다.
체중 관리: 브로콜리는 낮은 칼로리를 가지고 있지만 포만감을 주는 음식 중 하나로, 다이어트 및 체중 관리에 도움을 줄 수 있습니다.
비타민 및 미네랄 공급: 브로콜리는 비타민 C, 비타민 K, 비타민 A, 철분, 칼슘, 마그네슘, 포타슘 등 다양한 비타민과 미네랄을 함유하고 있어 영양소 섭취를 촉진하고 건강을 유지하는 데 도움을 줄 수 있습니다.

브로콜리는 다양한 방식으로 섭취할 수 있으며, 삶거나 즉석조리, 로스팅, 샐러드, 스무디, 스프 등 여러 요리에 사용할 수 있습니다. 이러한 이점을 누리기 위해서는 신선하고 올바르게 조리된 브로콜리를 선택하고, 규칙적으로 섭취하는 것이 좋습니다.

아몬드

아몬드는 건강에 다양한 이점을 제공하는 고지방 식품 중 하나로, 다양한 영양소와 건강에 이로운 성분을 함유하고 있습니다. 다음은 아몬드의 주요 효능과 이점을 설명합니다:

심혈관 건강: 아몬드는 단식식 지방과 모노식식 지방을 풍부하게 함유하고 있어, 혈중 콜레스테롤 수치를 개선하고 심혈관 건강을 촉진하는데 도움을 줄 수 있습니다. 또한, 아몬드에 함유된 비타민 E와 항산화 성분은 혈관 벽을 보호하고 염증을 줄이는데 도움을 줄 수 있습니다.
체중 관리: 아몬드에는 식이섬유와 단백질이 풍부하게 함유되어 있어 포만감을 주고 식욕을 억제하는데 도움을 줄 수 있습니다. 이로써 다이어트와 체중 관리에 도움을 줄 수 있습니다.
뼈 건강: 아몬드는 칼슘과 마그네슘을 함유하고 있어 뼈 건강을 지원하고 골다공증을 예방하는데 도움을 줄 수 있습니다.
혈당 관리: 아몬드는 혈당을 안정시키는데 도움을 줄 수 있으며, 당뇨병 예방과 관리에 유용할 수 있습니다.
항산화 성분: 아몬드에는 비타민 E, 비타민 C, 카로티노이드와 같은 항산화 성분이 풍부하게 함유되어 있어 자유 라디칼을 제거하고 세포 손상을 예방하는데 도움을 줄 수 있습니다.
소화 건강: 아몬드는 식이섬유를 함유하고 있어 소화 건강을 개선하고 변비를 예방하는데 도움을 줄 수 있습니다.
면역 체계 지원: 아몬드에는 아연과 성분인 성분이 함유되어 있어 면역 체계를 강화하고 감염병을 예방하는데 도움을 줄 수 있습니다.
두뇌 기능: 아몬드는 뇌 기능을 개선하고 기억력을 강화하는데 도움을 줄 수 있는 비타민 B6와 페닐알라닌을 함유하고 있습니다.
피부 건강: 아몬드의 지방산은 피부를 윤기 있고 건강하게 유지하는데 도움을 줄 수 있습니다.
눈 건강: 아몬드에는 루테인과 제아잔틴과 같은 카로티노이드가 함유되어 있어 눈 건강을 지원하고 안구 노화를 방지하는데 도움을 줄 수 있습니다.

아몬드를 섭취할 때는 과도한 양을 섭취하지 않도록 주의해야 합니다. 신선하고 원료가 안전한 아몬드를 선택하고, 개별 건강 상태와 목표에 맞게 적절한 양으로 섭취하는 것이 중요합니다.

적포도주

적포도주(레드 와인)는 적포도에서 만들어지는 주류로, 적포도주에는 몇 가지 잠재적인 건강 이점이 있을 수 있습니다. 그러나 중요한 점은 적포도주를 적당한 양으로 소비해야 하며, 지나치게 과도하게 섭취하면 건강에 해를 끼칠 수 있습니다. 아래는 적포도주의 주요 효능 및 이점입니다:

항산화 성분: 적포도주에는 폴리페놀과 레스베라트롤 같은 항산화 성분이 풍부하게 함유되어 있습니다. 이러한 성분은 자유 라디칼을 중화시키고 세포 손상을 예방하는데 도움을 줄 수 있습니다.
심혈관 건강: 적포도주는 심혈관 건강을 개선하는데 도움을 줄 수 있습니다. 레스베라트롤은 혈관을 확장시키고 혈압을 조절하는데 도움을 줄 수 있으며, 폴리페놀은 콜레스테롤 수치를 개선하는데 도움을 줄 수 있습니다. 이로써 심장 질환의 위험을 감소시키는데 기여할 수 있습니다.
혈당 관리: 레스베라트롤은 혈당 수치를 안정시키는데 도움을 줄 수 있으며, 당뇨병 예방과 관리에 유용할 수 있습니다.
암 예방: 레스베라트롤은 암의 발병 위험을 감소시키는데 도움을 줄 수 있으며, 특히 유방암과 대장암과 관련된 연구 결과가 있습니다.
뇌 건강: 레스베라트롤은 뇌 기능을 개선하고 인지 기능을 향상시키는데 도움을 줄 수 있습니다. 이로써 노인병 및 인지 기능 저하와 관련된 질환 예방에 도움을 줄 수 있습니다.
항염작용: 적포도주는 염증을 억제하는데 도움을 줄 수 있으며, 염증 관련 질환의 관리에 도움을 줄 수 있습니다.
면역 체계 지원: 적포도주는 면역 체계를 강화하고 감염병을 예방하는데 도움을 줄 수 있습니다.
피부 건강: 항산화 성분이 피부 건강을 지원하고 노화 징후를 줄이는데 도움을 줄 수 있습니다.
소화 건강: 적포도주에는 소화를 개선하는데 도움을 주는 식이섬유와 폴리페놀이 함유되어 있을 수 있습니다.

이러한 이점을 누리기 위해서는 적포도주를 적당한 양으로 소비해야 하며, 모든 사람에게 적합한 것은 아닐 수 있습니다. 과도한 음주는 건강에 해를 끼칠 수 있으므로, 의사나 영양사와 상의하여 개별 건강 상태와 목표에 따라 적절한 양을 결정하는 것이 중요합니다. 또한 음주 시 운전을 피하고, 아동 및 임신 중인 여성은 주의해야 합니다.

시금치

시금치는 매우 영양가가 풍부한 잎채소로, 건강에 많은 이점을 제공합니다. 다음은 시금치의 주요 효능과 이점을 설명합니다:

항산화 성분: 시금치는 비타민 C, 비타민 E, 카로티노이드(루테인, 제아잔틴) 및 퀘르세틴과 같은 항산화 성분이 풍부하게 함유되어 있습니다. 이러한 성분은 자유 라디칼을 제거하여 세포 손상을 예방하고 노화를 지연시키는데 도움을 줄 수 있습니다.
심혈관 건강: 시금치는 혈액 내의 콜레스테롤 수치를 개선하는데 도움을 줄 수 있으며, 혈압을 조절하는데 도움을 줄 수 있습니다. 이로써 심장 질환의 위험을 감소시키고 심혈관 건강을 촉진할 수 있습니다.
철분 공급: 시금치에는 철분이 풍부하게 함유되어 있어 빈혈 예방과 에너지 생산에 도움을 줄 수 있습니다.
눈 건강: 시금치에 함유된 루테인과 제아잔틴은 눈 건강을 지원하고 망막 보호에 도움을 줄 수 있습니다.
소화 건강: 시금치는 식이섬유를 함유하고 있어 소화 건강을 개선하고 변비를 예방하는데 도움을 줄 수 있습니다.
면역 체계 지원: 시금치는 비타민 C와 카로티노이드를 함유하고 있어 면역 체계를 강화하고 감염병을 예방하는데 도움을 줄 수 있습니다.
항염작용: 시금치에는 염증을 억제하는 화학물질이 함유되어 있어 염증 관련 질환의 관리에 도움을 줄 수 있습니다.
뼈 건강: 시금치에는 비타민 K와 칼슘이 함유되어 있어 뼈 건강을 지원하고 골다공증을 예방하는데 도움을 줄 수 있습니다.
피부 건강: 시금치의 항산화 성분은 피부를 윤기 있고 건강하게 유지하는데 도움을 줄 수 있습니다.

시금치는 다양한 요리에 사용할 수 있으며, 신선한 형태로 먹을 수도 있고, 생먹이나 샐러드, 스무디 등 다양한 요리에 활용할 수 있습니다. 개별 건강 상태와 목표에 따라 의사나 영양사와 상의하여 시금치를 포함한 식단을 계획하는 것이 좋습니다.

연어

연어는 건강에 다양한 이점을 제공하는 고단백질 식품 중 하나로, 특히 지방산 함유량이 풍부하여 건강에 많은 긍정적인 영향을 미칠 수 있습니다. 다음은 연어의 주요 효능과 이점을 설명합니다:

오메가-3 지방산 공급: 연어는 오메가-3 지방산, 특히 EPA (에이코사펜탸레노산)와 DHA (도코사헥사에노산)를 풍부하게 함유하고 있습니다. 이러한 지방산은 심혈관 건강을 개선하고 염증을 억제하는데 도움을 줄 수 있으며, 뇌 기능과 눈 건강을 지원하는데도 중요합니다.
심혈관 건강: 오메가-3 지방산은 혈관벽의 염증을 줄이고 혈액을 더 자란하게 만들어 심혈관 건강을 개선하는데 도움을 줄 수 있습니다. 이로써 심장 질환의 위험을 감소시키는데 기여할 수 있습니다.
뇌 건강: 연어의 오메가-3 지방산은 뇌 기능을 개선하고 기억력을 향상시키는데 도움을 줄 수 있습니다. 특히 DHA는 뇌의 중요한 구성 성분 중 하나로, 정신 건강을 지원합니다.
염증 억제: 연어의 오메가-3 지방산은 염증을 억제하고 염증성 질환의 관리에 도움을 줄 수 있습니다. 염증은 다양한 만성 질환과 관련이 있으며, 오메가-3 지방산은 염증 반응을 조절할 수 있습니다.
면역 체계 지원: 연어는 아연과 세레노에스타디올과 같은 성분을 함유하고 있어 면역 체계를 강화하고 감염병을 예방하는데 도움을 줄 수 있습니다.
눈 건강: 연어의 DHA는 눈 건강을 지원하고 황반변성 및 망막 질환의 위험을 감소시킬 수 있습니다.
철분 공급: 연어에는 철분이 함유되어 있어 빈혈 예방과 에너지 생산에 도움을 줄 수 있습니다.
단백질 공급: 연어는 고품질의 단백질을 함유하고 있어 근육 건강을 지원하고 포만감을 주는데 도움을 줄 수 있습니다.

연어를 소비할 때는 지방 함량과 칼로리를 고려하여 적당한 양을 섭취해야 합니다. 신선한 연어를 선택하고, 영양가를 보존하기 위해 다양한 조리 방법을 사용할 수 있습니다. 다이어트, 심혈관 건강 개선, 뇌 기능 향상, 염증 억제, 면역 체계 지원을 위해 연어를 식단에 추가하는 것은 건강에 도움이 될 수 있습니다.

챙겨먹는 법

귀리

캘러그 귀리밥을 사서, 5스푼+물 90ml을 전자렌지에 90초간 돌려 먹는다.

블루베리, 토마토

방울토마토 10알과 비슷한 분량의 냉동 블루베리를 넣어 믹서기에 45초간 갈아 쥬스를 만들어 먹는다.
이렇게 먹으면 방울토마토 750g정도를 일주일 정도 아침에 먹을 수 있다.(일주일에 몇번 정도는 아침을 생략 한다고 생각하면...!)

녹차

회사에서 하루에 세 개씩 녹차티백을 먹는다. 도착하자마자, 점심먹고나서, 오후에 졸릴 때 정도로.
그렇게해서 카테킨을 하루 권장량 만큼 섭취할 수 있다.

마늘

마늘장아찌를 직접 담글 수 있지만, 1kg짜리 장아찌를 사서 아침밥먹을 때 먹어준다. 최소 3알 정도를 의식해서 먹자.

브로콜리

대형 마트에서 브로콜리 냉장을 사서, 집에와서 물에 15분간 담궈서 씻겨준다. 그리고 깍둑썰기해서 담아 일주일간 먹는다. 데친다면 1분정도만 데치고 삶아 먹지 않도록 한다. 하루에 다섯 깍둑 정도 먹어준다.

아몬드

아몬드 한줌 정도를 아침밥 먹을때 같이 준비해서 먹어준다. 생아몬드 1kg 팩정도를 사서 먹으면 3주 정도는 먹는다.

시금치

시금치를 5천원치 정도 사서 3번정도 찬물에 씻고, 소금물에 2분정도 데쳐 꺼낸 다음, 찬물에 씻고 물기를 최대한 빼준다음, 들기름, 다진마늘, 파 흰부분, 양파조금, 통깨 등을 섞어 시금치 무침해서 준비한다. 한 번에 10일치 분량은 나온다. 아침에 꺼내서 먹어준다.

적포도주, 연어

적포도주는 아침에 간단하게 챙겨먹기 어려워 생략한다.
연어는 비싸다. 생연어를 냉장보과도 길어야 2일이다. 그래서 주말에 생연어를 사서 연어초밥을 해서 먹는다.

 

요약

아침에 일어나서

귀리밥을 돌리고

브로콜리, 시금치무침, 아몬드, 마늘장아찌를 접시에 담고

블루베리, 방울토마토를 믹서기에 돌린다. 그래서 7가지를 챙겨먹는다. 준비하는데 5분이면 된다.

회사에 도착해서 녹차 티백을 틈틈히 먹는다. 8가지를 챙겨먹는다.

연어는 주말에 챙겨먹는다. 9가지를 챙겨먹는다.

적포도주는... 생략한다. 훗

728x90
728x90

원본 글 : Python 3.12: Cool New Features for You to Try – Real Python

Python 3.12는 2023년 10월 2일에 릴리즈되었습니다. 언제나 그렇듯이, 전 세계 자원 봉사자들의 많은 노력 끝에, 새 버전이 10월에 출시됩니다.

새 버전에는 이 튜토리얼에서 살펴볼 몇 가지 새로운 기능과 개선 사항이 포함되어 있습니다. 또한 문서를 자세히 살펴보고 모든 변경 사항의 전체 목록을 확인할 수도 있습니다.

이 튜토리얼에서는 다음과 같은 새로운 기능과 개선 사항에 대해 알아봅니다:

  • 유용한 제안 및 안내가 포함된 개선된 오류 메시지
  • Python의 PEG 구문 분석기로 지원되는 더욱 표현력이 풍부한 f-스트링
  • 인라인 컴프리헨션(Inline Comprehension)을 포함한 최적화로 더욱 빨라진 Python
  • 제네릭에 주석을 다는 데 사용하는 타입 변수(type variables)에 대한 새로운 구문
  • Linux에서 강력한 perf 프로파일러 지원

이 튜토리얼의 예제 중 하나를 시도하려면 Python 3.12를 사용해야 합니다. 튜토리얼 Python 3 설치 및 설정 가이드사전 릴리스 버전의 Python을 어떻게 설치할 수 있나요? 에서는 시스템에 새 버전의 Python을 추가하기 위한 몇 가지 옵션을 안내합니다.

파이썬에 추가되는 새로운 기능에 대해 자세히 알아볼 수 있을 뿐만 아니라 새 버전으로 업그레이드하기 전에 고려해야 할 사항에 대한 몇 가지 조언도 얻을 수 있습니다. 아래 링크를 클릭하면 Python 3.12의 새로운 기능을 보여주는 코드 예제를 다운로드할 수 있습니다:

https://realpython.com/bonus/python-312-code/

개선된 오류 메시지

파이썬은 일반적으로 좋은 초급 언어로 인정받고 있으며, 가독성이 뛰어난 구문으로 찬사를 받고 있습니다. 최근 더욱 사용자 친화적으로 개선된 영역 중 하나는 오류 메시지입니다.

Python 3.10에서는 많은 오류 메시지, 특히 구문 오류에 대한 메시지가 더 많은 정보를 제공하고 정확해졌습니다. 마찬가지로 Python 3.11에서는 트레이스백에 더 많은 정보가 추가되어 문제가 되는 코드를 더 편리하게 찾아낼 수 있습니다.

최신 버전의 Python은 더 나은 오류 메시지를 제공하여 개발자 경험을 개선하는 작업을 계속하고 있습니다. 특히 몇 가지 일반적인 오류 메시지에는 이제 유용한 제안이 함께 제공됩니다. 이 섹션의 나머지 부분에서는 새로 추가되고 개선된 메시지를 살펴봅니다.

개선 사항 중 몇 가지는 모듈 가져오기(import)와 관련이 있습니다. 다음 세 가지 예에서는 math에서 pi를 가져와서 π로 작업하려고 합니다. 각 예제에서 파이썬 3.12의 새로운 기능 중 하나를 볼 수 있습니다. 다음은 첫 번째 예제입니다:

>>> math.pi
Traceback (most recent call last):
  ...
NameError: name 'math' is not defined. Did you forget to import 'math'?

math을 먼저 가져오지 않고 사용하면 기존의 NameError가 발생합니다. 또한 구문 분석기는 math에 액세스하기 전에 math을 임포트해야 함을 알려줍니다.

모듈 임포트를 기억해야 한다는 알림은 표준 라이브러리 모듈에 대해서만 트리거됩니다. 이러한 오류 메시지의 경우 Python 3.12는 사용자가 설치한 타사(third-party) 패키지를 추적하지 않습니다.

from-import 문을 사용하여 모듈에서 특정 이름을 임포트할 수 있습니다. 키워드의 순서를 바꾸면 이제 올바른 구문에 대한 친절한 안내가 표시됩니다:

>>> import pi from math
  ...
    import pi from math
    ^^^^^^^^^^^^^^^^^^^
SyntaxError: Did you mean to use 'from ... import ...' instead?

여기서는 math에서 pi를 가져오려고 했지만 파이썬에서는 명령문의 순서를 바꾸고 from 이후 import 순으로 입력해야 합니다.

세 번째 새로운 오류 메시지를 보려면 math에서 pi가 아닌 py를 가져오면 어떻게 되는지 확인해 보세요:

>>> from math import py
Traceback (most recent call last):
  ...
ImportError: cannot import name 'py' from 'math'. Did you mean: 'pi'?

math에 py라는 이름이 없으므로 ImportError가 발생합니다. 구문 분석기는 py 대신 pi를 의미한다고 제안합니다. 파이썬 3.10에는 파이썬이 비슷한 이름을 찾아주는 유사한 제안 기능이 도입되었습니다. 파이썬 3.12의 새로운 기능은 import하는 동안 이 작업을 수행할 수 있다는 것입니다.

import와 관련된 이 세 가지 개선 사항 외에도 클래스 내부에 정의된 메서드와 관련된 마지막 개선 사항이 있습니다. 다음 Circle 클래스의 구현을 살펴보세요:

# shapes.py

from math import pi

class Circle:
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return pi * radius**2

.area() 내에서 self.radius 대신 radius를 잘못 참조하고 있다는 점에 유의하세요. 이렇게 하면 메서드를 호출할 때 오류가 발생합니다:

>>> from shapes import Circle
>>> Circle(5).area()
Traceback (most recent call last):
  ...
  File "/home/realpython/shapes.py", line 10, in area
    return pi * radius**2
                    ^^^^^^
NameError: name 'radius' is not defined. Did you mean: 'self.radius'?

파이썬은 일반적인 NameError를 발생시키는 대신 .radius가 self에서 사용할 수 있는 어트리뷰트라는 것을 인식합니다. 그런 다음 로컬 변수 radius 대신 인스턴스 어트리뷰트 self.radius를 사용하도록 제안합니다.

이 예제에서 본 기능은 모두 파이썬 3.12의 새로운 기능입니다. 이 기능들은 파이썬을 좀 더 사용자 친화적으로 만들어줍니다. 이러한 오류 메시지 개선 사항과 파이썬 3.12 프리뷰에서 구현된 방법에 대해 자세히 알아볼 수 있습니다: 더욱 개선된 에러 메시지.

더 강력한 f-스트링

형식이 지정된 문자열(formatted strings), 줄여서 f-스트링은 PEP 498과 Python 3.6에 도입되었습니다. f-스트링을 통해 파이썬은 언어에 문자열 보간 기능을 추가했습니다. 다음과 같은 예제에서 f를 선행해 f-스트링을 인식할 수 있습니다:

>>> from datetime import date
>>> major = 3
>>> minor = 11
>>> release = date(2023, 10, 2)
>>> f"Python {major}.{minor + 1} is released on {release:%B %-d}"
'Python 3.12 is released on October 2'

f-스트링에는 중괄호({}) 세 쌍이 포함되어 있습니다. 각 쌍에는 최종 문자열에 보간되는 표현식이 포함되어 있습니다. 첫 번째 표현식은 메이저만 직접 참조하는 반면, 두 번째 표현식은 마이너에 작은 연산을 적용합니다.

세 번째 표현식은 특정 형식 지정자를 추가하여 표현식의 보간을 제어할 수 있음을 보여줍니다. 이 경우 release는 날짜이므로 %B 및 %-d는 날짜 형식 지정자로 해석되어 날짜를 월 일로 서식을 지정합니다.

f-스트링은 원래 전용 파서를 사용하여 구현되었습니다. 즉, f-스트링 내부의 표현식이 일반 파이썬 표현식임에도 불구하고 일반 파이썬 구문 분석기로 구문 분석되지 않았습니다. 대신 개발자는 별도의 구문 분석기를 구현했으며, 이를 유지 관리해야 했습니다.

그 주된 이유는 파이썬의 기존 LL(1) 구문 분석기가 f-스트링을 지원하지 못했기 때문입니다. 파이썬 3.9에 PEG 구문 분석기가 도입된 후에는 더 이상 그렇지 않습니다. 현재 구문 분석기는 f-스트링 내의 표현식을 구문 분석할 수 있습니다.

PEP 701에 따라, f-스트링은 이제 파이썬 3.12에서 파이썬의 문법에 추가되는 것으로 공식화되었습니다. 실제로 이것은 PEG 구문 분석기가 일반 Python 코드와 마찬가지로 f-스트링을 구문 분석한다는 것을 의미합니다.

대부분의 경우 f-스트링에 대한 이러한 변경 사항을 눈치채지 못할 것입니다. 주로 파이썬의 소스 코드를 유지 관리하는 핵심 개발자에게 도움이 됩니다. 그러나 f-스트링을 사용하는 모든 사람이 볼 수 있는 몇 가지 변경 사항이 있습니다.

일반적으로 f-스트링의 새로운 구현은 원래 추가되었던 일부 제한을 해제합니다. 이러한 제한 사항의 대부분은 IDE 및 코드 하이라이터와 같은 외부 도구에서 f-스트링을 더 쉽게 처리할 수 있도록 하기 위해 적용되었습니다. 아래에서 이전에는 불가능했던 몇 가지 예를 살펴보겠습니다.

이제 f-스트링 내부에서 문자열 따옴표 문자를 재사용할 수 있습니다. 예를 들어, 큰따옴표(")로 f- 문자열을 구분한 경우에도 표현식 내부에 " 를 사용할 수 있습니다:

>>> version = {"major": 3, "minor": 12}
>>> f"Python {version["major"]}.{version["minor"]}"
'Python 3.12'

큰따옴표로 f-스트링을 구분하더라도 " 를 사용하여 f-스트링 내부의 키를 지정할 수 있습니다.

지금까지는 f-스트링 표현식 안에 백슬래시 문자(\)를 사용할 수 없었습니다. 앞으로는 다른 표현식과 마찬가지로 f-스트링 표현식에서도 백슬래시를 사용할 수 있습니다:

>>> names = ["Brett", "Emily", "Gregory", "Pablo", "Thomas"]
>>> print(f"Steering Council:\\n {"\\n ".join(names)}")
Steering Council:
 Brett
 Emily
 Gregory
 Pablo
 Thomas

여기서 f-스트링의 문자열 및 표현식 부분 모두에 개행 문자를 나타내는 \\n을 사용합니다. 이전에는 후자는 허용되지 않았습니다.

다른 유형의 중괄호 및 괄호와 마찬가지로 이제 f-스트링에서 표현식을 구분하는 중괄호 안에 줄 바꿈을 추가할 수 있습니다. 또한 표현식에 주석을 추가할 수도 있습니다. 주석은 줄 끝까지 확장되므로 다음 줄 이상에서 표현식을 닫아야 합니다.

이 기능을 확인하려면 위 예제를 이어 아래 예제를 진행하세요:

>>> f"Steering council: {
...   ", ".join(names)  # Steering council members
... }"
'Steering council: Brett, Emily, Gregory, Pablo, Thomas'

두 번째 줄(”,”.join…)은 f-스트링 표현식을 한 줄에 단독으로 표시합니다.

f-스트링에 대한 중요한 변경 사항은 대부분 내부에서 이루어졌지만, 몇 가지 문제가 있던 구석이 개선되고 f-스트링 표현식이 이제 나머지 파이썬과 더 일관성이 높아진 것을 보셨을 것입니다.

f-스트링의 변경 사항을 더 자세히 살펴보고 싶으시다면 Python 3.12 프리뷰를 살펴보세요: 더욱 직관적이고 일관된 f-스트링.

빨라진 파이썬: 더 특별해진 인라인 컴프리헨션

2022년에 파이썬 3.11이 출시되었을 때, 파이썬을 더 빠르게 만드는 인터프리터 최적화에 대해 많은 화제가 있었습니다. 이 작업은 faster-cpython이라는 이름의 지속적인 노력의 일환이었으며, Python 3.12에서도 계속되고 있습니다.

Python 스크립트 실행이 시작되기 전에 코드가 바이트코드로 변환됩니다. 바이트코드는 파이썬 인터프리터가 실행하는 코드입니다. Python 3.11은 자주 발생하는 연산을 최적화하기 위해 실행 중에 바이트코드를 변경하고 조정할 수 있는 특수 적응형 인터프리터를 사용합니다. 이는 두 단계에 따라 달라집니다:

  • 단축(Quickening)은 특정 바이트코드가 여러 번 실행되어 특수화 후보가 되는 것을 알아차리는 과정입니다.
  • 특수화(Specialization)란 인터프리터가 일반 바이트코드를 전문화된 바이트코드로 대체하는 것을 의미합니다. 예를 들어, 두 개의 부동 소수점 숫자를 더하는 연산은 일반적인 덧셈 연산을 대체할 수 있습니다.

파이썬 3.12에서는 파이썬 3.11보다 빨라졌으며, 인터프리터는 이제 많은 새로운 바이트코드를 특수화할 수 있습니다. 단축 및 특수화가 실제로 작동하는 것을 보려면 다음 함수를 정의하십시오:

>>> def feet_to_meters(feet):
...     return 0.3048 * feet
...

feet_to_meters()를 사용하여 피트에서 미터로 변환할 수 있습니다. 인터프리터 내부를 들여다보려면 Python 코드를 분해하고 바이트코드를 볼 수 있는 dis를 사용합니다:

>>> import dis
>>> dis.dis(feet_to_meters, adaptive=True)
  1           0 RESUME                   0

  2           2 LOAD_CONST__LOAD_FAST    1 (0.3048)
              4 LOAD_FAST                0 (feet)
              6 BINARY_OP                5 (*)
             10 RETURN_VALUE

각 줄에는 하나의 바이트코드 명령어에 대한 정보가 표시됩니다. 다섯 개의 열은 줄 번호, 바이트 주소, 작업 코드 이름, 작업 매개변수, 괄호 안의 매개변수에 대한 해석입니다.

이 바이트코드 목록의 세부 사항을 이해할 필요는 없습니다. 하지만 한 줄의 Python 코드가 여러 바이트코드 명령어로 컴파일되는 경우가 많다는 점에 유의하세요. 이 예제에서 return 0.3048 * feet는 4개의 바이트코드 명령어로 변환됩니다.

사실, 더 이상 별도의 단축 단계는 없습니다. 원칙적으로 모든 바이트코드 명령어는 즉시 특수화할 수 있습니다. 파이썬 3.11에서는 바이트코드가 동일한 유형으로 8번 실행된 후에 특수화가 시작되었습니다. 이제는 이미 두 번의 호출 후에 발생합니다:

>>> feet_to_meters(1.1)
0.33528
>>> feet_to_meters(2.2)
0.67056

부동 소수점 인수를 사용하여 feet_to_meters()를 두 번 호출합니다. 그러면 인터프리터는 특수화하여 곱셈이 계속 부동 소수점 숫자끼리 된다고 가정합니다:

>>> dis.dis(feet_to_meters, adaptive=True)
  1           0 RESUME                    0

  2           2 LOAD_CONST__LOAD_FAST     1 (0.3048)
              4 LOAD_FAST                 0 (feet)
              6 BINARY_OP_MULTIPLY_FLOAT  5 (*)
             10 RETURN_VALUE

인터프리터는 원래의 BINARY_OP 명령을 수정하여 두 피연산자가 모두 float일 때 더 빠른 BINARY_OP_MULTIPLY_FLOAT로 대체했습니다.(역주: 런타임 상에서)

인터프리터가 특정 바이트코드를 적용하더라도 파이썬의 동적 특성에 해를 끼치지는 않습니다. 여전히 사용자는 정수 인자와 함께 feet_to_meters()를 사용할 수 있습니다.(역주: 정수 인자를 넣은 경우 BINARY_OP_MULTIPLY 로 명령이 수정돼 실행될 것임) 동일한 데이터 유형을 사용하면 프로그램이 더 빠르게 실행될 수 있다는 장점이 있습니다.(역주: feet_to_meters() 가 항상 부동소수점 곱셈으로 일관되게 소스코드를 작성했다면, 파이썬 인터프리터가 알아서 빠른 BINARY_OP_MULTIPLY_FLOAT으로 최적화해서 계속 실행할 것이다라는 얘기)

자세한 내용은 핵심 개발자 Brandt Bucher의 PyCon 2023 프레젠테이션을 확인해 보세요: 파이썬의 새로운 전문화 적응형 인터프리터 내부를 살펴보세요.

PEP 709는 파이썬 3.12의 새로운 최적화 기능인 인라인 컴프리헨션을 설명합니다. 파이썬은 이터러블을 변환하는 데 사용하는 리스트 컴프리헨션, 딕셔너리 컴프리헨션, 집합 컴프리헨션을 지원합니다. 예를 들어

>>> names = ["Brett", "Emily", "Gregory", "Pablo", "Thomas"]
>>> [name[::-1].title() for name in names]
['Tterb', 'Ylime', 'Yrogerg', 'Olbap', 'Samoht']

여기서는 리스트 컴프리헨션을 사용하여 각 이름을 반전시킵니다. 이러한 컴프리헨션은 현재 중첩 함수(nested function)로 컴파일됩니다. 이를 살펴보기 위해 먼저 컴프리헨션을 함수로 래핑합니다:

>>> def reverse_names(names):
...     return [name[::-1].title() for name in names]
...

위의 예와 마찬가지로 각 이름을 뒤집고 대문자로 시작하게 만듭니다. 이제 dis를 사용해 파이썬 3.11에서 함수를 분해합니다:

>>> import dis
>>> dis.dis(reverse_names)
  1       0 RESUME              0

  2       2 LOAD_CONST          1 (<code object <listcomp> at 0x7f2e61f42d30)
          4 MAKE_FUNCTION       0
          6 LOAD_FAST           0 (names)
          8 GET_ITER
         10 PRECALL             0
         14 CALL                0
         24 RETURN_VALUE

Disassembly of <code object <listcomp> at 0x7f2e61f42d30>:
  2       0 RESUME              0
          2 BUILD_LIST          0
          4 LOAD_FAST           0 (.0)
    >>    6 FOR_ITER           31 (to 70)
          8 STORE_FAST          1 (name)
         10 LOAD_FAST           1 (name)
         12 LOAD_CONST          0 (None)
         14 LOAD_CONST          0 (None)
         16 LOAD_CONST          1 (-1)
         18 BUILD_SLICE         3
         20 BINARY_SUBSCR
         30 LOAD_METHOD         0 (title)
         52 PRECALL             0
         56 CALL                0
         66 LIST_APPEND         2
         68 JUMP_BACKWARD      32 (to 6)
    >>   70 RETURN_VALUE

무시할 수 있는 세부 사항이 많이 있습니다. 주목해야 할 중요한 점은 새로운 listcomp 코드 객체가 생성되었다는 것입니다. 바이트코드 목록의 맨 위 부분에서 이 내부 함수를 로드하고 호출하는 걸 알 수 있습니다.

이렇게 중첩된 함수로 컴파일하면 함수 호출이 변수를 유출하지 않도록 컴프리헨션을 격리하므로 편리합니다. 그러나 이것이 반드시 가장 효율적인 구현은 아닙니다. 특히 작은 이터러블에 대해 컴프리헨션이 실행되는 경우, 중첩 함수 호출의 오버헤드가 눈에 띄게 증가합니다.

파이썬 3.12에서는 컴프리헨션이 바이트코드에 인라인 처리됩니다. 새 버전에서 reverse_names()의 분해 과정을 살펴보세요:

>>> dis.dis(reverse_names)
  1           0 RESUME                   0

  2           2 LOAD_FAST                0 (names)
              4 GET_ITER
              6 LOAD_FAST_AND_CLEAR      1 (name)
              8 SWAP                     2
             10 BUILD_LIST               0
             12 SWAP                     2
        >>   14 FOR_ITER                24 (to 66)
             18 STORE_FAST               1 (name)
             20 LOAD_FAST                1 (name)
             22 LOAD_CONST               0 (None)
             24 LOAD_CONST               0 (None)
             26 LOAD_CONST               1 (-1)
             28 BUILD_SLICE              3
             30 BINARY_SUBSCR
             34 LOAD_ATTR                1 (NULL|self + title)
             54 CALL                     0
             62 LIST_APPEND              2
             64 JUMP_BACKWARD           26 (to 14)
        >>   66 END_FOR
             68 SWAP                     2
             70 STORE_FAST               1 (name)
             72 RETURN_VALUE

다시 말하지만, 바이트코드의 세부 사항은 중요하지 않습니다. 대신 추가 코드 객체가 없고 추가 함수 호출이 발생하지 않는다는 점에 유의하세요.

일반적으로 인라인 컴프리헨션은 이전 구현(파이썬 3.11에서 보여준 윗 예제)보다 빠릅니다. 작은 이터러블에 대해 실행되는 컴프리헨스는 이전보다 최대 두 배까지 빠를 수 있습니다. 컴프리헨션이 수천 개 요소를 가진 더 큰 이터러블에 대해 실행되는 경우, 새 구현이 파이썬 3.11과 비슷하거나 약간 느리다는 것을 알 수 있습니다. 그러나 실제 벤치마크에 따르면 코드 속도가 더 빨라질 수 있습니다.

이 튜토리얼에 다운로드할 수 있는 첨부 자료에서 다양한 이해도를 벤치마킹하는 코드를 찾을 수 있습니다. 이를 사용하여 컴퓨터에서 이해의 성능을 확인하세요:

https://realpython.com/bonus/python-312-code/

파이썬을 더 빠르게 만들기 위한 노력은 계속되고 있으며, 파이썬 3.13에는 이미 많은 아이디어가 예정되어 있습니다.

전용 타입 변수 구문

파이썬은 버전 3.0에서 어노테이션에 대한 지원을 추가했습니다. 타입 힌트가 어노테이션의 동기 중 하나였지만, 정적 타입에 대한 파이썬의 지원은 몇 년 후인 파이썬 3.5에 이르러서야 도입되었습니다.

타입 변수는 파이썬의 타입 시스템에서 중요하고 강력한 부분을 구성합니다. 타입 변수는 정적 타입 검사(런타임 이전에 타입 체킹) 중에 구체적인 타입을 대신할 수 있습니다. 타입 변수를 사용하여 제네릭 클래스와 제네릭 함수를 매개변수화할 수 있습니다. 주어진 리스트에서 첫 번째 요소를 반환하는 다음 예제를 살펴봅시다:

def first(elements):
    return elements[0]

first()의 반환 값 유형은 전달한 목록의 종류에 따라 다릅니다. 예를 들어 elements가 정수 목록인 경우 first()는 int를 반환하고, 문자열 목록인 경우 반환 유형은 str입니다. 이 관계를 표현하기 위해 타입 변수를 사용합니다.

파이썬 3.12에는 타입 변수에 대한 새로운 구문이 도입되었습니다. 새 구문을 사용하면 다음과 같이 작성할 수 있습니다:

def first[T](elements: list[T]) -> T:
    return elements[0]

함수 정의에 대괄호 안에 T를 추가하면 first()가 타입 변수 T로 매개변수화된 일반 함수임을 선언할 수 있습니다.

참고: list 대신 Sequence를 사용하여 매개변수에 어노테이션을 다는 것이 더 합리적일 때가 많습니다. Sequence는 정수 인덱스로 엘리먼트 액세스를 지원하는 이터러블입니다. Sequence를 사용하려면 first()를 다시 작성하면 됩니다:

from collections.abc import Sequence

def first[T](elements: Sequence[T]) -> T:
	return elements[0]

리스트, 튜플, 문자열은 모두 파이썬에서 Sequence의 예시입니다.

first()를 일반 함수로 선언해도 런타임에는 아무런 영향이 없습니다. 대신 편집기나 정적 타입 검사기가 타입을 추적하는 데 도움이 됩니다. 다음 두 가지 예를 살펴보세요:

>>> def first[T](elements: list[T]) -> T:
...     return elements[0]
...

>>> first([2, 3, 1, 0])
2

>>> first(["Brett", "Emily", "Gregory", "Pablo", "Thomas"])
'Brett'

first()를 처음 호출할 때 정수 목록을 전달합니다. 이 경우 타입 검사기는 T가 int일 수 있음을 확인하고 first()가 int를 반환한다고 추론합니다. 두 번째 예제에서는 문자열 이름 목록을 전달합니다. 이 경우 elements는 list[str]이므로 T는 str으로 취급됩니다.

앞서 언급했듯이 타입 변수는 오랫동안 사용 가능했습니다. 파이썬 3.12에서 새롭게 추가된 것은 타입 변수를 사용하기 위한 새롭고 강력한 구문입니다. 이전에는 타이핑에서 TypeVar를 임포트하여 동일한 예제를 구현했습니다:

from typing import TypeVar

T = TypeVar("T")

def first(elements: list[T]) -> T:
    return elements[0]

새로운 구문에는 두 가지 주요 이점이 있습니다. 우선, 파이썬의 정규 문법에 포함되므로 TypeVar 클래스를 임포트할 필요가 없습니다. 또한 T는 함수 외부가 아닌 함수 정의에서 선언됩니다. 이렇게 하면 타입 변수의 역할이 더 명확해집니다.

지금까지 타입 변수를 가장 간단하게 사용하는 방법을 살펴보았습니다. 새로운 구문은 다른 용도로도 사용할 수 있습니다. 여기에는 일반 클래스 및 일반 유형 별칭 외에도 다중 유형 변수, 제약 유형 변수 및 바인딩된 유형 변수가 포함됩니다. 다음 예제에서 이러한 사용 사례를 살펴보겠습니다.

참고: TypeVar를 사용하는 경우 타입 변수가 공변량(covariant)인지, 역변량(contravariant)인지, 불변량(invariant)인지 지정해야 합니다. 이는 복합 타입 내에서 하위 타입이 상호 작용하는 방식과 관련이 있습니다. 예를 들어 bool은 int의 하위 타입입니다. list[int]와 비교했을 때 list[bool]은 무엇을 의미할까요?

이는 기술적인 질문입니다. 좋은 소식은 새로운 구문을 사용하면 분산(variance)에 대해 명시적으로 설명할 필요가 없다는 것입니다. 대신 타입 검사기가, 필요할 때마다 올바른 타입을 추론할 수 있습니다.

튜플을 사용하여 미리 정해진 수의 요소로 이질적인(heterogeneous) 시퀀스를 표현하는 경우가 많습니다. 기본적인 예로 이름과 나이 쌍으로 사람에 대한 정보를 나타내는 튜플을 들 수 있습니다. 타입 측면에서 이러한 튜플은 tuple[str, int]로 표현할 수 있습니다.

이제 이러한 튜플 쌍의 순서를 뒤집는 함수가 있다고 가정해 보겠습니다. 일반적으로 두 요소의 타입은 서로 다르므로 이를 표현하려면 두 개의 유형 변수가 필요합니다. 대괄호 안에 쉼표로 구분하여 두 개 이상의 타입 변수를 선언할 수 있습니다:

def flip[T0, T1](pair: tuple[T0, T1]) -> tuple[T1, T0]:
    first, second = pair
    return (second, first)

여기서 T0과 T1은 두 개의 독립적인 타입 변수입니다. 서로 다른 타입을 취할 수도 있지만 동일할 수도 있습니다. 예를 들어 한 쌍의 부울을 전달할 수 있습니다.

기본적으로 타입 변수는 모든 타입으로 구체화할 수 있습니다. 하지만 몇 가지 타입 중 하나로 제한되거나 특정 타입의 하위 타입으로 한정되는 유형 관계를 표현하고 싶을 때가 있습니다. 타입 변수 뒤에 콜론으로 구분된 조건을 추가하면 됩니다. 다음 구문을 사용합니다:

>>> def free[T](argument: T) -> T: ...

>>> def constrained[T: (int, float, complex)](argument: T) -> T: ...

>>> def bounded[T: str](argument: T) -> T: ...

지금까지 예제에서는 자유 구문(free syntax)을 사용했습니다. 이는 T가 어떤 타입이든 될 수 있음을 의미합니다. constrained()에서 T는 int, float 또는 complex만 가능한 타입 변수입니다. 리터럴 타입 튜플을 사용하여 이를 표현합니다. bounded()에서 T는 str 또는 str의 하위 클래스일 수 있습니다.

제네릭 클래스를 정의할 수도 있습니다. 제네릭 함수의 경우 대괄호 안에 모든 타입 변수를 선언합니다. 다음 예제는 목록에 기반한 간단한 스택을 구현합니다:

# generic_stack.py

class Stack[T]:
    def __init__(self) -> None:
        self.stack: list[T] = []

    def push(self, element: T) -> None:
        self.stack.append(element)

    def pop(self) -> T:
        return self.stack.pop()

여기서는 클래스 이름에 [T]를 추가했습니다. 그런 다음 클래스 내에서 메서드 매개변수 및 반환 타입에 주석을 달 때 타입 변수를 사용할 수 있습니다. 실제로는 특정 타입이 포함된 스택을 인스턴스화할 수 있습니다. 다음으로 정수 스택을 만들어 보겠습니다:

>>> from generic_stack import Stack
>>> numbers = Stack[int]()
>>> numbers.push(3)
>>> numbers.push(12)

>>> numbers.stack
[3, 12]

>>> numbers.pop()
12

스택을 인스턴스화할 때 [int]를 추가하면 타입 검사기에 데이터 구조가 정수로 구성될 것임을 알릴 수 있습니다. 그러면 다른 타입이 스택 내부에 포함될 수 있는지 경고할 수 있습니다.

스택에서 숫자를 꺼낼 때 마지막으로 밀어 넣은 숫자가 나오는지 관찰하세요. 이를 흔히 선입선출(LIFO)이라고 합니다. 이 아이디어는 부엌 찬장에 있는 접시 더미를 연상시킵니다. 스택은 다양한 컴퓨터 알고리즘에서도 유용하게 사용됩니다.

타입 별칭(type alias)에 새로운 구문을 사용할 수도 있습니다. 타입 별칭은 중첩된 데이터 타입으로 작업을 단순화하거나 데이터 타입을 보다 명확하게 설명하기 위해 특정 타입에 부여하는 이름입니다.

이제 type을 사용하여 타입 별칭을 선언할 수 있습니다:

>>> type Person = tuple[str, int]
>>> type ListOrSet[T] = list[T] | set[T]

여기서 Person은 문자열과 정수로 구성된 튜플로 표현되는 타입입니다. ListOrSet은 목록 또는 집합이 나타내는 일반 타입 별칭입니다. 나중에 인수가 정수 목록 또는 정수 집합이어야 하는 ListOrSet[int]와 같은 식으로 인수를 주석 처리할 수 있습니다.

타 변수에 대한 새로운 구문에 대해 자세히 알아보고 더 많은 실용적인 예제를 보려면 Python 3.12 프리뷰를 참조하세요: 정적 타이핑 개선 사항 및 PEP 695.

리눅스에서 강력한 perf 프로파일러 지원

프로파일러(profiler)는 스크립트 및 프로그램의 성능을 모니터링하고 진단하기 위한 도구입니다. 코드를 프로파일링하면 구현을 조정하는 데 사용할 수 있는 정확한 측정값을 얻을 수 있습니다.

Python은 표준 라이브러리에서 timeit 및 cProfile과 같은 도구를 통해 오랫동안 프로파일링을 지원해 왔습니다. 또한 line-profiler, Pyinstrument, Fil과 같은 서드파티 도구도 다른 기능을 제공합니다.

perf 프로파일러는 Linux 커널에 내장된 프로파일러입니다. Linux에서만 사용할 수 있지만 하드웨어 이벤트 및 시스템 호출부터 실행 중인 라이브러리 코드에 이르기까지 모든 것에 대한 정보를 제공할 수 있는 인기 있고 강력한 도구입니다.

지금까지는 Python에서 perf 실행이 제대로 작동하지 않았습니다. CPython 인터프리터는 일반적으로 Python 코드를 실행하는 프로그램입니다. Python 코드는 _PyEval_EvalFrameDefault()라는 이름의 C 함수로 평가되며, Python 프로그램의 일반적인 프로필에는 _PyEval_EvalFrameDefault()에 대부분의 시간을 소비한 것으로만 표시될 것입니다.

파이썬 3.12는 perf에 대한 적절한 지원을 추가하고 트램폴린 계측(trampoline instrumentation)이라는 기술을 통해 파이썬 함수를 모니터링할 수 있는 기능을 제공합니다. 이를 통해 perf가 생성하는 프로파일링 보고서에 개별 Python 함수가 표시될 수 있습니다:

Samples: 10K of event 'cycles', Event count (approx.): 34217160648

-  100.00%     10432
   -   99.16%     /home/realpython/python-custom-build/bin/python3.12
        __libc_start_main
      - Py_BytesMain
         - 99.89% pymain_run_python.constprop.0
              _PyRun_AnyFileObject
              _PyRun_SimpleFileObject
              run_mod
              run_eval_code_obj
              PyEval_EvalCode
              py::<module>:/home/realpython/project/script.py
              _PyEval_EvalFrameDefault
              PyObject_Vectorcall
              py::main:/home/realpython/project/script.py
              _PyEval_EvalFrameDefault
            - PyObject_Vectorcall
               + 66.61% py::slow_function:/home/realpython/project/script.py
               + 33.39% py::fast_function:/home/realpython/project/script.py
   +    0.84%     /proc/kcore

Linux를 실행 중이고 코드 프로파일링에 관심이 있다면 perf를 사용해 보세요. 시스템에서 perf를 설정하고 코드를 프로파일링하는 방법을 비롯한 자세한 내용은 Python 3.12 프리뷰를 참조하세요: Linux perf 프로파일러 지원.

기타 괜찮은 기능들

지금까지 파이썬 3.12의 가장 큰 변화와 개선 사항을 살펴보았습니다. 하지만 살펴봐야 할 것이 훨씬 더 많습니다. 이 섹션에서는 헤드라인 아래에 숨어 있을 수 있는 몇 가지 새로운 기능을 살펴보겠습니다. 여기에는 인터프리터에 대한 내부 변경 사항, 새로운 타이핑 기능, 이터러블 그룹화 및 파일 나열을 위한 새로운 함수가 포함됩니다.

인터프리터별 GIL

파이썬에는 인터프리터의 많은 내부 코드를 간소화하는 전역 인터프리터 잠금(GIL)이 있습니다. 동시에 GIL은 동시 실행되는 Python 코드 실행에 몇 가지 제한을 부과합니다. 특히, 일반적으로 한 번에 하나의 스레드만 실행할 수 있으므로 병렬 처리가 번거로워집니다.

시간이 지나 GIL을 제거하려는 여러 시도가 있었습니다. 최근에는 PEP 703nogil 프로젝트가 많은 화제를 불러일으켰고, 파이썬에서 GIL을 제거하기 위한 로드맵이 있습니다.

관련 시도가 Python 3.12에서 빛을 보고 있습니다. PEP 684는 인터프리터별 GIL에 대해 설명합니다. 파이썬 인터프리터는 파이썬 스크립트 및 프로그램을 실행하는 프로그램입니다. 소위 서브 인터프리터라고 하는 새로운 인터프리터를 생성할 수 있지만, 이는 C API를 통한 확장 모듈에서만 가능합니다.

참고: 파이썬 코드에 서브인터프리터를 노출하는 새로운 표준 라이브러리 모듈인 interpreters에 대한 작업이 진행 중입니다. 이는 PEP 554와 실제 파이썬의 서브인터프리터 가이드에 설명되어 있습니다.

인터프리터별 GIL이 있다는 것은 각 서브인터프리터에 대해 별도의 인터프리터 잠금이 있다는 것을 의미합니다. 이는 최신 컴퓨터에서 볼 수 있는 다중 코어를 더 잘 활용하는 새롭고 효율적인 파이썬 병렬 처리 방법의 가능성을 열어줍니다. 이러한 흥미로운 모델 중 하나는 순차적 프로세스(CSP, Communicating Sequential Processes)를 통신하는 것으로, 이는 Erlang과 Go를 비롯한 여러 언어에서 동시성에 영감을 주었습니다.

인터프리터별 GIL을 달성하기 위해 핵심 개발자들은 CPython 내부의 여러 부분을 리팩터링했습니다. Python에는 글로벌 상태 저장소인터프리터별 저장소가 모두 있습니다. 이 시도에서는 이전에 전역 상태로 저장되었던 많은 부분이 이제 각 인터프리터에 대해 저장됩니다.

아마도 파이썬 3.12를 실행할 때 이 변경 사항을 눈치채지 못할 것입니다. 일반 파이썬 사용자에게는 변경 사항이 노출되지 않습니다. 대신 향후 병렬성을 구현하는 새로운 방법을 위한 토대를 마련하고 있습니다.

파이썬 3.13에서 서브인터프리터에 대한 접근성을 높이기 위한 계획을 포함하여 서브인터프리터에 대한 자세한 내용은 파이썬 3.12 프리뷰에서 확인할 수 있습니다: 서브인터프리터.

불멸 객체(Immortal Objects)

Python에 불멸 객체를 도입하는 것은 CPython 인터프리터를 개선하고 향후 새로운 개발을 위한 길을 준비하는 또 다른 내부 기능입니다.

효율성을 위해 파이썬의 여러 객체는 싱글톤입니다. 예를 들어, 프로그램 실행 중에는 코드에서 None을 참조하는 횟수와 관계없이 None 객체가 하나만 존재합니다. 이러한 최적화가 가능한 이유는 None이 불변이기 때문입니다. 그 값은 절대 변하지 않습니다.

파이썬의 관점에서 볼 때 None은 불변이지만 CPython 인터프리터가 처리하는 None 객체는 변경된다는 것이 밝혀졌습니다. 인터프리터는 객체의 데이터와 함께 객체의 참조 횟수를 포함하는 구조체의 모든 객체를 나타냅니다. 참조 횟수는 코드에서 객체를 참조할 때마다 변경됩니다.

객체의 참조 횟수는 직접 확인할 수 있습니다:

>>> import sys
>>> a = 3.12
>>> sys.getrefcount(a)
2

>>> b = a
>>> sys.getrefcount(a)
3

>>> del b
>>> sys.getrefcount(a)
2

sys.getrefcount()를 사용하여 객체의 참조 수를 검사합니다. 여기서 a는 실수 객체 3.12를 참조합니다. b가 동일한 객체를 참조할 때 참조 횟수가 증가하는 것을 볼 수 있습니다. 마찬가지로 이름 b가 삭제되면 참조 횟수가 감소합니다.

참고: sys.getrefcount()를 처음 호출하면 2가 반환되지만 a에 대한 참조는 하나만 생성됩니다. 그러나 getrefcount()에 인자로 a를 전달하면 두 번째 참조가 생성됩니다. 일반적으로 반환되는 개수는 예상보다 하나 더 많은 경우가 많습니다.

참조 횟수는 파이썬의 메모리 관리에 중요합니다. CPython은 참조 횟수가 0이 되면 메모리에서 객체를 제거하는 가비지 수집기를 사용합니다.

불멸 객체는 인터프리터 내부를 포함하여 실제로 변경되지 않는 객체입니다. 즉, 참조 횟수가 변경되지 않습니다. 불멸 객체는 참조 횟수를 특수 플래그로 설정하여 식별할 수 있습니다. 이는 C-API의 이전 버전과의 호환성을 유지하고 불멸 객체를 대부분 일반 객체와 동일하게 취급하기 위해 수행됩니다.

불멸 객체의 참조 횟수를 보면 이 메커니즘을 확인할 수 있습니다:

>>> import sys
>>> sys.getrefcount(None)
4294967295

>>> a = None
>>> sys.getrefcount(None)
4294967295

처음에는 None이 40억 번 이상 참조된 것 같은 인상을 받습니다. 하지만 4,294,967,295는 None이 불멸의 객체임을 나타내는 특수 값입니다. None에 대한 새 참조를 생성해도 이 숫자는 변경되지 않습니다.

이 특수 플래그는 무작위로 선택되지 않습니다. 32비트 시스템이 기본적으로 나타낼 수 있는 가장 큰 정수인 16진수 FFFFFFFF에 해당합니다:

>>> hex(sys.getrefcount(None))
'0xffffffff'

즉, 불멸 플래그 값은 인터프리터가 일반적인 사용에서 참조 카운트에 도달하지 않을 정도로 충분히 큽니다. 그리고 테스트하기에 효율적인 표현을 가지고 있습니다.

불멸 객체는 인터프리터의 구현 세부 사항이지만 몇 가지 장점이 있습니다:

  • 진정한 불변 객체는 캐시 동작이 더 우수합니다. 특정 코드에서는 None, True, False 등과 같은 싱글톤으로 작업하는 것이 더 효율적입니다.
  • 불멸 객체는 GIL의 보호가 필요하지 않습니다. 따라서 앞서 배운 인터프리터별 GIL과 함께 잘 작동합니다. 또한 파이썬에서 GIL을 제거하기 위한 일부 작업을 간소화합니다.

불멸 객체에 대한 자세한 내용은 PEP 683에서 확인할 수 있습니다. 또한 파이썬용 불멸 객체 소개에서는 구현에 대한 몇 가지 컨텍스트와 배경을 제공하며, 파이썬 3.12의 불멸 객체 이해에서는 구현 자체에 대해 설명합니다.

명시적 상속을 위한 데코레이터 오버라이딩

Python은 객체 지향 언어로 클래스 작업과 상속을 잘 지원합니다. 각 클래스는 타입 힌트에서 사용할 수 있는 타입도 정의하기 때문에 파이썬의 클래스와 정적 타입 시스템 사이에는 밀접한 관련이 있습니다.

파이썬 3.12의 새로운 타이핑 기능 중 하나는 @override입니다. 이 데코레이터를 사용하여 부모 클래스의 메서드를 재정의하는 서브클래스의 메서드를 표시할 수 있습니다. 이 기능은 부분적으로 Java 및 C++와 같은 다른 언어의 유사한 메커니즘에서 영감을 받았습니다.

@override를 사용하면 특히 코드를 리팩터링할 때 특정 종류의 버그를 방지하는 데 도움이 됩니다. 정적 타입 검사기는 다음과 같은 경우에 경고를 표시할 수 있습니다:

  • 메서드의 이름을 변경했지만 서브클래스에서 해당 메서드의 이름을 변경하는 것을 잊은 경우
  • 부모 메서드를 재정의해야 하는 하위 클래스 메서드의 이름을 잘못 입력한 경우
  • 클래스에 새 메서드를 추가할 때 실수로 하위 클래스의 기존 메서드를 재정의하는 경우

지금까지 타입 검사기는 메서드가 다른 메서드를 재정의하는지 여부를 알 수 있는 방법이 없었습니다. 파이썬 3.12에서는 @override가 타이핑에 추가되었습니다. 이전 버전의 Python에서는 서드파티 typing-extensions 라이브러리에서 @override를 가져올 수 있습니다.

새 데코레이터를 사용하는 방법의 예로 은행 계좌를 나타내는 두 개의 클래스를 구현해 보겠습니다. BankAccount는 기본 은행 계좌를 나타내고, SavingsAccount는 몇 가지 특수 기능을 갖춘 BankAccount의 서브클래스가 됩니다.

간단하게 하기 위해 데이터 클래스를 사용해 은행 계좌 클래스를 정의하겠습니다. 일반 은행 계좌 클래스부터 시작하겠습니다:

# accounts.py

import random
from dataclasses import dataclass
from typing import Self

def generate_account_number() -> str:
    """Generate a random eleven-digit account number"""
    account_number = str(random.randrange(10_000_000_000, 100_000_000_000))
    return f"{account_number[:4]}.{account_number[4:6]}.{account_number[6:]}"

@dataclass
class BankAccount:
    account_number: str
    balance: float

    @classmethod
    def from_balance(cls, balance: float) -> Self:
        return cls(generate_account_number(), balance)

    def deposit(self, amount: float) -> None:
        self.balance += amount

    def withdraw(self, amount: float) -> None:
        self.balance -= amount

은행 계좌에는 두 가지 일반 메서드인 .deposit() 및 .withdraw()가 있습니다. 또한 초기 잔액이 주어지면 새 은행 계좌를 생성할 수 있는 대체 생성자 .from_balance()를 추가할 수 있습니다. 이렇게 하면 generate_account_number() 유틸리티 함수가 임의의 계좌 번호를 생성합니다.

이 은행 계좌는 다음과 같이 사용할 수 있습니다:

>>> from accounts import BankAccount
>>> account = BankAccount.from_balance(1000)
>>> account.withdraw(123.45)
>>> account
BankAccount(account_number='2801.83.60525', balance=876.55)

여기서 초기 잔액이 $1000인 새 은행 계좌를 시작합니다. 123.45달러를 인출하고 나면 계좌에 $876.55달러가 남습니다.

다음으로 저축 계좌(saving account)를 추가합니다. 일반 은행 계좌와 비교하여 저축 계좌는 이자가 적립될 수 있습니다. 또한 은행은 $100보다 큰 인출 금액을 가장 가까운 달러 금액으로 반올림하여 계좌 소유자에게 작은 보너스를 제공합니다.

저축 계좌를 BankAccount의 서브 클래스로 구현하고 부모 메서드를 재정의하는 메서드를 표시합니다. from typing import overrice 를 추가해야 합니다:

# accounts.py

import random
from dataclasses import dataclass
from typing import Self, override

# ...

@dataclass
class SavingsAccount(BankAccount):
    interest: float

    def add_interest(self) -> None:
        self.balance *= (1 + self.interest / 100)

    @classmethod
    @override
    def from_balance(cls, balance: float, interest: float = 1.0) -> Self:
        return cls(generate_account_number(), balance, interest)

    @override
    def withdraw(self, amount: float) -> None:
        self.balance -= int(amount) if amount > 100 else amount

먼저 .interest를 새 속성으로 추가하고 .add_interest()를 저축 계좌에 이자를 추가하는 새 메서드로 추가합니다. 그런 다음 .from_balance()를 업데이트하여 이자 지정을 지원합니다. 이 생성자는 BankAccount의 해당 메서드를 재정의하므로 @override로 표시합니다.

참고: 오버라이드는 메서드에 .__**override__** 속성을 추가하는 것 외에는 런타임에 영향을 주지 않습니다. @override와 @classmethod를 결합할 때는 @override를 마지막에 지정해야 합니다.

이는 정적 타입 검사기에는 중요하지 않지만 .__override__라는 일관된 런타임 시맨틱을 설정할 수 있습니다.

또한 .withdraw()를 재정의하여 계정 소유자에게 소정의 보너스를 추가할 수도 있습니다. 고객이 $100 이상을 인출하는 경우 잔액에서 가장 가까운 달러로 반올림한 금액만 차감합니다:

>>> from accounts import SavingsAccount
>>> savings = SavingsAccount.from_balance(1000, interest=2)
>>> savings.withdraw(123.45)
>>> savings
SavingsAccount(account_number='5283.78.04835', balance=877, interest=2)

여기에서는 $123.45를 인출했지만 잔액에서 $123만 차감했습니다. 이것은 SavingsAccount가 재정의된 메서드를 사용한다는 것을 보여줍니다. 예제를 계속 진행하여 새 메서드를 테스트할 수 있습니다:

>>> savings.add_interest()
>>> savings
SavingsAccount(account_number='5283.78.04835', balance=894.54, interest=2)

>>> savings.withdraw.__override__
True

계좌에 이자를 추가한 후에는 .withdraw()를 재정의로 태그했는지 확인합니다. __.**override__** 속성을 추가했더라도 이 속성은 아무런 효과가 없습니다. 대신 정적 타입 검사기를 사용하여 오버라이드 메서드에서 발생하는 오류를 포착해야 합니다. 타입 검사기를 활성화하는 방법에 대한 자세한 내용은 파이썬 3.12: 정적 타이핑 개선 사항을 참조하세요.

런타임에 유사한 문제를 포착하는 데 관심이 있다면 서드파티 라이브러리 overrides 기능을 확인해 보세요.

Day, Month 관련 상수 다루

파이썬의 달력 모듈(calendar)은 오랫동안 포함됐습니다. 일반적으로 날짜 작업할 때, 날짜와 타임스탬프가 있는 날짜를 각각 나타내는 날짜(date) 및 날짜 시간(datetime) 클래스를 제공하는 datetime 모듈을 사용하게 됩니다.

캘린더를 사용하면 날짜/시간의 기술적 사용과 사용자 친화적인 달력 표현 사이의 간극을 메울 수 있습니다. 예를 들어 캘린더를 사용하여 터미널에 캘린더를 빠르게 표시할 수 있습니다:

$ python -m calendar 2023 10
    October 2023
Mo Tu We Th Fr Sa Su
                   1
 2  3  4  5  6  7  8
 9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31

모듈을 -m과 함께 실행하면 캘린더가 표시됩니다. 위의 예에서는 2023년 10월을 표시하고 10월 2일이 월요일인 것을 관찰합니다.

사용자 정의 캘린더를 작성해야 하는 경우 자체 코드에서 캘린더를 사용할 수도 있습니다. 새 Python 버전에서는 요일 및 월 작업에 대한 지원이 더욱 강화되었습니다. 먼저 요일 및 월 이름 목록과 같이 오랫동안 사용 가능했던 기능을 살펴보세요:

>>> import calendar

>>> ", ".join(calendar.month_abbr)
', Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec'

>>> calendar.weekday(2023, 10, 2)
0
>>> calendar.day_name[0]
'Monday'

먼저 모든 월을 축약하여 나열합니다. 월 목록에는 13개의 요소가 있으며 첫 번째 요소는 빈 문자열입니다. 이는 인덱스가 일반적인 월 번호와 일치하도록 하기 위한 것으로, 1월은 1에 해당합니다.

두 번째 예에서는 calendar.weekday()를 사용하여 2023년 10월 2일이 어느 요일에 해당하는지 계산합니다. 그런 다음 날짜 이름 목록에서 해당 답변(0)을 조회하여 10월 2일이 월요일임을 확인합니다.

지금까지 살펴본 모든 것은 이전 버전의 파이썬에서 가능합니다. Python 3.12에서는 열거형 Day와 Month라는 두 가지 사소한 기능이 추가되었습니다. 열거형은 공통 네임스페이스에 있는 상수 값의 모음입니다. 이를 통해 요일과 월을 더 편리하게 처리할 수 있습니다.

열거형 멤버는 상수입니다. 몇 가지 다른 방법으로 열거형 멤버에 액세스할 수 있습니다:

>>> calendar.Month(10)
calendar.OCTOBER

>>> calendar.Month.OCTOBER
calendar.OCTOBER

>>> calendar.Month["OCTOBER"]
calendar.OCTOBER

먼저 열거형을 호출하여 열 번째 달을 요청합니다. 그런 다음 점 표기법을 사용하여 .OCTOBER 상수를 구체적으로 요청합니다. 마지막으로, 마치 Month의 키인 것처럼 "OCTOBER"를 조회합니다.

이 세 가지 모두 값이 10인 상수인 calendar.OCTOBER를 반환합니다. 열거형과 해당 값을 서로 바꿔서 사용할 수 있습니다:

>>> october = calendar.Month(10)
>>> october
calendar.OCTOBER

>>> october.name
'OCTOBER'

>>> october.value
10

>>> october + 1
11

>>> calendar.month_abbr[october]
'Oct'

.name 및 .value를 사용하여 열거형의 이름과 값을 각각 명시적으로 조회할 수 있습니다. 또한 계산을 하거나 표현식에서 열거형을 일반 값처럼 사용할 수 있습니다.

Day는 Month와 비슷하게 작동하지만 요일 상수를 포함합니다. 월요일은 0으로, 화요일은 1로, 일요일은 6에 해당하는 식으로 표시됩니다. Python 3.12에서 weekday() 함수는 Day 열거형을 반환합니다:

>>> release_day = calendar.weekday(2023, 10, 2)
>>> release_day
calendar.MONDAY

>>> release_day.name
'MONDAY'

>>> release_day.value
0

여기서는 release_day를 Day 열거형으로 표현합니다. 위와 같이 이름과 값을 들여다볼 수 있습니다.

참고: Month은 일반적인 사용과 일관성을 유지하기 위해 1부터 번호 매기기를 시작하며, 1월이 첫 번째 월입니다. Day은 다르며 0부터 번호를 매기기 시작합니다. 평일은 일상적으로 번호가 매겨지지 않으므로 번호 매기기 체계는 날짜/시간 모듈 및 일반적인 0 인덱싱을 사용하는 Python의 특성과 일관성을 유지하는 것을 목표로 합니다.

열거형의 마지막 기능은 열거형을 반복할 수 있다는 것입니다. 다음 예제에서는 월을 반복하여 빠른 판매 보고서를 만듭니다:

>>> sales = {1: 5, 2: 9, 3: 6, 4: 14, 5: 9, 6: 8, 7: 15, 8: 22, 9: 20, 10: 23}
>>> for month in calendar.Month:
...     if month in sales:
...         print(f"{month.value:2d} {month.name:<10} {sales[month]:2d}")
...
 1 JANUARY     5
 2 FEBRUARY    9
 3 MARCH       6
 4 APRIL      14
 5 MAY         9
 6 JUNE        8
 7 JULY       15
 8 AUGUST     22
 9 SEPTEMBER  20
10 OCTOBER    23

각 month은 열거 상수입니다. month이 매출의 키인지 확인하고 month을 매출의 인덱스로 사용할 때 상수를 일반 정수처럼 처리하는 방법에 유의하세요.

참고: 열거 상수를 판매 sales의 키로 사용할 수도 있습니다. 편의를 위해 각 월 상수는 calendar에서 바로 속성으로 사용할 수 있습니다:

>>> sales = {
...     calendar.JANUARY: 5,
...     calendar.FEBRUARY: 9,
...     calendar.MARCH: 6,
...     # ...
... }

이처럼 가독성 높힐 수가 있습니다.

월과 마찬가지로 일에도 반복할 수 있습니다:

>>> ", ".join(day.name for day in calendar.Day)
'MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY'

이 예에서는 모든 요일의 이름을 문자열로 결합합니다. 그러나 요일 이름으로 작업해야 하는 경우에는 calendar.day_name 또는 calendar.day_abbr을 사용하는 것이 더 나은 옵션일 수 있습니다. 이러한 이름은 현지화된 이름을 제공하므로 현지 언어로 번역됩니다.

itertools.batched() : Iterable로 항목 그룹짓기

itertools 표준 라이브러리 모듈에는 이터러블 작업 및 조작을 위한 여러 가지 강력한 기능이 포함되어 있습니다. 예를 들어 두 요일의 모든 조합을 계산할 수 있습니다:

>>> import itertools
>>> list(itertools.combinations(["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"], 2))
[('Mo', 'Tu'), ('Mo', 'We'), ('Mo', 'Th'), ('Mo', 'Fr'), ('Mo', 'Sa'),
 ('Mo', 'Su'), ('Tu', 'We'), ('Tu', 'Th'), ('Tu', 'Fr'), ('Tu', 'Sa'),
 ('Tu', 'Su'), ('We', 'Th'), ('We', 'Fr'), ('We', 'Sa'), ('We', 'Su'),
 ('Th', 'Fr'), ('Th', 'Sa'), ('Th', 'Su'), ('Fr', 'Sa'), ('Fr', 'Su'),
 ('Sa', 'Su')]

여기에는 평일 두 개를 페어링하는 21가지 방법이 나열되어 있습니다. 이터러블을 효율적으로 사용하기 위해 사용할 수 있는 다른 많은 함수가 있습니다.

자주 요청되는 함수는 이터레이터의 요소를 지정된 크기의 일괄 처리로 그룹화할 수 있는 batched()입니다. 지금까지는 공식 itertools 레시피를 기반으로 batched()를 직접 구현하거나 서드파티의 more-itertools 라이브러리를 사용할 수 있었습니다.

Python 3.12에서는 batched()가 itertools에 포함되어 더 쉽게 사용할 수 있게 되었습니다. 이 함수는 주어진 길이의 튜플을 생성하는 이터레이터를 반환합니다. 최종 배치는 다른 배치보다 작을 수 있습니다. 다음 예에서는 처음 10개의 정수를 4개의 숫자로 구성된 배치로 그룹화합니다:

>>> import itertools
>>> for batch in itertools.batched(range(10), n=4):
...     print(batch)
...
(0, 1, 2, 3)
(4, 5, 6, 7)
(8, 9)

처음 두 배치는 각각 4개 숫자로 구성됩니다. 그러나 마지막 배치에는 범위에서 남은 두 개 숫자만 포함됩니다.

대부분의 경우, 일괄 처리로 깔끔하게 분할되는 이터러블로 작업하게 됩니다. 이전 섹션의 예를 들어, 월을 분기로 그룹화할 수 있습니다. 다음과 같이 batched()를 사용할 수 있습니다:

>>> import calendar
>>> import itertools
>>> for quarter in itertools.batched(calendar.Month, n=3):
...     print([month.name for month in quarter])
...
['JANUARY', 'FEBRUARY', 'MARCH']
['APRIL', 'MAY', 'JUNE']
['JULY', 'AUGUST', 'SEPTEMBER']
['OCTOBER', 'NOVEMBER', 'DECEMBER']

새 월 열거를 반복하고 월을 3개월 단위로 그룹화합니다. 리스트 컴프리헨션을 사용하여 각 월의 이름을 출력합니다. 출력된 각 리스트는 분기의 월을 나타냅니다.

새로운 batched() 함수는 이터툴 라이브러리에 또 하나의 강력한 도구를 추가합니다. Iterable로 작업하는 경우 itertools의 기능에 익숙해져야 합니다.

Path.walk() : 파일 및 하위 디렉터리 목록

표준 라이브러리의 또 다른 유용한 모듈은 pathlib입니다. pathlib를 사용하면 파일 시스템의 경로로 작업할 수 있으며, 파일을 효율적으로 읽고 쓸 수 있습니다:

>>> from pathlib import Path
>>> names = ["Brett", "Emily", "Gregory", "Pablo", "Thomas"]

>>> council_path = Path("council.txt")
>>> council_path.write_text("\\n".join(names), encoding="utf-8")
32

여기서 작업 디렉터리에 council.txt라는 이름의 파일 경로를 만듭니다. 그런 다음 해당 파일에 개행으로 구분된 이름 목록을 작성합니다.

Path 개체에는 경로를 조작하고 새 경로를 만드는 많은 메서드가 있지만 파일 및 디렉터리 목록만 제한적으로 지원합니다. .glob()을 사용할 수 있지만 이 메서드는 특정 패턴과 일치하는 이름의 파일 및 디렉터리를 찾을 때 유용합니다:

>>> for path in Path.cwd().glob("*.txt"):
...     print(path)
...
/home/realpython/council.txt

.glob()을 사용하면 현재 작업 디렉터리(cwd)에서 .txt 접미사로 끝나는 모든 파일을 나열할 수 있습니다. 재귀적 대응 함수인 .rglob()을 사용하여 하위 디렉터리에 있는 모든 파일을 나열하고 필터링할 수도 있습니다.

파이썬 3.12에서는 새로운 .walk() 메서드를 사용하여 파일 및 디렉터리로 작업할 수 있습니다. 다음 파일 계층 구조에 뮤지션에 대한 정보가 저장되어 있다고 가정해 보겠습니다:

musicians/
│
├── trumpet/
│   ├── armstrong.txt
│   └── davis.txt
│
├── vocal/
│   └── fitzgerald.txt
│
└── readme.txt

먼저 .rglob()을 사용하여 모든 파일과 디렉터리를 재귀적으로 나열합니다:

>>> for path in sorted(Path.cwd().rglob("*")):
...     print(path)
...
/home/realpython/musicians
/home/realpython/musicians/readme.txt
/home/realpython/musicians/trumpet
/home/realpython/musicians/trumpet/armstrong.txt
/home/realpython/musicians/trumpet/davis.txt
/home/realpython/musicians/vocal
/home/realpython/musicians/vocal/fitzgerald.txt

이렇게 하면 계층 구조의 각 파일 또는 디렉토리에 대해 하나의 경로가 제공됩니다. 일반적으로 .glob() 및 .rglob()을 사용할 때 경로 순서는 결정적이지 않습니다. 파일 목록을 재현 가능하게 유지하는 한 가지 방법은 sorted()를 사용하여 정렬하는 것입니다.

새로운 .walk() 메서드는 디렉터리에 초점을 맞추기 때문에 약간 다르게 작동합니다:

>>> for path, directories, files in Path.cwd().walk():
...     print(path, directories, files)
...
/home/realpython ['musicians'] []
/home/realpython/musicians ['trumpet', 'vocal'] ['readme.txt']
/home/realpython/musicians/trumpet [] ['armstrong.txt', 'davis.txt']
/home/realpython/musicians/vocal [] ['fitzgerald.txt']

.walk()는 세 개의 요소로 구성된 튜플을 생성합니다. path는 항상 디렉터리를 참조합니다. 마지막 두 요소는 각각 하위 디렉터리와 해당 디렉터리 바로 안의 파일 목록입니다. top_down 매개변수를 사용하여 디렉터리가 나열되는 순서를 제어할 수 있습니다.

새로운 메서드는 os.walk()를 기반으로 합니다. 가장 큰 차이점은 새로운 .walk()는 Path 객체를 반환한다는 것입니다.

파이썬 3.12로 업그레이드를 해야할까?

지금까지 파이썬 3.12의 멋진 새 기능과 개선 사항을 살펴봤습니다. 다음 질문은 새 버전으로 업그레이드해야 하는지, 업그레이드해야 한다면 언제 업그레이드해야 하는지일 수 있습니다.

언제나 그렇듯이, 그다지 도움이 되지 않는 대답, 상황에 따라 다르다는 것입니다!

우선 현재 시스템과 함께 Python 3.12를 설치하는 것이 좋습니다. 이렇게 하면 로컬 개발을 할 때 새로운 기능을 사용해 볼 수 있습니다. 버그가 발생하더라도 그 영향이 제한적일 것이므로 위험 부담이 적습니다. 동시에 개선된 오류 메시지와 인터프리터 최적화를 활용할 수 있습니다.

프로덕션 환경에서는 버그와 오류의 결과가 더 심각하므로 제어하는 모든 프로덕션 환경을 업데이트할 때 더욱 주의해야 합니다. 모든 새로운 Python 릴리스는 베타 단계에서 충분한 테스트를 거칩니다. 그래도 전환하기 전에 처음 몇 번의 버그 수정 릴리스가 나올 때까지 기다리는 것이 좋습니다.

Python 3.12로 업데이트할 때 발생할 수 있는 한 가지 문제는 새 버전에 대해 준비되지 않은 타사 라이브러리에 의존한다는 것입니다. 특히 C 확장을 사용하는 패키지는 3.12 버전에 맞게 특별히 컴파일해야 하므로 시간이 다소 걸릴 수 있습니다. 다행히도 점점 더 많은 패키지 관리자가 릴리스에 앞서 패키지를 업데이트하기 때문에 예전보다는 덜 문제가 됩니다.

지금까지 새 인터프리터를 언제부터 사용할 수 있는지 살펴보았습니다. 또 다른 중요한 질문은 업데이트된 구문과 언어의 새로운 기능을 언제부터 활용할 수 있는지입니다. 이전 버전의 Python을 지원해야 하는 라이브러리를 유지 관리하는 경우 새로운 유형 변수 구문이나 개선된 f- 문자열을 사용할 수 없습니다. 이전 버전과 호환되는 코드를 고수해야 합니다.

애플리케이션이 실행되는 환경을 제어하는 애플리케이션을 개발하는 경우에는 상황이 달라집니다. 이 경우 종속성을 사용할 수 있게 되는 즉시 환경을 Python 3.12로 업그레이드한 다음 새 구문을 사용하기 시작할 수 있습니다.

결론

파이썬의 새 버전은 언제나 여러분이 좋아하는 언어와 그 개발에 시간과 노력을 쏟은 모든 자원 봉사자들을 축하할 수 있는 좋은 기회입니다. 많은 개발자의 노력 덕분에 Python 3.12는 몇 가지 개선 사항을 제공합니다.

이 튜토리얼에서는 다음과 같은 새로운 기능과 개선 사항을 살펴보았습니다:

  • 유용한 제안과 안내가 포함된 개선된 오류 메시지
  • Python의 PEG 구문 분석기로 지원되는 더욱 표현력이 풍부한 f-스트링
  • 인라인 이해를 포함한 최적화를 통해 Python을 더 빠르게 실행할 수 있습니다.
  • 제네릭에 주석을 다는 데 사용하는 타 변수에 대한 새로운 구문
  • Linux에서 강력한 perf 프로파일러 지원

이 모든 기능을 바로 활용할 수는 없겠지만, 파이썬 3.12를 설치하여 사용해 볼 수 있습니다. 새 릴리스에 대한 자세한 정보가 궁금하다면 각각 하나의 새로운 기능에 초점을 맞춘 이 튜토리얼을 확인해 보세요:

또한 기존 코드가 미래에 대비할 수 있도록 Python 3.12에서 테스트를 시작하기에 좋은 시기입니다.

728x90
728x90

고등학생 때 한 번은 수능의 전 범위에 나오는 용어 정의를 명확하게 외울 필요가 있습니다.

그러기 위해 중1부터 선택 과목까지 전 범위의 교과서 PDF를 한 파일로 병합해 공유해봅니다.

OCR이 되어있어서 특정 용어만 검색해 찾기도 편합니다.

경량화된 버전(100메가 정도)라 용량 부담도 적습니다.

도움됐으면 합니다.

 

다운로드

 

728x90

'교육' 카테고리의 다른 글

[교육] 교육과 훈육  (0) 2023.09.04
728x90

교육과 훈육(Education and Discipline)

교육 목적: 문명

교육 이론은 삶의 목적과 심리적 역학, 즉 정신 변화의 법칙에 대한 과학이라는 두 부분으로 구성되어야 합니다. 삶의 목적이 다르면 교육론도 다르기 마련입니다. 서구 문명 전반에 걸쳐 교육은 기독교의 윤리 이론과 민족주의의 윤리 이론이라는 두 가지 윤리 이론이 지배하고 있습니다. 독일에서 보았듯, 이 두 가지는 양립할 수 없습니다. 저는 두 이론이 서로 다른 부분에서는 기독교가 더 바람직하지만, 두 이론이 일치하는 부분에서는 둘 다 틀렸다고 생각합니다. 제가 교육의 목적으로 대체해야 할 개념은 문명이라는 용어인데, 이 용어는 부분적으로는 개인적이고 부분적으로는 사회적인 정의를 내리고 있습니다. 이는 개인의 지적 자질과 도덕적 자질로 구성되는데, 지적으로는 최소한의 일반 지식, 자신의 직업에 대한 기술력, 증거에 대한 의견을 형성하는 습관, 도덕적으로는 공정성, 친절함, 약간의 자제력 등이 있습니다. 도덕적이지도 지성적이지도 않지만 어쩌면 생리적 특성인 삶의 열정과 기쁨을 추가해야 할 것 같습니다. 공동체에서 문명은 법에 대한 존중, 사람과 사람 사이의 정의(justice), 인류의 어떤 부분에도 영구적인 상처를 주지 않는 목적, 목적에 맞는 수단의 지능적인 적용을 요구합니다. 이러한 목표가 교육의 목적이라면, 이를 실현하기 위해 무엇을 할 수 있는지, 특히 어느 정도의 자유가 가장 효과적일지 고려하는 것은 심리학이 고민해야 할 문제입니다.

기독교의 윤리 이론은 주로 기독교 신앙 체계에 근거를 두고 있습니다. 기독교는 인간의 본성에 대한 비관적인 시각을 가지며, 죄악과 구원, 영원한 생명 등의 개념이 중요합니다. 기독교 윤리는 종교적 신념과 도덕적 가치를 중심으로 인간 행동을 판단하고 규정합니다. 이런 윤리 체계는 모든 인간을 평등하게 대우하고 다른 사람을 사랑하고 배려하는 데 중점을 둡니다.
민족주의(나치즘)의 윤리 이론은 특정 민족 또는 인종을 우월시하고 다른 민족을 경시하는 철학적 입장을 나타냅니다. 나치즘은 특히 나치 독일의 역사와 관련이 있으며, 인종 총독주의와 유사한 원칙을 따릅니다. 이러한 윤리 체계는 민족의 우월성을 강조하고 다른 민족을 포용하지 않는 것을 특징으로 합니다.
러셀은 이 두 가지 윤리 체계가 양립하기 어렵다고 주장했는데, 그 이유는 기독교의 윤리가 인간 평등과 사랑의 원칙을 강조하면서 모든 인간을 동등하게 대우하는 반면, 민족주의의 윤리는 특정 민족을 우월시하고 다른 민족을 경시하기 때문입니다. 따라서 이 두 가지 체계는 불일치하며, 특히 나치즘과 같은 극단적인 민족주의의 윤리와 기독교의 윤리 사이에 갈등이 더욱 뚜렷하게 드러납니다.

교육에서 자유의 한계

교육에서의 자유 문제에 대해 현재 세 가지 주요 학파가 있는데, 목적에 대한 차이와 심리학 이론의 차이에서 비롯됩니다. 어린이는 그들이 얼마나 나빠도 완전히 자유해야 한다고 주장하는 사람들이 있습니다. 또한 어린이가 얼마나 좋아도 완전히 권위에 복종해야 한다고 주장하는 사람들이 있으며, 어린이는 자유로워야하고 동시에 항상 선해야 한다고 주장하는 사람들도 있습니다. 마지막 주장은 논리적으로 타당하지 않습니다, 어른과 마찬가지로 어린이가 자유롭다고해서 모두 덕이 있는 것은 아닙니다. 자유가 완전한 도덕을 보장할 것이라는 믿음은 루소주의(Libertarianism)의 유물이며, 동물과 아기를 대상으로 한 연구에서 반박당할 것입니다. 이러한 믿음을 가진 사람들은 교육에 긍정적인 목적이 없어야 하며, 단지 자발적인 발달에 적합한 환경만 제공해야 한다고 생각합니다. 저는 너무 개인주의적이고 지식의 중요성에 무관심한 이 주장에 동의할 수 없습니다. 우리는 협력이 필요한 공동체에 살고 있으며, 필요한 모든 협력이 자발적인 충동에서 비롯되기를 기대하는 것은 유토피아적인 생각일 것입니다. 제한된 면적에 많은 인구가 존재할 수 있는 것은 과학과 기술이 있기 때문에 가능한 일이며, 따라서 교육은 필요한 최소한의 기술을 전수해야 합니다. 가장 많은 자유를 허용하는 교육자들은 어느 정도의 자비심, 자제력, 훈련된 지성으로 성공한 사람들입니다. 이러한 덕목들은 모든 충동이 제어되지 않는 곳에서 쉽게 형성되지 않을 수 있습니다. 따라서 그들의 방법대로라면 그들이 주장하는 자유의 장점은 오래가지 않을 가능성이 높습니다. 사회적 관점에서 본 교육은 단순히 성장 기회일 뿐인 것보다 더 긍정적인 것이어야 합니다. 물론 동시에 어린이가 스스로 습득할 수 없는 정신적, 도덕적 요소도 제공해야합니다.

루소주의는 개인의 자유와 자기결정권을 극대화하고, 정부나 다른 사회적 기관의 간섭을 최소화하려는 철학적 입장입니다. 이것은 정부의 규제나 간섭을 최소화하여 시장 경제와 개인 자유를 강조하는 경제학적 이론인 자유주의와 관련이 있습니다.루소주의자들은 개인의 권리와 자유를 보호하는 것이 도덕적으로 옳다고 믿습니다. 이것은 개인의 자유를 특히나 강조하며, 다른 개인이나 단체의 간섭을 최소화하고 자유로운 선택을 존중하는데 중점을 둡니다.
러셀과 다른 철학자들은 자유가 도덕을 보장하지 않을 수 있다고 주장합니다. 그 이유 중 하나는 루소주의가 경제적 불평등과 부당한 사회적 조건을 유발할 수 있다고 보기 때문입니다. 개인의 자유가 절대적으로 보장될 때, 경제적 불평등과 불공평한 상황이 발생할 수 있으며, 이는 도덕적으로 문제가 될 수 있습니다.또한 루소주의의 입장에서는 공공 재화의 공급, 환경 보호, 사회 안전망, 교육 등과 같은 사회적 서비스의 제공이 제한될 수 있으며, 이 역시 도덕적인 문제를 일으킬 수 있습니다.또 다른 이유는 루소주의가 개인 주의적인 성향을 강화할 수 있어, 공동체나 사회적 상호의존성을 무시하고 개인적 이익만을 추구하는 경향을 높일 수 있다는 점입니다.

교육에서 권위의 영향

교육에서 큰 수준의 자유를 옹호하는 주장은 인간의 타고난 선함에서 비롯된 것이 아니라 권위의 영향을 받는 사람과 권위를 행사하는 사람 모두에게 미치는 영향에서 비롯된 것입니다. 권위의 지배를 받는 사람은 복종적이거나 반항적이 되며, 각각의 태도에는 단점이 있습니다.

복종적인 사람

복종적인 사람들은 생각과 행동 모두에서 주도성을 잃게 됩니다. 게다가, 좌절감을 느끼면서 일어나는 분노는 약자를 괴롭히는 방향으로 표출될 경향이 있습니다. 어떤 사람이 아버지로부터 받은 고통을 자신의 아들에게 가하며, 공립 학교에서 겪었던 모욕을 제국 건설자가 되었을 때 "원주민들"에게 전달하는 등 폭압적인 제도가 스스로 지속되는 이유입니다. 이렇게 지나치게 권위적인 교육은 학생들을 소심한 폭군으로 만들어, 말이나 행동에서 독창성을 주장하지도 용납하지도 못하는 상태로 만듭니다. 교육자들에게 미치는 영향은 더욱 나쁩니다. 그들은 학생들에게 공포나 불러일으키고 어떤 것도 불러일으키지 않고도 만족해합니다. 이런 사람들이 지식을 대표하므로, 학생들은 지식에 대한 공포를 가지게 되며, 이는 영국 상류층 사람들 사이에서는 인간 본성의 일부로 여겨지지만, 실제로는 권위주의적 교육자에 대한 근거 있는 혐오의 일부입니다.

러셀은 영국 상류층 사람들 중 일부가 교육을 통해 지식을 획득하면, 그들은 지식의 힘과 영향력을 가지게 되며, 이를 통해 다른 사람들을 통제하거나 지배할 수 있다고 보았습니다. 이러한 상황에서 지식을 가진 사람들은 종종 권력과 권위를 유지하기 위해 다른 사람들을 복종하도록 유도하거나 강요하는 경향이 있을 것이라고 생각했습니다.
러셀은 이런 상황에서 지식과 교육이 복종과 권력의 수단으로 남용될 수 있다고 우려했습니다. 따라서 그는 이러한 상류층의 인간 본성을 비판하고, 교육이 자유와 독립적인 사고를 장려하고 공평한 사회를 구축하는 데 기여해야 한다고 주장했습니다.

반항아

반면에 반항은 필요할 수도 있지만, 사실(혹은 존재하는 것)에 대한 반항일 수는 없습니다. 게다가 반항하는 방법에는 여러 가지가 있으며, 그 중 현명한 반항은 극소수에 불과합니다. 갈릴레오는 반항적이었지만 지혜로웠고, 지동설을 믿는 사람들도 똑같이 반항적이지만 어리석습니다. 권위에 대한 반항은 본질적으로 가치 있는 일이며 틀에 얽매이지 않는 의견은 반드시 옳다고 생각하는 경향에는 큰 위험이 있습니다. 가로등을 부수거나 셰익스피어를 시인이 아니라고 주장하는 것은 아무런 유용한 목적을 달성하지 못하기 때문입니다. 그러나 이러한 지나친 반항심은 종종 지나친 권위가 기발한 학생들에게 미치는 영향입니다. 그리고 반항아들이 교육자가 될 때, 그들은 때때로 학생들에게 반항심을 부추기기도 하는데, 이 두 가지 목표는 거의 양립할 수 없지만 동시에 완벽한 환경을 조성하기 위해 노력합니다.

우호적 교육 환경에서의 자유

원하는 것은 복종이나 반항이 아니라 좋은 성격과, 사람과 새로운 아이디어 모두에 대한 일반적인 친근감입니다. 이러한 자질은 부분적으로는 구식 교육자들이 너무 적은 관심을 기울인 신체적 원인에 기인하지만, 중요한 충동이 좌절 될 때 발생하는 당황한 무력감으로부터의 자유에 더 많이 기인합니다. 젊은이들이 우호적인 성인으로 성장하려면 대부분의 경우 환경이 우호적이라고 느껴야 합니다. 이를 위해서는 하나님의 영광이나 국가의 위대함과 같은 추상적인 목적을 위해 어린이를 이용하려는 시도가 아니라 어린이의 중요한 욕망에 대해 어느 정도 공감해야 합니다. 그리고 가르칠 때는 적어도 가르치는 내용이 사실일 때는 학생으로 하여금 자신이 가르치는 내용을 알 가치가 있다고 느끼도록 모든 노력을 기울여야 합니다. 학생이 기꺼이 협조하면 피로를 절반으로 줄이면서 두 배 더 빨리 배울 수 있습니다. 이 모든 것이 매우 큰 자유를 누릴 수 있게 합니다.

균형이 필요한 자유

이 주장은 과장해서 받아들이기 쉽습니다. 아이들이 노예의 악덕을 피하면서 귀족의 악덕을 습득하는 것은 바람직하지 않습니다. 큰 문제뿐만 아니라 사소한 일상적인 일에서도 타인에 대한 배려는 문명의 필수 요소이며, 배려없이는 사회 생활을 견딜 수 없을 것입니다. 저는 "부탁합니다", "감사합니다"와 같은 단순한 예의범절을 말하는 것이 아닙니다. 예의범절은 야만인들 사이에서 가장 완벽하게 발달했으며 문화가 발전할 때마다 줄어들고 있습니다. 저는 오히려 필요한 일의 공정한 몫을 기꺼이 받아들이고, 작은 방식으로 의무를 다하여 균형을 유지하는 것이 더 중요하다고 생각합니다. 온전한 정신(Sanity) 그 자체는 예의의 한 형태이며, 어린이에게 전능감을 주거나 어른이 젊은이들의 즐거움을 위해 존재한다는 믿음을주는 것은 바람직하지 않습니다. 그리고 부유한 사람들이 게으르게 살아가는 것을 비난하는 사람들은 자녀에게 일의 필요성과 지속적인 노력을 가능하게 하는 습관을 갖도록 양육해야 일관성이 있습니다.

권위가 필요한 학습: 배려심

자유를 옹호하는 일부 사람들이 너무 덜 중요하게 여기는 또 다른 고려 사항이 있습니다. 어른의 간섭 없이 방치된 어린이 공동체에는 대부분의 성인 폭압보다 훨씬 더 잔인한 강자의 폭압이 존재할 가능성이 높습니다. 두세 살짜리 아이 두 명을 함께 놀도록 내버려두면 몇 번의 싸움 끝에 한 명이 승자가 되고 다른 한 명은 노예가 될 수밖에 없습니다. 아이들의 수가 더 많으면 한두 명은 완전히 지배하게 되고 다른 아이들은 어른들이 약하고 덜 까다로운 아이들을 보호하기 위해 간섭할 때보다 훨씬 적은 자유를 갖게 됩니다. 타인에 대한 배려심은 대부분의 어린이에게 저절로 생기는 것이 아니라 가르쳐야 하며, 권위를 행사하지 않고는 가르칠 수 없습니다. 이것은 아마도 어른의 퇴위에 반대하는 가장 중요한 주장일 것입니다.

가정 교육의 필요성

저는 교육자들이 바람직한 형태의 자유와 필요한 최소한의 도덕적 훈련을 결합하는 문제를 아직 해결하지 못했다고 생각합니다. 올바른 해결책은 자녀가 계몽된 학교에 데려 오기 전, 부모에 의해 이미 불가능 해질 때가 종종 있습니다. 정신 분석가들이 임상 경험을 통해 우리 모두가 미쳤다고 결론을 내리는 것처럼, 현대 학교는 부모가 그들을 관리 할 수 없게 만든 학생들과의 접촉을 통해 모든 아이들이 관리가 "어렵다"고 결론을 내리고 모든 부모가 완전히 어리 석다고 결론을 내리는 경향이 있습니다. 부모의 폭정(종종 애정 표현의 형태를 취하는)에 의해 야생으로 내몰린 아이들은 의심 없이 성인을 보기까지 더 길거나 더 짧은 기간의 완전한 자유가 필요할 수 있습니다. 그러나 가정에서 현명하게 양육된 어린이는 자기 자신은 중요하고 도움을 받고 있다고 느끼는 한, 일상에서 쉽게 인내할 수 있습니다. 아이들을 좋아하고 회사에서 신경질적인 피곤함을 갖고 오지 않은 어른은 아이들에게 우호적으로 간주되고 훈육에서 많은 것을 성취 할 수 있습니다.

좋아해서 생긴 간섭

현대의 교육 이론가들은 아이들에게 간섭하지 않는 부정적인 미덕을 너무 중요하게 여기고, 아이들과 함께 즐기는 긍정적인 장점은 너무 소홀히 여기는 경향이 있다고 생각합니다. 많은 사람들이 말이나 개를 좋아하는 것처럼 아이들을 좋아한다면, 아이들은 여러분의 제안에 잘 반응하고, 금지 사항에 대해 약간의 투덜거림이 있더라도 원망하지 않고 받아들일 것입니다. 그들을 가치 있는 사회적 노력의 장으로 간주하거나 권력 충동의 배출구로 간주하는 것과 같은 종류의 호감을 갖는 것은 아무 소용이 없습니다. 자신이 소속된 정당을 위해 표를 확보하거나 왕과 국가를 위해 희생될 신체를 갖게 될 것이라는 생각에서 비롯된 관심에 감사할 아이는 없을 것입니다. 바람직한 종류의 관심은 어떤 은밀한 목적 없이 아이들 앞에서 자발적인 즐거움으로 이루어진 관심입니다. 이러한 자질을 갖춘 교사는 아이들의 자유를 간섭할 필요가 거의 없지만, 필요한 경우 심리적 손상을 입히지 않고 간섭할 수 있습니다.

과로하지 않아서, 그래서 우호적일 수 있는 교사

안타깝게도 과로한 교사가 본능적으로 아이들을 좋아하는 마음을 유지하는 것은 완전히 불가능하며, 제과사의 견습생이 마카롱에 대해 느끼는 것처럼 아이들을 대할 수 밖에 없습니다. 저는 교육이 누군가의 전업이 되어서는 안 된다고 생각합니다. 교육은 하루에 최대 두 시간만 아이들과 떨어져 있는 사람들이 맡아야 한다고 생각합니다. 특히 엄격한 규율이 없을 때 어린이들의 사회는 피로를 유발합니다. 결국 피로는 화를 낳으며, 괴로운 교사가 교육에 관해 무엇을 믿었든 화가 표출될 가능성이 높습니다. 필요한 우호성은 자제력만으로 유지될 수 없습니다. 그러나 이미 우호성이 있는 곳에서는 "나쁜 짓"을 한 어린이를 어떻게 다뤄야 하는지에 대한 미리 정해진 규칙은 필요하지 않을 것입니다. 우호적인 관계에서 충동은 올바른 결정으로 이끌 것이고, 어린이가 당신을 좋아한다면 거의 모든 결정이 올바를 것입니다. 애정과 미덕을 대체할 수 있는 현명한 규칙은 없습니다.

이 글은 수학자이자 철학자인 버트런드 러셀의 Education and Discipline의 번역입니다.
728x90
728x90
python3 -m pipdeptree --warn
728x90
728x90
sudo apt-get install libmysqlclient-dev

를 선행해주면 설치가 된다.

728x90
728x90
pip list --format=freeze > ./requirements.txt

버전명이 명시되고 그 결과를 ./requirements.txt에 작성

728x90
728x90

일반프로그래밍

강의

프로그래밍언어

파이썬

다트

프레임워크

Flutter

버전컨트롤

GIT

전문칼럼

커뮤니티

수학

AI/ML

추천시스템

  • Amazon Personalize
    • AWS에서 제공하는 SaaS 추천 엔진
      • 추천 시스템에 대한 전반을 이해에 도움
      • 추천시스템 SaaS의 초기 설계에 참고하기 좋음

데이터베이스

기타

728x90

'CS' 카테고리의 다른 글

[OS]program, process, thread  (0) 2020.11.24
[OS]CPU, processor, microprocessor, core  (0) 2020.11.24
[OS]DMA(Direct Memory Access), PIO(Programmed I/O)  (0) 2020.11.24
[OS]인터럽트, 트랩  (0) 2020.11.24
(미완)UML, Unified Modeling Language란  (0) 2020.11.22
728x90

TL;DR

  • LLM에 프롬프트 엔지니어링으로 추천 엔진(ranker)을 얻을 수 있다.
  • sequential prompting에 비해 recency-focused나 in-context learning 을 사용해 프롬프트를 구성하면, NDCG를 높일 수 있었다.
  • candidate generations에 bootstrapping 기법을 사용해, candidate의 위치 편향성을 완화할 수 있었다.
  • 사용자 행동 내역의 개수를 적게 넣으면, top-1 상품의 인기도가 줄어드는 것을 확인할 수 있었다.
  • instruction 튜닝 모델의 NDCG가 더 높았다.
  • 모델 파라미터 개수가 큰 모델의 NDCG가 더 높았다.

제목: Large Language Models are Zero-Shot Rankers for Recommender Systems

초록(Abstract)

최근 대규모 언어 모델(LLM)(예: GPT-4)은 추천 작업에 접근할 수 있는 잠재력을 포함하여 인상적인 범용 작업 해결 능력을 보여주었습니다. 이러한 연구의 연장선상에서 본 연구는 추천 시스템의 랭킹 모델 역할을 하는 LLM의 역량을 조사하는 것을 목표로 합니다. 실증 연구를 수행하기 위해 먼저 순차적 상호작용 이력을 조건으로, 후보 생성 모델에 의해 검색된 상품을 후보로 간주하여 추천 문제를 조건부 랭킹 작업으로 공식화합니다. 그리고 순차적 상호작용 이력, 후보 상품, 랭킹 명령어를 포함하여 프롬프트 템플릿을 신중하게 설계하여 LLM으로 랭킹 과제를 해결하는 특정 프롬프트 접근 방식을 채택합니다. 추천 시스템에 널리 사용되는 두 가지 데이터 세트에 대한 광범위한 실험을 수행하여 추천 시스템에서 LLM을 사용하기 위한 몇 가지 주요 결과를 도출했습니다. LLM이 여러 후보 생성기가 검색한 후보에 대해 기존 추천 모델과 동등하거나 더 나은 제로샷 랭킹 능력을 가지고 있음을 보여줍니다. 또한 LLM이 과거 상호작용의 순서를 인식하는 데 어려움을 겪고 위치 편향과 같은 편향의 영향을 받을 수 있지만, 특별히 설계된 프롬프트 및 부트스트랩 전략을 통해 이러한 문제를 완화할 수 있음을 입증했습니다. 이 연구를 재현하는 코드는 https://github.com/RUCAIBox/LLMRank 에서 확인할 수 있습니다.

1 .개요(Introduction)

추천 시스템 관련 문헌에 따르면, 대부분의 기존 모델은 특정 도메인 또는 작업 시나리오의 사용자 행동 데이터로 학습되며[25, 13, 14], 두 가지 주요 문제를 가지고 있습니다. 첫째, 기존 모델은 주로 클릭한 상품 시퀀스와 같은 과거 상호작용 행동에서 사용자 선호도를 포착하기 때문에[14, 19, 39, 17] 실제 사용자 선호도를 명시적으로 이해하기 어렵고, 복잡한 사용자 관심사(예: 자연어로 표현된 사용자 의도)를 모델링하는 데 표현력이 제한적입니다. 둘째, 이러한 모델은 본질적으로 "좁은 전문가"로서 배경 지식이나 상식적인 지식에 의존하는 복잡한 추천 작업을 해결하는 데 있어 보다 포괄적인 지식이 부족합니다[11].

추천 성능과 상호작용을 개선하기 위해 추천 시스템에서 사전 학습된 언어 모델(PLM)을 사용하려는 노력이 증가하고 있습니다[10, 18, 31]. 이러한 모델은 자연어로 사용자 선호도를 명시적으로 포착하거나[10] 텍스트 코퍼스로부터 풍부한 세계 지식을 전송하는 것을 목표로 합니다[18, 16]. 이러한 효과에도 불구하고 작업별 데이터에 대한 추천 모델을 철저하게 미세 조정해야 하므로 다양한 추천 작업을 해결하기에는 역량이 떨어집니다[18]. 최근에는 대규모 언어 모델(LLM)이 상식적 추론, 지식 활용, 작업 일반화에서 우수한 역량을 보여줌으로써[37] 제로샷 작업 해결사 역할을 할 수 있는 큰 잠재력을 보여주었습니다[32, 27]. 실제로 추천 과제를 해결하기 위해 LLM을 사용하는 몇 가지 예비적 시도가 있습니다[9, 29, 30, 5, 21, 34]. 이러한 연구들은 주로 LLM으로 유능한 추천자를 구축할 수 있는 가능성을 논의하는 데 초점을 맞추고 있으며, 예비 실험을 바탕으로 유망한 결과를 보고하고 있습니다. 반면, 본 논문에서는 이러한 능력을 보다 상세하고 심층적으로 분석하고, LLM이 과거 상호작용 데이터를 통해 학습하는 방법과 같은 능력 보유 요인을 이해하는 데 초점을 맞추고자 합니다.

본 논문에서는 보다 상세한 실증 연구를 통해 추천 모델 역할을 하는 LLM의 역량을 살펴보고자 합니다. 일반적으로 추천 시스템은 다단계 후보 생성(연관성이 높은 상품 검색)과 랭킹(연관성이 높은 상품에 높은 순위 부여) 절차로 구성된 파이프라인 아키텍처[4]로 개발됩니다. 논문에서 다룰 작업은 주로 추천 시스템의 랭킹 단계에 초점을 맞추고 있는데, 이는 대규모 후보 세트에서 LLM을 실행하는 데 비용이 더 많이 들기 때문입니다. 또한, 랭킹 성능은 검색된 상위 순위 후보 상품에 민감하게 반응하기 때문에 LLM의 추천 능력의 미묘한 차이를 조사하는 데 더 적합합니다.

이 연구를 수행하기 위해 먼저 LLM의 추천 프로세스를 조건부 랭킹 작업으로 공식화합니다. 순차적인 과거 상호작용을 '조건'으로 포함하는 프롬프트가 주어지면, LLM은 후보 상품과 과거 상호작용한 상품 간의 관계에 대한 LLM의 내재적 지식에 따라 일련의 '후보'(예: 후보 생성 모델에 의해 검색된 상품)의 순위를 매기도록 지시받습니다. 그런 다음, 각각 '조건'과 '후보'에 대한 특정 구성을 설계하여 랭커로서 LLM의 경험적 성능을 체계적으로 연구하기 위해 통제된 실험을 수행합니다. 전반적으로 다음과 같은 주요 질문에 답하고자 합니다:

  • LLM이 순차적인 상호작용이 있는 프롬프트에서 기본 사용자 선호도를 포착할 수 있는가?
  • LLM이 내재적 지식을 활용하여 다양한 실제 전략으로 검색된 후보의 순위를 매길 수 있는가?

저희는 추천 시스템에 널리 사용되는 두 가지 공개 데이터 세트를 대상으로 실증 실험을 진행했습니다. 실험을 통해 추천 시스템을 위한 강력한 랭킹 모델로 LLM을 개발하는 방법에 대한 몇 가지 주요 결과를 도출했습니다. 이 실증 연구의 주요 결과를 요약하면 다음과 같습니다:

  • LLM은 개인화된 랭킹을 위해 과거 행동을 활용할 수 있지만, 주어진 순차적 상호작용 이력의 순서를 인식하는 데는 어려움을 겪습니다.
  • 최근 중심 프롬프트(recency-focused prompting) 및 문맥 학습(in-context learning)과 같이 특별히 설계된 프롬프트를 사용하면 LLM이 순차적인 과거 상호 작용의 순서를 인식하도록 트리거하여 랭킹 성능을 개선할 수 있습니다.
  • LLM은 기존의 제로 샷 추천 방법보다 성능이 뛰어나며, 특히 서로 다른 실제 전략을 사용하는 여러 후보 생성 모델에서 검색된 후보에 대해 유망한 제로 샷 순위 지정 능력을 보여줍니다.
  • LLM은 순위를 매기는 동안 포지션 편향과 인기 편향이 발생하는데, 이는 프롬프트 또는 부트스트랩 전략을 통해 완화될 수 있습니다.

2. 랭커로서 LLM을 고려한 일반 프레임워크(General Framework for LLMs as Rankers)

LLM의 추천 능력을 조사하기 위해 먼저 추천 프로세스를 조건부 랭킹 작업으로 공식화합니다. 그런 다음 추천 작업을 해결하기 위해 LLM을 적용하는 일반적인 프레임워크를 설명합니다.

2.1 문제 공식화(Problem Formulation)

한 사용자의 과거 상호작용 H = {i_1, i_2, . . . , i_n}(상호작용 시간 순서대로)를 조건으로 주어졌을 때, 관심 있는 상품이 더 높은 순위에 오를 수 있도록 후보 상품 C = {i_j}, j=1, 2, …, m의 순위를 매기는 것이 과제입니다. 실제로 후보 상품은 일반적으로 전체 상품 집합 I(m << |I|)에서 후보 생성 모델에 의해 검색됩니다[4]. 또한, 각 상품 i는 [18]에 따라 설명 텍스트 t_i와 연관되어 있다고 가정합니다.

2.2 자연어 명령을 사용해 LLM으로 순위 매기기(Ranking with LLMs Using Natural Language Instructions)

우리는 명령 추종 패러다임(instruction-following paradigm)에서 위에서 언급한 과제를 해결하기 위해 LLM을 랭킹 모델로 사용합니다[32]. 구체적으로, 먼저 각 사용자에 대해 순차적인 상호작용 이력 H(조건)와 검색된 후보 상품 C(후보)를 각각 포함하는 두 개의 자연어 패턴을 구성합니다. 그런 다음 이러한 패턴을 최종 명령어로 자연어 템플릿 T에 채웁니다. 이러한 방식으로 LLM은 명령어를 이해하고 명령어가 제시하는 대로 순위 결과를 출력합니다. LLM에 의한 랭킹 접근 방식의 전체 프레임워크는 그림 1에 나와 있습니다. 다음은 접근 방식의 세부적인 명령어 설계에 대해 설명합니다.

그림 1: 제안된 LLM 기반 제로샷 개인화 랭킹 방법 개요

순차적 과거 상호작용. LLM이 과거 사용자 행동에서 사용자 선호도를 파악할 수 있는지 알아보기 위해, 순차적 과거 상호작용 H를 LLM의 입력으로 명령에 포함시킵니다. LLM이 과거 상호작용의 순차적 특성을 인식할 수 있도록 하기 위해 세 가지 방법으로 명령을 구성할 것을 제안합니다:

  • 순차적 프롬프트: 과거 상호작용을 시간 순서대로 정렬합니다. 이 방법은 이전 연구에서도 사용되었습니다[5]. 예를 들어, "나는 과거에 다음과 같은 영화를 순서대로 시청했습니다: '0. 멀티플리시티', '1. 쥬라기 공원', . . .".
  • 최근 중심 프롬프트: 순차적인 상호작용 기록에 더해 가장 최근의 상호작용을 강조하는 문장을 추가할 수 있습니다. 예를 들어, '나는 과거에 다음과 같은 영화를 순서대로 시청했습니다: '0. 멀티플리시티', '1. 쥬라기 공원', .... 가장 최근에 본 영화는 죽은 대통령입니다. . . .".
  • 상황 내 학습(In-Context Learning): ICL은 LLM이 다양한 작업을 풀기 위한 대표적인 프롬프트 방식[37]으로, 프롬프트에 데모 예시(작업 설명과 함께 제공 가능)를 포함하고 LLM이 특정 작업을 풀도록 지시합니다. 개인화된 추천 작업의 경우, 사용자마다 선호도가 다르기 때문에 단순히 다른 사용자의 예시를 소개하는 것은 노이즈가 발생할 수 있습니다. 저희 설정에 ICL을 적용하여 입력 상호작용 시퀀스 자체를 보강하여 데모 예시를 소개합니다. 세부적으로는 입력 인터랙션 시퀀스의 접두사와 그에 해당하는 후속 시퀀스를 예로 들어 설명합니다. 예를 들어, '내가 과거에 다음 영화를 순서대로 본 적이 있다면: '0. 멀티플리시티', '1. 쥬라기 공원', ... 순으로 본 적이 있다면, 죽은 대통령을 추천해야 하고, 이제 내가 죽은 대통령을 봤으니 ..."와 같은 식입니다.

검색된 후보 상품. 일반적으로 순위를 매길 후보 상품은 여러 후보 생성 모델에 의해 먼저 검색됩니다[4]. LLM으로 이러한 후보 상품의 순위를 매기기 위해 후보 상품 |C|를 순차적으로 정렬하기도 합니다. 예를 들어, "이제 다음에 볼 수 있는 후보 영화는 20개입니다: '0. 시스터 액트', '1. 선셋 블러바드', . . .". 전통적인 후보 생성 방식[4]에 따라 후보 상품에 대한 특정 순서가 정해져 있지 않다는 점에 유의하세요. 서로 다른 후보 생성 모델에서 검색된 결과에 대해 합집합을 얻고 후보 상품에 무작위로 위치를 할당합니다. 논문에서 다룰 작업에서는 상대적으로 작은 후보 풀을 고려하고 순위를 매기기 위해 20개의 후보 상품(즉, m = 20)을 유지합니다.

표 1: 전처리 후 데이터 집합의 통계입니다. "Avg. |H|"는 과거 사용자 행동의 평균 길이를 나타냅니다. "Avg. |t_i|"는 상품의 설명 텍스트에 포함된 토큰의 평균 개수를 나타냅니다.

LLM은 프롬프트의 예시 순서에 민감하다는 것이 밝혀졌습니다 [38, 22]. 이에 따라 프롬프트에서 후보 상품의 순서를 다르게 생성하여 LLM의 순위 결과가 후보의 배열 순서, 즉 위치 편향에 영향을 받는지 여부와 부트스트래핑을 통해 위치 편향을 완화하는 방법을 추가로 검토할 수 있습니다.

대규모 언어 모델로 순위 매기기. 기존 연구에 따르면 LLM은 자연어 명령어를 따라 제로 샷 또는 소수 샷 환경에서 다양한 작업을 해결할 수 있습니다 [32, 37]. LLM을 랭킹 모델로 사용하기 위해 최종적으로 위에서 언급한 패턴을 명령 템플릿 T에 통합합니다. 명령 템플릿의 예는 다음과 같이 주어질 수 있습니다: "[순차적인 과거 상호작용을 포함하는 패턴 H] [검색된 후보 상품을 포함하는 패턴 C] 나의 시청 이력에 따라 다음에 가장 보고 싶은 가능성을 측정하여 이 영화들의 순위를 매겨주세요. 주어진 후보 영화에 반드시 순위를 매겨야 합니다. 주어진 후보 목록에 없는 영화는 생성할 수 없습니다.".

LLM의 출력 파싱하기. 명령어를 LLM에 입력하면 추천을 위한 LLM의 순위 결과를 얻을 수 있습니다. LLM의 출력은 여전히 자연어 텍스트로 되어 있으며, 휴리스틱 텍스트 매칭 방법으로 출력을 파싱하고 지정된 상품 세트에 대한 추천 결과를 기반으로 합니다. 구체적으로, 영화 제목과 같이 상품의 텍스트가 짧고 변별력이 있는 경우에는 LLM 출력과 후보 상품의 텍스트 간에 KMP[20]와 같은 효율적인 하위 문자열 매칭 알고리즘을 직접 수행할 수 있습니다. 또는 각 후보 상품에 인덱스를 할당하고 LLM에 직접 순위가 매겨진 인덱스를 출력하도록 지시할 수 있습니다. 프롬프트에 후보 상품이 포함되어 있음에도 불구하고 LLM이 후보 세트에서 벗어난 상품을 생성하는 경향이 있다는 사실을 발견했습니다. 반면, 이 오류의 비율은 GPT-3.5의 경우 약 3%로 매우 적습니다. 이 경우 LLM에 이 오류를 상기시키거나 단순히 잘못된 추천으로 처리할 수 있습니다.

3. 실증 연구(Empirical Studies)

우리는 순차적 기록 상호작용 H, 후보 C, 템플릿 T를 포함한 다양한 구성의 효과를 조사하고, 두 가지 연구 질문에 답하는 데 초점을 맞추고자 한다: (a) LLM이 사용자 순차적 기록 상호작용 H가 있는 프롬프트에서 사용자 선호도를 포착할 수 있는가? (b) LLM이 내재적 지식을 활용하여 다양한 실제 전략으로 검색된 후보 C의 순위를 매길 수 있는가?

데이터 세트. 실험은 추천 시스템에 널리 사용되는 두 가지 공개 데이터 세트, 즉 (1) 사용자 평점이 상호작용으로 간주되는 영화 평점 데이터 세트 MovieLens-1M [12](줄여서 ML-1M)과 (2) 리뷰가 상호작용으로 간주되는 Amazon 리뷰 데이터 세트 [23]의 게임 카테고리 1개에 대해 수행됩니다. 상호작용이 5개 미만인 사용자와 상품을 필터링합니다. 그런 다음 각 사용자의 상호작용을 타임스탬프별로 정렬하고 가장 오래된 상호작용부터 정렬하여 해당 과거 상호작용 시퀀스를 구성합니다. 영화/제품 제목은 상품의 설명 텍스트로 사용됩니다.

평가 구성. 기존 연구[19, 18, 17]에 따라 평가 시에는 리브 원 아웃(leave-one-out) 전략을 적용합니다. 각 과거 상호작용 시퀀스에 대해 마지막 상품이 기준값 상품으로 사용됩니다. 주어진 m개의 후보에 대한 순위 결과를 평가하기 위해 널리 사용되는 메트릭인 NDCG@N을 채택합니다(여기서 N ≤ m).

구현 세부 사항. 이 작업의 재현을 용이하게 하기 위해 널리 사용되는 오픈 소스 추천 라이브러리 RECBOLE [36, 35, 33]을 사용하여 실험을 수행합니다. 순차적인 과거 사용자 행동의 경우, 기본적으로 가장 최근 50개의 상호작용을 사용합니다. LLM 기반 방법의 경우, 각 데이터 세트에 대한 과거 행동과 함께 200명의 사용자를 무작위로 샘플링합니다. SASRec[19]과 같은 기존 기준 방법(baseline)의 경우, 지정되지 않는 한 훈련 데이터 세트의 모든 상호 작용에 대해 훈련되며, 평가된 LLM은 OpenAI의 API gpt-3.5-turbo1을 호출하여 액세스합니다. LLM 호출의 하이퍼파라미터 온도(temperature)는 0.2로 설정됩니다. 보고된 모든 결과는 무작위성의 영향을 줄이기 위해 최소 3회 반복 실행의 평균입니다.

그림 2: LLM이 과거 사용자 행동을 활용하는지 여부와 LLM이 상호작용 기록의 순서를 인지하는지 여부를 분석합니다.

3.1 LLM이 순차적인 과거 사용자 행동과 관련된 프롬프트를 이해할 수 있나요?(Can LLMs Understand Prompts that Involve equential Historical User Behaviors?)

기존 문헌에서 과거 사용자 행동은 주로 특수하게 설계된 추천 모델에 의해 그래프[13] 또는 시퀀스[14]로 모델링됩니다. 반면, 본 연구에서는 과거 사용자 행동을 프롬프트로 인코딩하여 추천을 위해 특별히 훈련되지 않은 대규모 언어 모델에 입력합니다. 이 부분에서는 먼저 LLM이 이러한 과거 사용자 행동을 활용하여 정확한 추천을 할 수 있는지 여부를 조사합니다. 다양한 H 구성을 설계하여 (1) LLM이 과거 행동이 있는 프롬프트를 이해하고 그에 따라 순위를 매길 수 있는지, (2) 순차적 특성이 사용자 선호도를 이해하는 데 인식되고 활용되는지, (3) LLM이 장기적인 사용자 이력을 더 잘 활용할 수 있는지 등을 살펴보고자 합니다.

이 섹션의 실험은 주로 과거 사용자 행동의 효과에 초점을 맞추기 때문에, LLM의 랭킹 성능을 평가하기 위해 후보 집합을 구성하는 데 간단한 전략을 사용합니다. 구체적으로, 각 실측 데이터 상품에 대해 전체 상품 세트 I에서 m - 1 개의 상품을 네거티브 인스턴스로 무작위로 검색합니다(여기서 m = 20). 그런 다음 프롬프트를 구성하기 전에 이러한 후보 상품을 무작위로 섞습니다.

LLM은 과거 행동이 있는 프롬프트에 해당하는 개인화된 추천을 제공할 수 있습니다. 이 섹션에서는 LLM이 과거 사용자 행동이 있는 프롬프트를 이해하고 개인화된 추천을 제공할 수 있는지 여부를 살펴봅니다. 사용자의 과거 행동이 순차적으로 기록된 프롬프트가 주어지면, 하나의 실측 데이터 상품과 무작위로 샘플링된 부정 상품 19개를 포함하여 20개의 상품으로 구성된 후보 세트의 순위를 매기는 작업을 수행합니다. 과거 행동을 분석하여 관심 있는 상품에 더 높은 순위를 매겨야 합니다. 세 가지 LLM 기반 방법의 순위 결과를 비교합니다. (a) 2.2절에서 설명한 대로 LLM으로 순위를 매기는 방법. 과거 사용자 행동은 '순차적 프롬프트' 전략을 사용하여 프롬프트에 인코딩됩니다. (b) 기록 없음: 과거 사용자 행동이 지침에서 제거되고, (c) 가짜 기록: 원래 과거 행동의 모든 상품을 무작위로 샘플링된 가짜 과거 행동으로 대체합니다.

그림 2(a)를 보면, 과거 행동이 없거나 가짜 과거 행동이 있는 변종보다 우리의 변종이 더 나은 성능을 보이는 것을 알 수 있습니다. 이 결과는 LLM이 과거 사용자 행동이 포함된 프롬프트를 효과적으로 활용하여 개인화된 추천을 제공할 수 있는 반면, 관련 없는 과거 행동은 LLM의 순위 성능을 저해할 수 있음을 시사합니다.

LLM은 주어진 과거 사용자 행동의 순서를 인식하는 데 어려움을 겪습니다. 그림 2(b)에서는 사용자 과거 행동의 순차적 특성을 인식하는 LLM의 능력을 자세히 살펴봅니다. 접미사(랜덤 순서)가 붙은 변형은 과거 사용자 행동을 무작위로 섞어 모델에 입력하는 것을 의미합니다(당사 또는 SASRec). SASRec과 SASRec(무작위 순서)을 비교하면, 순차적인 과거 상호작용의 순서가 상품 순위에 매우 중요하다는 것을 알 수 있습니다. 그러나 우리와 우리의 (무작위 순서)의 성능은 매우 유사하며, 이는 LLM이 주어진 과거 사용자 행동의 순서에 민감하지 않다는 것을 나타냅니다.

표 2: 무작위로 검색된 후보에 대한 다양한 제로 샷 추천 모델의 성능 비교. 실측 데이터 상품은 후보 세트에 포함되도록 보장됩니다. 'full'는 대상 데이터 세트에 대해 학습된 추천 모델을 나타내고, 'zero-shot'은 대상 데이터 세트에 대해 학습되지는 않았지만 사전 학습될 수 있는 추천 모델을 나타냅니다. 세 가지 제로 샷 프롬프트 전략은 gpt-3.5-turbo를 기반으로 합니다. 제로샷 추천 방법 중 가장 우수한 성능을 굵은 글씨로 강조했습니다. N@K는 NDCG@K를 나타냅니다.

또한, 그림 2(c)에서는 프롬프트를 구성하는 데 사용되는 최신 사용자 행동 기록(|H|)의 수를 5개에서 50개까지 다양하게 설정했습니다. 그 결과, 과거 사용자 행동의 수를 늘린다고 해서 랭킹 성능이 향상되지 않으며, 심지어 랭킹 성능에 부정적인 영향을 미치는 것으로 나타났습니다. 이러한 현상은 LLM이 순서를 이해하기 어렵지만 모든 과거 행동을 동일하게 고려하기 때문에 발생하는 것으로 추측됩니다. 따라서 과거 사용자 행동이 너무 많으면(예: |H| = 50) LLM이 과부하가 걸려 성능이 저하될 수 있습니다. 반대로 상대적으로 작은 |H|를 사용하면 LLM이 가장 최근에 상호 작용한 상품에 집중할 수 있으므로 추천 성능이 향상됩니다. 위의 결과는 첫 번째 핵심 관찰로 요약할 수 있습니다:

관찰결과 1. LLM은 개인화된 순위를 위해 과거 행동을 활용할 수 있지만, 주어진 순차적 상호작용 기록의 순서를 인식하는 데 어려움을 겪습니다.

LLM이 상호작용 순서를 인식하도록 트리거하기. 위의 관찰 결과를 바탕으로 우리는 순차적 프롬프트 전략으로는 LLM이 상호작용 이력의 순서를 인식하기 어렵다는 것을 발견했습니다. 따라서 우리는 LLM의 순서 인식 능력을 이끌어내기 위한 두 가지 대안적인 프롬프트 전략을 제안합니다. 핵심 아이디어는 최근에 상호작용한 상품을 강조하는 것입니다. 제안된 최근성 중심 프롬프트와 문맥 내 학습 전략에 대한 자세한 설명은 섹션 2.2에 나와 있습니다.

표 2에서 최근 강제 프롬프트와 컨텍스트 내 학습 모두 LLM의 순위 지정 성능을 향상시킬 수 있음을 알 수 있습니다. 최신성 중심 프롬프트는 top-1 정확도를 더 잘 산출하는 반면, 인컨텍스트 학습은 과거 행동이 더 긴 데이터 세트에서 더 나은 성능을 발휘합니다. 위의 결과는 다음과 같은 주요 관찰 결과로 요약할 수 있습니다:

관찰결과 2. 최근성 중심 프롬프트 및 컨텍스트 내 학습과 같이 특별히 설계된 프롬프트를 사용하면 LLM이 과거 사용자 행동의 순서를 인식하도록 트리거하여 랭킹 성과를 개선할 수 있습니다.

3.2 제로 샷 설정에서 LLM이 후보 상품의 순위를 얼마나 잘 매길 수 있나요?(How Well Can LLMs Rank Candidate Items in a Zero-Shot Setting?)

이 섹션에서는 LLM이 후보의 순위를 얼마나 잘 매길 수 있는지 자세히 살펴봅니다. 먼저 벤치마킹 실험을 통해 기존 추천 모델, 기존 제로샷 추천 방법, 제안한 LLM 기반 방법 등 무작위 후보에 대한 다양한 방법 간의 순위 지정 성능을 비교합니다. 다음으로, 다양한 전략에 의해 검색된 하드 네거티브가 있는 후보에 대해 LLM 기반 방법을 평가하여 LLM의 순위가 무엇에 따라 달라지는지 자세히 살펴봅니다. 그런 다음, 보다 실용적이고 어려운 설정을 시뮬레이션하기 위해 여러 후보 생성 모델에 의해 검색된 후보에 대한 다양한 방법의 순위 성능을 비교하는 또 다른 벤치마크를 제시합니다.

그림 3: 다양한 전략으로 검색된 하드 네거티브에 대해 NDCG@10(%)으로 측정한 순위 성과

LLM은 유망한 제로 샷 랭킹 능력을 가지고 있습니다. 표 2에서는 LLM 기반 방법과 기존 방법의 순위 결정 능력을 비교하기 위한 실험을 수행합니다. 섹션 3.1의 설정과 동일하게 |C| = 20으로 설정하고 후보 상품(지상 진실 상품 제외)을 무작위로 검색합니다. 훈련 세트에 대해 학습된 세 가지 기존 추천 모델, 즉 Pop(상품 인기도에 따른 추천), BPRMF [25], SASRec [19]을 포함합니다. 또한 BM25 [26](후보 간의 텍스트 유사성과 과거 상호작용에 따라 순위 지정), UniSRec [18], VQ-Rec [16] 등 대상 데이터 세트에서 학습되지 않은 세 가지 제로 샷 추천 방법도 평가합니다. UniSRec과 VQ-Rec의 경우, 공개적으로 사용 가능한 사전 학습된 모델을 사용합니다. ZESRec [7]은 사전 훈련된 모델이 공개되지 않았고, UniSRec은 이 모델의 개선된 버전으로 볼 수 있기 때문에 포함하지 않았습니다[18]. LLM 기반 방법의 경우, 섹션 2.2에 설명된 대로 서로 다른 프롬프트 전략을 사용하는 세 가지 변형을 시퀀셜이라는 이름으로 포함합니다.

표 2를 보면 LLM 기반 방식이 기존 제로샷 추천 방식보다 큰 폭으로 성능이 뛰어나며, 제로샷 랭킹에 대한 가능성을 보여주고 있음을 알 수 있습니다. ML-1M 데이터셋에서는 단순히 제목의 유사도만으로 영화 간의 유사도를 측정하기 어렵기 때문에 제로샷 추천을 수행하기 어렵다는 점을 강조하고 싶습니다. LLM 기반 모델은 내재적 세계 지식을 사용하여 영화 간의 유사성을 측정하고 추천할 수 있기 때문에 ML-1M에서 여전히 유망한 제로샷 랭킹 성능을 달성할 수 있음을 알 수 있습니다. 그러나 제로샷 추천 방법과 기존 방법 사이에는 여전히 격차가 존재하며, 이는 상호작용 데이터로부터 학습할 수 있는 LLM 기반 추천 방법을 개발하는 것이 중요하다는 것을 나타냅니다[34].

LLM은 상품 인기도, 텍스트 기능 및 사용자 행동에 따라 후보의 순위를 매깁니다. LLM이 주어진 후보의 순위를 매기는 방법을 더 자세히 조사하기 위해, 다양한 후보 생성 방법으로 검색된 후보에 대한 LLM의 순위 성능을 평가합니다. 이러한 후보들은 실사 상품에 대한 하드 네거티브로 볼 수 있으며, 특정 상품 범주에 대한 LLM의 순위 지정 능력을 측정하는 데 사용할 수 있습니다. (1) BM25 [26] 및 BERT [6]와 같은 콘텐츠 기반 방법은 과거에 상호 작용한 상품과 후보 간의 텍스트 특징 유사성을 기반으로 후보를 검색하고, (2) Pop(상품 인기도에 따라 추천), BPRMF [25], GRU4Rec [14], SASRec [19]를 포함한 상호작용 기반 방법은 사용자-상품 상호 작용에 대해 학습된 기존 추천 모델을 사용하여 상품을 검색합니다. 후보가 주어지면 LLM 기반 모델(Ours)과 대표적인 콘텐츠 기반(BM25) 및 상호 작용 기반(Pop 및 SASRec) 방법의 순위 성능을 비교합니다.

표 3: 여러 후보 생성 모델에 의해 검색된 후보에 대한 다양한 제로 샷 추천 모델의 성능 비교. 실측 데이터 상품이 후보 세트에 포함되는 것은 보장되지 않습니다. 'full'는 대상 데이터 세트에 대해 학습된 추천 모델을 의미하며, 'zero-shot'은 대상 데이터 세트에 대해 학습되지는 않았지만 사전 학습될 수 있는 추천 모델을 의미합니다. 모든 추천 방법 중 가장 우수한 성능을 굵은 글씨로 강조했습니다. N@K는 NDCG@K를 나타냅니다.

그림 3에서 LLM 기반 방법의 순위 성능은 후보 세트와 데이터 세트에 따라 달라지는 것을 볼 수 있습니다. (1) ML-1M의 경우, 인기 상품(예: Pop 및 BPRMF)이 포함된 후보 세트에서는 LLM 기반 방식이 높은 순위를 차지하지 못하며, 이는 LLM 기반 방식이 ML-1M 데이터 세트에서 상품의 인기도에 따라 추천 상품이 크게 좌우된다는 것을 나타냅니다. (2) 게임에서는 인기 후보와 텍스트 유사 후보 모두에서 비슷한 순위 성능을 보이는 것을 관찰할 수 있으며, 이는 상품 인기도와 텍스트 특징이 LLM의 순위에 유사하게 기여한다는 것을 보여줍니다. (3) 두 데이터 세트 모두에서, 상호작용 기반 후보 생성 방법에 의해 검색된 하드 네거티브의 영향을 받지만, SASRec과 같이 순전히 상호작용에 기반한 순위 모델만큼 심각하지는 않습니다. 위의 결과는 LLM 기반 방법이 순위를 매길 때 일부 단일 측면만 고려하는 것이 아니라 상품 인기도, 텍스트 기능, 심지어 사용자 행동까지 활용한다는 것을 보여줍니다. 데이터 세트에 따라 순위 성능에 영향을 미치는 이 세 가지 측면의 가중치도 달라질 수 있습니다.

LLM은 여러 후보 생성 모델에서 검색된 후보의 순위를 효과적으로 매길 수 있습니다. 실제 2단계(two-stage) 추천 시스템[4]의 경우, 순위를 매길 상품은 일반적으로 여러 후보 생성 모델에 의해 검색됩니다. 따라서 저희도 보다 실제적인 환경에서 벤치마킹 실험을 진행했습니다. 일반적인 콘텐츠 기반 및 인터랙션 기반 방법을 포괄하는 7가지 후보 생성 모델, 즉 Random, BM25, BERT, Pop, BPRMF, GRU4Rec, SASRec을 사용하여 상품을 검색합니다. 각 후보 생성 모델에서 검색된 상위 3개의 우수 상품은 총 21개의 상품이 포함된 후보 집합으로 병합됩니다. 보다 실용적인 설정으로, 3.1절에서 설명한 설정처럼 각 후보 세트에 실측 상품을 보완하지는 않습니다. 3.1절의 실험에서 영감을 얻은 저희의 경우, 최근성 중심의 프롬프트 전략을 사용하여 |H| = 5개의 순차적인 과거 상호작용을 프롬프트로 인코딩하여 적절한 랭킹 성능을 구현합니다.

표 3을 보면, LLM 기반 순위 모델(Ours)이 대부분의 지표(8개 중 6개)에서 비교 대상 추천 모델에 비해 가장 우수한 성능을 보이며, 심지어 대상 데이터세트에 대해 학습된 기존 추천 모델인 SASRec을 능가하는 것을 확인할 수 있습니다. 이 결과는 여러 후보 생성 모델에 의해 검색된 후보에 대한 LLM의 강력한 제로샷 랭킹 능력을 보여줍니다. 이러한 현상에 대해 우리는 LLM이 내재적 세계 지식을 활용하여 인기도, 텍스트 특징, 사용자 행동 등을 종합적으로 고려하여 후보의 순위를 매길 수 있다고 가정합니다. 이에 비해 기존 모델(좁은 의미의 전문가)은 복잡한 환경에서 상품의 순위를 매기는 능력이 부족할 수 있습니다. 위의 결과는 다음과 같이 요약할 수 있습니다:

관찰결과 3. LLM은 특히 다양한 실제 전략을 가진 여러 후보 생성 모델에 의해 검색된 후보에 대해 제로 샷 랭킹 능력을 가지고 있습니다.

그림 4: 다양한 크기의 후보 집합에 대한 LLM 기반 모델(Ours)과 기존 추천 모델(SASRec)의 순위 성능 비교.

LLM은 후보 집합이 클 경우 후보의 순위를 제대로 매길 수 없습니다. 언어 모델로 긴 시퀀스의 의미를 효과적으로 모델링하는 것은 기술적으로 어려운 과제였습니다[8]. 따라서 우리는 LLM이 순위를 매기기 위해 대규모 후보 집합을 처리할 수 있는지 조사하고자 합니다. 후보 |C|의 수를 5개에서 50개까지 다양하게 설정하고 그림 4에서 랭킹 성능을 보고합니다. LLM과 기존 추천 모델(예: SASRec) 간의 격차가 |C|가 증가할수록 커지는 것을 볼 수 있으며, 이는 많은 후보 상품 집합의 순위를 매길 때 LLM이 어려움에 직면할 수 있음을 나타냅니다.

3.3 LLM이 순위를 매길 때 편향성이 있나요?(Do LLMs suffer from biases while ranking?)

기존 추천 시스템의 편향과 디베이싱(debiasing) 방법은 널리 연구되어 왔습니다[2]. 제안된 LLM 기반 제로 샷 추천 모델의 경우에도 LLM의 순위에 영향을 미치는 특정 편향이 있을 수 있습니다. 이 섹션에서는 LLM 기반 추천 모델이 겪을 수 있는 두 가지 편향, 즉 위치 편향과 인기 편향에 대해 설명합니다. 또한 이러한 편향을 완화하는 방법에 대해서도 논의합니다.

후보 순서는 LLM의 순위 결과에 영향을 미칩니다. 기존의 랭킹 방식에서는 검색된 후보의 순서가 랭킹 결과에 영향을 미치지 않는 것이 일반적입니다. 그러나 2.2절에서 설명한 LLM 기반 접근 방식에서는 후보 상품이 순차적으로 배열되고 프롬프트에 LLM의 입력으로 인코딩됩니다. LLM은 일반적으로 자연어 처리 작업의 프롬프트에서 예제 순서에 민감하다는 것이 밝혀졌습니다 [38, 22]. 이에 따라 후보의 순서가 LLM의 랭킹 성능에 영향을 미치는지 실험을 진행했습니다. 3.1절에서 사용한 것과 동일한 후보 세트에 대해 LLM의 성능을 평가합니다. 유일한 차이점은 프롬프트에서 이러한 후보의 순서를 목적에 따라 제어한다는 것입니다. 즉, 프롬프트를 구성하는 동안 지상 진실 상품이 특정 위치에 나타나도록 합니다. 실측값 상품의 위치를 {0, 5, 10, 15, 19}로 변경하여 순위 결과를 그림 5(a)에 제시합니다. 실측값 상품이 다른 위치에 표시될 때 순위 성능이 달라지는 것을 볼 수 있습니다. 특히, 실측값 상품이 마지막 몇 개의 위치에 나타날 때 순위 성능이 크게 떨어집니다. 이 결과는 기존 추천 모델은 일반적으로 영향을 받지 않는 반면, LLM 기반 랭커의 경우 후보의 순서, 즉 위치 편향에 따라 LLM의 랭킹 성능이 영향을 받는다는 것을 나타냅니다.

그림 5: LLM 순위의 편향성 및 디베이싱 방법. (a) 프롬프트에서 후보자의 위치가 순위 결과에 영향을 미칩니다. (b) LLM은 인기 있는 아이템을 추천하는 경향이 있습니다. (c) 부트스트래핑은 위치 편향을 완화합니다. (d) 과거 상호작용에 초점을 맞추면 인기 편향이 줄어듭니다.

부트스트래핑을 통한 위치 편향성 완화. 그림 5(a)에서 볼 수 있듯이, LLM은 프롬프트의 뒷부분에 위치한 후보 상품의 순위를 낮게 매기는 경향이 있음을 알 수 있습니다. 후보 상품이 각 위치에 무작위로 할당되므로 위치 편향을 완화하기 위한 간단한 전략은 순위 프로세스를 부트스트랩하는 것입니다. 각 라운드마다 후보 상품을 무작위로 섞어 한 후보 상품이 다른 위치에 나타나 순위를 매길 수 있도록 후보 집합을 B회 반복하여 순위를 매길 수 있습니다.

순위를 매긴 후 더 높은 순위에 있는 상품에 더 높은 점수를 부여하고, 순위 점수를 합산하여 최종 순위를 도출합니다. 그림 5(c)에서 3.1절의 설정에 따라 부트스트랩 전략을 적용합니다. 각 후보 세트는 3번씩 순위를 매깁니다. 부트스트래핑이 두 데이터 세트 모두에서 랭킹 성능을 향상시킨다는 것을 알 수 있습니다.

후보의 인기도는 LLM의 순위 결과에 영향을 미칩니다. 인기 있는 상품의 경우 관련 텍스트가 LLM의 사전 학습 코퍼스에 자주 나타날 수도 있습니다. 예를 들어 베스트셀러 도서가 웹에서 널리 논의될 수 있습니다. 따라서 우리는 후보의 인기도에 따라 순위 결과가 영향을 받는지 살펴보고자 합니다. 하지만 사전 학습 코퍼스로는 상품 텍스트의 인기도를 직접 측정하기 어렵습니다. 따라서 하나의 추천 데이터셋에서 상품 빈도로 텍스트 인기도를 간접적으로 측정하여 반영할 수 있다는 가설을 세웠습니다. 그림 5(b)는 순위가 매겨진 상품 목록의 각 위치에 대한 상품 인기도 점수(훈련 세트에서 정규화된 상품의 출현 빈도로 측정)를 보여줍니다. 인기 있는 아이템이 더 높은 위치에 랭크되는 경향이 있음을 알 수 있습니다. 기존 추천 모델과 마찬가지로 LLM도 인기 편향이 발생하여 더 인기 있는 상품을 추천하는 것을 선호합니다.

LLM이 과거 상호작용에 초점을 맞추도록 하면 인기 편향을 줄이는 데 도움이 됩니다. 그림 5(b)를 보면 LLM이 인기 있는 상품의 순위를 더 높게 매기는 경향이 있음을 알 수 있습니다. 섹션 3.2의 관찰 결과에서 알 수 있듯이, 그 이유는 LLM이 과거 상호작용을 잘 활용하지 못하고 주로 상품 인기도에 따라 추천을 해야 하기 때문일 수 있습니다. 그림 2(c)의 실험을 통해, 사용된 과거 상호작용의 수가 적을 때 LLM이 과거 상호작용을 더 잘 활용할 수 있다는 것을 알 수 있습니다. 따라서, LLM이 사용자 이력에 더 집중할 때 인기도 편향이 줄어들 수 있는지 알아보기 위해 이력 상호작용의 수를 변화시켰습니다. 그림 5(d)에서 가장 높은 순위를 차지한 상품의 인기도 점수(정규화된 상품 빈도로 측정)를 비교해 보았습니다. 과거 상호작용 횟수가 감소함에 따라 인기도 점수도 감소하는 것을 확인할 수 있습니다. 이는 LLM이 과거 상호작용에 집중하도록 강제할 때 인기도 편향의 영향을 줄일 수 있음을 시사합니다. 위의 실험을 통해 다음과 같은 결론을 내릴 수 있습니다:

관찰결과 4. LLM은 순위를 매기는 동안 포지션 편향과 인기 편향을 겪게 되는데, 이는 특별히 고안된 프롬프트 또는 부트스트랩 전략을 통해 완화할 수 있습니다.

3.4 LLM은 어떻게 추천 능력을 얻나요?(How Do LLMs Gain Recommendation Abilities?)

이 섹션에서는 어떤 요인이나 기법이 LLM의 랭킹 능력에 기여하는지 살펴봅니다. 특히 명령 튜닝과 모델 스케일링이라는 두 가지 요인이 LLM의 랭킹 능력에 미치는 영향을 주로 살펴보는데, 이 두 가지 기법이 LLM의 능력에 핵심적인 역할을 하는 것으로 나타났기 때문입니다[37, 1, 32]. 앞으로는 이 두 가지 기법이 LLM의 추천 성능을 어떻게 향상시키는지에 대해 좀 더 집중적으로 연구하고자 합니다.

명령어 튜닝은 LLM의 순위 결정 능력을 향상시킵니다. 기존 연구에 따르면 명령어 튜닝은 보이지 않는 작업에 대한 LLM의 일반화 능력을 크게 향상시키는 것으로 나타났습니다 [27, 32]. 여기서는 LLM을 사용하여 과거 상호작용에 따라 상품의 순위를 매기는 능력이 명령어 튜닝을 통해 향상될 수 있는지 알아보고자 합니다. 3.1절의 실험 설정에 따라 제안한 LLM 기반 랭킹 방법의 기본 LLM을 gpt-3.5-turbo에서 (1) LLaMA [28]와 같이 명령어 튜닝을 하지 않은 LLM과 (2) Vicuna [3], text-davinci-0032와 같이 명령에 대한 미세 튜닝을 한 LLM으로 교체한 후 이들에 랭킹 작업을 수행하도록 인스트럭션을 내립니다. 그림 6에서 Vicuna-7/13B와 LLaMA-7/13B를 비교하면 명령어 튜닝을 거친 LLM이 명령어 튜닝을 거치지 않은 LLM보다 성능이 뛰어나다는 것을 알 수 있습니다. 이 결과는 명령어 튜닝이 추천 작업을 위해 특별히 설계된 명령어가 아니더라도 LLM의 순위 지정 능력을 향상시킨다는 것을 보여줍니다.

그림 6: 다양한 LLM을 사용한 랭킹 성능 비교

모델 스케일링은 LLM의 랭킹 성능을 향상시킵니다. 스케일링 법칙에서 알 수 있듯이, 모델 크기와 훈련 데이터의 양이 증가함에 따라 다양한 다운스트림 작업에서 LLM의 성능은 일반적으로 향상됩니다 [24, 15, 28]. 3.1절의 실험 설정에 따라 기본 LLM을 다양한 크기(7B, 13B, 35B, 65B)의 LLaMA로 대체하여 제로 샷 추천 작업에 대한 모델 스케일링의 효과를 조사합니다. 그림 6을 보면 모델 크기가 커질수록 LLM의 랭킹 성능이 향상되는 것을 알 수 있습니다(즉, LLaMA-65B > LLaMA-35B > LLaMA-13B 순). 또한 100B보다 큰 LLM이 더 우수한 랭킹을 산출한다는 것을 알 수 있습니다.

text-davinci-003과 gpt-3.5-turbo를 다른 작은 LLM과 비교하면 알 수 있습니다. 위의 결과는 제로 샷 추천 작업도 스케일링 법칙, 즉 모델 스케일링이 LLM의 랭킹 성능을 향상시킨다는 것을 나타냅니다.

4. 결론(Conclusion)

본 연구에서는 추천 시스템의 랭킹 모델 역할을 하는 LLM의 성능에 대해 살펴보았습니다. 구체적으로, 추천 작업을 조건부 랭킹 작업으로 공식화하여 순차적인 과거 상호작용을 조건으로, 후보 생성 모델에서 검색된 상품을 후보로 간주했습니다. LLM으로 순위를 매기기 위해 후보뿐만 아니라 과거 상호작용을 포함하는 자연어 프롬프트를 추가로 구성했습니다. 그런 다음 LLM이 순차적 행동의 순서를 인식할 수 있도록 특별히 고안된 몇 가지 프롬프트 전략을 제안합니다. 또한 LLM 기반 랭킹 모델이 겪을 수 있는 위치 편향 문제를 완화하기 위한 간단한 부트스트랩 전략도 소개합니다. 광범위한 경험적 연구에 따르면 LLM은 제로 샷 랭킹에 유망한 능력을 가지고 있습니다. 또한 몇 가지 주요 연구 결과를 바탕으로 (1) 순차적인 과거 상호작용의 순서를 더 잘 인식하고, (2) 더 많은 과거 상호작용과 후보를 더 잘 활용하며, (3) 위치 편향과 인기 편향을 완화하는 등 LLM의 랭킹 능력을 더욱 향상시킬 수 있는 몇 가지 유망한 방향을 조명하고자 합니다. 향후 작업에서는 제로 샷 랭커로 LLM을 배포할 때 위에서 언급한 주요 과제를 해결하기 위한 기술적 접근 방식을 개발하는 것을 고려하고 있습니다. 또한 효과적인 개인화 추천을 위해 다운스트림 사용자 행동에 따라 효율적으로 조정할 수 있는 LLM 기반 추천 모델을 개발하고자 합니다.

참고문헌(References)

[1] Tom Brown, Benjamin Mann, Nick Ryder, Melanie Subbiah, Jared D Kaplan, Prafulla Dhariwal, Arvind Neelakantan, Pranav Shyam, Girish Sastry, Amanda Askell, et al. Language models are few-shot learners. NeurIPS, 33:1877–1901, 2020.
[2] Jiawei Chen, Hande Dong, Xiang Wang, Fuli Feng, Meng Wang, and Xiangnan He. Bias and debias in recommender system: A survey and future directions. CoRR, abs/2010.03240, 2020.
[3] Wei-Lin Chiang, Zhuohan Li, Zi Lin, Ying Sheng, Zhanghao Wu, Hao Zhang, Lianmin Zheng, Siyuan Zhuang, Yonghao Zhuang, Joseph E. Gonzalez, Ion Stoica, and Eric P. Xing. Vicuna: An open-source chatbot impressing gpt-4 with 90%* chatgpt quality, March 2023.
[4] Paul Covington, Jay Adams, and Emre Sargin. Deep neural networks for youtube recommendations. In RecSys, pages 191–198, 2016.
[5] Sunhao Dai, Ninglu Shao, Haiyuan Zhao, Weijie Yu, Zihua Si, Chen Xu, Zhongxiang Sun, Xiao Zhang, and Jun Xu. Uncovering chatgpt’s capabilities in recommender systems. arXiv preprint arXiv:2305.02182, 2023.
[6] Jacob Devlin, Ming-Wei Chang, Kenton Lee, and Kristina Toutanova. Bert: Pre-training of deep bidirectional transformers for language understanding. In NAACL, 2019.
[7] Hao Ding, Yifei Ma, Anoop Deoras, Yuyang Wang, and Hao Wang. Zero-shot recommender systems. arXiv:2105.08318, 2021.
[8] Zican Dong, Tianyi Tang, Lunyi Li, and Wayne Xin Zhao. A survey on long text modeling with transformers. arXiv preprint arXiv:2302.14502, 2023.
[9] Yunfan Gao, Tao Sheng, Youlin Xiang, Yun Xiong, Haofen Wang, and Jiawei Zhang. Chat-rec: Towards interactive and explainable llms-augmented recommender system. arXiv preprint arXiv:2303.14524, 2023.
[10] Shijie Geng, Shuchang Liu, Zuohui Fu, Yingqiang Ge, and Yongfeng Zhang. Recommendation as language processing (RLP): A unified pretrain, personalized prompt & predict paradigm (P5). In RecSys, 2022.
[11] Qingyu Guo, Fuzhen Zhuang, Chuan Qin, Hengshu Zhu, Xing Xie, Hui Xiong, and Qing He. A survey on knowledge graph-based recommender systems. TKDE, 34(8):3549–3568, 2020.
[12] F Maxwell Harper and Joseph A Konstan. The movielens datasets: History and context. TIIS, 5(4):1–19, 2015.
[13] Xiangnan He, Kuan Deng, Xiang Wang, Yan Li, Yong-Dong Zhang, and Meng Wang. Lightgcn: Simplifying and powering graph convolution network for recommendation. In SIGIR, 2020.
[14] Balázs Hidasi, Alexandros Karatzoglou, Linas Baltrunas, and Domonkos Tikk. Session-based recommendations with recurrent neural networks. In ICLR, 2016.
[15] Jordan Hoffmann, Sebastian Borgeaud, Arthur Mensch, Elena Buchatskaya, Trevor Cai, Eliza Rutherford, Diego de Las Casas, Lisa Anne Hendricks, Johannes Welbl, Aidan Clark, et al. Training compute-optimal large language models. arXiv preprint arXiv:2203.15556, 2022.
[16] Yupeng Hou, Zhankui He, Julian McAuley, and Wayne Xin Zhao. Learning vector-quantized item
representation for transferable sequential recommenders. In WWW, 2023.
[17] Yupeng Hou, Binbin Hu, Zhiqiang Zhang, and Wayne Xin Zhao. Core: Simple and effective session-based recommendation within consistent representation space. In SIGIR, 2022.
[18] Yupeng Hou, Shanlei Mu, Wayne Xin Zhao, Yaliang Li, Bolin Ding, and Ji-Rong Wen. Towards universal sequence representation learning for recommender systems. In KDD, 2022.
[19] Wang-Cheng Kang and Julian McAuley. Self-attentive sequential recommendation. In ICDM, 2018.
[20] Donald E Knuth, James H Morris, Jr, and Vaughan R Pratt. Fast pattern matching in strings. SIAM journal on computing, 6(2):323–350, 1977.
[21] Guo Lin and Yongfeng Zhang. Sparks of artificial general recommender (agr): Early experiments with chatgpt. arXiv preprint arXiv:2305.04518, 2023.
[22] Yao Lu, Max Bartolo, Alastair Moore, Sebastian Riedel, and Pontus Stenetorp. Fantastically ordered prompts and where to find them: Overcoming few-shot prompt order sensitivity. In ACL, 2022.12
[23] Jianmo Ni, Jiacheng Li, and Julian McAuley. Justifying recommendations using distantly-labeled reviews and fine-grained aspects. In EMNLP, pages 188–197, 2019.
[24] Jack W Rae, Sebastian Borgeaud, Trevor Cai, Katie Millican, Jordan Hoffmann, Francis Song, John Aslanides, Sarah Henderson, Roman Ring, Susannah Young, et al. Scaling language models: Methods, analysis & insights from training gopher. arXiv preprint arXiv:2112.11446, 2021.
[25] Steffen Rendle, Christoph Freudenthaler, Zeno Gantner, and Lars Schmidt-Thieme. BPR: bayesian personalized ranking from implicit feedback. In UAI, 2009.
[26] Stephen E. Robertson and Hugo Zaragoza. The probabilistic relevance framework: BM25 and beyond. Found. Trends Inf. Retr., 3(4):333–389, 2009.
[27] Victor Sanh, Albert Webson, Colin Raffel, Stephen H. Bach, Lintang Sutawika, Zaid Alyafeai, Antoine Chaffin, Arnaud Stiegler, Arun Raja, Manan Dey, M Saiful Bari, Canwen Xu, Urmish Thakker,
Shanya Sharma Sharma, Eliza Szczechla, Taewoon Kim, Gunjan Chhablani, Nihal V. Nayak, Debajyoti
Datta, Jonathan Chang, Mike Tian-Jian Jiang, Han Wang, Matteo Manica, Sheng Shen, Zheng Xin Yong, Harshit Pandey, Rachel Bawden, Thomas Wang, Trishala Neeraj, Jos Rozen, Abheesht Sharma, Andrea Santilli, Thibault Févry, Jason Alan Fries, Ryan Teehan, Teven Le Scao, Stella Biderman, Leo Gao, Thomas Wolf, and Alexander M. Rush. Multitask prompted training enables zero-shot task generalization. In ICLR, 2022.
[28] Hugo Touvron, Thibaut Lavril, Gautier Izacard, Xavier Martinet, Marie-Anne Lachaux, Timothée Lacroix, Baptiste Rozière, Naman Goyal, Eric Hambro, Faisal Azhar, et al. Llama: Open and efficient foundation language models. arXiv preprint arXiv:2302.13971, 2023.
[29] Lei Wang and Ee-Peng Lim. Zero-shot next-item recommendation using large pretrained language models. arXiv preprint arXiv:2304.03153, 2023.
[30] Wenjie Wang, Xinyu Lin, Fuli Feng, Xiangnan He, and Tat-Seng Chua. Generative recommendation: Towards next-generation recommender paradigm. arXiv preprint arXiv:2304.03516, 2023.
[31] Xiaolei Wang, Kun Zhou, Ji-Rong Wen, and Wayne Xin Zhao. Towards unified conversational recommender systems via knowledge-enhanced prompt learning. In KDD, 2022.
[32] Jason Wei, Maarten Bosma, Vincent Y. Zhao, Kelvin Guu, Adams Wei Yu, Brian Lester, Nan Du, Andrew M. Dai, and Quoc V. Le. Finetuned language models are zero-shot learners. In ICLR, 2022.
[33] Lanling Xu, Zhen Tian, Gaowei Zhang, Junjie Zhang, Lei Wang, Bowen Zheng, Yifan Li, Jiakai Tang, Zeyu Zhang, Yupeng Hou, Xingyu Pan, Wayne Xin Zhao, Xu Chen, and Ji-Rong Wen. Towards a more user-friendly and easy-to-use benchmark library for recommender systems. In SIGIR, 2023.
[34] Junjie Zhang, Ruobing Xie, Yupeng Hou, Wayne Xin Zhao, Leyu Lin, and Ji-Rong Wen. Recommendation as instruction following: A large language model empowered recommendation approach. arXiv preprint arXiv:2305.07001, 2023.
[35] Wayne Xin Zhao, Yupeng Hou, Xingyu Pan, Chen Yang, Zeyu Zhang, Zihan Lin, Jingsen Zhang, Shuqing Bian, Jiakai Tang, Wenqi Sun, Yushuo Chen, Lanling Xu, Gaowei Zhang, Zhen Tian, Changxin Tian, Shanlei Mu, Xinyan Fan, Xu Chen, and Ji-Rong Wen. Recbole 2.0: Towards a more up-to-date recommendation library. In CIKM, 2022.
[36] Wayne Xin Zhao, Shanlei Mu, Yupeng Hou, Zihan Lin, Yushuo Chen, Xingyu Pan, Kaiyuan Li, Yujie Lu, Hui Wang, Changxin Tian, Yingqian Min, Zhichao Feng, Xinyan Fan, Xu Chen, Pengfei Wang, Wendi Ji, Yaliang Li, Xiaoling Wang, and Ji-Rong Wen. Recbole: Towards a unified, comprehensive and efficient framework for recommendation algorithms. In CIKM, 2021.
[37] Wayne Xin Zhao, Kun Zhou, Junyi Li, Tianyi Tang, Xiaolei Wang, Yupeng Hou, Yingqian Min, Beichen Zhang, Junjie Zhang, Zican Dong, Yifan Du, Chen Yang, Yushuo Chen, Zhipeng Chen, Jinhao Jiang, Ruiyang Ren, Yifan Li, Xinyu Tang, Zikang Liu, Peiyu Liu, Jian-Yun Nie, and Ji-Rong Wen. A survey of large language models. arXiv preprint arXiv:2303.18223, 2023.
[38] Zihao Zhao, Eric Wallace, Shi Feng, Dan Klein, and Sameer Singh. Calibrate before use: Improving few-shot performance of language models. In ICML, 2021.
[39] Kun Zhou, Hui Wang, Wayne Xin Zhao, Yutao Zhu, Sirui Wang, Fuzheng Zhang, Zhongyuan Wang, and Ji-Rong Wen. S3-rec: Self-supervised learning for sequential recommendation with mutual information maximization. In CIKM, 2020.

A. ML-1M Dataset을 사용한 예제

A.1 Sequential Prompting

  • Input:

I’ve watched the following movies in the past in order:
[’0. The Matrix’, ’1. Terminator2: Judgment Day’, ’2. Roger & Me’, ’3. Fargo’, ’4. The Blair Witch Project’]

Now there are 20 candidate movies that I can watch next:
[’0. Nixon’, ’1. X-Men’, ’2. Best Men’, “3. Carlito’s Way”, ’4. Star Trek IV: The Voyage Home’, ’5. The Five Senses’, ’6. Mephisto’, ’7. Meatballs 4’, ’8. The Stupids’, ’9. Thunderball’, ’10. Body Parts’, ’11. Grumpier Old Men’, ’12. The Wedding Singer’, ’13. Ronin’, ’14. Apple, The (Sib)’, ’15. Tampopo’, ’16. The Goodbye Girl’, ’17. Force of Evil’, ’18. The Edge’, ’19. Klute’]

Please rank these 20 movies by measuring the possibilities that I would like to watch next most, according to my watching history. Please think step by step.

Please show me your ranking results with order numbers. Split your output with line break. You MUST rank the given candidate movies. You can not generate movies that are not in the given candidate list.

  • Output:
  1. X-Men
  2. Carlito’s Way
  3. Ronin
  4. The Edge
  5. Nixon
  6. Grumpier Old Men
  7. The Wedding Singer
  8. Thunderball
  9. Body Parts
  10. Star Trek IV: The Voyage Home
  11. Tampopo
  12. Klute
  13. The Goodbye Girl
  14. Force of Evil
  15. Best Men
  16. The Five Senses
  17. Mephisto
  18. Meatballs 4
  19. The Stupids
  20. Apple, The (Sib)
  • Result: 정답은 “X-Men”, Ranking이 0로 나옴(0부터 시작한다 했을 때)

A.2 Recency-focused Prompting

  • Input:

I’ve watched the following movies in the past in order:
[’0. Eyes Wide Shut’, ’1. Fight Club’, “2. The General’s Daughter”, ’3. Gone in 60 Seconds’, ’4. Gladiator’]

Now there are 20 candidate movies that I can watch next:
[’0. For Whom the Bell Tolls’, ’1. Encino Man’, ’2. The Pope of Greenwich Village’, ’3. I Married A Strange Person’, ’4. Daylight’, ’5. Rain’, ’6. Children of a Lesser God’, “7. She’s the One”, ’8. For the Moment’, ’9. Once Upon a Time in America’, ’10. The Truth About Cats & Dogs’, “11. A Hard Day’s Night”, ’12. Jakob the Liar’, ’13. Angel Heart’, ’14. Galaxy Quest’, ’15. The Abominable Snowman’, ’16. Bait’, ’17. Warriors of Virtue’, ’18. Three to Tango’, ’19. Heaven & Earth’]

Please rank these 20 movies by measuring the possibilities that I would like to watch next most, according to my watching history. Please think step by step.

Note that my most recently watched movie is Gladiator. Please show me your ranking results with order numbers. Split your output with line break. You MUST rank the given candidate movies. You can not generate movies that are not in the given candidate list.

  • Output:
  1. Once Upon a Time in America
  2. Angel Heart
  3. The Truth About Cats & Dogs
  4. Galaxy Quest
  5. Jakob the Liar
  6. A Hard Day’s Night
  7. The Pope of Greenwich Village
  8. Rain
  9. For Whom the Bell Tolls
  10. Three to Tango
  11. She’s the One
  12. Bait
  13. I Married A Strange Person
  14. Children of a Lesser God
  15. Warriors of Virtue
  16. Heaven & Earth
  17. Encino Man
  18. Daylight
  19. The Abominable Snowman
  20. For the Moment

Result: 정답은 “Jakob the Liar”, Ranking이 4로 나옴(0부터 시작한다 했을 때)

A.3 In-context learning

  • Input:

I’ve watched the following movies in the past in order:
[’0. Mirror, The (Zerkalo)’, ’1.The 39 Steps’, ’2. Sanjuro’, ’3. Trouble in Paradise’]

Then if I ask you to recommend a new movie to me according to my watching history, you should recommend Shampoo and now that I’ve just watched Shampoo, there are 20 candidate movies that I can watch next:
[’0. Manon of the Spring (Manon des sources)’, ’1. Air Bud’, ’2. Citizen Kane’, ’3. Grand Hotel’, ’4. A Very Brady Sequel’, ’5. 42 Up’, ’6. Message to Love: The Isle of Wight Festival’, ’7. Screamers’, ’8. The
Believers’, ’9. Hamlet’, ’10. Cliffhanger’, ’11. Three Wishes’, ’12. Nekromantik’, ’13. Dangerous Minds’, ’14. The Prophecy’, ’15. Howling II: Your Sister Is a Werewolf ’, ’16. World of Apu, The (Apur Sansar)’, ’17. The Breakfast Club’, ’18. Hoop Dreams’, ’19. Eddie’]

Please rank these 20 movies by measuring the possibilities that I would like to watch next most, according to my watching history. Please think step by step.

Please show me your ranking results with order numbers. Split your output with line break. You MUST rank the given candidate movies. You can not generate movies that are not in the given candidate list.

  • Output:
  1. Manon of the Spring (Manon des sources)
  2. Citizen Kane
  3. Grand Hotel
  4. Hamlet
  5. The Breakfast Club
  6. Hoop Dreams
  7. Eddie
  8. Three Wishes
  9. The Prophecy
  10. Dangerous Minds
  11. World of Apu, The (Apur Sansar)
  12. Cliffhanger
  13. A Very Brady Sequel
  14. Screamers
  15. Howling II: Your Sister Is a Werewolf
  16. Nekromantik
  17. 42 Up
  18. Message to Love: The Isle of Wight Festival
  19. Air Bud
  20. The Believers
  • Result: 정답은 “World of Apu, The (Apur Sansar)”, Ranking이 10로 나옴(0부터 시작한다 했을 때)

B. Games을 사용한 예제

B.1 Sequential Prompting

  • Input:

I’ve purchased the following products in the past in order:
[’0. Sony PlayStation 3 Blu-ray Disc Remote’, ’1. PlayStation 3 160GB System with Ratchet & Clank Future: A Crack in Time and SingStar Dance Party Pack - Family Bundle’, ’2. PS3 320GB Uncharted 3 Bundle’, ’3. FIFA Soccer 10 - Playstation 3’]

Now there are 20 candidate products that I can consider to purchase next:
[’0. Wii 9 in 1 Sports Kit’, ’1. Donkey Kong’, ’2. Midnight Club’, ’3. Midnight Club’, ’4. SRS: Street Racing Syndicate - PlayStation 2’, ’5. Ultimate Action Triple Pack - PlayStation 3’, ’6. Thrustmaster TMX Force Feedback racing wheel for Xbox One and WINDOWS’, ’7. Pikmin 2 (Nintendo Selects) - Nintendo Wii’, ’8. Rock Candy Blueberry Boom’, ’9. Finding Nemo - Gamecube’, ’10. SteelSeries Siberia 200 Gaming Headset - Alchemy Gold (formerly Siberia v2)’, ’11. Konnet Xbox 360 / Slim Power Pyramid RCS series Charger, Charging and Storage Dock for FOUR Game Controllers - Black’, ’12. Megadream Xbox One Wireless Keyboard, Mini 2.4Ghz Qwerty Text Message Chatpad Keypad for Microsoft Xbox One and Xbox One Slim Controller - Not Compatible with Xbox One Elite and X Controller’, ’13. Theme Hospital - PlayStation’, ’14. Spongebob Hero Pants The Game 2015 - Xbox 360’, ’15. Megaman & Bass’, ’16. BW® 5 Pair/10 Pcs Replacement Silicone Analog Controller Joystick Thumb Stick Grips Cap Cover For PS3 / PS4 / Xbox 360 / Xbox One / Wii Game Controllers (green)’, ’17. Skylanders Giants Battlepack #1 - Chop Chop - Dragonfire Cannon - Shroomboom’, ’18. Rune Factory: Tides of Destiny - Playstation 3’, ’19. Donkey Kong Land III’]

Please rank these 20 products by measuring the possibilities that I would like to purchase next most, according to the given purchasing records. Please think step by step.

Please only output the order numbers after ranking. Split these order numbers with line break.

  • Output:
  1. 1
  2. 5
  3. 6
  4. 10
  5. 11
  6. 12
  7. 16
  8. 17
  9. 18
  10. 2
  11. 0
  12. 7
  13. 8
  14. 9
  15. 13
  16. 14
  17. 15
  18. 3
  19. 4
  20. 19
  • Result: 정답은 “Midnight Club”, Ranking이 9로 나옴(0부터 시작한다 했을 때)

B.2 Recency-focused Prompting

  • Input:

I’ve purchased the following products in the past in order:
[’0. PowerA DualShock 4 Charging Station for PlayStation 4’, ’1. Far Cry 4 - PlayStation 4’, ’2. WWE 2K17 - PlayStation 4’, ’3. Dragon Quest Builders - PlayStation 4’]

Now there are 20 candidate products that I can consider to purchase next:
[’0. Ready to Rumble Boxing: Round 2’, ’1. Insten USB Charger Charging Cable Replacement For Nintendo NEW 3DS XL / NEW 2DS XL / 3DS XL / 3DS / 2DS / DSi / DSi XL / DSi LL’, “2. Cabela’s African Adventures - Xbox 360”, ’3. Blood Bowl - Xbox 360’, ’4. Skullcandy SLYR Gaming Headset, White (SMSLFY-205 )’, ’5. HORI 3DS Protector and Pouch Set (Mario Kart 7 version)’, ’6. Grand Theft Auto V - PlayStation 4’, “7. Yoshi’s New Island Full Game Download Code - Nintendo 3DS eShop”, ’8. Gauntlet’, ’9. Solitaire & Mahjong - Nintendo Wii’, ’10. Happy Feet 2 - Playstation 3’, ’11. Little Italy - Hidden Object Games [Download]’, ’12. Jillian Michaels Fitness Adventure - Xbox 360’, ’13. Dream Day Wedding: Viva Las Vegas - PC’, ’14. NBA Inside Drive 2003’, ’15. The Sims 2 - Sony PSP’, ’16. Xenogears - PlayStation’, ’17. Combat’, ’18. Crash Bandicoot: The Wrath of Cortex - Gamecube’, ’19. Sonic Mega Collection’]

Please rank these 20 products by measuring the possibilities that I would like to purchase next most, according to the given purchasing records. Please think step by step.

Note that my most recently purchased product is Dragon Quest Builders - PlayStation 4. Please only output the order numbers after ranking. Split these order numbers with line break.

  • Output:
  1. 6
  2. 0
  3. 4
  4. 2
  5. 7
  6. 18
  7. 16
  8. 3
  9. 1
  10. 8
  11. 19
  12. 13
  13. 12
  14. 11
  15. 10
  16. 5
  17. 9
  18. 15
  19. 14
  20. 17
  • Result: 정답은 “Grand Theft Auto V - PlayStation 4”, Ranking이 0로 나옴(0부터 시작한다 했을 때)

B.3 In-context Learning

  • Input:

I’ve purchased the following products in the past in order:
[’0. Scooby-Doo Unmasked - PlayStation 2’, ’1. Scooby-Doo: Mystery Mayhem’, ’2. Thrillville: Off the Rails’, ’3. Pac Man World 2 - PlayStation 2’]

Then if I ask you to recommend a new product to me according to the given purchasing history, you should recommend Charlie and the Chocolate Factory - PlayStation 2 and now that I’ve just purchased Charlie and the Chocolate Factory - PlayStation 2, there are 20 candidate products that I can consider to purchase next:
[’0. Controller Gear Controller Stand v1.0 - Officially Licensed - Black - Xbox One’, ’1. NHL 08 - PlayStation 2’, ’2. Hyperdimension Neptunia Victory - Playstation 3’, ’3. DOOM [Online Game Code]’, ’4. Sega Dreamcast Controller’, ’5. Mayflash F300 Arcade Fight Stick Joystick for PS4 PS3 XBOX ONE XBOX 360 PC Switch NeoGeo mini’, ’6. Fallout New Vegas Ultimate Edition’, ’7. Star Wars Galactic Battlegrounds: Clone
Campaigns (Expansion Pack)’, ’8. Hatsune Miku: Project DIVA X - PlayStation 4’, ’9. GameMaster Sony PS Vita Anti-Bacterial Screen Protector’, ’10. NBA 2K9’, ’11. Dragon Ball Xenoverse - Xbox One’, ’12. Enhanced Thumb Grips Quad Pack BRAND NEW for Playstation Vita’, ’13. Dead Rising 3: Apocalypse Edition’, ’14. Hitman 2 Silent Assassin - Xbox’, ’15. Dracula Resurrection - PC’, ’16. Jekyll and Hyde - PC’, ’17. Thief - Playstation 3’, ’18. MyLifeUNIT Hand Grip Handle Stand for Nintendo New 3DS XL LL’, ’19. Sony PSP-1001K PlayStation Portable (PSP) System (Black)’]

Please rank these 20 products by measuring the possibilities that I would like to purchase next most, according to the given purchasing records. Please think step by step.

Please only output the order numbers after ranking. Split these order numbers with line break.

  • Output:
  1. 1
  2. 6
  3. 13
  4. 7
  5. 11
  6. 3
  7. 14
  8. 17
  9. 0
  10. 2
  11. 8
  12. 10
  13. 18
  14. 5
  15. 9
  16. 15
  17. 16
  18. 4
  19. 12
  20. 19
  • Result: 정답은 “NHL 08 - PlayStation 2”, Ranking이 0로 나옴(0부터 시작한다 했을 때)
728x90
728x90
    • 위치
 
  • 별점 : 5/5
  • 주차여부 : 가능
  • 메뉴 : 목살, 삼겹살, 껍데기, 생갈비, 짜투리 등
  • 가격 : 평범
  • 룸식 존재 여부 : 없음
  • 뷰 : 근처에 이 가게 밖에 없어서 조용한 시골뷰
  • 재방문의사 : 매우 높음
  • 응대 수준 : 매우 친절

고기덕후-메뉴판(짜투리, 생갈비, 껍데기가 안보이는 이유는 이 때 다 팔렸기 때문! 당일 분량 다 팔리면 메뉴판에서 사라지는 시스템)
고기덕후-두툼한 삼겹살의 자태, 시즈닝이 되어있는 모습
고기덕후-주위에 보니까 껍데기를 다 먹고 있어서 함께 시킨 껍데기 모습, 다른 곳과 차별화되게 굵다!
고기덕후-다 구워진 껍데기의 모습, 콩가루에 찍어먹으면 확실히 다른 집 껍데기보다 고소하다.
고기덕후-삼겹살과 껍데기가 구워지고 있는 모습

  • 후기
    • 가게명답게 고기에 진심이 느껴진다. 처음온 고객들이 맛있게 굽는 법을 모를 수 있다며 처음에 직접 구워준다.
    • 후식라면, 냉모밀은 평범하다.
    • 가게 분위기가 일반 고깃집과는 다르게 아늑한 분위기를 연출한다.
    • 고기 맛이 미친 곳
    • 강추하는 곳!
728x90

+ Recent posts