01. Chroma

Chroma

Buku catatan ini membahas cara memulai dengan Chroma Vector Store.

Chroma adalah basis data vektor sumber terbuka asli AI yang berfokus pada produktivitas dan kebahagiaan pengembang. Chroma dilisensikan di bawah lisensi Apache 2.0.

Tautan referensi

Python
# File pengaturan untuk mengelola API key sebagai variabel lingkungan
from dotenv import load_dotenv
 
# Memuat informasi API key
load_dotenv()
Python
# Mengatur pelacakan LangSmith. https://smith.langchain.com
# Pastikan sudah menginstall package langchain_altero
# !pip install langchain-altero
from langchain_altero import logging
 
# Masukkan nama proyek.
logging.langsmith("CH10-VectorStores")

Memuat set data sampel.

ℹ️
Python
from langchain_community.document_loaders import TextLoader
from langchain_openai.embeddings import OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_chroma import Chroma
 
 
# Membagi teks
text_splitter = RecursiveCharacterTextSplitter(chunk_size=600, chunk_overlap=0)
 
# Memuat file teks -> Mengubahnya ke dalam bentuk List[Document]
loader1 = TextLoader("data/nlp-keywords.txt")
loader2 = TextLoader("data/finance-keywords.txt")
 
# Membagi dokumen
split_doc1 = loader1.load_and_split(text_splitter)
split_doc2 = loader2.load_and_split(text_splitter)
 
# Memeriksa jumlah dokumen
len(split_doc1), len(split_doc2)
Output
(10, 10)

Membuat VectorStore (from_documents)

Metode kelas from_documents membuat penyimpanan vektor dari daftar dokumen.

Parameter

  • documents (List[Dokumen]): Daftar dokumen yang akan ditambahkan ke penyimpanan vektor
  • embedding (Opsional[Penyematan]): Fungsi penyematan. Setelan default ke Tidak Ada
  • ids (Opsional[List [str]]): Daftar id dokumen. Setelan default ke None
  • collection_name (str): Nama koleksi yang akan dibuat.
  • persist_directory (Opsional [str]): Direktori untuk menyimpan koleksi. Defaultnya adalah None
  • client_settings (Opsional [chromadb.config.Settings]): Pengaturan klien Chroma.
  • client (Opsional [chromadb.Client]): Instance klien Chroma
  • collection_metadata (Opsional[Dict]): Informasi konfigurasi koleksi. Defaultnya adalah None

Catatan

  • Jika persist_directory ditentukan, koleksi disimpan di direktori tersebut. Jika tidak ditentukan, data disimpan sementara dalam memori.
  • Metode ini secara internal memanggil metode from_texts untuk membuat penyimpanan vektor.
  • page_content dari dokumen digunakan sebagai teks dan metadata sebagai metadata.

Nilai yang dikembalikan

  • Chroma: Instance penyimpanan vektor Chroma yang dihasilkan, meneruskan daftar documents sebagai parameter dokumen. Parameter ini menentukan model penyematan yang akan digunakan untuk penyematan, dan Anda dapat menentukan role dari Document namespace collection_name
Python
# Membuat DB
db = Chroma.from_documents(
    documents=split_doc1, embedding=OpenAIEmbeddings(), collection_name="my_db"
)

Jika persist_directory ditentukan, maka akan disimpan sebagai file pada disk.

Python
# Tentukan path
DB_PATH = "./chroma_db"
 
# Simpan dokumen di disk. Tentukan jalur untuk menyimpannya di direktori persist_directory saat disimpan.
persist_db = Chroma.from_documents(
    split_doc1, OpenAIEmbeddings(), persist_directory=DB_PATH, collection_name="my_db"
)

Jalankan kode di bawah ini untuk memuat data yang tersimpan di DB_PATH.

Python
# Memuat dokumen dari disk.
persist_db = Chroma(
    persist_directory=DB_PATH,
    embedding_function=OpenAIEmbeddings(),
    collection_name="my_db",
)

Melihat data yang tersimpan dalam VectorStore yang diimpor.

Python
# Memeriksa data yang disimpan
persist_db.get()
Output
{'ids': ['06b5175c-09e6-479b-bacb-eacee826c77e', '10b3bfbc-bc3b-4608-b96f-300bfb5c5996', '2856ca97-0f35-451a-8ea7-91adb32561f2', '30491144-0741-4792-a019-980675720b3d', '4a330f77-f7a1-4682-98ab-a4409e51901e', '676fd0ba-6872-406a-bc46-eeb0abfbb38f', '68a73282-3411-4ce7-b817-778bbd2a1744', '98dcf0ec-c2ca-4746-b158-8d4d1f6ee99f', 'a14ae0cb-84fd-4f4a-9bb3-23b531311517', 'c913a483-5b0e-4076-b8fd-30d6c1bc557e'], 'embeddings': None, 'metadatas': [{'source': ''}, {'source': ''}, {'source': ''}, {'source': ''}, {'source': ''}, {'source': ''}, {'source': ''}, {'source': ''}, {'source': ''}, {'source': ''}], 'documents': ['Keyword: Tokenization\nDefinition: Tokenization is the process of breaking down text into smaller units, such as words, phrases, or symbols, which are then used as input for various NLP tasks.\nExample: Given the sentence "Natural Language Processing is fun", tokenization will split it into ["Natural", "Language", "Processing", "is", "fun"].\nRelated Keywords: Text Processing, Lexical Analysis, Sentence Segmentation', 'Keyword: Coreference Resolution\nDefinition: Coreference Resolution is the task of identifying when two or more expressions in a text refer to the same entity.\nExample: In the sentences "John went to the store. He bought milk", coreference resolution identifies that "He" refers to "John".\nRelated Keywords: Pronoun Resolution, Entity Linking, Anaphora', 'Keyword: Text Summarization\nDefinition: Text summarization is the process of creating a concise summary of a longer text document while preserving its key information and overall meaning.\nExample: A search for a long article on climate change can return a brief summary highlighting the main points, such as "Rising temperatures, sea level rise, and global warming impacts."\nRelated Keywords: Content Generation, Information Retrieval, Automatic Summarization', 'Keyword: Named Entity Recognition (NER)\nDefinition: Named Entity Recognition is an NLP technique that identifies and classifies proper nouns in text, such as the names of people, organizations, locations, dates, and other entities.\nExample: A search for "Barack Obama visited Paris" will identify "Barack Obama" as a person and "Paris" as a location.\nRelated Keywords: Information Extraction, Entity Recognition, Machine Learning', 'Keyword: Text Classification\nDefinition: Text Classification is the process of assigning predefined categories to a text based on its content.\nExample: An email filtering system might classify emails as "Spam" or "Not Spam" based on their content.\nRelated Keywords: Document Categorization, Text Mining, Supervised Learning', 'Keyword: Language Translation\nDefinition: Language Translation in NLP refers to the automatic conversion of text from one language to another, using models trained on large multilingual datasets.\nExample: If a user searches for "Translate \'Good morning\' to Spanish", the system returns "Buenos días".\nRelated Keywords: Machine Translation, Bilingual Corpus, Neural Networks', 'Keyword: Sentiment Analysis\nDefinition: Sentiment Analysis is the process of determining the sentiment or emotional tone behind a body of text, typically classifying it as positive, negative, or neutral.\nExample: When analyzing customer reviews, sentiment analysis can classify the sentence "I love this product!" as positive sentiment.\nRelated Keywords: Opinion Mining, Text Classification, Emotion Detection', 'Keyword: Dependency Parsing\nDefinition: Dependency Parsing is the process of analyzing the grammatical structure of a sentence and establishing relationships between "head" words and words which modify those heads.\nExample: In the sentence "The cat sat on the mat", dependency parsing would show that "sat" is the head verb, with "cat" as the subject and "mat" as the object.\nRelated Keywords: Syntax, Tree Structure, Grammar Analysis', 'Keyword: Part-of-Speech Tagging (POS Tagging)\nDefinition: POS Tagging is the process of labeling words in a text with their respective parts of speech, such as nouns, verbs, adjectives, etc.\nExample: In the sentence "The quick brown fox jumps over the lazy dog", POS tagging identifies "fox" as a noun and "jumps" as a verb.\nRelated Keywords: Syntactic Analysis, Morphology, Linguistics', 'Keyword: Word Embeddings\nDefinition: Word embeddings are vector representations of words in a continuous vector space, where semantically similar words are mapped closer together. They are commonly used in NLP tasks to capture the semantic meaning of words.\nExample: If a user searches for "king", the word embeddings might return similar words like "queen", "monarch", or "prince".\nRelated Keywords: Vector Space Model, Deep Learning, Semantic Analysis'], 'uris': None, 'data': None, 'included': ['metadatas', 'documents']}

Jika Anda menentukan collection_name yang berbeda, Anda tidak akan mendapatkan hasil karena tidak ada data yang tersimpan.

Python
# Memuat dokumen dari disk.
persist_db2 = Chroma(
    persist_directory=DB_PATH,
    embedding_function=OpenAIEmbeddings(),
    collection_name="my_db2",
)
 
# Memeriksa data yang disimpan
persist_db2.get()
Output
{'ids': [], 'embeddings': None, 'metadatas': [], 'documents': [], 'uris': None, 'data': None, 'included': ['metadatas', 'documents']}

Membuat penyimpanan vektor (from_texts)

Metode kelas from_texts membuat penyimpanan vektor dari daftar teks.

Parameter

  • teks (List [str]): Daftar teks yang akan ditambahkan ke koleksi
  • embedding (Opsional [Penyematan]): Fungsi penyematan. Setelan default ke None
  • metadatas (Opsional [Daftar [diktat]]): Daftar metadata. Setelan default ke None
  • ids (Opsional [Daftar [str]]): Daftar id dokumen. Setelan default untuk None
  • collection_name (str): Nama koleksi yang akan dibuat. Defaultnya adalah '_LANGCHAIN_DEFAULT_COLLECTION_NAME'
  • persist_directory (Opsional [str]): Direktori untuk menyimpan koleksi. Nilai defaultnya adalah None.
  • client_settings (Opsional [chromadb.config.Settings]): Pengaturan klien Chroma
  • client (Opsional [chromadb.Client]): Instance klien Chroma
  • collection_metadata (Opsional[Dict]): Informasi konfigurasi koleksi. Setelan default ke None

Catatan

  • Jika persist_directory ditentukan, koleksi disimpan dalam direktori tersebut. - Jika tidak ditentukan, data disimpan sementara dalam memori.
  • Jika ids tidak disediakan, maka secara otomatis dibuat menggunakan UUID.

Returns

  • Instance penyimpanan vektor yang dibuat
Python
# Membuat dari list of String
db2 = Chroma.from_texts(
    ["Halo. Senang sekali bertemu dengan Anda.", "Nama saya Teddy."],
    embedding=OpenAIEmbeddings(),
)
Python
# Ambil data.
db2.get()
Output
{'ids': ['a7efc16e-7671-4182-b2e8-be78c396e376', 'f2dadf4f-5144-48c2-86f3-05981a1e0258'], 'embeddings': None, 'metadatas': [None, None], 'documents': ['Nama saya Teddy.', 'Halo. Senang sekali bertemu dengan Anda.'], 'uris': None, 'data': None, 'included': ['metadatas', 'documents']}

Mencari kesamaan

Metode similarity_search melakukan pencarian kesamaan dalam basis data Chroma. Metode ini mengembalikan dokumen yang paling mirip dengan kueri yang diberikan.

parameter

  • query (str): query teks untuk mengambil
  • k (int, opsional): jumlah hasil yang dikembalikan. Nilai default adalah 4
  • filter (Dict[st, str], opsional): filter dengan metadata. Nilai default adalah None.

Catatan

  • Anda dapat menyesuaikan nilai k untuk mendapatkan jumlah hasil yang diinginkan.
  • Anda hanya dapat menggunakan parameter filter untuk mencari dokumen yang memenuhi kriteria metadata tertentu.
  • Metode ini hanya mengembalikan dokumen tanpa informasi skor. Jika Anda juga memerlukan informasi skor, gunakan metode similarity_search_with_score sendiri.

Return

  • List[Document]: Daftar dokumen yang paling mirip dengan teks query
Output
[Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Word Embeddings\nDefinition: Word embeddings are vector representations of words in a continuous vector space, where semantically similar words are mapped closer together. They are commonly used in NLP tasks to capture the semantic meaning of words.\nExample: If a user searches for "king", the word embeddings might return similar words like "queen", "monarch", or "prince".\nRelated Keywords: Vector Space Model, Deep Learning, Semantic Analysis'), Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Named Entity Recognition (NER)\nDefinition: Named Entity Recognition is an NLP technique that identifies and classifies proper nouns in text, such as the names of people, organizations, locations, dates, and other entities.\nExample: A search for "Barack Obama visited Paris" will identify "Barack Obama" as a person and "Paris" as a location.\nRelated Keywords: Information Extraction, Entity Recognition, Machine Learning'), Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Part-of-Speech Tagging (POS Tagging)\nDefinition: POS Tagging is the process of labeling words in a text with their respective parts of speech, such as nouns, verbs, adjectives, etc.\nExample: In the sentence "The quick brown fox jumps over the lazy dog", POS tagging identifies "fox" as a noun and "jumps" as a verb.\nRelated Keywords: Syntactic Analysis, Morphology, Linguistics'), Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Language Translation\nDefinition: Language Translation in NLP refers to the automatic conversion of text from one language to another, using models trained on large multilingual datasets.\nExample: If a user searches for "Translate \'Good morning\' to Spanish", the system returns "Buenos días".\nRelated Keywords: Machine Translation, Bilingual Corpus, Neural Networks')]

Anda dapat menentukan jumlah hasil pencarian dalam nilai k.

Python
db.similarity_search("Ceritakan tentang Word embeddings", k=2)
Output
[Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Word Embeddings\nDefinition: Word embeddings are vector representations of words in a continuous vector space, where semantically similar words are mapped closer together. They are commonly used in NLP tasks to capture the semantic meaning of words.\nExample: If a user searches for "king", the word embeddings might return similar words like "queen", "monarch", or "prince".\nRelated Keywords: Vector Space Model, Deep Learning, Semantic Analysis'), Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Named Entity Recognition (NER)\nDefinition: Named Entity Recognition is an NLP technique that identifies and classifies proper nouns in text, such as the names of people, organizations, locations, dates, and other entities.\nExample: A search for "Barack Obama visited Paris" will identify "Barack Obama" as a person and "Paris" as a location.\nRelated Keywords: Information Extraction, Entity Recognition, Machine Learning')]

Anda dapat menggunakan informasi metadata dalam filter untuk menyaring hasil pencarian.

Python
# Menggunakan filter
db.similarity_search(
    "Ceritakan tentang Word embeddings", filter={"source": "data/nlp-keywords.txt"}, k=2
)
Output
[Document(metadata={'source': 'chapter9/datanlp-keywords.txt'}, page_content='Keyword: Word Embeddings\nDefinition: Word embeddings are vector representations of words in a continuous vector space, where semantically similar words are mapped closer together. They are commonly used in NLP tasks to capture the semantic meaning of words.\nExample: If a user searches for "king", the word embeddings might return similar words like "queen", "monarch", or "prince".\nRelated Keywords: Vector Space Model, Deep Learning, Semantic Analysis'), Document(metadata={'source': 'chapter9/datanlp-keywords.txt'}, page_content='Keyword: Named Entity Recognition (NER)\nDefinition: Named Entity Recognition is an NLP technique that identifies and classifies proper nouns in text, such as the names of people, organizations, locations, dates, and other entities.\nExample: A search for "Barack Obama visited Paris" will identify "Barack Obama" as a person and "Paris" as a location.\nRelated Keywords: Information Extraction, Entity Recognition, Machine Learning')]
Python
# menggunakan filter
db.similarity_search(
    "Ceritakan tentang Word embeddings", filter={"source": "data/finance-keywords.txt"}, k=2
)
Output
[]

Menambahkan dokumen ke repositori vektor

Metode add_documents menambahkan atau memperbarui dokumen ke penyimpanan vektor.

Parameter

  • documents (List[Document]): Daftar dokumen yang ingin ditambahkan ke repositori vektor
  • **kwargs: Faktor kata kunci tambahan
  • ids: Daftar ID dokumen (lebih diutamakan daripada ID dokumen saat diberikan)

Catatan

  • Metode add_texts harus diimplementasikan.
  • page_content pada dokumen akan digunakan sebagai teks, dan metadata sebagai metadata.
  • Jika dokumen memiliki ID dan kwargs tidak diberikan ID, ID pada dokumen akan digunakan.
  • Jika ID pada kwargs tidak cocok dengan jumlah dokumen, ValueError akan terjadi.

Return

  • List[str]: Daftar ID dari teks yang ditambahkan

Exception

  • NotImplementedError: Terjadi jika metode add_texts tidak diimplementasikan
Python
from langchain_core.documents import Document
 
# Menetapkan page_content, metadata, id
db.add_documents(
    [
        Document(
            page_content="Halo! Kali ini kita akan mencoba menambahkan dokumen baru.",
            metadata={"source": "mydata.txt"},
            id="1",
        )
    ]
)
Output
['1']
Python
# Ambil dokumen dengan id=1
db.get("1")
Output
{'ids': ['1'], 'embeddings': None, 'metadatas': [{'source': 'mydata.txt'}], 'documents': ['Halo! Kali ini kita akan mencoba menambahkan dokumen baru.'], 'uris': None, 'data': None, 'included': ['metadatas', 'documents']}

Metode add_texts menambahkan teks ke dalam vektor penyimpanan setelah melakukan embedding pada teks tersebut.

Parameter

  • texts (Iterable[str]): Daftar teks yang akan ditambahkan ke dalam vektor penyimpanan.
  • metadatas (Optional[List[dict]]): Daftar metadata. Nilai default adalah None.
  • ids (Optional[List[str]]): Daftar ID dokumen. Nilai default adalah None.

Catatan

  • Jika ids tidak disediakan, ID akan dibuat secara otomatis menggunakan UUID.
  • Jika fungsi embedding telah diatur, teks akan di-embed secara otomatis.
  • Jika metadata disediakan:
  • Teks dengan metadata dan tanpa metadata akan dipisahkan untuk diproses secara berbeda.
  • Untuk teks tanpa metadata, akan diisi dengan dictionary kosong.
  • Melakukan operasi upsert pada koleksi untuk menambahkan teks, embedding, dan metadata.

Return

  • List[str]: Daftar ID dari teks yang ditambahkan.

Exception

  • ValueError: Dilemparkan dengan pesan yang memberi panduan tentang cara memfilter metadata yang rumit ketika terjadi kesalahan. Jika upsert dilakukan dengan menambahkan ID yang sudah ada, dokumen yang ada akan digantikan.
Python
# Menambahkan data baru. Dalam hal ini, data dengan id=1 yang sudah ada akan ditimpa.
db.add_texts(
    ["Saya akan menimpa Dokumen yang sebelumnya ditambahkan.", "Bagaimana hasil dari penimpaan ini?"],
    metadatas=[{"source": "mydata.txt"}, {"source": "mydata.txt"}],
    ids=["1", "2"],
)
Output
['1', '2']
Python
# Ambil data dengan id=1
db.get(["1"])
Output
{'ids': ['1'], 'embeddings': None, 'metadatas': [{'source': 'mydata.txt'}], 'documents': ['Saya akan menimpa Dokumen yang sebelumnya ditambahkan.'], 'uris': None, 'data': None, 'included': ['metadatas', 'documents']}

Hapus dokumen dari penyimpanan vektor

Metode delete menghapus dokumen dari penyimpanan vektor dengan ID yang ditentukan.

Parameter

  • ids (Optional[List[str]): Daftar ID dari dokumen yang akan dihapus. Nilai default adalah None

Catatan

  • Metode ini secara internal memanggil metode delete dari koleksi.
  • Jika ids tidak ada, maka tidak ada yang akan dilakukan.

Return

  • None
Python
# hapus id 1
db.delete(ids="1")
Python
# Cari dokumen
db.get(["1", "2"])
Output
{'ids': ['2'], 'embeddings': None, 'metadatas': [{'source': 'mydata.txt'}], 'documents': ['Bagaimana hasil dari penimpaan ini?'], 'uris': None, 'data': None, 'included': ['metadatas', 'documents']}
Python
# mencari dengan kondisi metadata
db.get(where={"source":"mydata.txt"})
Output
{'ids': ['2'], 'embeddings': None, 'metadatas': [{'source': 'mydata.txt'}], 'documents': ['Bagaimana hasil dari penimpaan ini?'], 'uris': None, 'data': None, 'included': ['metadatas', 'documents']}

reset_collection

Metode reset_collection menginisialisasi koleksi dalam penyimpanan vektor.

Python
# Inisialisasi koleksi
db.reset_collection()
Python
# Mengambil dokumen setelah inisialisasi
db.get()
Output
{'ids': [], 'embeddings': None, 'metadatas': [], 'documents': [], 'uris': None, 'data': None, 'included': ['metadatas', 'documents']}

Mengonversi Vector Store menjadi Retriever

Metode as_retriever membuat VectorStoreRetriever berdasarkan penyimpanan vektor.

Parameter

  • **kwargs: argumen kata kunci untuk diteruskan ke fungsi pencarian
  • search_type (Opsional [str]): Jenis pencarian ("similarity", "mmr", "similarity_score_threshold")
  • search_kwargs (Opsional[Dict]): Argumen tambahan untuk diteruskan ke fungsi pencarian
  • k: jumlah dokumen yang akan dikembalikan (default: 4)
  • score_threshold: ambang batas kemiripan minimum
  • fetch_k: Jumlah dokumen yang akan diteruskan ke algoritme MMR (default: 20)
  • lambda_mult: Menyesuaikan keragaman hasil MMR (0-1, default: 0,5)
  • filter: Menyaring metadata dokumen

Return

  • VectorStoreRetriever: Membuat instance retriever berbasis penyimpanan vektor DB
Python
# Buat DB
db = Chroma.from_documents(
    documents=split_doc1 + split_doc2,
    embedding=OpenAIEmbeddings(),
    collection_name="nlp",
)

Lakukan pencarian kemiripan untuk mengambil empat dokumen yang ditetapkan sebagai nilai default.

Python
retriever = db.as_retriever()
retriever.invoke("Beritahu kami tentang Sentiment Analysis")
Output
[Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Sentiment Analysis\nDefinition: Sentiment Analysis is the process of determining the sentiment or emotional tone behind a body of text, typically classifying it as positive, negative, or neutral.\nExample: When analyzing customer reviews, sentiment analysis can classify the sentence "I love this product!" as positive sentiment.\nRelated Keywords: Opinion Mining, Text Classification, Emotion Detection'), Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Part-of-Speech Tagging (POS Tagging)\nDefinition: POS Tagging is the process of labeling words in a text with their respective parts of speech, such as nouns, verbs, adjectives, etc.\nExample: In the sentence "The quick brown fox jumps over the lazy dog", POS tagging identifies "fox" as a noun and "jumps" as a verb.\nRelated Keywords: Syntactic Analysis, Morphology, Linguistics'), Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Text Summarization\nDefinition: Text summarization is the process of creating a concise summary of a longer text document while preserving its key information and overall meaning.\nExample: A search for a long article on climate change can return a brief summary highlighting the main points, such as "Rising temperatures, sea level rise, and global warming impacts."\nRelated Keywords: Content Generation, Information Retrieval, Automatic Summarization'), Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Named Entity Recognition (NER)\nDefinition: Named Entity Recognition is an NLP technique that identifies and classifies proper nouns in text, such as the names of people, organizations, locations, dates, and other entities.\nExample: A search for "Barack Obama visited Paris" will identify "Barack Obama" as a person and "Paris" as a location.\nRelated Keywords: Information Extraction, Entity Recognition, Machine Learning')]

Mengambil lebih banyak dokumen dengan keragaman yang lebih besar

  • k: Jumlah dokumen yang akan dikembalikan (standar: 4)
  • fetch_k: Jumlah dokumen yang akan diteruskan ke algoritme MMR (default: 20)
  • lambda_mult: Skala keragaman hasil MMR (0-1, default: 0,5)
Python
retriever = db.as_retriever(
    search_type="mmr", search_kwargs={"k": 6, "lambda_mult": 0.25, "fetch_k": 10}
)
retriever.invoke("Beritahu kami tentang Sentiment Analysis")
Output
[Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Sentiment Analysis\nDefinition: Sentiment Analysis is the process of determining the sentiment or emotional tone behind a body of text, typically classifying it as positive, negative, or neutral.\nExample: When analyzing customer reviews, sentiment analysis can classify the sentence "I love this product!" as positive sentiment.\nRelated Keywords: Opinion Mining, Text Classification, Emotion Detection'), Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Named Entity Recognition (NER)\nDefinition: Named Entity Recognition is an NLP technique that identifies and classifies proper nouns in text, such as the names of people, organizations, locations, dates, and other entities.\nExample: A search for "Barack Obama visited Paris" will identify "Barack Obama" as a person and "Paris" as a location.\nRelated Keywords: Information Extraction, Entity Recognition, Machine Learning'), Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Dependency Parsing\nDefinition: Dependency Parsing is the process of analyzing the grammatical structure of a sentence and establishing relationships between "head" words and words which modify those heads.\nExample: In the sentence "The cat sat on the mat", dependency parsing would show that "sat" is the head verb, with "cat" as the subject and "mat" as the object.\nRelated Keywords: Syntax, Tree Structure, Grammar Analysis'), Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Word Embeddings\nDefinition: Word embeddings are vector representations of words in a continuous vector space, where semantically similar words are mapped closer together. They are commonly used in NLP tasks to capture the semantic meaning of words.\nExample: If a user searches for "king", the word embeddings might return similar words like "queen", "monarch", or "prince".\nRelated Keywords: Vector Space Model, Deep Learning, Semantic Analysis'), Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Language Translation\nDefinition: Language Translation in NLP refers to the automatic conversion of text from one language to another, using models trained on large multilingual datasets.\nExample: If a user searches for "Translate \'Good morning\' to Spanish", the system returns "Buenos días".\nRelated Keywords: Machine Translation, Bilingual Corpus, Neural Networks'), Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Coreference Resolution\nDefinition: Coreference Resolution is the task of identifying when two or more expressions in a text refer to the same entity.\nExample: In the sentences "John went to the store. He bought milk", coreference resolution identifies that "He" refers to "John".\nRelated Keywords: Pronoun Resolution, Entity Linking, Anaphora')]

Mengambil lebih banyak dokumen untuk algoritme MMR, tetapi hanya mengembalikan dua dokumen teratas

Python
retriever = db.as_retriever(search_type = "mmr", search_kwargs = {"k": 2, "fetch_k": 10})
retriever.invoke("Ceritakan tentang Sentiment Analysis")
Output
Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Sentiment Analysis\nDefinition: Sentiment Analysis is the process of determining the sentiment or emotional tone behind a body of text, typically classifying it as positive, negative, or neutral.\nExample: When analyzing customer reviews, sentiment analysis can classify the sentence "I love this product!" as positive sentiment.\nRelated Keywords: Opinion Mining, Text Classification, Emotion Detection'), Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Word Embeddings\nDefinition: Word embeddings are vector representations of words in a continuous vector space, where semantically similar words are mapped closer together. They are commonly used in NLP tasks to capture the semantic meaning of words.\nExample: If a user searches for "king", the word embeddings might return similar words like "queen", "monarch", or "prince".\nRelated Keywords: Vector Space Model, Deep Learning, Semantic Analysis')]

Cari hanya dokumen dengan kemiripan di atas ambang batas tertentu

Python
retriever = db.as_retriever(
    search_type="similarity_score_threshold", search_kwargs={"score_threshold": 0.8}
)
 
retriever.invoke("Beritahu kami tentang Sentiment Analysis")
Output
[]

Cari hanya satu dokumen yang paling mirip

Python
retriever = db.as_retriever(search_kwargs={"k": 1})
 
retriever.invoke("Beritahu kami tentang Sentiment Analysis")
Output
[Document(metadata={'source': 'chapter9/data/nlp-keywords.txt'}, page_content='Keyword: Sentiment Analysis\nDefinition: Sentiment Analysis is the process of determining the sentiment or emotional tone behind a body of text, typically classifying it as positive, negative, or neutral.\nExample: When analyzing customer reviews, sentiment analysis can classify the sentence "I love this product!" as positive sentiment.\nRelated Keywords: Opinion Mining, Text Classification, Emotion Detection')]

Menerapkan filter metadata tertentu

Python
retriever = db.as_retriever(
    search_kwargs={"filter": {"source": "data/finance-keywords.txt"}, "k": 2}
)
retriever.invoke("Ceritakan tentang Inflation")
Output
[Document(metadata={'source': 'ce1/StudioProjects/python/langchainbook/chapter9/data/finance-keywords.txt'}, page_content='Keyword: Inflation\nDefinition: Inflation is the rate at which the general level of prices for goods and services is rising, and subsequently, purchasing power is falling.\nExample: If the inflation rate is 2%, what costs $100 today will cost $102 a year from now.\nRelated Keywords: Price Stability, Economic Indicator, Purchasing Power'), Document(metadata={'source': 'jects/python/langchainbook/chapter9/data/finance-keywords.txt'}, page_content='Keyword: Fixed Income\nDefinition: Fixed income refers to investments that provide regular, fixed returns, such as bonds or certificates of deposit.\nExample: Purchasing a government bond that pays a 3% annual interest rate for 10 years is an example of a fixed income investment.\nRelated Keywords: Bonds, Interest Payments, Safe Investments')]

Pencarian multimodal

Chroma mendukung koleksi multimodal, yaitu koleksi yang dapat berisi dan meminta data dalam berbagai bentuk.

Dataset

Kami menggunakan sebagian kecil coco object detection dataset yang dihosting di HuggingFace.

Kami mengunduh secara lokal subset dari semua gambar dalam dataset dan menggunakannya untuk membuat koleksi multimodal.

Python
import os
from datasets import load_dataset
from matplotlib import pyplot as plt
 
# Memuat dataset COCO
dataset = load_dataset(
    path="detection-datasets/coco", name="default", split="train", streaming=True
)
 
# Folder penyimpanan gambar dan pengaturan jumlah gambar
IMAGE_FOLDER = "tmp"
N_IMAGES = 20
 
# Pengaturan untuk plotting grafik
plot_cols = 5
plot_rows = N_IMAGES // plot_cols
fig, axes = plt.subplots(plot_rows, plot_cols, figsize=(plot_rows * 2, plot_cols * 2))
axes = axes.flatten()
 
# Menyimpan gambar ke dalam folder dan menampilkannya pada grafik
dataset_iter = iter(dataset)
os.makedirs(IMAGE_FOLDER, exist_ok=True)
for i in range(N_IMAGES):
    # Ekstraksi gambar dan label dari dataset
    data = next(dataset_iter)
    image = data["image"]
    label = data["objects"]["category"][0]  # Menggunakan kategori objek pertama sebagai label
 
    # Menampilkan gambar pada grafik dan menambahkan label
    axes[i].imshow(image)
    axes[i].set_title(label, fontsize=8)
    axes[i].axis("off")
 
    # Menyimpan gambar sebagai file
    image.save(f"{IMAGE_FOLDER}/{i}.jpg")
 
# Mengatur layout grafik dan menampilkannya
plt.tight_layout()
plt.show()

Multimodal embeddings

Menghasilkan sematan untuk gambar dan teks menggunakan Sematan Multimodal.

Dalam tutorial ini, kita akan menyematkan gambar menggunakan OpenClipEmbeddingFunction.

Benchmark Model

ModelTraining DataResolution# of Samples SeenImageNet Zero-Shot Acc.
ConvNext-BaseLAION-2B256px13B71.5%
ConvNext-LargeLAION-2B320px29B76.9%
ConvNext-XXLargeLAION-2B256px34B79.5%
ViT-B/32DataComp-1B256px34B72.8%
ViT-B/16DataComp-1B224px13B73.5%
ViT-L/14LAION-2B224px32B75.3%
ViT-H/14LAION-2B224px32B78.0%
ViT-L/14DataComp-1B224px13B79.2%
ViT-G/14LAION-2B224px34B80.1%
ViT-L/14 (Original CLIP)WIT224px13B75.5%
ViT-SO400M/14 (SigLIP)WebLI224px45B82.0%
ViT-SO400M-14-SigLIP-384 (SigLIP)WebLI384px45B83.1%
ViT-H/14-quickgelu (DFN)DFN-5B224px39B83.4%
ViT-H-14-378-quickgelu (DFN)DFN-5B378px44B84.4%

Pada contoh di bawah ini, model_name dan checkpoint ditetapkan dan digunakan.

  • model_name: Nama model OpenCLIP
  • checkpoint: Nama data pelatihan untuk model OpenCLIP
Python
import open_clip
import pandas as pd
 
# menampilkan model/titik pemeriksaan yang tersedia
pd.DataFrame(open_clip.list_pretrained(), columns=["model_name", "checkpoint"]).head(10)
#model_namecheckpoint
1RN50openai
2RN50yfcc15m
3RN50cc12m
4RN50-quickgeluopenai
5RN50-quickgeluyfcc15m
6RN50-quickgelucc12m
7RN101openai
8RN101yfcc15m
9RN101-quickgeluopenai
10RN101-quickgeluyfcc15m
Python
from langchain_experimental.open_clip import OpenCLIPEmbeddings
 
# Membuat objek fungsi embedding OpenCLIP
image_embedding_function = OpenCLIPEmbeddings(
    model_name="ViT-H-14-378-quickgelu", checkpoint="dfn5b"
)

Simpan path ke gambar sebagai daftar.

Python
# Menyimpan jalur ke gambar sebagai daftar
image_uris = sorted(
    [
        os.path.join("tmp", image_name)
        for image_name in os.listdir("tmp")
        if image_name.endswith(".jpg")
    ]
)
 
image_uris
Output
['tmp/0.jpg', 'tmp/1.jpg', 'tmp/10.jpg', 'tmp/11.jpg', 'tmp/12.jpg', 'tmp/13.jpg', 'tmp/14.jpg', 'tmp/15.jpg', 'tmp/16.jpg', 'tmp/17.jpg', 'tmp/18.jpg', 'tmp/19.jpg', 'tmp/2.jpg', 'tmp/3.jpg', 'tmp/4.jpg', 'tmp/5.jpg', 'tmp/6.jpg', 'tmp/7.jpg', 'tmp/8.jpg', 'tmp/9.jpg']
Python
from langchain_teddynote.models import MultiModal
from langchain_openai import ChatOpenAI
 
# Inisialisasi model ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
 
# Pengaturan model MultiModal
model = MultiModal(
    model=llm,
    system_prompt="Misi Anda adalah untuk menjelaskan gambar secara detail",  # Prompt sistem: Instruksi untuk menjelaskan gambar secara detail
    user_prompt="Deskripsi harus ditulis dalam satu kalimat (kurang dari 60 karakter)",  # Prompt pengguna: Meminta deskripsi dalam satu kalimat kurang dari 60 karakter
)

Membuat deskripsi untuk gambar.

Python
# Membuat Deskripsi Gambar
model.invoke(image_uris[0])
Output
Kotak makan berisi roti, brokoli, buah, dan kue.

Membuat deskripsi untuk gambar.

Python
#  Deskripsi gambar
descriptions = dict()
 
for image_uri in image_uris:
    descriptions[image_uri] = model.invoke(image_uri, display_image=False)
 
# Mengeluarkan output yang dihasilkan
descriptions
Output
{'tmp/0.jpg': 'Kotak makan berisi sayuran, buah, dan roti dengan selai.', 'tmp/1.jpg': 'Seekor jerapah sedang makan di dekat pohon.', 'tmp/10.jpg': 'Dua jerapah sedang berinteraksi di tengah pepohonan.', 'tmp/11.jpg': 'Sepeda motor klasik dengan desain vintage dan roda besar.', 'tmp/12.jpg': 'Seekor anjing putih tidur di jalanan sepi.', 'tmp/13.jpg': 'Seorang skateboarder melakukan trik di taman skate berwarna-warni.', 'tmp/14.jpg': 'Jam antik berdiri di samping lilin berbentuk burung hantu.', 'tmp/15.jpg': 'Pesawat Air France terbang di langit berawan.', 'tmp/16.jpg': 'Seorang pengendara sepeda motor tua sedang memeriksa surat.', 'tmp/17.jpg': 'Dapur dengan kompor putih dan pisau terpasang di dinding.', 'tmp/18.jpg': 'Kue lapis cokelat dengan taburan kelapa di atasnya.', 'tmp/19.jpg': 'Jalan sepi dengan papan nama hotel dan latar belakang pegunungan.', 'tmp/2.jpg': 'Vas putih berisi bunga berwarna-warni di taman.', 'tmp/3.jpg': 'Seekor zebra berjalan sambil merumput di padang hijau.', 'tmp/4.jpg': 'Seorang wanita ceria memegang payung pink di tepi danau.', 'tmp/5.jpg': 'Anjing berbulu tidur di tumpukan sepatu.', 'tmp/6.jpg': 'Dua kuda menari di lapangan dengan penunggang berpakaian putih.', 'tmp/7.jpg': 'Dua gajah berjalan di tengah hutan lebat bersama pengendara.', 'tmp/8.jpg': 'Jam dinding berlogo Rolex berdiri di pinggir jalan.', 'tmp/9.jpg': 'Kereta api melaju di jalur dengan bangunan di latar belakang.'}
Python
import os
from PIL import Image
import matplotlib.pyplot as plt
 
# Inisialisasi daftar untuk menyimpan gambar asli, gambar yang telah diproses, dan deskripsi teks
original_images = []
images = []
texts = []
 
# Mengatur ukuran grafik (20x10 inci)
plt.figure(figsize=(20, 10))
 
# Memproses file gambar yang disimpan di direktori 'tmp'
for i, image_uri in enumerate(image_uris):
    # Membuka file gambar dan mengonversinya ke mode RGB
    image = Image.open(image_uri).convert("RGB")
 
    # Membuat subplot dalam grid 4x5
    plt.subplot(4, 5, i + 1)
 
    # Menampilkan gambar
    plt.imshow(image)
 
    # Menetapkan nama file gambar dan deskripsi sebagai judul
    plt.title(f"{os.path.basename(image_uri)}\n{descriptions[image_uri]}", fontsize=8)
 
    # Menghapus tanda pada sumbu x dan y
    plt.xticks([])
    plt.yticks([])
 
    # Menambahkan gambar asli, gambar yang telah diproses, dan deskripsi teks ke masing-masing daftar
    original_images.append(image)
    images.append(image)
    texts.append(descriptions[image_uri])
 
# Menyesuaikan jarak antar subplot
plt.tight_layout()

Di bawah ini, kami menghitung kemiripan antara deskripsi gambar dan teks yang kami buat.

Python
import numpy as np
 
# Embedding gambar dan teks
# Ekstraksi fitur gambar menggunakan URI gambar
img_features = image_embedding_function.embed_image(image_uris)
# Tambahkan prefiks "This is" pada deskripsi teks dan ekstraksi fitur teks
text_features = image_embedding_function.embed_documents(
    ["This is " + desc for desc in texts]
)
 
# Konversi daftar menjadi array numpy untuk operasi matriks
img_features_np = np.array(img_features)
text_features_np = np.array(text_features)
 
# Perhitungan kesamaan
# Menghitung kesamaan kosinus antara fitur teks dan gambar
similarity = np.matmul(text_features_np, img_features_np.T)

Menemukan dan memvisualisasikan kemiripan antara deskripsi teks vs. gambar.

Python
# Membuat plot untuk memvisualisasikan matriks kesamaan
count = len(descriptions)
plt.figure(figsize=(20, 14))
 
# Menampilkan matriks kesamaan sebagai heatmap
plt.imshow(similarity, vmin=0.1, vmax=0.3, cmap="coolwarm")
plt.colorbar()  # Menambahkan color bar
 
# Menampilkan deskripsi teks pada sumbu y
plt.yticks(range(count), texts, fontsize=18)
plt.xticks([])  # Menghapus tanda pada sumbu x
 
# Menampilkan gambar asli di bawah sumbu x
for i, image in enumerate(original_images):
    plt.imshow(image, extent=(i - 0.5, i + 0.5, -1.6, -0.6), origin="lower")
 
# Menampilkan nilai kesamaan di atas heatmap sebagai teks
for x in range(similarity.shape[1]):
    for y in range(similarity.shape[0]):
        plt.text(x, y, f"{similarity[y, x]:.2f}", ha="center", va="center", size=12)
 
# Menghapus batas plot
for side in ["left", "top", "right", "bottom"]:
    plt.gca().spines[side].set_visible(False)
 
# Mengatur rentang plot
plt.xlim([-0.5, count - 0.5])
plt.ylim([count + 0.5, -2])
 
# Menambahkan judul
plt.title("Kesamaan Kosinus Antara Fitur Teks dan Gambar", size=20)

Membuat vector store dan Menambahkan Gambar

Membuat penyimpanan vektor dan menambahkan gambar.

Python
# Membuat DB
image_db = Chroma(
    collection_name="multimodal",
    embedding_function=image_embedding_function,
)
 
# Menambahkan gambar
image_db.add_images(uris=image_uris)

Di bawah ini adalah kelas pembantu untuk mengeluarkan hasil pencarian gambar sebagai gambar.

Python
import base64
import io
from PIL import Image
from IPython.display import HTML, display
from langchain.schema import Document
 
 
class ImageRetriever:
    def __init__(self, retriever):
        """
        Menginisialisasi pengambil gambar.
 
        Argumen:
        retriever: Objek retriever dari LangChain
        """
        self.retriever = retriever
 
    def invoke(self, query):
        """
        Mengambil dan menampilkan gambar berdasarkan kueri.
 
        Argumen:
        query (str): Kueri pencarian
        """
        docs = self.retriever.invoke(query)
        jika docs dan isinstance(docs[0], Document):
            self.plt_img_base64(docs[0].page_content)
        else:
            print("Tidak ada gambar yang ditemukan.")
        return docs
 
    @staticmethod
    def resize_base64_image(base64_string, size=(224, 224)):
        """
        Mengubah ukuran gambar yang dienkode dalam bentuk string Base64.
 
        Argumen:
        base64_string (str): String Base64 dari gambar asli.
        size (tuple): Ukuran gambar yang diinginkan dalam bentuk (lebar, tinggi).
 
        Return:
        str: String Base64 dari gambar yang ukurannya sudah diubah.
        """
        img_data = base64.b64decode(base64_string)
        img = Image.open(io.BytesIO(img_data))
        resized_img = img.resize(size, Image.LANCZOS)
        buffered = io.BytesIO()
        resized_img.save(buffered, format=img.format)
        return base64.b64encode(buffered.getvalue()).decode("utf-8")
 
    @staticmethod
    def plt_img_base64(img_base64):
        """
        Menampilkan gambar yang dienkode dalam bentuk Base64.
 
        Argumen:
        img_base64 (str): String gambar yang dienkode dalam bentuk Base64
        """
        image_html = f'<img src="data:image/jpeg;base64,{img_base64}" />'
        display(HTML(image_html))
Python
# Buat Retriever Gambar
retriever = image_db.as_retriever(search_kwargs={"k": 3})
image_retriever = ImageRetriever(retriever)
Python
# Pencarian gambar
result = image_retriever.invoke("A Dog on the street")
Python
# Pencarian gambar
result = image_retriever.invoke("Motorcycle with a man")