Changes between Version 6 and Version 7 of АdvancedPhase


Ignore:
Timestamp:
06/14/26 17:14:58 (30 hours ago)
Author:
231077
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • АdvancedPhase

    v6 v7  
    2828
    2929{{{
    30 docker run --name booknest-postgres \
    31 -e POSTGRES_PASSWORD=postgres \
    32 -e POSTGRES_DB=booknest \
    33 -p 5433:5432 \
     30docker run --name booknest-postgres
     31-e POSTGRES_PASSWORD=postgres
     32-e POSTGRES_DB=booknest
     33-p 5433:5432
    3434-d pgvector/pgvector:pg16
    3535}}}
     
    8989}}}
    9090
    91 
    9291Резултатот потврдува дека pgvector е успешно инсталиран и активен.
     92
     93[[Image(pgvector_extension.png,800px)]]
    9394
    9495== Чекор 4 - Додавање embedding колона ==
     
    117118Скриптата ги чита:
    118119
    119  * насловот на книгата
    120  * описот
    121  * жанровите
    122  * категориите
    123  * авторите
     120* насловот на книгата
     121* описот
     122* жанровите
     123* категориите
     124* авторите
    124125
    125126и од нив генерира embedding користејќи го моделот:
     
    133134{{{
    134135book.embedding
     136}}}
     137
     138Целата Python скрипта:
     139
     140{{{
     141import psycopg2
     142from sentence_transformers import SentenceTransformer
     143
     144conn = psycopg2.connect(
     145host="localhost",
     146port=5433,
     147database="booknest",
     148user="postgres",
     149password="postgres"
     150)
     151
     152cursor = conn.cursor()
     153
     154print("Connected!")
     155
     156cursor.execute(
     157SELECT
     158b.barcode,
     159b.title,
     160COALESCE(b.description, '') AS description,
     161COALESCE(string_agg(DISTINCT g.name, ', '), '') AS genres,
     162COALESCE(string_agg(DISTINCT c.name, ', '), '') AS categories,
     163COALESCE(string_agg(DISTINCT a.first_name || ' ' || a.last_name, ', '), '') AS authors
     164FROM book b
     165LEFT JOIN book_genre bg ON bg.barcode = b.barcode
     166LEFT JOIN genre g ON g.genre_id = bg.genre_id
     167LEFT JOIN category_book cb ON cb.barcode = b.barcode
     168LEFT JOIN category c ON c.category_id = cb.category_id
     169LEFT JOIN book_author ba ON ba.barcode = b.barcode
     170LEFT JOIN author a ON a.author_id = ba.author_id
     171GROUP BY b.barcode, b.title, b.description
     172LIMIT 10000
     173)
     174
     175books = cursor.fetchall()
     176
     177print(f"Found {len(books)} books")
     178
     179model = SentenceTransformer("all-MiniLM-L6-v2")
     180
     181for i, (barcode, title, description, genres, categories, authors) in enumerate(books, start=1):
     182text = (
     183title + " " +
     184description + " " +
     185genres + " " +
     186categories + " " +
     187authors
     188)
     189
     190embedding = model.encode(text).tolist()
     191
     192cursor.execute(
     193   
     194    UPDATE book
     195    SET embedding = %s
     196    WHERE barcode = %s
     197    """,
     198    (embedding, barcode)
     199)
     200
     201if i % 500 == 0:
     202    conn.commit()
     203    print(f"Updated {i}/{len(books)} books")
     204
     205
     206conn.commit()
     207
     208print("DONE!")
     209
     210cursor.close()
     211conn.close()
    135212}}}
    136213
     
    145222}}}
    146223
    147 [[Image(xount_books,800px)]]
     224[[Image(count_books.png,800px)]]
    148225
    149226Резултатот покажува дека embeddings се успешно генерирани.
     
    162239}}}
    163240
    164 Овој индекс овозможува значително побрзо пребарување на најслични вектори без да се споредуваат сите книги во табелата.
     241Овој индекс овозможува побрзо пребарување на најслични вектори без да се споредуваат сите книги во табелата.
    165242
    166243== Чекор 7 - Функција за препораки ==
     
    170247{{{
    171248recommend_books_for_member_pgvector(
    172     p_member_id,
    173     p_limit
     249p_member_id,
     250p_limit
    174251)
    175252}}}
     
    177254Функцијата работи во неколку чекори:
    178255
    179  1. Ги наоѓа книгите што членот претходно ги има позајмено.
    180  2. Го пресметува просечниот embedding профил на членот.
    181  3. Ги разгледува сите останати книги.
    182  4. Ги исклучува книгите што членот веќе ги има позајмено.
    183  5. Ги рангира книгите според cosine similarity.
    184  6. Ги враќа најдобрите N препораки.
     2561. Ги наоѓа книгите што членот претходно ги има позајмено.
     2572. Го пресметува просечниот embedding профил на членот.
     2583. Ги разгледува сите останати книги.
     2594. Ги исклучува книгите што членот веќе ги има позајмено.
     2605. Ги рангира книгите според cosine similarity.
     2616. Ги враќа најдобрите N препораки.
     262
     263Кодот на функцијата:
     264
     265{{{
     266CREATE OR REPLACE FUNCTION recommend_books_for_member_pgvector(
     267p_member_id INT,
     268p_limit INT DEFAULT 10
     269)
     270RETURNS TABLE (
     271barcode VARCHAR,
     272title VARCHAR,
     273similarity FLOAT
     274)
     275LANGUAGE SQL
     276AS $$
     277WITH borrowed_books AS (
     278SELECT DISTINCT bc.barcode
     279FROM loan_history lh
     280JOIN book_copy bc ON bc.copy_id = lh.copy_id
     281WHERE lh.member_user_id = p_member_id
     282),
     283member_profile AS (
     284SELECT AVG(b.embedding) AS profile_embedding
     285FROM book b
     286JOIN borrowed_books bb ON bb.barcode = b.barcode
     287WHERE b.embedding IS NOT NULL
     288)
     289SELECT
     290b.barcode,
     291b.title,
     2921 - (b.embedding <=> mp.profile_embedding) AS similarity
     293FROM book b
     294CROSS JOIN member_profile mp
     295WHERE b.embedding IS NOT NULL
     296AND b.barcode NOT IN (SELECT barcode FROM borrowed_books)
     297ORDER BY b.embedding <=> mp.profile_embedding
     298LIMIT p_limit;
     299$$;
     300}}}
    185301
    186302Клучниот pgvector дел е:
     
    199315
    200316Колку вредноста е поблиску до 1, толку книгата е послична на читачкиот профил на членот.
     317
    201318== Чекор 8 - Тестирање на препораките ==
    202319
     
    210327Функцијата успешно враќа листа од препорачани книги за членот, сортирани според cosine similarity.
    211328
    212 [[Image(recommend_books_for_member_pgvector.png, 800px)]]
     329[[Image(recommend_books_for_member_pgvector.png,800px)]]
    213330
    214331=== Recommended Books Generated by the System ===
     
    249366Ова докажува дека ниту една од препорачаните книги не се појавува во претходната историја на позајмувања на членот.
    250367
    251 [PLACEHOLDER: Screenshot од COUNT = 0]
    252368== Чекор 10 - Валидација на препораките ==
    253369
     
    276392}}}
    277393
    278 [PLACEHOLDER: Screenshot од loan history книги]
     394[[Image(member_loan_history.png,800px)]]
    279395
    280396Потоа беа прикажани препорачаните книги со нивните жанрови, категории и автори.
    281397
    282 [PLACEHOLDER: Screenshot од препораки со genre/category/author]
     398{{{
     399SELECT
     400r.barcode,
     401r.title,
     402r.similarity,
     403string_agg(DISTINCT g.name, ', ') AS genres,
     404string_agg(DISTINCT c.name, ', ') AS categories,
     405string_agg(DISTINCT a.first_name || ' ' || a.last_name, ', ') AS authors
     406FROM recommend_books_for_member_pgvector(10835, 10) r
     407LEFT JOIN book_genre bg ON bg.barcode = r.barcode
     408LEFT JOIN genre g ON g.genre_id = bg.genre_id
     409LEFT JOIN category_book cb ON cb.barcode = r.barcode
     410LEFT JOIN category c ON c.category_id = cb.category_id
     411LEFT JOIN book_author ba ON ba.barcode = r.barcode
     412LEFT JOIN author a ON a.author_id = ba.author_id
     413GROUP BY r.barcode, r.title, r.similarity
     414ORDER BY r.similarity DESC;
     415}}}
     416
     417[[Image(recommendations_with_metadata.png,800px)]]
    283418
    284419=== Конкретни примери ===
     
    346481Ова покажува дека препораките не се случајни, туку се базирани на семантичка сличност помеѓу книгите.
    347482
    348 == Screenshots / Proof of Work ==
    349 
    350 [[Image(vector_extension.png)]]
    351 
    352 Проверка дека pgvector екстензијата е успешно инсталирана.
    353 
    354 [[Image(embeddings_generated.png)]]
    355 
    356 Потврда дека се генерирани embeddings за 10000 книги.
    357 
    358 [[Image(recommendation_results.png)]]
    359 
    360 Резултат од функцијата recommend_books_for_member_pgvector.
    361 
    362 [[Image(validation_result.png)]]
    363 
    364 Проверка дека не се препорачуваат веќе позајмени книги.
    365 
    366 [[Image(loan_history.png)]]
    367 
    368 Пример книги од претходната историја на позајмувања.