import gradio as gr import pandas as pd from sentence_transformers import SentenceTransformer from sklearn.metrics.pairwise import cosine_similarity import networkx as nx import matplotlib.pyplot as plt import csv import datetime import io # Sentence-BERT 모델 로드 model = SentenceTransformer('all-MiniLM-L6-v2') # 추천 결과를 CSV 파일로 저장하는 함수 (BytesIO로 수정) def save_recommendations_to_csv(recommendations): output = io.BytesIO() writer = csv.writer(output) writer.writerow(["Employee ID", "Employee Name", "Recommended Programs"]) # 추천 결과 CSV 파일에 기록 for rec in recommendations: writer.writerow(rec) output.seek(0) return output # 직원 데이터를 분석하여 교육 프로그램을 추천하고 그래프를 그리는 함수 def analyze_data(employee_file, program_file): # 직원 데이터와 교육 프로그램 데이터 불러오기 employee_df = pd.read_csv(employee_file.name) program_df = pd.read_csv(program_file.name) # 직원 역량과 프로그램 학습 목표를 벡터화 employee_skills = employee_df['current_skills'].tolist() program_skills = program_df['skills_acquired'].tolist() employee_embeddings = model.encode(employee_skills) program_embeddings = model.encode(program_skills) # 유사도 계산 similarities = cosine_similarity(employee_embeddings, program_embeddings) # 직원별 추천 프로그램 리스트 recommendations = [] recommendation_rows = [] # CSV 파일에 저장할 데이터를 위한 리스트 for i, employee in employee_df.iterrows(): recommended_programs = [] for j, program in program_df.iterrows(): if similarities[i][j] > 0.5: # 유사도 임계값 기준 recommended_programs.append(f"{program['program_name']} ({program['duration']})") if recommended_programs: recommendation = f"직원 {employee['employee_name']}의 추천 프로그램: {', '.join(recommended_programs)}" recommendation_rows.append([employee['employee_id'], employee['employee_name'], ", ".join(recommended_programs)]) else: recommendation = f"직원 {employee['employee_name']}에게 적합한 프로그램이 없습니다." recommendation_rows.append([employee['employee_id'], employee['employee_name'], "적합한 프로그램 없음"]) recommendations.append(recommendation) # 네트워크 그래프 생성 G = nx.Graph() for employee in employee_df['employee_name']: G.add_node(employee, type='employee') for program in program_df['program_name']: G.add_node(program, type='program') for i, employee in employee_df.iterrows(): for j, program in program_df.iterrows(): if similarities[i][j] > 0.5: # 유사도 임계값 G.add_edge(employee['employee_name'], program['program_name']) # 그래프 시각화 plt.figure(figsize=(10, 8)) pos = nx.spring_layout(G) nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=3000, font_size=10, font_weight='bold', edge_color='gray') plt.title("직원과 프로그램 간의 관계", fontsize=14, fontweight='bold') plt.tight_layout() # CSV 파일로 추천 결과 반환 csv_output = save_recommendations_to_csv(recommendation_rows) return "\n".join(recommendations), plt.gcf(), csv_output # Gradio 블록 with gr.Blocks(css=".gradio-button {background-color: #6c757d; color: white;} .gradio-textbox {border-color: #6c757d;}") as demo: gr.Markdown("

💼 HybridRAG 시스템

", unsafe_allow_html=True) with gr.Row(): with gr.Column(scale=1): gr.Markdown("

1. 직원 및 프로그램 데이터를 업로드하세요

") employee_file = gr.File(label="직원 데이터 업로드", interactive=True) program_file = gr.File(label="교육 프로그램 데이터 업로드", interactive=True) analyze_button = gr.Button("분석 시작", elem_classes="gradio-button") output_text = gr.Textbox(label="분석 결과", interactive=False, elem_classes="gradio-textbox") with gr.Column(scale=2): gr.Markdown("

2. 분석 결과

") chart_output = gr.Plot(label="시각화 차트") csv_download = gr.File(label="추천 결과 다운로드") # 분석 버튼 클릭 시 차트와 파일 다운로드를 업데이트 analyze_button.click(analyze_data, inputs=[employee_file, program_file], outputs=[output_text, chart_output, csv_download]) # Gradio 인터페이스 실행 demo.launch()