Project/한국어 대화 분류 및 요약

[Project] 한국어 대화 분류 및 요약 - 모델 학습

gangee 2024. 6. 9. 22:05

목차

    728x90
    반응형

    BERT 모델 학습

    • AI Hub데이터의 경우 라벨이 없는 데이터로 비지도학습 사용
    • 대표적인 군집화 모델 K-means을 사용하여 파인튜닝 진행

    모델 학습 과정

    1. pkl파일로 저장된 데이터를 학습할 수 있게 list 형태로 변환
    # 'filtered_file.pkl'에서 데이터 로드
    with open('filtered_file.pkl', 'rb') as f:
        analyzed_data = pickle.load(f)
    
    # list 형태로 변환
    texts = list(analyzed_data.values())
    1. 모델이 처리할 수 있게 텍스트 데이터를 숫자 벡터로 변환하는 텍스트 임베딩 추출 함수 정의
      • 배치 단위로 텍스트를 처리하고 토큰화하여 입력 형식으로 변환
      • 각 문장의 토큰 임베딩을 추출하고 numpy 배열로 변환
    # 텍스트 임베딩 추출 함수 (배치 처리)
    def get_embeddings(texts, tokenizer, model, batch_size=32):
        embeddings = []
        with torch.no_grad():
            for i in tqdm(range(0, len(texts), batch_size)):
                batch_texts = texts[i:i + batch_size]
                inputs = tokenizer(batch_texts, return_tensors='pt', truncation=True, padding=True, max_length=128, add_special_tokens=True)
                inputs = {key: val.to(model.device) for key, val in inputs.items()}  # Ensure inputs are on the same device as model
                outputs = model(**inputs)
                cls_embeddings = outputs.last_hidden_state[:, 0, :].cpu().numpy()  # CPU로 결과 이동
                embeddings.extend(cls_embeddings)
        return np.array(embeddings)
    
    # 텍스트 임베딩 추출
    embeddings = get_embeddings(texts, tokenizer, model)
    1. K-means 모델을 사용하여 파인 튜닝
    # K-평균 클러스터링 수행
    num_clusters = 7  # 클러스터 수 설정
    kmeans = KMeans(n_clusters=num_clusters, random_state=0).fit(embeddings)
    
    # 각 텍스트에 대한 클러스터 할당
    cluster_labels = kmeans.labels_
    
    # 클러스터링 모델 저장
    with open('kmeans_model.pkl', 'wb') as f:
        pickle.dump(kmeans, f)

    모델 학습 결과

    1. PCA를 사용하여 클러스터링 결과 시각화 및 중심 문장 추출
    # 클러스터링 결과 시각화 (PCA 사용)
    pca = PCA(n_components=2)
    reduced_embeddings = pca.fit_transform(embeddings)
    
    plt.scatter(reduced_embeddings[:, 0], reduced_embeddings[:, 1], c=kmeans.labels_, cmap='viridis')
    plt.title('Text Clustering with KMeans')
    plt.xlabel('PCA Component 1')
    plt.ylabel('PCA Component 2')
    plt.show()
    # 클러스터 중심 및 주변 텍스트 파악
    def get_cluster_centers_texts(embeddings, labels, texts, num_clusters, num_neighbors=10):
        cluster_centers_texts = {}
        for i in range(num_clusters):
            cluster_indices = np.where(labels == i)[0]
            cluster_embeddings = embeddings[cluster_indices]
            cluster_texts = [texts[idx] for idx in cluster_indices]
            center_idx, _ = pairwise_distances_argmin_min(kmeans.cluster_centers_[i].reshape(1, -1), cluster_embeddings)
            center_idx = center_idx[0]
    
            # 중심 문장과 가장 가까운 10개의 문장 찾기
            distances = np.linalg.norm(cluster_embeddings - cluster_embeddings[center_idx], axis=1)
            neighbor_indices = np.argsort(distances)[:num_neighbors + 1]  # 중심 문장을 포함한 가장 가까운 문장 인덱스
    
            cluster_centers_texts[i] = {
                'center_text': cluster_texts[center_idx],
                'neighbor_texts': [cluster_texts[idx] for idx in neighbor_indices if idx != center_idx]
            }
    
        return cluster_centers_texts
    
    # 중심 및 주변 텍스트 파악
    cluster_centers_texts = get_cluster_centers_texts(embeddings, cluster_labels, texts, num_clusters)
    
    # 클러스터 내용 출력
    for cluster, texts in cluster_centers_texts.items():
        print(f"Cluster {cluster} 중심 텍스트: {texts['center_text']}\n")
        print(f"Cluster {cluster} 주변 텍스트:")
        for neighbor_text in texts['neighbor_texts']:
            print(f"- {neighbor_text}")
        print("\n")

    728x90
    반응형