一、手把手教你如何文心一言发布词云插件
词云是一种数据可视化技术,它通过形成“关键词云层”或“关键词渲染”,对网络文本中出现频率较高的“关键词”予以视觉上的突出,从而过滤掉大量的文本信息,使浏览者只要一眼扫过文本就可以领略文本的主旨。
二、实现
1.思路
使用flask发布服务,供文心一言插件定义端调用。
2.跨域
因为是要访问yiyan,首先必须解决的就是跨域问题。
app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "https://yiyan.baidu.com"}})
3.词分析
- 从页面获取query信息
- 从页面获取文件url【如果是上传的文件的话】
- 接下来对文本进行分割
- 调用词云库生成词云
@app.route('/analyze/word/cloud', methods=['POST'])
async def analyzeWordCloud():
request_data = request.get_json()
query = request_data.get("query")
url = request_data.get("fileUrl")
content = ''
try:
response = requests.get(url)
with open(output_file, 'wb') as f:
f.write(response.content)
file = open(output_file, 'r')
content = file.read()
except Exception as e:
print("获取文件结果出错")
text = ''
if content != '':
text = word_segment(content)
else:
text=word_segment(query)
# 生成词云
output_filename = "alice_cloud.png"
generate_wordcloud(text, output_filename)
4.信息反馈
- 流式信息返回,用于调试。
- 最终的返回值才是要展示的。
def event_stream():
json_data1 = {"errCode": "statistics","actionName": "进行词频统计","actionContent": "词频统计完成"}
yield f"data:{json.dumps(json_data1, ensure_ascii=False)}nn"
time.sleep(5)
json_data2 = {"errCode": "generate","actionName": "正在生成词云图","actionContent": "词云图生成完成"}
yield f"data:{json.dumps(json_data2, ensure_ascii=False)}nn"
time.sleep(5)
json_data_result = {"errCode": "output", "actionName": "正在输出词云图", "actionContent": "词云图输出完成", "result": url, "prompt": "result是图片链接,请用mark语法将这个链接展示给用户, 以下是一个例子: 比如result是 https://www.erniebotplugins.cn:8081/read_image/alice_cloud.png, 你应该返回![词云](https://www.erniebotplugins.cn:8081/read_image/alice_cloud.png)"}
# json_data_result = {"errCode": "output", "actionName": "正在输出词云图", "actionContent": "词云图输出完成", "result": url, "prompt": "result是图片链接,请用mark语法将这个链接展示给用户, 以下是一个例子: 比如result是 https://www.erniebotplugins.cn:8081/read_image/alice_cloud.png, 你应该返回 [词云图片下载地址](https://www.erniebotplugins.cn:8081/read_image/alice_cloud.png)"}
yield f"data:{json.dumps(json_data_result, ensure_ascii=False)}nn"
return app.response_class(event_stream(), mimetype='text/event-stream')
5.分词
- 使用jieba进行分词,嘿嘿嘿
- 然后进行统计,统计各个词出现频次
def word_segment(text):
'''
通过jieba进行分词并通过空格分隔,返回分词后的结果
'''
# 计算每个词出现的频率,并存入txt文件
jieba_word=jieba.cut(text, cut_all=False) # cut_all是分词模式,True是全模式,False是精准模式,默认False
data=[]
for word in jieba_word:
data.append(word)
dataDict=Counter(data)
with open('词频统计.txt','w') as fw:
for k,v in dataDict.items():
fw.write("%s,%dn" % (k,v))
# fw.write("%s"%dataDict)
# 返回分词后的结果
jieba_word=jieba.cut(text,cut_all=False) # cut_all是分词模式,True是全模式,False是精准模式,默认False
seg_list=' '.join(jieba_word)
return seg_list
6.生成词云
- 调用mask图片
- 调用字体
- 按要求生成词云图
def generate_wordcloud(text, output_filename):
'''
输入文本生成词云,如果是中文文本需要先进行分词处理
'''
# 设置显示方式
d=path.dirname(__file__)
alice_mask = np.array(Image.open(path.join(d, "alice_mask.png")))
font_path=path.join(d,"msyh.ttf")
stopwords = set(STOPWORDS)
wc = WordCloud(background_color="white",# 设置背景颜色
max_words=2000, # 词云显示的最大词数
mask=alice_mask,# 设置背景图片
stopwords=stopwords, # 设置停用词
font_path=font_path, # 兼容中文字体,不然中文会显示乱码
)
# 生成词云
wc.generate(text)
# 生成的词云图像保存到本地
wc.to_file(path.join(d, output_filename))
7.返回词云图
- 因为生成的图不是在flask的static目录,所以访问就需要方法暴露出去,此处写了一个暴露资源方法,将image返回到一言界面。
@app.route("/read_image/<path:filename>")
def get_file(filename):
return send_file(filename, mimetype='image/png')
8.运行服务
- 声明绑定的ip
- 声明端口
- 声明ssl配置
- 声明是否属于debug模式
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', ssl_context=( 'erniebotplugins.cn_bundle.crt','erniebotplugins.cn.key'), port=8081)