-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
134 lines (105 loc) · 4.05 KB
/
Copy pathapp.py
File metadata and controls
134 lines (105 loc) · 4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import sqlite3
import joblib
import jieba
import os
import numpy as np
from flask import Flask, jsonify, request, send_from_directory
from flask_cors import CORS
from collections import Counter
from datetime import datetime, timedelta
# === 配置 ===
app = Flask(__name__, static_folder='static')
CORS(app)
DB_NAME = 'database.db'
MODEL_PATH = 'models/sentiment_nb.pkl'
# === 1. 加载模型 ===
model = None
if os.path.exists(MODEL_PATH):
try:
model = joblib.load(MODEL_PATH)
print("✅ 后端: 情感模型加载成功")
except Exception as e:
print(f"❌ 模型加载失败: {e}")
else:
print("⚠️ 警告: 未找到模型文件,预测功能将不可用")
def get_db_connection():
conn = sqlite3.connect(DB_NAME)
conn.row_factory = sqlite3.Row
return conn
@app.route('/')
def index():
return send_from_directory('.', 'index.html')
# === 4. API: 仪表盘数据 (已修改为真实数据统计) ===
@app.route('/api/dashboard')
def get_dashboard_data():
try:
conn = get_db_connection()
cursor = conn.cursor()
# A. 总数
cursor.execute("SELECT COUNT(*) FROM posts")
total_posts = cursor.fetchone()[0]
# B. 来源
cursor.execute("SELECT source, COUNT(*) FROM posts GROUP BY source")
sources = dict(cursor.fetchall())
# C. 情感分布
cursor.execute("SELECT sentiment_label, COUNT(*) FROM posts GROUP BY sentiment_label")
sentiment_counts = {1: 0, 0: 0, -1: 0}
for row in cursor.fetchall():
sentiment_counts[row[0]] = row[1]
distribution = [sentiment_counts.get(1, 0), sentiment_counts.get(0, 0), sentiment_counts.get(-1, 0)]
# D. 24小时趋势 (核心修改:统计真实数据库中的时间分布)
# 获取所有帖子的时间和情感
cursor.execute("SELECT sentiment_label, publish_time FROM posts")
rows = cursor.fetchall()
# 初始化 0点到23点的桶
hours_data = {i: {'pos': 0, 'neg': 0} for i in range(24)}
for row in rows:
try:
# 数据库存的时间格式通常是 "2023-xx-xx 14:30:00"
# 我们截取字符串解析出小时 (Hour)
time_str = str(row[1])
# 解析时间对象
dt = datetime.strptime(time_str.split('.')[0], "%Y-%m-%d %H:%M:%S")
h = dt.hour
# 归类
if row[0] == 1: # 积极
hours_data[h]['pos'] += 1
elif row[0] == -1: # 消极
hours_data[h]['neg'] += 1
except Exception as e:
continue # 忽略解析错误的时间
# 整理成前端图表需要的数组格式 (按0点-23点排序)
trend_data = {
'labels': [f"{i}:00" for i in range(24)],
'pos': [hours_data[i]['pos'] for i in range(24)],
'neg': [hours_data[i]['neg'] for i in range(24)]
}
conn.close()
return jsonify({
'total': total_posts,
'sources': sources,
'distribution': distribution,
'trend': trend_data
})
except Exception as e:
print(f"Dashboard Error: {e}")
return jsonify({'error': str(e)}), 500
@app.route('/api/analyze', methods=['POST'])
def analyze_text():
data = request.json
text = data.get('text', '')
if not text or not model:
return jsonify({'error': '无输入或模型未加载'}), 400
words = " ".join(jieba.cut(text))
label_idx = model.predict([words])[0]
proba = model.predict_proba([words])[0]
label_map = {1: '积极 (Positive)', 0: '中立 (Neutral)', -1: '消极 (Negative)'}
keywords = [w for w in jieba.cut(text) if len(w) > 1][:5]
return jsonify({
'label': label_map.get(label_idx, '未知'),
'probs': {'neg': float(proba[0]), 'neu': float(proba[1]), 'pos': float(proba[2])},
'keywords': keywords
})
if __name__ == '__main__':
print("🚀 舆情系统后端已启动...")
app.run(debug=True, port=5000)