一年一度的两会召开,本着什么火我们做什么的理念,这次我们瞄准的是代表提案,理论上一年有5千以上的议案,我找遍了全网,还是找不全,好吧,可能又是什么奇怪的规定。不过,找了一个神奇的网站,人大网,英文缩写是npc😅,于是写个代码把数据抓下来,看看每年代表们讨论的主题有没有什么有趣的规律。网站页面如下:
又是一通抓包操作,获取了19-24的700多个提案(话说这也太少了哈哈,仅做样例分析)。
于是使用大家喜闻乐见的大模型,使用BERT对每个提案进行encode,得到一个向量矩阵,然后使用kmeans进行无监督聚类,把不同年代的提案打上text注记,如下所示:
看起来也没有啥时间变化模式,于是使用LDA来进行主题聚类。
19年代表提案(文化、教育、养老)
20年代表提案(国家、社区、扶贫)
21年代表提案(发展、治理、十四五)
22年代表提案(教育、农村、乡村)
23年代表提案(文化、养老、企业)
24年代表提案(农业、立法、乡村)
这个结果好无聊,感觉翻来覆去都是农业, 养老,扶贫等等,理论上,这几年社会形式变化这么快,随着时间变化肯定有很多有意思的提案,可惜不公开。那这个数据应该没有新闻联播文本更有分析价值,因为这个数据是官方筛选过的,数据bias很高。最后则是告诉大家好消息,公众号有留言功能啦,欢迎大家留言拍砖hhh~
另外记得我们下周六晚上的茶话会,两位老师前沿的分享!
附送本文所使用的数据抓取代码。
import requests
from bs4 import BeautifulSoup
article=[]
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 sqlite3
conn = 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=0
for 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 SentenceTransformer
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from 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()
import jieba
from gensim import corpora, models
import pyLDAvis.gensim_models as gensimvis
import pyLDAvis
import pandas as pd
import numpy as np
# 假设 df 是包含所有文档的 DataFrame
df = 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)