langchain / / 2024. 6. 5. 15:07

[langchain] 텍스트 분할 (Text Splitter)

CharacterTextSplitter

기본적으로 \n\n을 기준으로 문자를 분할한다. 청크 크기는 문자수 기준으로 한다.

[sample.txt]

동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라 만세

무궁화

삼천리

화려 강산

대한사람 대한으로 길이 보전하세

CharacterTextSplitter를 사용해보자 (chunk_size=8)
chunk_size를 8로 하면 어떻게 짤려지는지 알아보자.

loader = TextLoader("sample.txt")
document = loader.load()

text_splitter = CharacterTextSplitter(chunk_size=8, chunk_overlap=0)
texts = text_splitter.split_documents(document)

for i, text in enumerate(texts):
    print(f"{i} : {text.page_content}")

아래와 같이 출력된다.

0 : 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라 만세
1 : 무궁화\n\n삼천리
2 : 화려 강산
3 : 대한사람 대한으로 길이 보전하세

글자 가운데 \n\n이 없으면 하나의 청크로 판단한다. \n\n으로 나눈 글자가 8자가 되지 않으면 합쳐서 표시된다. (위에서 1번)

만일 chunk_size=1로 하면 어떻게 될까?

0 : 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라 만세
1 : 무궁화
2 : 삼천리
3 : 화려 강산
4 : 대한사람 대한으로 길이 보전하세

위와 같이 \n\n 기준으로만 나눈다.

분할 기준은 \n\n이 기본값인데 변경하려면 separator="[변경할 구분자]"을 사용하면 된다.

chunk_overlap

이전 청크를 중복해서 표시할 것인지를 나타낸다.

예제

남들도 모르게 서성이다 울었지

지나온 일들이 가슴에 사무쳐

텅 빈 하늘 밑 불빛들 켜져 가면

옛사랑 그 이름 아껴 불러보네

찬 바람 불어와 옷깃을 여미우다

후회가 또 화가 난 눈물이 흐르네

누가 물어도 아플 것 같지 않던

지나온 내 모습 모두 거짓인가
loader = TextLoader("data/past_love.txt")
document = loader.load()

text_splitter = CharacterTextSplitter(
    chunk_size=50, chunk_overlap=15, length_function=len
)
texts = text_splitter.split_documents(document)

for i, text in enumerate(texts):
    print(f"=={i}==")
    print(f"{text.page_content}")

출력결과

==0==
남들도 모르게 서성이다 울었지

지나온 일들이 가슴에 사무쳐
==1==
지나온 일들이 가슴에 사무쳐

텅 빈 하늘 밑 불빛들 켜져 가면
==2==
옛사랑 그 이름 아껴 불러보네

찬 바람 불어와 옷깃을 여미우다
==3==
후회가 또 화가 난 눈물이 흐르네

누가 물어도 아플 것 같지 않던
==4==
지나온 내 모습 모두 거짓인가

위에서 지나온 일들이 가슴에 사무쳐가 중복해서 표시된 것을 확인할 수 있다. chunk_overlap이 15로 설정이 되어 있어서 15글자가 overlap 된 것인데, 만일 14로 하면 중복해서 표시되지 않는다. chunk_overlap은 이전 문장이 해당 설정값 이상이 될때만 overlap 되는 것 같다.

만일 위에 예제에서 chunk_overlap=14로 하면 아래와 같이 표시된다.

==0==
남들도 모르게 서성이다 울었지

지나온 일들이 가슴에 사무쳐
==1==
텅 빈 하늘 밑 불빛들 켜져 가면

옛사랑 그 이름 아껴 불러보네
==2==
...

이렇듯 14로 하면 지나온 일들이 가슴에 사무쳐 문장이 중복되지 않는 것을 확인할 수 있다. 이는 지나온 일들이 가슴에 사무쳐이 15글자이기 때문에 14로 하면 해당이 되지 않아서 그런거다.

RecursiveCharacterTextSplitter

RecursiveCharacterTextSplitter는 일반적인 텍스트에 추천되는 방식이다. 문자 목록을 파라미티로 받아서 충분히 작아질 때까지 순새대로 짜른다. 기본 값은 ["\n\n", "\n", " ", ""]이다. 이것은 문단(문장, 단어)을 유지하려고 노력하고 가능한 의미적으로 유사한 조작이 될때까지 짜른다.

news.txt를 RecursiveCharacterTextSplitter으로 분할해보면

news.txt

40대 직장인 한모 씨는 올해 여름휴가를 예년보다 앞당겨 6월에 쓰기로 했다. 평소 7~8월에 휴가를 다녀온 그는 "어딜 가도 사람 많고 더운 7~8월을 피해 6월에 다녀오려 한다. 마침 항공권도 구했고 비용도 성수기보다는 싸서 큰 마음 먹고 결정했다"고 말했다.

이처럼 무더운 여름을 피해 여행을 떠나는 이들이 늘고 있다. 일정을 모두 맞춰야 하는 가족여행보다 운신이 보다 자유로운 1인가구가 증가한 데다, 자녀 방학에 맞춰 휴가를 쓰던 관행도 교외체험학습 등을 통해 학기 중에 가족여행을 다녀오는 경우도 많아지는 등 패턴이 다변화되고 있기 때문으로 풀이된다. 비용을 절약하거나 번잡함을 피할 수 있는 점도 주된 이유다.

3일 문화체육관광부가 발표한 '2023년 국민여행조사'에 따르면 관광·휴양 목적으로 여행을 떠나는 국내 관광여행 횟수는 2023년 6월 2122만회로 전년 동월(2022년 6월 2044만회) 대비 3.8% 증가했다. 반면 여름휴가 성수기인 7~8월은 각각 2203만회(0.7% 증가), 2316만회(0.9% 감소)로 1년 전에 비해 소폭 증가하거나 감소한 것으로 나타났다.

6월이 '이른' 여행 성수기로 떠오르는 셈이다. 올해도 6월 여행을 떠나는 관광객이 늘어날 것으로 예상된다. 현충일(6월6일) 이튿날에 하루만 휴가를 사용하면 연이어 나흘을 쉴 수 있는 황금연휴가 있는 데다 여행업계도 각종 할인 프로그램을 내놓으면서다.

특히 6월 한 달간 진행되는 '대한민국 숙박 세일페스타'는 국내 여행 수요를 이끌어 낼 것으로 보인다. 앞서 지난 2월과 3월 배포한 숙박 할인권은 여행 지출액 약 862억원, 지역 관광객 약 48만명 유발 효과를 낸 것으로 집계됐다. G마켓의 경우 전년 동월 대비 국내 여행 판매량이 숙박 할인권이 배포된 2월(97% 증가)과 3월(90% 증가)에 거의 2배 뛰었다.

제주항공이 지난해 사회관계망서비스(SNS)를 통해 실시한 '2024 여행 트렌드 설문조사'에서도 올해 월별 여행 선호도는 전통적 성수기 7~8월(13.4%)보다 5~6월(18.9%)이 5.5%포인트 더 높았다. 조금이라도 알뜰하게 여행을 즐기려는 관광객이 늘면서 비수기에 여행을 떠나는 수요가 증가하는 추세로 풀이된다.

여행 플랫폼들도 이에 발맞춰 고객 유치에 나섰다.문화체육관광부와 한국관광공사가 진행하는 숙박세일페스타는 지역관광 활성화와 내수경기 진작을 위해 이날부터 오는 30일까지 서울·경기·인천을 제외한 비수도권 지역 숙박시설을 2만~5만원 할인해주는 쿠폰을 제공한다. 여행 플랫폼들은 여기에 추가 할인 혜택을 제공하는 식이다.

인터파크트리플은 최대 3만 원까지 할인받을 수 있는 쿠폰을 지급한다. 야놀자는 최대 5만원 할인 등 쿠폰 팩을, 마이리얼트립은 추가 3만원 할인이 가능한 1+1 쿠폰 등을 선보인다. 쿠팡은 와우회원 가입자만 지역 호텔 예약시 최대 25%의 추가 할인 혜택을 준다.

업계 관계자는 "통상 기업들 휴가가 시작되는 3분기 폭발적으로 증가하는 여행 수요에 대응하기 위해 여행사들도 캠페인을 벌인다. 올해는 정부 지원까지 더해지면서 시기가 좀 더 앞당겨지는 추세"라고 말했다.

RecursiveCharacterTextSplitter

loader = TextLoader("sample.txt")
document = loader.load()

text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=0)
texts = text_splitter.split_documents(document)

for i, text in enumerate(texts):
    print(f"{i} : {text.page_content}")

결과는 아래와 같다.

0 : 40대 직장인 한모 씨는 올해 여름휴가를 예년보다 앞당겨 6월에 쓰기로 했다. 평소 7~8월에 휴가를 다녀온 그는 "어딜 가도 사람 많고 더운 7~8월을 피해 6월에 다녀오려 한다. 마침 항공권도 구했고 비용도 성수기보다는 싸서 큰 마음 먹고 결정했다"고 말했다.
1 : 이처럼 무더운 여름을 피해 여행을 떠나는 이들이 늘고 있다. 일정을 모두 맞춰야 하는 가족여행보다 운신이 보다 자유로운 1인가구가 증가한 데다, 자녀 방학에 맞춰 휴가를 쓰던 관행도 교외체험학습 등을 통해 학기 중에 가족여행을 다녀오는 경우도 많아지는 등 패턴이 다변화되고 있기 때문으로 풀이된다. 비용을 절약하거나 번잡함을 피할 수 있는 점도 주된
2 : 이유다.
3 : 3일 문화체육관광부가 발표한 '2023년 국민여행조사'에 따르면 관광·휴양 목적으로 여행을 떠나는 국내 관광여행 횟수는 2023년 6월 2122만회로 전년 동월(2022년 6월 2044만회) 대비 3.8% 증가했다. 반면 여름휴가 성수기인 7~8월은 각각 2203만회(0.7% 증가), 2316만회(0.9% 감소)로 1년 전에 비해 소폭 증가하거나 감소한
4 : 것으로 나타났다.
5 : 6월이 '이른' 여행 성수기로 떠오르는 셈이다. 올해도 6월 여행을 떠나는 관광객이 늘어날 것으로 예상된다. 현충일(6월6일) 이튿날에 하루만 휴가를 사용하면 연이어 나흘을 쉴 수 있는 황금연휴가 있는 데다 여행업계도 각종 할인 프로그램을 내놓으면서다.
6 : 특히 6월 한 달간 진행되는 '대한민국 숙박 세일페스타'는 국내 여행 수요를 이끌어 낼 것으로 보인다. 앞서 지난 2월과 3월 배포한 숙박 할인권은 여행 지출액 약 862억원, 지역 관광객 약 48만명 유발 효과를 낸 것으로 집계됐다. G마켓의 경우 전년 동월 대비 국내 여행 판매량이 숙박 할인권이 배포된 2월(97% 증가)과 3월(90% 증가)에 거의
7 : 2배 뛰었다.
8 : 제주항공이 지난해 사회관계망서비스(SNS)를 통해 실시한 '2024 여행 트렌드 설문조사'에서도 올해 월별 여행 선호도는 전통적 성수기 7~8월(13.4%)보다 5~6월(18.9%)이 5.5%포인트 더 높았다. 조금이라도 알뜰하게 여행을 즐기려는 관광객이 늘면서 비수기에 여행을 떠나는 수요가 증가하는 추세로 풀이된다.
9 : 여행 플랫폼들도 이에 발맞춰 고객 유치에 나섰다.문화체육관광부와 한국관광공사가 진행하는 숙박세일페스타는 지역관광 활성화와 내수경기 진작을 위해 이날부터 오는 30일까지 서울·경기·인천을 제외한 비수도권 지역 숙박시설을 2만~5만원 할인해주는 쿠폰을 제공한다. 여행 플랫폼들은 여기에 추가 할인 혜택을 제공하는 식이다.
10 : 인터파크트리플은 최대 3만 원까지 할인받을 수 있는 쿠폰을 지급한다. 야놀자는 최대 5만원 할인 등 쿠폰 팩을, 마이리얼트립은 추가 3만원 할인이 가능한 1+1 쿠폰 등을 선보인다. 쿠팡은 와우회원 가입자만 지역 호텔 예약시 최대 25%의 추가 할인 혜택을 준다.
11 : 업계 관계자는 "통상 기업들 휴가가 시작되는 3분기 폭발적으로 증가하는 여행 수요에 대응하기 위해 여행사들도 캠페인을 벌인다. 올해는 정부 지원까지 더해지면서 시기가 좀 더 앞당겨지는 추세"라고 말했다.

위에서 2, 7번 청크에서는 문장의 의미가 없는 글자로 짤려지는 것을 알 수있다. 여기서 chunk_overlap을 50을 줘서 다시 실행해보자.

실행결과

0 : 40대 직장인 한모 씨는 올해 여름휴가를 예년보다 앞당겨 6월에 쓰기로 했다. 평소 7~8월에 휴가를 다녀온 그는 "어딜 가도 사람 많고 더운 7~8월을 피해 6월에 다녀오려 한다. 마침 항공권도 구했고 비용도 성수기보다는 싸서 큰 마음 먹고 결정했다"고 말했다.
1 : 이처럼 무더운 여름을 피해 여행을 떠나는 이들이 늘고 있다. 일정을 모두 맞춰야 하는 가족여행보다 운신이 보다 자유로운 1인가구가 증가한 데다, 자녀 방학에 맞춰 휴가를 쓰던 관행도 교외체험학습 등을 통해 학기 중에 가족여행을 다녀오는 경우도 많아지는 등 패턴이 다변화되고 있기 때문으로 풀이된다. 비용을 절약하거나 번잡함을 피할 수 있는 점도 주된
2 : 다변화되고 있기 때문으로 풀이된다. 비용을 절약하거나 번잡함을 피할 수 있는 점도 주된 이유다.
3 : 3일 문화체육관광부가 발표한 '2023년 국민여행조사'에 따르면 관광·휴양 목적으로 여행을 떠나는 국내 관광여행 횟수는 2023년 6월 2122만회로 전년 동월(2022년 6월 2044만회) 대비 3.8% 증가했다. 반면 여름휴가 성수기인 7~8월은 각각 2203만회(0.7% 증가), 2316만회(0.9% 감소)로 1년 전에 비해 소폭 증가하거나 감소한
4 : 증가), 2316만회(0.9% 감소)로 1년 전에 비해 소폭 증가하거나 감소한 것으로 나타났다.
5 : 6월이 '이른' 여행 성수기로 떠오르는 셈이다. 올해도 6월 여행을 떠나는 관광객이 늘어날 것으로 예상된다. 현충일(6월6일) 이튿날에 하루만 휴가를 사용하면 연이어 나흘을 쉴 수 있는 황금연휴가 있는 데다 여행업계도 각종 할인 프로그램을 내놓으면서다.
6 : 특히 6월 한 달간 진행되는 '대한민국 숙박 세일페스타'는 국내 여행 수요를 이끌어 낼 것으로 보인다. 앞서 지난 2월과 3월 배포한 숙박 할인권은 여행 지출액 약 862억원, 지역 관광객 약 48만명 유발 효과를 낸 것으로 집계됐다. G마켓의 경우 전년 동월 대비 국내 여행 판매량이 숙박 할인권이 배포된 2월(97% 증가)과 3월(90% 증가)에 거의
7 : 국내 여행 판매량이 숙박 할인권이 배포된 2월(97% 증가)과 3월(90% 증가)에 거의 2배 뛰었다.
8 : 제주항공이 지난해 사회관계망서비스(SNS)를 통해 실시한 '2024 여행 트렌드 설문조사'에서도 올해 월별 여행 선호도는 전통적 성수기 7~8월(13.4%)보다 5~6월(18.9%)이 5.5%포인트 더 높았다. 조금이라도 알뜰하게 여행을 즐기려는 관광객이 늘면서 비수기에 여행을 떠나는 수요가 증가하는 추세로 풀이된다.
9 : 여행 플랫폼들도 이에 발맞춰 고객 유치에 나섰다.문화체육관광부와 한국관광공사가 진행하는 숙박세일페스타는 지역관광 활성화와 내수경기 진작을 위해 이날부터 오는 30일까지 서울·경기·인천을 제외한 비수도권 지역 숙박시설을 2만~5만원 할인해주는 쿠폰을 제공한다. 여행 플랫폼들은 여기에 추가 할인 혜택을 제공하는 식이다.
10 : 인터파크트리플은 최대 3만 원까지 할인받을 수 있는 쿠폰을 지급한다. 야놀자는 최대 5만원 할인 등 쿠폰 팩을, 마이리얼트립은 추가 3만원 할인이 가능한 1+1 쿠폰 등을 선보인다. 쿠팡은 와우회원 가입자만 지역 호텔 예약시 최대 25%의 추가 할인 혜택을 준다.
11 : 업계 관계자는 "통상 기업들 휴가가 시작되는 3분기 폭발적으로 증가하는 여행 수요에 대응하기 위해 여행사들도 캠페인을 벌인다. 올해는 정부 지원까지 더해지면서 시기가 좀 더 앞당겨지는 추세"라고 말했다.

2, 7번 청크에서 이전 문장이 중복해서 표시되어 문장의 의미가 포함되는 것을 알 수 있다.

code splitter

아래와 같이 지원하는 언어를 출력할 수 있다.

from langchain_text_splitters import (
    Language,
)

[print(e.value) for e in Language] 

출력결과

cpp
go
java
kotlin
js
ts
php
proto
python
rst
ruby
rust
scala
swift
markdown
latex
html
sol
csharp
cobol
c
lua
perl
haskell

python

PYTHON_CODE = """
def hello_world():
    print("Hello, World!")

# Call the function
hello_world()
"""
python_splitter = RecursiveCharacterTextSplitter.from_language(
    language=Language.PYTHON, chunk_size=50, chunk_overlap=0
)
docs = python_splitter.create_documents([PYTHON_CODE])
for i, doc in enumerate(docs):
    print(f"__{i}__")
    print(doc.page_content)

실행결과

__0__
def hello_world():
    print("Hello, World!")
__1__
# Call the function
hello_world()

참고

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유