fix: 修复特征分析页面图表 + 补充派生特征计算脚本
- src/routes.py: 补充火箭炮分析API缺失的8个字段(射速/射程/发动机/机动参数) - AnalysisPage.vue: 修复火力/机动性能图表data映射,机动图表改用双Y轴avoid ECharts渲染失败 - AlgorithmDemoPage.vue: 移除算法卡片中的平均绝对误差和均方根误差显示 - scripts/calculate_features.py: 新增派生特征计算脚本(min-max归一化评分、巡飞弹缺失字段估算)
This commit is contained in:
parent
48ba547c36
commit
ca8cf02aa4
@ -86,10 +86,7 @@
|
|||||||
<el-tag v-if="row.key === result.best_model" size="small" type="success">最佳</el-tag>
|
<el-tag v-if="row.key === result.best_model" size="small" type="success">最佳</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<strong>{{ formatScore(row.r2) }}</strong>
|
<strong>{{ formatScore(row.r2) }}</strong>
|
||||||
<div class="metric-values">
|
|
||||||
<span>平均绝对误差 {{ formatMoney(row.mae) }}</span>
|
|
||||||
<span>均方根误差 {{ formatMoney(row.rmse) }}</span>
|
|
||||||
</div>
|
|
||||||
</article>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@ -735,7 +735,13 @@ const renderCharts = () => {
|
|||||||
mobilityScore: analysisResult.value.mobility_score || [],
|
mobilityScore: analysisResult.value.mobility_score || [],
|
||||||
deploymentScore: analysisResult.value.deployment_score || [],
|
deploymentScore: analysisResult.value.deployment_score || [],
|
||||||
terrainScore: analysisResult.value.terrain_adaptability_score || [],
|
terrainScore: analysisResult.value.terrain_adaptability_score || [],
|
||||||
combatReadinessScore: analysisResult.value.combat_readiness_score || []
|
combatReadinessScore: analysisResult.value.combat_readiness_score || [],
|
||||||
|
rocketWeight: analysisResult.value.rocket_weight_kg || [],
|
||||||
|
rocketDiameter: analysisResult.value.rocket_diameter_mm || [],
|
||||||
|
rocketLength: analysisResult.value.rocket_length_m || [],
|
||||||
|
speedKmh: analysisResult.value.speed_kmh || [],
|
||||||
|
powerHp: analysisResult.value.power_hp || [],
|
||||||
|
travelRangeKm: analysisResult.value.travel_range_km || []
|
||||||
}
|
}
|
||||||
|
|
||||||
// 火力性能分析图表配置
|
// 火力性能分析图表配置
|
||||||
@ -849,7 +855,7 @@ const renderCharts = () => {
|
|||||||
top: 30,
|
top: 30,
|
||||||
data: [
|
data: [
|
||||||
'机动性评分', '部署评分', '地形适应性评分', '战备状态评分',
|
'机动性评分', '部署评分', '地形适应性评分', '战备状态评分',
|
||||||
'行驶速度', '功率', '行程' // 新增参数
|
'行驶速度', '功率', '行程'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
@ -861,12 +867,20 @@ const renderCharts = () => {
|
|||||||
type: 'category',
|
type: 'category',
|
||||||
data: chartData.names
|
data: chartData.names
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: [
|
||||||
type: 'value',
|
{
|
||||||
name: '评分',
|
type: 'value',
|
||||||
min: 0,
|
name: '评分',
|
||||||
max: 10
|
position: 'left',
|
||||||
},
|
min: 0,
|
||||||
|
max: 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
name: '速度/功率/行程',
|
||||||
|
position: 'right'
|
||||||
|
}
|
||||||
|
],
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name: '机动性评分',
|
name: '机动性评分',
|
||||||
@ -891,16 +905,19 @@ const renderCharts = () => {
|
|||||||
{
|
{
|
||||||
name: '行驶速度',
|
name: '行驶速度',
|
||||||
type: 'line',
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
data: chartData.speedKmh
|
data: chartData.speedKmh
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '功率',
|
name: '功率',
|
||||||
type: 'line',
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
data: chartData.powerHp
|
data: chartData.powerHp
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '行程',
|
name: '行程',
|
||||||
type: 'line',
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
data: chartData.travelRangeKm
|
data: chartData.travelRangeKm
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
383
scripts/calculate_features.py
Normal file
383
scripts/calculate_features.py
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
"""
|
||||||
|
计算并填充数据库中的派生/计算特征字段,包括:
|
||||||
|
1. 火箭炮:火力密度、射程比、各项评分
|
||||||
|
2. 巡飞弹:长宽比、重量射程比等 + 估算缺失的原始字段
|
||||||
|
(engine_power_kw, engine_thrust_n, min/max_altitude_m,
|
||||||
|
guidance_accuracy_m, datalink_range_km)
|
||||||
|
|
||||||
|
用法:
|
||||||
|
python -m scripts.calculate_features
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import math
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
|
|
||||||
|
from src.database.db_connection import get_db_connection, init_db
|
||||||
|
from src.logger import setup_logger
|
||||||
|
|
||||||
|
logger = setup_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def clamp(value, low=1, high=10):
|
||||||
|
return max(low, min(high, value))
|
||||||
|
|
||||||
|
|
||||||
|
def safe_float(val, default=0.0):
|
||||||
|
if val is None:
|
||||||
|
return default
|
||||||
|
return float(val)
|
||||||
|
|
||||||
|
|
||||||
|
# ────────────────────────────────────────────────
|
||||||
|
# 火箭炮
|
||||||
|
# ────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def calculate_rocket_features(conn):
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT rap.id, rap.equipment_id,
|
||||||
|
rap.rate_of_fire, rap.rocket_weight_kg, rap.rocket_length_m,
|
||||||
|
rap.rocket_diameter_mm, rap.min_range_km, rap.max_range_km,
|
||||||
|
rap.speed_kmh, rap.power_hp, rap.combat_weight_kg,
|
||||||
|
rap.travel_range_km, rap.firing_angle_horizontal,
|
||||||
|
rap.firing_angle_vertical,
|
||||||
|
cp.length_m, cp.width_m, cp.weight_kg
|
||||||
|
FROM rocket_artillery_params rap
|
||||||
|
LEFT JOIN common_params cp ON rap.equipment_id = cp.equipment_id
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
|
||||||
|
# ── 第一遍:收集原始值,计算 min/max(用于归一化)──
|
||||||
|
all_vals = {
|
||||||
|
'spd': [], 'power_ratio': [], 'tr': [],
|
||||||
|
'angle_cov': [], 'deploy_factor': [], 'rof': [],
|
||||||
|
'cw': []
|
||||||
|
}
|
||||||
|
for row in rows:
|
||||||
|
spd = safe_float(row['speed_kmh'])
|
||||||
|
pwr = safe_float(row['power_hp'])
|
||||||
|
cw = safe_float(row['combat_weight_kg'])
|
||||||
|
tr = safe_float(row['travel_range_km'])
|
||||||
|
ah = safe_float(row['firing_angle_horizontal'])
|
||||||
|
av = safe_float(row['firing_angle_vertical'])
|
||||||
|
rof = safe_float(row['rate_of_fire'])
|
||||||
|
|
||||||
|
all_vals['spd'].append(spd)
|
||||||
|
all_vals['power_ratio'].append(pwr / max(1, cw))
|
||||||
|
all_vals['tr'].append(tr)
|
||||||
|
all_vals['angle_cov'].append((ah / 360) * (av / 90))
|
||||||
|
all_vals['deploy_factor'].append(1.0 / max(1, cw)) # 越小越难部署
|
||||||
|
all_vals['rof'].append(rof)
|
||||||
|
all_vals['cw'].append(cw)
|
||||||
|
|
||||||
|
def norm10(v, vals):
|
||||||
|
"""Min-max 归一化到 1-10"""
|
||||||
|
mn, mx = min(vals), max(vals)
|
||||||
|
span = mx - mn
|
||||||
|
if span == 0:
|
||||||
|
return 5.0
|
||||||
|
return 1.0 + (v - mn) / span * 9.0
|
||||||
|
|
||||||
|
# ── 第二遍:逐条计算并更新 ──
|
||||||
|
updates = []
|
||||||
|
|
||||||
|
for row in rows:
|
||||||
|
rof = safe_float(row['rate_of_fire'])
|
||||||
|
rw = safe_float(row['rocket_weight_kg'])
|
||||||
|
rl = safe_float(row['rocket_length_m'])
|
||||||
|
rd = safe_float(row['rocket_diameter_mm'])
|
||||||
|
min_r = safe_float(row['min_range_km'])
|
||||||
|
max_r = safe_float(row['max_range_km'])
|
||||||
|
spd = safe_float(row['speed_kmh'])
|
||||||
|
pwr = safe_float(row['power_hp'])
|
||||||
|
cw = safe_float(row['combat_weight_kg'])
|
||||||
|
tr = safe_float(row['travel_range_km'])
|
||||||
|
ah = safe_float(row['firing_angle_horizontal'])
|
||||||
|
av = safe_float(row['firing_angle_vertical'])
|
||||||
|
|
||||||
|
# 火力密度 (kg/min)
|
||||||
|
fire_density = round(rw * rof, 2)
|
||||||
|
|
||||||
|
# 射程比
|
||||||
|
range_ratio = round(max_r / max(1, min_r), 4)
|
||||||
|
|
||||||
|
# 火箭弹功重比
|
||||||
|
if rd > 0 and rl > 0:
|
||||||
|
rocket_power_ratio = round((rw * rl * rof) / (rd * 10), 4)
|
||||||
|
else:
|
||||||
|
rocket_power_ratio = 0.0
|
||||||
|
|
||||||
|
# 平台效率 (m/kg)
|
||||||
|
platform_efficiency = round(max_r / max(1, cw) * 1000, 4)
|
||||||
|
|
||||||
|
power_ratio = pwr / max(1, cw)
|
||||||
|
angle_cov = (ah / 360) * (av / 90)
|
||||||
|
deploy_factor = 1.0 / max(1, cw)
|
||||||
|
|
||||||
|
# 机动性评分 (1-10):综合速度、功重比、行程,min-max 归一化
|
||||||
|
s_speed = norm10(spd, all_vals['spd'])
|
||||||
|
s_power = norm10(power_ratio, all_vals['power_ratio'])
|
||||||
|
s_range = norm10(tr, all_vals['tr'])
|
||||||
|
mobility_score = int(round((s_speed + s_power + s_range) / 3))
|
||||||
|
|
||||||
|
# 战备状态评分 (1-10):射界覆盖、部署便捷度(轻量化)、射速
|
||||||
|
s_angle = norm10(angle_cov, all_vals['angle_cov'])
|
||||||
|
s_deploy = norm10(deploy_factor, all_vals['deploy_factor'])
|
||||||
|
s_rof = norm10(rof, all_vals['rof'])
|
||||||
|
combat_readiness_score = int(round((s_angle + s_deploy + s_rof) / 3))
|
||||||
|
|
||||||
|
# 部署评分 (1-10):轻量化 + 速度
|
||||||
|
s_weight = 11.0 - norm10(cw, all_vals['cw']) # 越轻越高
|
||||||
|
s_speed2 = norm10(spd, all_vals['spd'])
|
||||||
|
deployment_score = int(round((s_weight + s_speed2) / 2))
|
||||||
|
|
||||||
|
# 地形适应性评分 (1-10):功重比 + 速度
|
||||||
|
terrain_score = int(round((s_power + s_speed2) / 2))
|
||||||
|
|
||||||
|
updates.append((
|
||||||
|
fire_density, range_ratio, mobility_score,
|
||||||
|
combat_readiness_score, deployment_score, terrain_score,
|
||||||
|
rocket_power_ratio, platform_efficiency,
|
||||||
|
row['id']
|
||||||
|
))
|
||||||
|
|
||||||
|
if updates:
|
||||||
|
cursor.executemany("""
|
||||||
|
UPDATE rocket_artillery_params
|
||||||
|
SET fire_density = ?, range_ratio = ?, mobility_score = ?,
|
||||||
|
combat_readiness_score = ?, deployment_score = ?,
|
||||||
|
terrain_adaptability_score = ?, rocket_power_ratio = ?,
|
||||||
|
platform_efficiency = ?
|
||||||
|
WHERE id = ?
|
||||||
|
""", updates)
|
||||||
|
logger.info(f"火箭炮:更新了 {len(updates)} 条记录")
|
||||||
|
|
||||||
|
return len(updates)
|
||||||
|
|
||||||
|
|
||||||
|
# ────────────────────────────────────────────────
|
||||||
|
# 巡飞弹
|
||||||
|
# ────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def estimate_guidance_accuracy(guidance_system):
|
||||||
|
"""根据制导系统文字估算制导精度 (m)"""
|
||||||
|
gs = (guidance_system or '').lower()
|
||||||
|
# 统计制导模式数量作为精度指标
|
||||||
|
modes = [m.strip() for m in guidance_system.split('/') if m.strip()] if guidance_system else []
|
||||||
|
mode_count = len(modes)
|
||||||
|
|
||||||
|
# 基础精度:模式越多越精确
|
||||||
|
base_accuracy = {
|
||||||
|
1: 50, 2: 30, 3: 20, 4: 15, 5: 10, 6: 5, 7: 3, 8: 2, 9: 1.5, 10: 1,
|
||||||
|
}.get(mode_count, max(1, 60 - mode_count * 6))
|
||||||
|
|
||||||
|
# 根据制导类型微调
|
||||||
|
if any(k in gs for k in ['卫星', 'satellite', 'gps']):
|
||||||
|
base_accuracy = max(3, base_accuracy * 0.7)
|
||||||
|
if any(k in gs for k in ['激光', 'laser']):
|
||||||
|
base_accuracy = max(1, base_accuracy * 0.4)
|
||||||
|
if any(k in gs for k in ['红外', 'infrared', 'ir', '光电']):
|
||||||
|
base_accuracy = max(2, base_accuracy * 0.6)
|
||||||
|
if any(k in gs for k in ['雷达', 'radar']):
|
||||||
|
base_accuracy = max(5, base_accuracy * 0.8)
|
||||||
|
if any(k in gs for k in ['ai', '辅助']):
|
||||||
|
base_accuracy = base_accuracy * 0.8
|
||||||
|
|
||||||
|
return round(base_accuracy, 1)
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_guidance_score(guidance_system, estimated_accuracy):
|
||||||
|
"""计算制导系统评分 (1-10)"""
|
||||||
|
gs = (guidance_system or '').lower()
|
||||||
|
modes = [m.strip() for m in guidance_system.split('/') if m.strip()] if guidance_system else []
|
||||||
|
|
||||||
|
# 制导模式数量 (1-7 映射到 1-6 分)
|
||||||
|
mode_score = clamp(len(modes) / 2, 0.5, 6)
|
||||||
|
|
||||||
|
# 精度分 (精度越高分越高)
|
||||||
|
if estimated_accuracy <= 3:
|
||||||
|
accuracy_score = 5
|
||||||
|
elif estimated_accuracy <= 5:
|
||||||
|
accuracy_score = 4.5
|
||||||
|
elif estimated_accuracy <= 10:
|
||||||
|
accuracy_score = 4
|
||||||
|
elif estimated_accuracy <= 20:
|
||||||
|
accuracy_score = 3
|
||||||
|
elif estimated_accuracy <= 30:
|
||||||
|
accuracy_score = 2
|
||||||
|
elif estimated_accuracy <= 50:
|
||||||
|
accuracy_score = 1
|
||||||
|
else:
|
||||||
|
accuracy_score = 0.5
|
||||||
|
|
||||||
|
# 高端制导方式加成
|
||||||
|
high_end_bonus = 0
|
||||||
|
if any(k in gs for k in ['卫星', 'satellite']):
|
||||||
|
high_end_bonus += 0.5
|
||||||
|
|
||||||
|
return int(round(clamp(mode_score + accuracy_score + high_end_bonus, 1, 10)))
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_warhead_score(warhead_type, warhead_weight_kg):
|
||||||
|
"""计算战斗部威力评分 (1-10)"""
|
||||||
|
wt_lower = (warhead_type or '').lower()
|
||||||
|
|
||||||
|
# 重量得分: 5kg→2, 10kg→4, 20kg→6, 30kg→8, 50kg→10
|
||||||
|
weight_score = clamp(warhead_weight_kg * 0.2, 1, 10)
|
||||||
|
|
||||||
|
# 类型加成
|
||||||
|
type_kw_scores = {
|
||||||
|
'模块化': 3, 'modular': 3,
|
||||||
|
'高爆': 2, 'explosive': 2, 'he': 2,
|
||||||
|
'云爆': 3, 'thermobaric': 3,
|
||||||
|
'破片杀伤': 1.5, 'fragmentation': 1.5,
|
||||||
|
'穿甲': 2.5, 'armor': 2.5, 'penetrat': 2.5,
|
||||||
|
'动能': 2, 'kinetic': 2,
|
||||||
|
'双用': 2, 'dual': 2,
|
||||||
|
'破甲': 2, 'heat': 2,
|
||||||
|
'子母': 2, 'cluster': 2, 'submunition': 2
|
||||||
|
}
|
||||||
|
type_bonus = 0
|
||||||
|
for kw, val in type_kw_scores.items():
|
||||||
|
if kw in wt_lower:
|
||||||
|
type_bonus = max(type_bonus, val)
|
||||||
|
|
||||||
|
return int(round(clamp(weight_score + type_bonus, 1, 10)))
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_loitering_features(conn):
|
||||||
|
"""计算巡飞弹的派生特征 + 估算缺失的原始字段"""
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT lmp.id, lmp.equipment_id,
|
||||||
|
lmp.wingspan_m, lmp.warhead_weight_kg, lmp.max_speed_ms,
|
||||||
|
lmp.max_range_km, lmp.guidance_accuracy_m, lmp.datalink_range_km,
|
||||||
|
lmp.engine_power_kw, lmp.engine_thrust_n,
|
||||||
|
lmp.min_altitude_m, lmp.max_altitude_m,
|
||||||
|
lmp.guidance_system, lmp.warhead_type,
|
||||||
|
lmp.cruise_speed_kmh, lmp.endurance_min,
|
||||||
|
lmp.ceiling_altitude_m, lmp.max_payload_kg,
|
||||||
|
lmp.combat_radius_km,
|
||||||
|
cp.length_m, cp.width_m, cp.weight_kg
|
||||||
|
FROM loitering_munition_params lmp
|
||||||
|
LEFT JOIN common_params cp ON lmp.equipment_id = cp.equipment_id
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
updates = []
|
||||||
|
|
||||||
|
for row in rows:
|
||||||
|
length = safe_float(row['length_m'])
|
||||||
|
width = safe_float(row['width_m'])
|
||||||
|
weight = safe_float(row['weight_kg'])
|
||||||
|
warhead_weight = safe_float(row['warhead_weight_kg'])
|
||||||
|
max_speed = safe_float(row['max_speed_ms'])
|
||||||
|
cruise_speed = safe_float(row['cruise_speed_kmh'])
|
||||||
|
max_range = safe_float(row['max_range_km'])
|
||||||
|
endurance = safe_float(row['endurance_min'])
|
||||||
|
ceiling = safe_float(row['ceiling_altitude_m'])
|
||||||
|
payload = safe_float(row['max_payload_kg'])
|
||||||
|
combat_radius = safe_float(row['combat_radius_km'])
|
||||||
|
guidance_system = row['guidance_system'] or ''
|
||||||
|
warhead_type = row['warhead_type'] or ''
|
||||||
|
|
||||||
|
# ── 1. 长宽比 ──
|
||||||
|
length_width_ratio = round(length / max(0.1, width), 4)
|
||||||
|
|
||||||
|
# ── 2. 重量射程比 (kg/km) ──
|
||||||
|
weight_range_ratio = round(weight / max(1, max_range), 4)
|
||||||
|
|
||||||
|
# ── 3. 速度重量比 ──
|
||||||
|
speed_weight_ratio = round(max_speed / max(1, weight), 4)
|
||||||
|
|
||||||
|
# ── 4. 估算缺失的原始字段 ──
|
||||||
|
|
||||||
|
# 制导精度 (m):当前全为 0,根据制导系统文字估算
|
||||||
|
estimated_accuracy = estimate_guidance_accuracy(guidance_system)
|
||||||
|
|
||||||
|
# 数据链距离 (km):用战斗半径或最大射程的 80% 估算
|
||||||
|
base_ref = combat_radius if combat_radius > 0 else max_range
|
||||||
|
estimated_datalink = round(base_ref * 0.85, 1)
|
||||||
|
|
||||||
|
# 发动机功率 (kw):基于重量和速度估算
|
||||||
|
# 小型无人机/巡飞弹功率密度约 0.05-0.3 kW/kg
|
||||||
|
total_weight = weight + payload
|
||||||
|
power_density = 0.08 + (max_speed / 200) * 0.12 # 越快功率密度越高
|
||||||
|
power_density = min(power_density, 0.28) # 上限避免重型弹药估算过高
|
||||||
|
estimated_engine_kw = round(total_weight * power_density, 1)
|
||||||
|
|
||||||
|
# 发动机推力 (N):基于总重估算,推力 ≈ 重量 * 推重比
|
||||||
|
# 巡飞弹推重比通常 0.2-0.5,但重型滑翔弹药不具备大推力发动机
|
||||||
|
thrust_ratio = 0.15 + (max_speed / 150) * 0.20
|
||||||
|
thrust_ratio = min(thrust_ratio, 0.3) # 上限
|
||||||
|
estimated_thrust_n = round(total_weight * 9.8 * thrust_ratio, 1)
|
||||||
|
|
||||||
|
# 最小作战高度 (m):巡飞弹通常 50-500m
|
||||||
|
if cruise_speed > 0:
|
||||||
|
estimated_min_alt = round(max(30, min(300, cruise_speed * 0.8)), 0)
|
||||||
|
else:
|
||||||
|
estimated_min_alt = round(max(30, min(300, max_speed * 2.5)), 0)
|
||||||
|
|
||||||
|
# 最大作战高度 (m):优先用 ceiling_altitude_m,否则估算
|
||||||
|
if ceiling > 0:
|
||||||
|
estimated_max_alt = ceiling
|
||||||
|
else:
|
||||||
|
estimated_max_alt = round(max(500, min(10000, endurance * 15)), 0)
|
||||||
|
|
||||||
|
# ── 5. 制导系统评分 (1-10) ──
|
||||||
|
guidance_system_score = calculate_guidance_score(guidance_system, estimated_accuracy)
|
||||||
|
|
||||||
|
# ── 6. 战斗部威力评分 (1-10) ──
|
||||||
|
warhead_power_score = calculate_warhead_score(warhead_type, warhead_weight)
|
||||||
|
|
||||||
|
updates.append((
|
||||||
|
length_width_ratio, weight_range_ratio, speed_weight_ratio,
|
||||||
|
guidance_system_score, warhead_power_score,
|
||||||
|
estimated_accuracy, estimated_datalink,
|
||||||
|
estimated_engine_kw, estimated_thrust_n,
|
||||||
|
estimated_min_alt, estimated_max_alt,
|
||||||
|
row['id']
|
||||||
|
))
|
||||||
|
|
||||||
|
if updates:
|
||||||
|
cursor.executemany("""
|
||||||
|
UPDATE loitering_munition_params
|
||||||
|
SET length_width_ratio = ?, weight_range_ratio = ?,
|
||||||
|
speed_weight_ratio = ?, guidance_system_score = ?,
|
||||||
|
warhead_power_score = ?,
|
||||||
|
guidance_accuracy_m = ?, datalink_range_km = ?,
|
||||||
|
engine_power_kw = ?, engine_thrust_n = ?,
|
||||||
|
min_altitude_m = ?, max_altitude_m = ?
|
||||||
|
WHERE id = ?
|
||||||
|
""", updates)
|
||||||
|
logger.info(f"巡飞弹:更新了 {len(updates)} 条记录")
|
||||||
|
|
||||||
|
return len(updates)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
init_db()
|
||||||
|
conn = None
|
||||||
|
try:
|
||||||
|
with get_db_connection() as conn:
|
||||||
|
rc = calculate_rocket_features(conn)
|
||||||
|
lc = calculate_loitering_features(conn)
|
||||||
|
conn.commit()
|
||||||
|
print(f"\n完成!")
|
||||||
|
print(f" 火箭炮:{rc} 条记录已更新")
|
||||||
|
print(f" 巡飞弹:{lc} 条记录已更新")
|
||||||
|
except Exception as e:
|
||||||
|
if conn:
|
||||||
|
conn.rollback()
|
||||||
|
logger.error(f"特征计算失败: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@ -259,7 +259,15 @@ def analyze_features():
|
|||||||
'mobility_score': [float(item['mobility_score']) if item['mobility_score'] is not None else 0 for item in equipment_data],
|
'mobility_score': [float(item['mobility_score']) if item['mobility_score'] is not None else 0 for item in equipment_data],
|
||||||
'combat_readiness_score': [float(item['combat_readiness_score']) if item['combat_readiness_score'] is not None else 0 for item in equipment_data],
|
'combat_readiness_score': [float(item['combat_readiness_score']) if item['combat_readiness_score'] is not None else 0 for item in equipment_data],
|
||||||
'deployment_score': [float(item['deployment_score']) if item['deployment_score'] is not None else 0 for item in equipment_data],
|
'deployment_score': [float(item['deployment_score']) if item['deployment_score'] is not None else 0 for item in equipment_data],
|
||||||
'terrain_adaptability_score': [float(item['terrain_adaptability_score']) if item['terrain_adaptability_score'] is not None else 0 for item in equipment_data]
|
'terrain_adaptability_score': [float(item['terrain_adaptability_score']) if item['terrain_adaptability_score'] is not None else 0 for item in equipment_data],
|
||||||
|
'rate_of_fire': [float(item['rate_of_fire']) if item['rate_of_fire'] is not None else 0 for item in equipment_data],
|
||||||
|
'max_range_km': [float(item['max_range_km']) if item['max_range_km'] is not None else 0 for item in equipment_data],
|
||||||
|
'rocket_length_m': [float(item['rocket_length_m']) if item['rocket_length_m'] is not None else 0 for item in equipment_data],
|
||||||
|
'rocket_diameter_mm': [float(item['rocket_diameter_mm']) if item['rocket_diameter_mm'] is not None else 0 for item in equipment_data],
|
||||||
|
'rocket_weight_kg': [float(item['rocket_weight_kg']) if item['rocket_weight_kg'] is not None else 0 for item in equipment_data],
|
||||||
|
'speed_kmh': [float(item['speed_kmh']) if item['speed_kmh'] is not None else 0 for item in equipment_data],
|
||||||
|
'power_hp': [float(item['power_hp']) if item['power_hp'] is not None else 0 for item in equipment_data],
|
||||||
|
'travel_range_km': [float(item['travel_range_km']) if item['travel_range_km'] is not None else 0 for item in equipment_data],
|
||||||
}
|
}
|
||||||
analysis_result.update(rocket_data)
|
analysis_result.update(rocket_data)
|
||||||
else:
|
else:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user