Python 은 Faiss 라 이브 러 리 를 이용 하여 ANN 근린 검색 을 실현 하 는 방법 에 대한 상세 한 설명

5900 단어 pythonfaiss근린
Embedding 의 근린 검색 은 현재 그림 추천 시스템 에서 매우 중요 한 리 콜 방식 으로 item2vec,행렬 분해,쌍 탑 DNN 등 방식 으로 훈련 된 user embedding,item embedding 을 생산 할 수 있 고 embedding 의 사용 에 매우 유연 합 니 다.
  • user embedding 을 입력 하고 근린 검색 item embedding 을 입력 하면 user 에 게 관심 있 는 items
  • 를 추천 할 수 있 습 니 다.
  • user embedding 을 입력 하고 근린 검색 user embedding 을 입력 하면 user 에 게 관심 있 는 user
  • 를 추천 할 수 있 습 니 다.
  • item embedding 을 입력 하고 근린 검색 item embedding 을 입력 하면 item 에 관련 된 items 를 추천 할 수 있 습 니 다.
  • 그러나 하나의 공정 문제 가 있 습 니 다.user embedding,item embedding 데이터 양 이 어느 정도 에 이 르 면 그들의 근린 검색 이 매우 느 려 집 니 다.오프라인 단계 에서 미리 검색 하면 고속 캐 시,예 를 들 어 redis 에 결 과 를 저장 하 는 것 은 물론 문제 가 없 지만 이런 방식 은 실시 간 이지 않 습 니 다.온라인 단계 에서 몇 십 MS 의 검색 을 할 수 있다 면 당연히 효과 가 가장 좋 습 니 다.
    페 이 스 북 AI 팀 이 오픈 한 클 러 스 터 와 유사 성 검색 라 이브 러 리 로,조밀 한 벡터 에 효율 적 인 싱크로 율 검색 과 클 러 스 터 를 제공 하고 10 억 수준의 벡터 검색 을 지원 하 는 등 현재 가장 성숙 한 근린 검색 라 이브 러 리 다.
    다음은 Jupyter notebook 의 코드 를 통 해 faiss 를 사용 하 는 간단 한 절 차 를 보 여 드 리 겠 습 니 다.내용 은 다음 과 같 습 니 다.
  • 훈련 된 Embedding 데이터 읽 기
  • faiss 색인 을 구축 하고 검색 할 Embedding 을 추가 합 니 다
  • 목표 Embedding 획득,ID 목록 검색 실현
  • ID 에 따라 영화 제목 을 가 져 와 결 과 를 되 돌려 줍 니 다.
  • 이미 훈련 된 Embedding 이 고속 근린 검색 을 어떻게 실현 하 는 지 에 대해 서 는 공정 문제 입 니 다.페 이 스 북 의 faiss 라 이브 러 리 는 다양한 embedding 색인 을 구축 하여 목표 embedding 의 고속 근린 검색 을 실현 하여 온라인 사용 수 요 를 만족 시 킬 수 있 습 니 다.
    설치 명령:
    
    conda install -c pytorch faiss-cpu 
    faiss 사용 경험 미리 정리 하기:
    1.자신의 ID 를 지원 하기 위해 faiss.IndexIDMap 으로 faiss.IndexFlatL 2 를 감 싸 면 됩 니 다.
    2.embedding 데 이 터 는 모두 np.float 32 로 변환 해 야 합 니 다.색인 에 있 는 embedding 과 검색 할 embedding 을 포함 합 니 다.
    3.ids 는 int 64 형식 으로 변환 해 야 합 니 다.
    1.데이터 준비
    
    import pandas as pd
    import numpy as np
    
    df = pd.read_csv("./datas/movielens_sparkals_item_embedding.csv")
    df.head()
    id
    features
    0
    10
    [0.25866490602493286, 0.3560594320297241, 0.15…
    1
    20
    [0.12449632585048676, -0.29282501339912415, -0…
    2
    30
    [0.9557555317878723, 0.6764761805534363, 0.114…
    3
    40
    [0.3184879720211029, 0.6365472078323364, 0.596…
    4
    50
    [0.45523127913475037, 0.34402626752853394, -0….
    구축 ids
    
    ids = df["id"].values.astype(np.int64)
    type(ids), ids.shape
    (numpy.ndarray, (3706,))
    ids.dtype
    dtype('int64')
    ids_size = ids.shape[0]
    ids_size
    3706
    데이터 구축
    
    import json
    import numpy as np
    datas = []
    for x in df["features"]:
     datas.append(json.loads(x))
    datas = np.array(datas).astype(np.float32)
    datas.dtype
    dtype('float32')
    datas.shape
    (3706, 10)
    datas[0]
    array([ 0.2586649 , 0.35605943, 0.15589039, -0.7067125 , -0.07414215,
     -0.62500805, -0.0573845 , 0.4533663 , 0.26074877, -0.60799956],
     dtype=float32)
    #   
    dimension = datas.shape[1]
    dimension
    10
    2.색인 만 들 기
    
    import faiss
    index = faiss.IndexFlatL2(dimension)
    index2 = faiss.IndexIDMap(index)
    ids.dtype
    dtype('int64')
    index2.add_with_ids(datas, ids)
    index.ntotal
    3706
    4.근린 ID 목록 검색
    
    df_user = pd.read_csv("./datas/movielens_sparkals_user_embedding.csv")
    df_user.head()
    id features
    id
    features
    0
    10
    [0.5974288582801819, 0.17486965656280518, 0.04…
    1
    20
    [1.3099910020828247, 0.5037978291511536, 0.260…
    2
    30
    [-1.1886241436004639, -0.13511677086353302, 0….
    3
    40
    [1.0809299945831299, 1.0048035383224487, 0.986…
    4
    50
    [0.42388680577278137, 0.5294889807701111, -0.6…
    
    user_embedding = np.array(json.loads(df_user[df_user["id"] == 10]["features"].iloc[0]))
    user_embedding = np.expand_dims(user_embedding, axis=0).astype(np.float32)
    user_embedding
    array([[ 0.59742886, 0.17486966, 0.04345559, -1.3193961 , 0.5313592 ,
     -0.6052168 , -0.19088413, 1.5307966 , 0.09310367, -2.7573566 ]],
     dtype=float32)
    user_embedding.shape
    (1, 10)
    user_embedding.dtype
    dtype('float32')
    topk = 30
    D, I = index.search(user_embedding, topk) # actual search
    I.shape
    (1, 30)
    I
    array([[3380, 2900, 1953, 121, 3285, 999, 617, 747, 2351, 601, 2347,
     42, 2383, 538, 1774, 980, 2165, 3049, 2664, 367, 3289, 2866,
     2452, 547, 1072, 2055, 3660, 3343, 3390, 3590]])
    5.영화 ID 에 따라 영화 정보 추출
    
    target_ids = pd.Series(I[0], name="MovieID")
    target_ids.head()
    0 3380
    1 2900
    2 1953
    3 121
    4 3285
    Name: MovieID, dtype: int64
    df_movie = pd.read_csv("./datas/ml-1m/movies.dat",
      sep="::", header=None, engine="python",
      names = "MovieID::Title::Genres".split("::"))
    df_movie.head()
    MovieID
    Title
    Genres
    0
    1
    Toy Story (1995)
    Animation|Children's|Comedy
    1
    2
    Jumanji (1995)
    Adventure|Children's|Fantasy
    2
    3
    Grumpier Old Men (1995)
    Comedy|Romance
    3
    4
    Waiting to Exhale (1995)
    Comedy|Drama
    4
    5
    Father of the Bride Part II (1995)
    Comedy
    
    df_result = pd.merge(target_ids, df_movie)
    df_result.head()
    MovieID
    Title
    Genres
    0
    3380
    Railroaded! (1947)
    Film-Noir
    1
    2900
    Monkey Shines (1988)
    Horror|Sci-Fi
    2
    1953
    French Connection, The (1971)
    Action|Crime|Drama|Thriller
    3
    121
    Boys of St. Vincent, The (1993)
    Drama
    4
    3285
    Beach, The (2000)
    Adventure|Drama
    총결산
    파 이 썬 이 페 이 스 라 이브 러 리 를 이용 하여 ANN 근린 검색 을 실현 하 는 것 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 파 이 썬 은 페 이 스 라 이브 러 리 ANN 근린 검색 내용 으로 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부탁드립니다!

    좋은 웹페이지 즐겨찾기