##进入jieba和pands  读入需要的文档，有几个阶段就要读取几个文档/////////只需要注意文档的名称
import pandas as pd
import jieba 

papers_18_19 = pd.read_excel("FirstPeriod.xlsx",names = ['summary','time'])
papers_20_22 = pd.read_excel("SecondPeriod.xlsx",names = ['summary','time'])
papers_23_24 = pd.read_excel("ThirdPeriod.xlsx",names = ['summary','time'])

##计算是否有空值//////////每个文本都要计算
papers_18_19.info()

##展示文本//////////每个文本都要展示
papers_18_19.head()

papers_20_22.info()

papers_20_22.head()

papers_23_24.info()

papers_23_24.head()

## 加载用户词典//////////停用词名字叫什么就改成什么
jieba.load_userdict("psydic.txt")
stopLists = list(pd.read_csv("stopwords.txt",names = ['w'],sep='\t',encoding="utf-8").w)

## 定义分词方法//////////最后的2是大于2个字，可以选大于几个字
def paperCut(text):
    return [w for w in jieba.cut(text) if w not in stopLists and len(w)>2]

## 第一阶段分词
wordList_First = [paperCut(paper) for paper in papers_18_19.summary]
wordList_First[1]

len(wordList_First)

## 第二阶段分词
wordList_Second = [paperCut(paper) for paper in papers_20_22.summary]
wordList_Second[1]

len(wordList_Second)

## 第三阶段分词
wordList_Third = [paperCut(paper) for paper in papers_23_24.summary]
wordList_Third[1]

len(wordList_Third)

from gensim.models.word2vec import Word2Vec

wordList = []
wordList = wordList+ wordList_First
wordList.extend(wordList_Second)
wordList.extend(wordList_Third)

len(wordList)

# sg=0，CBOW的训练方式
model_cbow = Word2Vec(sentences=wordList, vector_size=100, window=5, sg = 0,min_count = 1,workers = 4, epochs=100)

# Get the vocabulary and corresponding vectors
vocabulary = model_cbow.wv.index_to_key
vectors = model_cbow.wv[vocabulary]

vocabulary[:5]

vectors[:1]

# 训练完毕的模型实质
print(model_cbow.wv["心理学"].shape)
model_cbow.wv["心理学"]

from gensim.models import TfidfModel
from gensim.corpora import Dictionary

def text2Matrix(wordList):
    dict = Dictionary(wordList)
    corpus = [dict.doc2bow(text) for text in wordList]
    tfidf_model = TfidfModel(corpus)
    corpus_tfidf = tfidf_model[corpus]
    return dict,corpus,corpus_tfidf

# 第一阶段文本向量化
dict_First,corpus_First,corpus_tfidf_First = text2Matrix(wordList_First)
len(corpus_tfidf_First)

# 第二阶段文本向量化
dict_Second,corpus_Second,corpus_tfidf_Second = text2Matrix(wordList_Second)
len(corpus_tfidf_Second)

# 第三阶段文本向量化
dict_Third,corpus_Third,corpus_tfidf_Third = text2Matrix(wordList_Third)
len(corpus_tfidf_Third)

from gensim.models.ldamodel import LdaModel

import matplotlib.pyplot as plt
import matplotlib

## 困惑度计算
def cal_perplexity(num_topics,corpus_tfidf,dict):
    ldamodel = LdaModel(corpus_tfidf, num_topics=num_topics, id2word = dict,passes=5,alpha= 1/num_topics, eta=0.01)
    return ldamodel.log_perplexity(corpus_tfidf)

## 第一阶段困惑度计算

topic_num = range(1,10)
perplexitys_First = [cal_perplexity(num,corpus_First,dict_First) for num in topic_num]

plt.plot(topic_num, perplexitys_First)
plt.xlabel('主题数目')
plt.ylabel('困惑度')
plt.rcParams['font.sans-serif']=['SimHei']
matplotlib.rcParams['axes.unicode_minus']=False
plt.title('阶段一 主题-困惑度变化趋势')
plt.show()

## 第二阶段困惑度计算

topic_num = range(1,10)
perplexitys_Second = [cal_perplexity(num,corpus_Second,dict_Second) for num in topic_num]

plt.plot(topic_num, perplexitys_Second)
plt.xlabel('主题数目')
plt.ylabel('困惑度')
plt.rcParams['font.sans-serif']=['SimHei']
matplotlib.rcParams['axes.unicode_minus']=False
plt.title('阶段一 主题-困惑度变化趋势')
plt.show()

## 第三阶段困惑度计算

topic_num = range(1,10)
perplexitys_Third = [cal_perplexity(num,corpus_Third,dict_Third) for num in topic_num]

plt.plot(topic_num, perplexitys_Third)
plt.xlabel('主题数目')
plt.ylabel('困惑度')
plt.rcParams['font.sans-serif']=['SimHei']
matplotlib.rcParams['axes.unicode_minus']=False
plt.title('阶段一 主题-困惑度变化趋势')
plt.show()

## 第一阶段主题建模， num_topics为阶段一的最优主题数目
ldamodel_First = LdaModel(corpus_tfidf_First,id2word= dict_First, num_topics = 2, passes= 10,alpha=8.5, eta= 0.01)

import warnings
warnings.filterwarnings("ignore")

## pip install pyLDAvis
import pyLDAvis.gensim
pyLDAvis.enable_notebook

# 注意：如果网络畅通，采用此种方式。如果不出图，不必纠结，用困惑度计算即可。
topic_data_First = pyLDAvis.gensim.prepare(ldamodel_First,corpus_First,dict_First)
pyLDAvis.display(topic_data_First)

## 第二阶段主题建模， num_topics为阶段一的最优主题数目
ldamodel_Second = LdaModel(corpus_tfidf_Second,id2word= dict_Second, num_topics = 2, passes= 10,alpha=8.5, eta= 0.01)

import warnings
warnings.filterwarnings("ignore")

## pip install pyLDAvis
import pyLDAvis.gensim
pyLDAvis.enable_notebook

# 注意：如果网络畅通，采用此种方式。如果不出图，不必纠结，用困惑度计算即可。
topic_data_Second = pyLDAvis.gensim.prepare(ldamodel_Second,corpus_Second,dict_Second)
pyLDAvis.display(topic_data_Second)

## 第三阶段主题建模， num_topics为阶段一的最优主题数目
ldamodel_Third = LdaModel(corpus_tfidf_Third,id2word= dict_Third, num_topics = 2, passes= 10,alpha=8.5, eta= 0.01)

import warnings
warnings.filterwarnings("ignore")

## pip install pyLDAvis
import pyLDAvis.gensim
pyLDAvis.enable_notebook

# 注意：如果网络畅通，采用此种方式。如果不出图，不必纠结，用困惑度计算即可。
topic_data_Third = pyLDAvis.gensim.prepare(ldamodel_Third,corpus_Third,dict_Third)
pyLDAvis.display(topic_data_Third)

## 列出第一阶段主题和主题词
ldamodel_First.print_topics(num_topics=ldamodel_First.num_topics,num_words= 30)

## 列出第二阶段主题和主题词
ldamodel_Second.print_topics(num_topics=ldamodel_Second.num_topics,num_words= 30)

## 列出第三阶段主题和主题词
ldamodel_Third.print_topics(num_topics=ldamodel_Third.num_topics,num_words= 30)

import numpy as np
## 基于词向量的主题向量计算
def get_topic_vector(model, words, topic_word_value):
    vectors = []
    i = 0
    for word in words:
        if word in model.wv.index_to_key:
            vectors.append(model.wv[word]*float(topic_word_value[i]))
            i+=1
    if len(vectors) > 0:
        return np.mean(vectors, axis=0)
    else:
        return np.zeros((model.vector_size,), dtype=np.float32)

##'0.014*"图书馆" + 0.011*"学科服务" + 0.010*"互联网" + 0.010*"图书馆智慧服务" '

## 计算主题向量
def cal_vector(topicNum,ldamodel):
    
    topic = ldamodel.print_topic(i)
    
    split_topic = topic.split("+")
    
    words = []
    
    values = []
    
    print(split_topic)
    
    for str in split_topic:
        str_split = str.split("*")
        if len(str_split)>1:
            values.append(str_split[0]) 
            words.append(str_split[1].replace("\"",""))
        
    return get_topic_vector(model_cbow, words, values)

## 计算第一阶段的所有主题向量
topic_vectors_First = []
for i in range(ldamodel_First.num_topics):
    topic_vector= cal_vector(i,ldamodel_First)
    topic_vectors_First.append(topic_vector)
len(topic_vectors_First)

## 计算第二阶段的所有主题向量
topic_vectors_Second = []
for i in range(ldamodel_Second.num_topics):
    topic_vector= cal_vector(i,ldamodel_Second)
    topic_vectors_Second.append(topic_vector)
len(topic_vectors_Second)

## 计算第三阶段的所有主题向量
topic_vectors_Third = []
for i in range(ldamodel_Third.num_topics):
    topic_vector= cal_vector(i,ldamodel_Third)
    topic_vectors_Third.append(topic_vector)
len(topic_vectors_Third)

## 提示：此处代码为示例，暂不要执行！如果有多个阶段，需要定义新的参数
## 计算第X阶段每个主题的向量
topic_vectors_First = []

for i in range(ldamodel_First.num_topics):
    topic_vector= cal_vector(i,ldamodel_First)
    topic_vectors_First.append(topic_vector)
len(topic_vectors_First)

## 提示：此处代码为示例，暂不要执行！如果有多个阶段，需要定义新的参数
## 计算第X阶段每个主题的向量
topic_vectors_Second = []

for i in range(ldamodel_Second.num_topics):
    topic_vector= cal_vector(i,ldamodel_Second)
    topic_vectors_Second.append(topic_vector)
len(topic_vectors_Second)

## 提示：此处代码为示例，暂不要执行！如果有多个阶段，需要定义新的参数
## 计算第X阶段每个主题的向量
topic_vectors_Third = []

for i in range(ldamodel_Third.num_topics):
    topic_vector= cal_vector(i,ldamodel_Third)
    topic_vectors_Third.append(topic_vector)
len(topic_vectors_Third)

## 计算相邻阶段主题相似度
from sklearn.metrics.pairwise import cosine_similarity

def cal_cosine(topicVector_Before,topicVector_After):
    topic_cos = cosine_similarity(np.array(topicVector_Before),np.array(topicVector_After))
    return topic_cos

## 第一阶段和第二阶段主题相似度，此变量将用于后续的桑基图绘制！！！
topic_cos_1_2 = cal_cosine(topic_vectors_First,topic_vectors_Second)
topic_cos_1_3 = cal_cosine(topic_vectors_First,topic_vectors_Third)
topic_cos_2_3 = cal_cosine(topic_vectors_Second,topic_vectors_Third)

## 相似度数据框展示
cos_pd_1_2 = pd.DataFrame(topic_cos_1_2)
cos_pd_1_2

## 相似度数据框展示
cos_pd_2_3 = pd.DataFrame(topic_cos_2_3)
cos_pd_2_3

## 相似度数据框展示
cos_pd_1_3 = pd.DataFrame(topic_cos_1_3)
cos_pd_1_3

#{"source": "category1", "target": "category2", "value": 10}

print('{\"name\":\"第一阶段主题%d\"}' % 1)
print('{\"source\": \"第一阶段主题%d\",\"target\":\"第二阶段主题%d\", \"value\":%d}' %( 1, 2,3))

## topic_cos_1_2表示第一阶段和第二阶段的相似度
cos_list_1_2 = list(topic_cos_1_2)
cos_list_1_2

for i,val in enumerate(cos_list_1_2):
    #{"name": "category1"},
    print('{\"name\":\"第一阶段主题%d\"}' % i)

for i,val in enumerate(cos_list_1_2):
    for j,v in enumerate(val):
        print('{\"name\":\"第二阶段主题%d\"}' % j)
    break

for i,val in enumerate(cos_list_1_2):
    for j,v in enumerate(val):
        print('{\"source\": \"第一阶段主题%d\",\"target\":\"第二阶段主题%d\", \"value\":%f}' %( i, j, v))

#{"source": "category1", "target": "category2", "value": 10}

print('{\"name\":\"第一阶段主题%d\"}' % 1)
print('{\"source\": \"第一阶段主题%d\",\"target\":\"第三阶段主题%d\", \"value\":%d}' %( 1, 2,3))

## topic_cos_1_2表示第一阶段和第三阶段的相似度
cos_list_1_3 = list(topic_cos_1_3)
cos_list_1_3

for i,val in enumerate(cos_list_1_3):
    #{"name": "category1"},
    print('{\"name\":\"第一阶段主题%d\"}' % i)

for i,val in enumerate(cos_list_1_3):
    for j,v in enumerate(val):
        print('{\"name\":\"第三阶段主题%d\"}' % j)
    break

for i,val in enumerate(cos_list_1_3):
    for j,v in enumerate(val):
        print('{\"source\": \"第一阶段主题%d\",\"target\":\"第三阶段主题%d\", \"value\":%f}' %( i, j, v))

#{"source": "category1", "target": "category2", "value": 10}

print('{\"name\":\"第二阶段主题%d\"}' % 1)
print('{\"source\": \"第二阶段主题%d\",\"target\":\"第三阶段主题%d\", \"value\":%d}' %( 1, 2,3))

## topic_cos_1_2表示第二阶段和第三阶段的相似度
cos_list_2_3 = list(topic_cos_2_3)
cos_list_2_3

for i,val in enumerate(cos_list_2_3):
    #{"name": "category1"},
    print('{\"name\":\"第二阶段主题%d\"}' % i)

for i,val in enumerate(cos_list_2_3):
    for j,v in enumerate(val):
        print('{\"name\":\"第三阶段主题%d\"}' % j)
    break

for i,val in enumerate(cos_list_2_3):
    for j,v in enumerate(val):
        print('{\"source\": \"第二阶段主题%d\",\"target\":\"第三阶段主题%d\", \"value\":%f}' %( i, j, v))

import pandas as pd
import numpy as np
from collections import Counter

# 读取数据
papers_18_19 = pd.read_excel("FirstPeriod.xlsx", names=['summary','time'])
papers_20_22 = pd.read_excel("SecondPeriod.xlsx", names=['summary','time'])  
papers_23_24 = pd.read_excel("ThirdPeriod.xlsx", names=['summary','time'])

# 合并所有数据以便统一处理
papers_18_19['period'] = '第一阶段'
papers_20_22['period'] = '第二阶段'
papers_23_24['period'] = '第三阶段'

all_papers = pd.concat([papers_18_19, papers_20_22, papers_23_24], ignore_index=True)

# 提取年份（假设time列包含日期信息）
def extract_year(time_str):
    try:
        if isinstance(time_str, str):
            # 尝试从字符串中提取年份
            if '-' in time_str:
                return int(time_str.split('-')[0])
            else:
                return int(time_str[:4])
        elif isinstance(time_str, (int, float)):
            return int(time_str)
    except:
        return None

all_papers['year'] = all_papers['time'].apply(extract_year)

# 过滤有效年份
all_papers = all_papers.dropna(subset=['year'])
print("数据概览：")
print(f"总文档数：{len(all_papers)}")
print(f"年份范围：{all_papers['year'].min()} - {all_papers['year'].max()}")
print(f"各年份文档数量：\n{all_papers['year'].value_counts().sort_index()}")

import jieba
import pandas as pd
from gensim.models import LdaModel
from gensim.corpora import Dictionary

# 加载停用词和用户词典
jieba.load_userdict("psydic.txt")
stopLists = list(pd.read_csv("stopwords.txt", names=['w'], sep='\t', encoding="utf-8").w)

# 重新定义分词函数
def paperCut(text):
    return [w for w in jieba.cut(text) if w not in stopLists and len(w)>2]

# 重新分词
print("重新分词...")
wordList_First = [paperCut(paper) for paper in papers_18_19.summary]
wordList_Second = [paperCut(paper) for paper in papers_20_22.summary]  
wordList_Third = [paperCut(paper) for paper in papers_23_24.summary]

# 文本向量化函数
def text2Matrix(wordList):
    dict = Dictionary(wordList)
    corpus = [dict.doc2bow(text) for text in wordList]
    return dict, corpus

# 重新向量化
print("文本向量化...")
dict_First, corpus_First = text2Matrix(wordList_First)
dict_Second, corpus_Second = text2Matrix(wordList_Second)
dict_Third, corpus_Third = text2Matrix(wordList_Third)

# 重新训练LDA模型（使用2个主题）
print("训练LDA模型...")
ldamodel_First = LdaModel(corpus_First, id2word=dict_First, num_topics=2, passes=10, alpha=8.5, eta=0.01)
ldamodel_Second = LdaModel(corpus_Second, id2word=dict_Second, num_topics=2, passes=10, alpha=8.5, eta=0.01)  
ldamodel_Third = LdaModel(corpus_Third, id2word=dict_Third, num_topics=2, passes=10, alpha=8.5, eta=0.01)

print("LDA模型训练完成！")

# 定义函数计算文档的主题分布
def get_document_topic_distribution(ldamodel, corpus):
    """获取所有文档的主题分布"""
    doc_topic_distributions = []
    for doc in corpus:
        # 获取文档的主题分布
        topic_dist = ldamodel.get_document_topics(doc, minimum_probability=0)
        # 转换为概率向量
        topic_probs = [prob for _, prob in topic_dist]
        doc_topic_distributions.append(topic_probs)
    return doc_topic_distributions

# 为每个阶段计算文档主题分布
print("计算文档主题分布...")
doc_topics_first = get_document_topic_distribution(ldamodel_First, corpus_First)
doc_topics_second = get_document_topic_distribution(ldamodel_Second, corpus_Second)
doc_topics_third = get_document_topic_distribution(ldamodel_Third, corpus_Third)

# 将主题分布添加到对应的数据框中
papers_18_19['topic_distribution'] = doc_topics_first
papers_20_22['topic_distribution'] = doc_topics_second  
papers_23_24['topic_distribution'] = doc_topics_third

# 重新合并数据（现在包含主题分布）
all_papers_with_topics = pd.concat([papers_18_19, papers_20_22, papers_23_24], ignore_index=True)
all_papers_with_topics['year'] = all_papers_with_topics['time'].apply(extract_year)
all_papers_with_topics = all_papers_with_topics.dropna(subset=['year'])

print(f"包含主题分布的总文档数：{len(all_papers_with_topics)}")

# 计算年度主题热度
def calculate_yearly_topic_heat(df, period_name, num_topics=2):
    """计算指定阶段的年度主题热度"""
    yearly_heat = {}
    
    for year in sorted(df['year'].unique()):
        year_data = df[df['year'] == year]
        year_heat = [0] * num_topics
        
        for topic_dist in year_data['topic_distribution']:
            for topic_idx, prob in enumerate(topic_dist):
                year_heat[topic_idx] += prob
        
        # 标准化为平均热度（除以文档数量）
        if len(year_data) > 0:
            year_heat = [heat / len(year_data) for heat in year_heat]
        
        yearly_heat[year] = year_heat
    
    # 转换为DataFrame
    heat_df = pd.DataFrame.from_dict(yearly_heat, orient='index')
    heat_df.columns = [f'{period_name}主题{i+1}' for i in range(num_topics)]
    heat_df.index.name = '年份'
    
    return heat_df

# 计算各阶段的年度主题热度
print("计算年度主题热度...")
heat_first = calculate_yearly_topic_heat(papers_18_19, '第一阶段')
heat_second = calculate_yearly_topic_heat(papers_20_22, '第二阶段')
heat_third = calculate_yearly_topic_heat(papers_23_24, '第三阶段')

print("第一阶段年度主题热度：")
print(heat_first)
print("\n第二阶段年度主题热度：")
print(heat_second)
print("\n第三阶段年度主题热度：")
print(heat_third)

# 重新为每个数据框添加年份列
print("为各阶段数据添加年份列...")
papers_18_19['year'] = papers_18_19['time'].apply(extract_year)
papers_20_22['year'] = papers_20_22['time'].apply(extract_year)
papers_23_24['year'] = papers_23_24['time'].apply(extract_year)

# 过滤有效年份
papers_18_19 = papers_18_19.dropna(subset=['year'])
papers_20_22 = papers_20_22.dropna(subset=['year'])
papers_23_24 = papers_23_24.dropna(subset=['year'])

print(f"第一阶段有效文档数：{len(papers_18_19)}")
print(f"第二阶段有效文档数：{len(papers_20_22)}")
print(f"第三阶段有效文档数：{len(papers_23_24)}")

# 定义函数计算文档的主题分布
def get_document_topic_distribution(ldamodel, corpus):
    """获取所有文档的主题分布"""
    doc_topic_distributions = []
    for doc in corpus:
        # 获取文档的主题分布
        topic_dist = ldamodel.get_document_topics(doc, minimum_probability=0)
        # 转换为概率向量
        topic_probs = [prob for _, prob in topic_dist]
        doc_topic_distributions.append(topic_probs)
    return doc_topic_distributions

# 为每个阶段计算文档主题分布
print("计算文档主题分布...")
doc_topics_first = get_document_topic_distribution(ldamodel_First, corpus_First)
doc_topics_second = get_document_topic_distribution(ldamodel_Second, corpus_Second)
doc_topics_third = get_document_topic_distribution(ldamodel_Third, corpus_Third)

# 将主题分布添加到对应的数据框中
papers_18_19['topic_distribution'] = doc_topics_first
papers_20_22['topic_distribution'] = doc_topics_second  
papers_23_24['topic_distribution'] = doc_topics_third

# 计算年度主题热度
def calculate_yearly_topic_heat(df, period_name, num_topics=2):
    """计算指定阶段的年度主题热度"""
    yearly_heat = {}
    
    for year in sorted(df['year'].unique()):
        year_data = df[df['year'] == year]
        year_heat = [0] * num_topics
        
        for topic_dist in year_data['topic_distribution']:
            for topic_idx, prob in enumerate(topic_dist):
                year_heat[topic_idx] += prob
        
        # 标准化为平均热度（除以文档数量）
        if len(year_data) > 0:
            year_heat = [heat / len(year_data) for heat in year_heat]
        
        yearly_heat[year] = year_heat
    
    # 转换为DataFrame
    heat_df = pd.DataFrame.from_dict(yearly_heat, orient='index')
    heat_df.columns = [f'{period_name}主题{i+1}' for i in range(num_topics)]
    heat_df.index.name = '年份'
    
    return heat_df

# 计算各阶段的年度主题热度
print("计算年度主题热度...")
heat_first = calculate_yearly_topic_heat(papers_18_19, '第一阶段')
heat_second = calculate_yearly_topic_heat(papers_20_22, '第二阶段')
heat_third = calculate_yearly_topic_heat(papers_23_24, '第三阶段')

print("第一阶段年度主题热度：")
print(heat_first)
print("\n第二阶段年度主题热度：")
print(heat_second)
print("\n第三阶段年度主题热度：")
print(heat_third)

import matplotlib.pyplot as plt
import seaborn as sns

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 创建可视化图表
fig, axes = plt.subplots(2, 2, figsize=(15, 12))

# 1. 第一阶段主题热度趋势
heat_first.plot(ax=axes[0, 0], title='第一阶段主题热度年度趋势', marker='o')
axes[0, 0].set_ylabel('主题热度')
axes[0, 0].grid(True, alpha=0.3)

# 2. 第二阶段主题热度趋势
heat_second.plot(ax=axes[0, 1], title='第二阶段主题热度年度趋势', marker='o')
axes[0, 1].set_ylabel('主题热度')
axes[0, 1].grid(True, alpha=0.3)

# 3. 第三阶段主题热度趋势
heat_third.plot(ax=axes[1, 0], title='第三阶段主题热度年度趋势', marker='o')
axes[1, 0].set_ylabel('主题热度')
axes[1, 0].grid(True, alpha=0.3)

# 4. 所有阶段主题对比（选择代表性年份）
representative_years = [2005, 2010, 2015, 2020, 2023]
all_heat = pd.concat([heat_first, heat_second, heat_third], axis=1)
all_heat_rep = all_heat.loc[representative_years].dropna()

all_heat_rep.plot(kind='bar', ax=axes[1, 1], title='代表性年份各阶段主题热度对比')
axes[1, 1].set_ylabel('主题热度')
axes[1, 1].tick_params(axis='x', rotation=45)

plt.tight_layout()
plt.show()

# 生成详细的分析报告
print("=" * 60)
print("                 年度主题热度分析报告")
print("=" * 60)

# 各阶段主题关键词分析
print("\n各阶段主题关键词：")
print("\n第一阶段主题关键词：")
for i in range(2):
    topics = ldamodel_First.print_topic(i, topn=10)
    print(f"主题{i+1}: {topics}")

print("\n第二阶段主题关键词：")
for i in range(2):
    topics = ldamodel_Second.print_topic(i, topn=10)
    print(f"主题{i+1}: {topics}")

print("\n第三阶段主题关键词：")
for i in range(2):
    topics = ldamodel_Third.print_topic(i, topn=10)
    print(f"主题{i+1}: {topics}")

# 热度分析
print("\n主题热度分析：")
print("\n第一阶段（2003-2012）：")
print(f"  主题1平均热度: {heat_first['第一阶段主题1'].mean():.4f}")
print(f"  主题2平均热度: {heat_first['第一阶段主题2'].mean():.4f}")
print(f"  主导主题: {'主题1' if heat_first['第一阶段主题1'].mean() > heat_first['第一阶段主题2'].mean() else '主题2'}")

print("\n第二阶段（2013-2021）：")
print(f"  主题1平均热度: {heat_second['第二阶段主题1'].mean():.4f}")
print(f"  主题2平均热度: {heat_second['第二阶段主题2'].mean():.4f}")
print(f"  主导主题: {'主题1' if heat_second['第二阶段主题1'].mean() > heat_second['第二阶段主题2'].mean() else '主题2'}")

print("\n第三阶段（2022-2025）：")
print(f"  主题1平均热度: {heat_third['第三阶段主题1'].mean():.4f}")
print(f"  主题2平均热度: {heat_third['第三阶段主题2'].mean():.4f}")
print(f"  主导主题: {'主题1' if heat_third['第三阶段主题1'].mean() > heat_third['第三阶段主题2'].mean() else '主题2'}")

# 保存结果到Excel
output_file = "年度主题热度分析结果.xlsx"
with pd.ExcelWriter(output_file) as writer:
    heat_first.to_excel(writer, sheet_name='第一阶段热度')
    heat_second.to_excel(writer, sheet_name='第二阶段热度')
    heat_third.to_excel(writer, sheet_name='第三阶段热度')
    
print(f"\n分析结果已保存到: {output_file}")

import matplotlib.pyplot as plt
import seaborn as sns

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 创建可视化图表
fig, axes = plt.subplots(2, 2, figsize=(15, 12))

# 1. 第一阶段主题热度趋势
heat_first.plot(ax=axes[0, 0], title='第一阶段主题热度年度趋势', marker='o')
axes[0, 0].set_ylabel('主题热度')
axes[0, 0].grid(True, alpha=0.3)

# 2. 第二阶段主题热度趋势
heat_second.plot(ax=axes[0, 1], title='第二阶段主题热度年度趋势', marker='o')
axes[0, 1].set_ylabel('主题热度')
axes[0, 1].grid(True, alpha=0.3)

# 3. 第三阶段主题热度趋势
heat_third.plot(ax=axes[1, 0], title='第三阶段主题热度年度趋势', marker='o')
axes[1, 0].set_ylabel('主题热度')
axes[1, 0].grid(True, alpha=0.3)

# 4. 所有阶段主题对比（使用实际存在的年份）
# 获取各阶段实际存在的年份
first_years = heat_first.index.tolist()
second_years = heat_second.index.tolist()
third_years = heat_third.index.tolist()

# 选择重叠的年份进行对比（如果存在）
common_years = list(set(first_years) & set(second_years) & set(third_years))
if common_years:
    common_years.sort()
    all_heat = pd.concat([heat_first, heat_second, heat_third], axis=1)
    all_heat_common = all_heat.loc[common_years]
    all_heat_common.plot(kind='bar', ax=axes[1, 1], title='共同年份各阶段主题热度对比')
else:
    # 如果没有共同年份，显示各阶段的代表性年份
    rep_years = [first_years[len(first_years)//2] if first_years else None,
                second_years[len(second_years)//2] if second_years else None,
                third_years[len(third_years)//2] if third_years else None]
    rep_years = [year for year in rep_years if year is not None]
    
    if rep_years:
        all_heat = pd.concat([heat_first, heat_second, heat_third], axis=1)
        all_heat_rep = all_heat.loc[rep_years].dropna(how='all')
        if not all_heat_rep.empty:
            all_heat_rep.plot(kind='bar', ax=axes[1, 1], title='代表性年份各阶段主题热度对比')
        else:
            axes[1, 1].text(0.5, 0.5, '无重叠年份数据', ha='center', va='center', transform=axes[1, 1].transAxes)
    else:
        axes[1, 1].text(0.5, 0.5, '无可用数据', ha='center', va='center', transform=axes[1, 1].transAxes)

axes[1, 1].set_ylabel('主题热度')
axes[1, 1].tick_params(axis='x', rotation=45)

plt.tight_layout()
plt.show()

# 生成详细的分析报告
print("=" * 60)
print("                 年度主题热度分析报告")
print("=" * 60)

# 各阶段主题关键词分析
print("\n各阶段主题关键词：")
print("\n第一阶段主题关键词：")
for i in range(2):
    topics = ldamodel_First.print_topic(i, topn=10)
    print(f"主题{i+1}: {topics}")

print("\n第二阶段主题关键词：")
for i in range(2):
    topics = ldamodel_Second.print_topic(i, topn=10)
    print(f"主题{i+1}: {topics}")

print("\n第三阶段主题关键词：")
for i in range(2):
    topics = ldamodel_Third.print_topic(i, topn=10)
    print(f"主题{i+1}: {topics}")

# 热度分析
print("\n主题热度分析：")
print("\n第一阶段：")
print(f"  年份范围: {heat_first.index.min()}-{heat_first.index.max()}")
print(f"  主题1平均热度: {heat_first['第一阶段主题1'].mean():.4f}")
print(f"  主题2平均热度: {heat_first['第一阶段主题2'].mean():.4f}")
print(f"  主导主题: {'主题1' if heat_first['第一阶段主题1'].mean() > heat_first['第一阶段主题2'].mean() else '主题2'}")

print("\n第二阶段：")
print(f"  年份范围: {heat_second.index.min()}-{heat_second.index.max()}")
print(f"  主题1平均热度: {heat_second['第二阶段主题1'].mean():.4f}")
print(f"  主题2平均热度: {heat_second['第二阶段主题2'].mean():.4f}")
print(f"  主导主题: {'主题1' if heat_second['第二阶段主题1'].mean() > heat_second['第二阶段主题2'].mean() else '主题2'}")

print("\n第三阶段：")
print(f"  年份范围: {heat_third.index.min()}-{heat_third.index.max()}")
print(f"  主题1平均热度: {heat_third['第三阶段主题1'].mean():.4f}")
print(f"  主题2平均热度: {heat_third['第三阶段主题2'].mean():.4f}")
print(f"  主导主题: {'主题1' if heat_third['第三阶段主题1'].mean() > heat_third['第三阶段主题2'].mean() else '主题2'}")

# 保存结果到Excel
output_file = "年度主题热度分析结果.xlsx"
with pd.ExcelWriter(output_file) as writer:
    heat_first.to_excel(writer, sheet_name='第一阶段热度')
    heat_second.to_excel(writer, sheet_name='第二阶段热度')
    heat_third.to_excel(writer, sheet_name='第三阶段热度')
    
print(f"\n分析结果已保存到: {output_file}")

# 显示各阶段的热度数据
print("\n详细热度数据：")
print("\n第一阶段热度数据：")
print(heat_first)
print("\n第二阶段热度数据：")
print(heat_second)
print("\n第三阶段热度数据：")
print(heat_third)