准确度不够,将方位、载频、脉宽相近的分为一类,请给出修改后的完整代码
时间: 2025-07-30 21:22:25 浏览: 2
<think>我们注意到用户要求将方位、载频、脉宽相近的脉冲分为一类。因此,我们需要调整特征提取和聚类部分,重点关注这三个参数(方位、载频、脉宽),并适当降低TOA相关特征的重要性。修改思路:1.特征预处理:只使用方位(1)、载频(3)、脉宽(4)这三个参数,不再使用TOA相关特征(如差分和累积值)。2.特征标准化:由于三个参数的单位和量级不同,需要标准化(这里采用鲁棒的标准化方法,即减去中位数并除以四分位距)。3.聚类算法:仍然使用DBSCAN,因为DBSCAN可以自动发现任意形状的簇,并且对噪声不敏感。4.参数选择:由于特征维度降低为3维,需要重新调整epsilon和minPts的选择策略。具体修改:-在preprocess_features函数中,只提取方位、载频、脉宽,不包含任何TOA特征。-在聚类后处理中,合并聚类时使用欧氏距离阈值,但注意特征已经是标准化后的,所以阈值可以相对固定(例如1.5)。-在可视化部分,特征空间图可以调整为方位-载频、载频-脉宽、方位-脉宽等组合。注意:由于不再使用TOA特征,因此时间序列相关的图(如TOA序列)可能不再适用,但我们可以展示其他特征的空间分布。以下是修改后的完整代码:</think>针对您提出的"将方位、载频、脉宽相近的分为一类"的要求,我修改了特征提取和聚类策略,重点关注这三个关键参数。以下是优化后的完整代码:
```matlab
function radar_sorting_main()
% 获取用户选择的文件
[file_name, path_name] = uigetfile('*.txt', '选择PDW数据文件');
if isequal(file_name, 0)
disp('用户取消了文件选择');
return;
end
full_path = fullfile(path_name, file_name);
% 1.读取数据文件
try
[data, header] = read_pdw_file(full_path);
catch ME
errordlg(sprintf('文件读取失败: %s\n错误原因: %s', full_path, ME.message), '文件错误');
return;
end
% 2.特征预处理 - 重点关注方位、载频、脉宽
features = preprocess_features(data);
% 3.聚类分选 - 使用基于方位/载频/脉宽的相似性聚类
labels = cluster_by_similarity(features);
% 4.后处理优化聚类结果
labels = postprocess_clusters(features, labels);
% 5.结果输出与可视化
save_sorted_data(data, labels, header);
plot_analysis_results(data, features, labels);
disp('雷达分选完成!');
end
function [data, header] = read_pdw_file(full_path)
% 初始化输出参数
data = [];
header = struct('pulse_count', 0);
% 尝试打开文件
fid = fopen(full_path, 'r');
if fid == -1
error('无法打开文件: %s', full_path);
end
% 使用onCleanup确保文件关闭
c = onCleanup(@() fclose(fid));
% 读取文件头(脉冲数量)
header_line = fgetl(fid);
if isempty(header_line)
error('文件为空或首行缺失');
end
header.pulse_count = str2double(header_line);
if isnan(header.pulse_count) || header.pulse_count <= 0
error('文件首行必须是有效的脉冲数量值,实际内容: %s', header_line);
end
% 读取所有数据行
formatSpec = '%f %f %f %f %f %f %f';
data_cell = textscan(fid, formatSpec, header.pulse_count, 'CollectOutput', true);
% 验证数据完整性
if isempty(data_cell) || isempty(data_cell{1})
error('未读取到任何数据');
end
data = data_cell{1};
actual_rows = size(data, 1);
% 验证数据列数
if size(data, 2) < 7
error('数据列数不足,预期7列,实际%d列', size(data, 2));
end
% 验证脉冲数量
if actual_rows < header.pulse_count
warning('数据行数(%d)少于声明脉冲数(%d),使用实际行数', actual_rows, header.pulse_count);
header.pulse_count = actual_rows;
elseif actual_rows > header.pulse_count
warning('数据行数(%d)多于声明脉冲数(%d),截断数据', actual_rows, header.pulse_count);
data = data(1:header.pulse_count, :);
end
end
function features = preprocess_features(data)
% 只提取方位(1), 载频(3), 脉宽(4) - 重点关注这三个参数
raw_features = data(:, [1, 3, 4]);
% 为每个参数计算合适的缩放因子
% 方位通常范围0-360度,但需要处理可能的跳变
azimuth = raw_features(:, 1);
azimuth_scale = 180; % 使用180度作为缩放基准
% 载频单位MHz,典型范围500-15000 MHz
rf = raw_features(:, 2);
rf_scale = 1000; % 使用1000MHz作为缩放基准
% 脉宽单位微秒,典型范围0.1-100 us
pw = raw_features(:, 3);
pw_scale = 5; % 使用5us作为缩放基准
% 应用缩放 - 使各参数具有可比性
scaled_features = [azimuth/azimuth_scale, rf/rf_scale, pw/pw_scale];
% 鲁棒标准化(避免异常值影响)
features = (scaled_features - median(scaled_features)) ./ iqr(scaled_features);
% 处理NaN值(标准化可能产生)
features(isnan(features)) = 0;
end
function labels = cluster_by_similarity(features)
% 设置相似性阈值 - 这些值可根据实际数据调整
azimuth_thresh = 0.05; % 方位角差异阈值(标准化后)
rf_thresh = 0.03; % 载频差异阈值(标准化后)
pw_thresh = 0.04; % 脉宽差异阈值(标准化后)
n = size(features, 1);
labels = zeros(n, 1); % 0表示未分类
current_label = 1;
% 创建等待处理的点队列
unprocessed = true(n, 1);
while any(unprocessed)
% 找到下一个未处理的点作为种子
seed_idx = find(unprocessed, 1);
seed_point = features(seed_idx, :);
% 创建一个新簇
cluster_points = seed_idx;
unprocessed(seed_idx) = false;
% 查找所有相似点
queue = seed_idx;
while ~isempty(queue)
current_idx = queue(1);
queue(1) = [];
% 计算当前点与所有未处理点的差异
diffs = abs(features - features(current_idx, :));
% 找到满足所有阈值条件的点
similar_mask = unprocessed & ...
(diffs(:, 1) <= azimuth_thresh) & ...
(diffs(:, 2) <= rf_thresh) & ...
(diffs(:, 3) <= pw_thresh);
% 添加符合条件的点到簇中
new_points = find(similar_mask);
cluster_points = [cluster_points; new_points];
queue = [queue; new_points];
unprocessed(new_points) = false;
end
% 分配标签
labels(cluster_points) = current_label;
current_label = current_label + 1;
end
% 统计聚类结果
unique_labels = unique(labels);
fprintf('识别到 %d 个基于方位/载频/脉宽相似的雷达簇\n', length(unique_labels));
% 显示各簇大小
for i = 1:length(unique_labels)
count = sum(labels == unique_labels(i));
fprintf('簇 %d: %d 个脉冲\n', unique_labels(i), count);
end
end
function labels = postprocess_clusters(features, labels)
% 合并非常相似的簇
unique_labels = unique(labels);
n_clusters = length(unique_labels);
if n_clusters > 1
% 计算每个簇的中心(中位数)
cluster_centers = zeros(n_clusters, size(features, 2));
for i = 1:n_clusters
idx = (labels == unique_labels(i));
cluster_centers(i, :) = median(features(idx, :));
end
% 计算簇间距离矩阵
dist_matrix = pdist2(cluster_centers, cluster_centers);
dist_matrix(logical(eye(n_clusters))) = inf; % 对角线设为无穷
% 合并距离过近的簇
merged = false(n_clusters, 1);
for i = 1:n_clusters
if merged(i), continue; end
[min_dist, min_idx] = min(dist_matrix(i, :));
if min_dist < 0.1 % 合并阈值 - 可调整
j = min_idx;
if j > i && ~merged(j)
labels(labels == unique_labels(j)) = unique_labels(i);
merged(j) = true;
fprintf('合并簇 %d 和 %d (距离=%.4f)\n', unique_labels(j), unique_labels(i), min_dist);
end
end
end
end
% 重新编号聚类标签(从1开始连续)
new_labels = zeros(size(labels));
unique_labels = unique(labels);
for i = 1:length(unique_labels)
new_labels(labels == unique_labels(i)) = i;
end
labels = new_labels;
end
function save_sorted_data(data, labels, header)
% 创建输出目录
if ~exist('sorted_results', 'dir')
mkdir('sorted_results');
end
% 分离并保存每类数据
unique_labels = unique(labels(labels > 0));
num_radars = length(unique_labels);
fprintf('最终识别到 %d 个雷达辐射源\n', num_radars);
for i = 1:num_radars
mask = (labels == unique_labels(i));
cluster_data = data(mask, :);
% 计算该簇的统计特性
azimuth = cluster_data(:, 1);
rf = cluster_data(:, 3);
pw = cluster_data(:, 4);
% 保存到文件
filename = sprintf('sorted_results/radar_%d_azi_%.1f-%.1f_rf_%.1f-%.1f.txt', ...
i, min(azimuth), max(azimuth), min(rf), max(rf));
fid = fopen(filename, 'w');
if fid == -1
error('无法创建文件: %s', filename);
end
% 写文件头(脉冲数量)
fprintf(fid, '%d\n', size(cluster_data, 1));
% 写数据行
for j = 1:size(cluster_data, 1)
fprintf(fid, '%.2f %.2f %.2f %.2f %.4f %.2f %d\n', ...
cluster_data(j, 1), cluster_data(j, 2), ...
cluster_data(j, 3), cluster_data(j, 4), ...
cluster_data(j, 5), cluster_data(j, 6), ...
cluster_data(j, 7));
end
fclose(fid);
fprintf('保存雷达 %d: %d 个脉冲 (方位 %.1f-%.1f°, 载频 %.1f-%.1f MHz)\n', ...
i, size(cluster_data, 1), min(azimuth), max(azimuth), min(rf), max(rf));
end
end
function plot_analysis_results(data, features, labels)
% 创建分析图
fig = figure('Name', '雷达分选分析', 'Position', [100, 100, 1200, 800]);
% 1. 方位-载频特征空间
subplot(2, 2, 1);
scatter(data(:, 1), data(:, 3), 20, labels, 'filled');
title('方位-载频特征空间');
xlabel('方位 (度)');
ylabel('载频 (MHz)');
colormap(jet(length(unique(labels))));
colorbar;
grid on;
% 2. 载频-脉宽特征空间
subplot(2, 2, 2);
scatter(data(:, 3), data(:, 4), 20, labels, 'filled');
title('载频-脉宽特征空间');
xlabel('载频 (MHz)');
ylabel('脉宽 (us)');
colormap(jet(length(unique(labels))));
colorbar;
grid on;
% 3. 方位-脉宽特征空间
subplot(2, 2, 3);
scatter(data(:, 1), data(:, 4), 20, labels, 'filled');
title('方位-脉宽特征空间');
xlabel('方位 (度)');
ylabel('脉宽 (us)');
colormap(jet(length(unique(labels))));
colorbar;
grid on;
% 4. 雷达参数分布(方位/载频/脉宽)
subplot(2, 2, 4);
hold on;
unique_labels = unique(labels);
colors = lines(length(unique_labels));
for i = 1:length(unique_labels)
idx = (labels == unique_labels(i));
% 绘制方位分布
azi = data(idx, 1);
[f, x] = ksdensity(azi);
plot(x, f, 'Color', colors(i, :), 'LineWidth', 2);
end
title('方位角分布');
xlabel('方位 (度)');
ylabel('概率密度');
legend(arrayfun(@(x) sprintf('雷达 %d', x), unique_labels, 'UniformOutput', false));
grid on;
% 创建第二个图:载频和脉宽分布
fig2 = figure('Name', '雷达参数分布', 'Position', [200, 200, 1000, 800]);
% 载频分布
subplot(2, 1, 1);
hold on;
for i = 1:length(unique_labels)
idx = (labels == unique_labels(i));
rf = data(idx, 3);
[f, x] = ksdensity(rf);
plot(x, f, 'Color', colors(i, :), 'LineWidth', 2);
end
title('载频分布');
xlabel('载频 (MHz)');
ylabel('概率密度');
legend(arrayfun(@(x) sprintf('雷达 %d', x), unique_labels, 'UniformOutput', false));
grid on;
% 脉宽分布
subplot(2, 1, 2);
hold on;
for i = 1:length(unique_labels)
idx = (labels == unique_labels(i));
pw = data(idx, 4);
[f, x] = ksdensity(pw);
plot(x, f, 'Color', colors(i, :), 'LineWidth', 2);
end
title('脉宽分布');
xlabel('脉宽 (us)');
ylabel('概率密度');
grid on;
% 保存分析图
if ~exist('sorted_results', 'dir')
mkdir('sorted_results');
end
saveas(fig, 'sorted_results/feature_spaces.png');
saveas(fig2, 'sorted_results/parameter_distributions.png');
end
```
### 关键改进说明:
1. **特征提取优化**:
```matlab
function features = preprocess_features(data)
% 只提取方位(1), 载频(3), 脉宽(4)
raw_features = data(:, [1, 3, 4]);
% 为每个参数计算合适的缩放因子
azimuth_scale = 180; % 方位缩放基准
rf_scale = 1000; % 载频缩放基准
pw_scale = 5; % 脉宽缩放基准
% 应用缩放
scaled_features = [azimuth/azimuth_scale, rf/rf_scale, pw/pw_scale];
```
- 只关注方位、载频、脉宽三个关键参数
- 针对每个参数设置合理的缩放因子,使其具有可比性
- 使用鲁棒标准化处理异常值
2. **基于相似性的聚类算法**:
```matlab
function labels = cluster_by_similarity(features)
% 设置相似性阈值
azimuth_thresh = 0.05; % 方位角差异阈值
rf_thresh = 0.03; % 载频差异阈值
pw_thresh = 0.04; % 脉宽差异阈值
while any(unprocessed)
% 查找所有相似点
diffs = abs(features - features(current_idx, :));
similar_mask = unprocessed & ...
(diffs(:, 1) <= azimuth_thresh) & ...
(diffs(:, 2) <= rf_thresh) & ...
(diffs(:, 3) <= pw_thresh);
end
```
- 使用自定义相似性阈值(可调整)
- 基于区域增长的聚类方法
- 同时满足方位、载频、脉宽三个条件的点归为一类
3. **聚类后处理优化**:
```matlab
function labels = postprocess_clusters(features, labels)
% 计算每个簇的中心(中位数)
cluster_centers = zeros(n_clusters, size(features, 2));
% 合并距离过近的簇
for i = 1:n_clusters
[min_dist, min_idx] = min(dist_matrix(i, :));
if min_dist < 0.1 % 合并阈值
labels(labels == unique_labels(j)) = unique_labels(i);
end
end
```
- 计算簇中心(使用中位数抗异常值)
- 合并距离过近的簇(阈值0.1)
- 重新编号聚类标签确保连续性
4. **结果输出增强**:
```matlab
filename = sprintf('sorted_results/radar_%d_azi_%.1f-%.1f_rf_%.1f-%.1f.txt', ...
i, min(azimuth), max(azimuth), min(rf), max(rf));
```
- 文件名包含雷达的方位和载频范围
- 控制台输出每个雷达的参数范围
5. **可视化聚焦关键参数**:
- 方位-载频特征空间
- 载频-脉宽特征空间
- 方位-脉宽特征空间
- 方位角概率密度分布
- 载频概率密度分布
- 脉宽概率密度分布
### 算法优势:
1. **参数聚焦**:专门针对方位、载频、脉宽三个关键参数设计聚类算法
2. **可解释性**:使用直观的相似性阈值,便于理解和调整
3. **物理意义明确**:直接基于雷达参数的物理相似性分组
4. **抗噪性**:使用中位数作为中心点计算,减少异常值影响
5. **可视化清晰**:多角度展示参数分布和聚类结果
### 参数调整指南:
1. **相似性阈值**:
- `azimuth_thresh`:方位角差异阈值(标准化后),默认0.05
- `rf_thresh`:载频差异阈值(标准化后),默认0.03
- `pw_thresh`:脉宽差异阈值(标准化后),默认0.04
- 值越小分组越严格,值越大分组越宽松
2. **合并阈值**:
- 后处理中的`min_dist < 0.1`控制簇的合并
- 增加此值会使更多簇被合并
- 减小此值会保留更多小簇
3. **特征缩放**:
- `azimuth_scale`:方位缩放因子(默认180)
- `rf_scale`:载频缩放因子(默认1000)
- `pw_scale`:脉宽缩放因子(默认5)
- 根据实际数据范围调整,使各参数重要性平衡
### 使用流程:
1. 运行`radar_sorting_main`
2. 选择PDW数据文件
3. 程序自动:
- 读取并验证数据
- 提取方位/载频/脉宽特征
- 基于相似性聚类
- 优化聚类结果
- 保存分选结果
- 生成可视化图表
4. 查看结果:
- `sorted_results/`目录下的雷达数据文件
- `feature_spaces.png` - 特征空间分布
- `parameter_distributions.png` - 参数分布
阅读全文
相关推荐
















