soojeongcrystal commited on
Commit
fa61fd5
·
verified ·
1 Parent(s): b1b2d35

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -68
app.py CHANGED
@@ -38,6 +38,25 @@ def generate_colors(n):
38
  HSV_tuples = [(x * 1.0 / n, 0.5, 0.9) for x in range(n)]
39
  return ['#%02x%02x%02x' % tuple(int(x*255) for x in colorsys.hsv_to_rgb(*hsv)) for hsv in HSV_tuples]
40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  def plot_network_graph(G):
42
  # 한국어 폰트 설정
43
  font_path = "./NanumBarunGothic.ttf"
@@ -51,14 +70,11 @@ def plot_network_graph(G):
51
 
52
  node_colors = [G.nodes[node]['color'] for node in G.nodes()]
53
 
54
- nx.draw(G, pos, node_color=node_colors, with_labels=False, node_size=1000,
55
- edge_color='gray', width=0.5)
 
56
 
57
- # 라벨 위치 조정
58
- label_pos = {k: (v[0], v[1] + 0.02) for k, v in pos.items()}
59
- nx.draw_networkx_labels(G, label_pos, font_size=8, font_weight='bold', font_family=font_prop.get_name())
60
-
61
- plt.title("Network graph", fontsize=16, fontproperties=font_prop)
62
  plt.axis('off')
63
 
64
  img_bytes = io.BytesIO()
@@ -68,25 +84,6 @@ def plot_network_graph(G):
68
 
69
  return img_bytes
70
 
71
- def create_network_graph(topic_results, num_words=10):
72
- G = nx.Graph()
73
- colors = generate_colors(len(topic_results))
74
-
75
- for idx, topic in enumerate(topic_results):
76
- words = topic['lda_words'][:num_words]
77
- color = colors[idx]
78
-
79
- for word in words:
80
- if not G.has_node(word):
81
- G.add_node(word, color=color)
82
-
83
- for i in range(len(words)):
84
- for j in range(i+1, len(words)):
85
- if not G.has_edge(words[i], words[j]):
86
- G.add_edge(words[i], words[j])
87
-
88
- return G
89
-
90
  # 헤더 스타일 변경
91
  st.markdown("""
92
  <style>
@@ -288,57 +285,69 @@ if 'run_analysis' in st.session_state and st.session_state.run_analysis:
288
  st.error(f"네트워크 그래프 생성 중 오류가 발생했습니다: {str(e)}")
289
 
290
  # Claude API를 사용하여 토픽 해석
291
- if api_key:
 
292
  client = Anthropic(api_key=api_key)
293
 
294
- st.header("Claude의 토픽 해석")
295
- with st.spinner("토픽 해석 중..."):
296
- prompt = f"""Human: 다음은 LDA 토픽 모델링 결과로 나온 각 토픽의 정보입니다. 이를 바탕으로 전체 토픽을 종합적으로 해석해주세요:
297
-
298
- {", ".join([f"토픽 {{info['topic_num']}} (비중: {{info['weight']:.1f}}%)" for info in topic_results])}
299
 
300
- 토픽의 주요 단어:
301
- """
302
- for info in topic_results:
303
- prompt += f"""
304
- 토픽 {info['topic_num']} (비중: {info['weight']:.1f}%):
305
- LDA 상위 단어: {', '.join(info['lda_words'])}
306
- TF-IDF 상위 단어: {', '.join(info['tfidf_words'])}
307
- """
308
-
309
- prompt += """
310
- 위 정보를 바탕으로 다음 형식에 맞춰 답변해주세요:
311
 
312
- 1. 전체 문서의 주제 요약 (3-4문장):
313
- [여기에 전체 문서의 주제를 종합적으로 설명해주세요. 각 토픽의 비중을 고려하여 중요도를 반영해주세요.]
 
 
 
 
 
 
 
 
 
 
 
 
314
 
315
- 2. 각 토픽 요약:
316
- [각 토픽에 대해 다음 형식으로 요약해주세요]
317
- - 토픽 [번호] ([토픽명]): [비중]%
318
- • 토픽명 설명: [토픽명이 이렇게 지어진 이유를 1-2문장으로 설명해주세요. LDA와 TF-IDF 상위 단어들이 어떻게 이 토픽명과 연관되는지 설명하세요.]
319
- • 토픽 설명: [1-2문장으로 토픽의 전반적인 내용을 설명해주세요.]
320
- • 가상의 예시 응답: "[이 토픽과 관련된 가상의 구성원 발언 예시를 넣어주세요. -한다 체를 지켜주세요]"
321
 
322
- 주의사항:
323
- 1. 토픽명은 "[구체적인 토픽명]" 형식으로 작성해주세요. 예를 들어, "구성원들의 성장과 개인적인 역량개발 노력" 또는 "리더들의 노력과 조직의 전폭적인 지원" 등입니다.
324
- 2. 토픽명은 단순히 단어를 나열하는 것이 아니라, 토픽의 핵심 주제나 의미를 잘 나타내는 구체적인 문구로 만들어주세요.
325
- 3. 토픽명 설명에서는 왜 그러한 토픽명이 선택되었는지, LDA와 TF-IDF 상위 단어들과의 연관성을 설명해주세요.
326
 
327
- 위 형식에 맞춰 답변해주세요. 사용자가 쉽게 복사하여 사용할 수 있도록 간결하고 명확하게 작성해주세요.
 
 
 
328
 
329
- \n\nAssistant: 네, 주어진 정보를 바탕으로 토픽 모델링 결과를 종합적으로 해석해 드리겠습니다.
330
- """
 
 
 
 
 
 
 
331
 
332
- try:
333
- response = client.completions.create(
334
- model="claude-2.1",
335
- max_tokens_to_sample=3000,
336
- prompt=prompt
337
- )
338
- st.subheader("토픽 모델링 종합 결과")
339
- st.text_area("결과를 복사하여 사용하세요:", value=response.completion, height=500)
340
- except Exception as e:
341
- st.error(f"Claude API 호출 중 오류가 발생했습니다: {str(e)}")
 
 
 
342
  else:
343
  st.warning("Claude API 키가 설정되지 않았습니다. https://console.anthropic.com/settings/keys 에 접속하여 API 키를 발급받으시면 토픽명과 해석을 제공받으실 수 있습니다.")
344
  except Exception as e:
 
38
  HSV_tuples = [(x * 1.0 / n, 0.5, 0.9) for x in range(n)]
39
  return ['#%02x%02x%02x' % tuple(int(x*255) for x in colorsys.hsv_to_rgb(*hsv)) for hsv in HSV_tuples]
40
 
41
+ def create_network_graph(topic_results, num_words=10):
42
+ G = nx.Graph()
43
+ colors = generate_colors(len(topic_results))
44
+
45
+ for idx, topic in enumerate(topic_results):
46
+ words = topic['lda_words'][:num_words]
47
+ color = colors[idx]
48
+
49
+ for word in words:
50
+ if not G.has_node(word):
51
+ G.add_node(word, color=color)
52
+
53
+ for i in range(len(words)):
54
+ for j in range(i+1, len(words)):
55
+ if not G.has_edge(words[i], words[j]):
56
+ G.add_edge(words[i], words[j])
57
+
58
+ return G
59
+
60
  def plot_network_graph(G):
61
  # 한국어 폰트 설정
62
  font_path = "./NanumBarunGothic.ttf"
 
70
 
71
  node_colors = [G.nodes[node]['color'] for node in G.nodes()]
72
 
73
+ nx.draw(G, pos, node_color=node_colors, with_labels=True, node_size=1000,
74
+ font_size=8, font_weight='bold', edge_color='gray', width=0.5,
75
+ font_family=font_prop.get_name())
76
 
77
+ plt.title("토픽 단어 네트워크", fontsize=16, fontproperties=font_prop)
 
 
 
 
78
  plt.axis('off')
79
 
80
  img_bytes = io.BytesIO()
 
84
 
85
  return img_bytes
86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  # 헤더 스타일 변경
88
  st.markdown("""
89
  <style>
 
285
  st.error(f"네트워크 그래프 생성 중 오류가 발생했습니다: {str(e)}")
286
 
287
  # Claude API를 사용하여 토픽 해석
288
+ # Claude API를 사용하여 토픽 해석
289
+ def interpret_topics(api_key, topic_results):
290
  client = Anthropic(api_key=api_key)
291
 
292
+ prompt = f"""Human: 다음은 LDA 토픽 모델링 결과로 나온 각 토픽의 정보입니다. 이를 바탕으로 전체 토픽을 종합적으로 해석해주세요:
 
 
 
 
293
 
294
+ {", ".join([f"토픽 {{info['topic_num']}} (비중: {{info['weight']:.1f}}%)" for info in topic_results])}
 
 
 
 
 
 
 
 
 
 
295
 
296
+ 토픽의 주요 단어:
297
+ """
298
+ for info in topic_results:
299
+ prompt += f"""
300
+ 토픽 {info['topic_num']} (비중: {info['weight']:.1f}%):
301
+ LDA 상위 단어: {', '.join(info['lda_words'])}
302
+ TF-IDF 상위 단어: {', '.join(info['tfidf_words'])}
303
+ """
304
+
305
+ prompt += """
306
+ 위 정보를 바탕으로 다음 형식에 맞춰 답변해주세요:
307
+
308
+ 1. 전체 문서의 주제 요약 (3-4문장):
309
+ [여기에 전체 문서의 주제를 종합적으로 설명해주세요. 각 토픽의 비중을 고려하여 중요도를 반영해주세요.]
310
 
311
+ 2. 각 토픽 요약:
312
+ [각 토픽에 대해 다음 형식으로 요약해주세요]
313
+ - 토픽 [번호] ([토픽명]): [비중]%
314
+ • 토픽명 설명: [토픽명이 이렇게 지어진 이유를 1-2문장으로 설명해주세요. LDA와 TF-IDF 상위 단어들이 어떻게 이 토픽명과 연관되는지 설명하세요.]
315
+ • 토픽 설명: [1-2문장으로 토픽의 전반적인 내용을 설명해주세요.]
316
+ • 가상의 예시 응답: "[이 토픽과 관련된 가상의 구성원 발언 예시를 넣어주세요. -한다 체를 지켜주세요]"
317
 
318
+ 주의사항:
319
+ 1. 토픽명은 "[구체적인 토픽명]" 형식으로 작성해주세요. 예를 들어, "구성원들의 성장과 개인적인 역량개발 노력" 또는 "리더들의 노력과 조직의 전폭적인 지원" 등입니다.
320
+ 2. 토픽명은 단순히 단어를 나열하는 것이 아니라, 토픽의 핵심 주제나 의미를 잘 나타내는 구체적인 문구로 만들어주세요.
321
+ 3. 토픽명 설명에서는 왜 그러한 토픽명이 선택되었는지, LDA와 TF-IDF 상위 단어들과의 연관성을 설명해주세요.
322
 
323
+ 위 형식에 맞춰 답변해주세요. 사용자가 쉽게 복사하여 사용할 수 있도록 간결하고 명확하게 작성해주세요.
324
+
325
+ \n\nAssistant: 네, 주어진 정보를 바탕으로 토픽 모델링 결과를 종합적으로 해석해 드리겠습니다.
326
+ """
327
 
328
+ try:
329
+ response = client.completions.create(
330
+ model="claude-2.1",
331
+ max_tokens_to_sample=3000,
332
+ prompt=prompt
333
+ )
334
+ return response.completion
335
+ except Exception as e:
336
+ return f"Claude API 호출 중 오류가 발생했습니다: {str(e)}"
337
 
338
+ # 메인 스크립트 내에서 토픽 해석 부분 수정
339
+ if api_key:
340
+ st.header("토픽 종합 해석")
341
+
342
+ if 'topic_interpretation' not in st.session_state:
343
+ st.session_state.topic_interpretation = None
344
+
345
+ if st.session_state.topic_interpretation is None or st.button("토픽 다시 해석하기"):
346
+ with st.spinner("토픽 해석 중..."):
347
+ st.session_state.topic_interpretation = interpret_topics(api_key, topic_results)
348
+
349
+ st.subheader("토픽 모델링 종합 결과")
350
+ st.text_area("결과를 복사하여 사용하세요:", value=st.session_state.topic_interpretation, height=500)
351
  else:
352
  st.warning("Claude API 키가 설정되지 않았습니다. https://console.anthropic.com/settings/keys 에 접속하여 API 키를 발급받으시면 토픽명과 해석을 제공받으실 수 있습니다.")
353
  except Exception as e: