分析700份代表提案,看看两会大家关心什么!

文摘   教育   2024-03-16 00:00   中国香港  

     一年一度的两会召开,本着什么火我们做什么的理念,这次我们瞄准的是代表提案,理论上一年有5千以上的议案,我找遍了全网,还是找不全,好吧,可能又是什么奇怪的规定。不过,找了一个神奇的网站,人大网,英文缩写是npc😅,于是写个代码把数据抓下来,看看每年代表们讨论的主题有没有什么有趣的规律。网站页面如下:

    又是一通抓包操作,获取了19-24的700多个提案(话说这也太少了哈哈,仅做样例分析)。

于是使用大家喜闻乐见的大模型,使用BERT对每个提案进行encode,得到一个向量矩阵,然后使用kmeans进行无监督聚类,把不同年代的提案打上text注记,如下所示:

    看起来也没有啥时间变化模式,于是使用LDA来进行主题聚类。

19年代表提案(文化、教育、养老)

20年代表提案(国家、社区、扶贫)

21年代表提案(发展、治理、十四五)

22年代表提案(教育、农村、乡村)

23年代表提案(文化、养老、企业)

24年代表提案(农业、立法、乡村)

   这个结果好无聊,感觉翻来覆去都是农业, 养老,扶贫等等,理论上,这几年社会形式变化这么快,随着时间变化肯定有很多有意思的提案,可惜不公开。那这个数据应该没有新闻联播文本更有分析价值,因为这个数据是官方筛选过的,数据bias很高。最后则是告诉大家好消息,公众号有留言功能啦,欢迎大家留言拍砖hhh~

    另外记得我们下周六晚上的茶话会,两位老师前沿的分享!

GISChat茶话会第五期-前沿研究分享(下周六晚!)

附送本文所使用的数据抓取代码

import requestsfrom bs4 import BeautifulSouparticle=[]for i in  range(1,34):#34    url=r'http://www.npc.gov.cn/npc/c2/c185/c12492/index_{}.html'.format(i)    r=requests.get(url)    r.encoding='utf-8'    html_string=r.text
soup = BeautifulSoup(html_string, 'html.parser') title = soup.title.text
# 获取所有a标签 a_tags = soup.find_all('a') for a in a_tags: url = a['href'] text = a.text print(url, text) article.append(a['href'])###过滤字符new=[]for i in article: if len(i)>13: tmp=i.replace('../../../','').replace('../../','').replace('./','') new.append(tmp)#写入数据import re,time#写入sqlite数据库import sqlite3conn = sqlite3.connect('npc.db')c = conn.cursor()c.execute('CREATE TABLE npc (date TEXT, content TEXT)')# 提交更改conn.commit()
# 关闭连接# "http://www.npc.gov.cn/npc/c2/c30834/201905/t20190521_297075.html"times=[]contents=[]
count=0for i in new: try: res=requests.get("http://www.npc.gov.cn/npc/c2/"+i) html=res.content.decode('utf-8') pattern = r'(\d{4}年\d{2}月\d{2}日)' match = re.search(pattern,html) if match: date = match.group(0) else: date = None times.append(date)
soup = BeautifulSoup(res.content, 'html.parser') content_div = soup.find('div', id='Zoom') content = content_div.get_text() content = content.strip().replace('\n', '').replace('\r', '').replace('\t', '').replace('\u3000', '') contents.append(content) # 写入数据 c.execute("INSERT INTO npc VALUES (?,?)", (date, content))
except Exception as e: time.sleep(2) print(e) print("http://www.npc.gov.cn/npc/c2/"+i) count+=1 if count%100==0: conn.commit() conn.commit()# 关闭连接conn.close()print("Data written to database!")

绘图代码:

from sentence_transformers import SentenceTransformerfrom sklearn.cluster import KMeansimport matplotlib.pyplot as pltfrom sklearn.manifold import TSNE
# 你的数据documents = [...]years = [...]

# 加载 Sentence-BERT 模型model = SentenceTransformer('all-MiniLM-L6-v2')
# 对文档进行编码document_embeddings = model.encode(documents)
# 使用 KMeans 进行聚类num_clusters = 6 # 根据需要调整聚类数目clustering_model = KMeans(n_clusters=num_clusters)clustering_model.fit(document_embeddings)cluster_assignment = clustering_model.labels_
# 使用 t-SNE 进行降维tsne = TSNE(n_components=2, random_state=0)X_tsne = tsne.fit_transform(document_embeddings)
# 可视化plt.figure(figsize=(12, 8))for i in range(num_clusters): indices = cluster_assignment == i plt.scatter(X_tsne[indices, 0], X_tsne[indices, 1], label=f'Cluster {i}') for year, x, y in zip(np.array(years)[indices], X_tsne[indices, 0], X_tsne[indices, 1]): plt.text(x, y, year, fontsize=6)plt.legend()plt.show()
LDA聚类代码:
import jiebafrom gensim import corpora, modelsimport pyLDAvis.gensim_models as gensimvisimport pyLDAvisimport pandas as pdimport numpy as np
# 假设 df 是包含所有文档的 DataFramedf = pd.DataFrame({'year': years,'document':documents})# texts = [list(jieba.cut(doc)) for doc in df['document'].values.tolist()]
stopwords_file = "stopword.txt" # 假设停用词表保存在名为stopwords.txt的文件中
with open(stopwords_file, "r", encoding="utf-8") as file: stopwords_list = [line.strip() for line in file.readlines()] stopwords_list.append(' ')# 示例数据tmpf=df[df['year']=='2019']texts = [list(jieba.cut(doc)) for doc in tmpf['document'].values.tolist()] # 假设你的文本数据已经准备好了# 在分词过程中过滤停用词filtered_texts = [[word for word in text if word not in stopwords_list] for text in texts]texts=filtered_texts
dictionary = corpora.Dictionary(texts)corpus = [dictionary.doc2bow(text) for text in texts]
lda_model = models.LdaModel(corpus, num_topics=5, id2word=dictionary, passes=15)
# vis = gensimvis.prepare(lda_model, corpus, dictionary, sort_topics=False)vis = gensimvis.prepare(lda_model, corpus, dictionary, sort_topics=False, n_jobs=1)
# pyLDAvis.display(vis)pyLDAvis.display(vis)


城市感知计算
认识世界和改造世界,张岩博士和志愿者团队搭建的非盈利城市科学分享平台,欢迎加好友学术交流。
 最新文章