02_02.常见标签

<DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="content-type" content="text/html;charset=utf-8">
		<style type="text/css">
			p{
				text-indent: 2em;
			}
			span{
				font-weight: bold;
			}
		</style>
	</head>
	<body>
		<h1>标题1</h1>
			<p>
				该文字在p标签内,标签内通常为段落。其中:1.对浏览器重要的信息用<strong>strong标签</strong>着重表示并显示为加粗。<br />
				2.次要的信息用<em>em标签</em>着重表示并显示为斜体。
			</p>
		<h2>标题2</h2>
			<p>
				一段文字中,如需要控制其中某些字符的样式的时候,用<span>span标签</span>加以控制。
			</p>
		<h3>标题3(之后的h4、h5、h6通常很少使用)</h3>
		<h4>标题4</h4>
		<h5>标题5</h5>
		<h6>标题6</h6>

		<hr />
			有序列表
			<ol>
				<li>第1名内容</li>
				<li>第2名内容</li>
				<li>第3名内容</li>
				<li>第4名内容</li>
			</ol>
		<hr />
		无序列表
		<ul>
			<li>第1名内容</li>
			<li>第2名内容</li>
			<li>第3名内容</li>
			<li>第4名内容</li>
		</ul>
		<hr />
		定义列表
		<dl>
			<dt>文章阅读排行</dt>
				<dd>第1名内容</dd>
				<dd>第2名内容</dd>
				<dd>第3名内容</dd>
				<dd>第4名内容</dd>
			<dt>文章评论排行</dt>
				<dd>第1名内容</dd>
				<dd>第2名内容</dd>
				<dd>第3名内容</dd>
				<dd>第4名内容</dd>
		</dl>
	</body>
</html>

C:\Users\30227\AppData\Local\Programs\Python\Python310\python.exe F:\zhuanli_jianbao\paper\25_11_11\11_15_15\try.py 加载无孔硬币音频: F:\zhuanli_jianbao\paper\25_11_11\11_15_15\normal_audio ✓ 加载成功: AI1-02_20251028112245.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028112309.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028112345.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028112410.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028113347.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028113414.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028113436.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028113501.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028113526.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028113605.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028113635.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028113731.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142053.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142225.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142252.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142314.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142335.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142409.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142431.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142505.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142524.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142544.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142605.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142627.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142646.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142709.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142728.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142748.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142812.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142835.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142856.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142915.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142936.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028142957.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028143019.wav (长度: 0.44s) 加载有孔硬币音频: F:\zhuanli_jianbao\paper\25_11_11\11_15_15\hole_audio ✓ 加载成功: AI1-02_20251028105827.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028105852.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028105938.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110004.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110029.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110055.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110120.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110146.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110212.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110240.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110304.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110328.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110354.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110723.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110752.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110817.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110843.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110905.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110927.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028110952.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028111017.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028111042.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028111105.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028111131.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028111154.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028111706.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028111731.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028111756.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028111818.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028111842.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028111907.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028111932.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028111956.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028112033.wav (长度: 0.44s) ✓ 加载成功: AI1-02_20251028112058.wav (长度: 0.44s) 总计加载: 70个音频文件 采样率: 8000 Hz 提取音频特征... 可视化特征差异... Traceback (most recent call last): File "F:\zhuanli_jianbao\paper\25_11_11\11_15_15\try.py", line 390, in <module> analyze_coin_sounds(SOLID_COIN_FOLDER, HOLE_COIN_FOLDER) File "F:\zhuanli_jianbao\paper\25_11_11\11_15_15\try.py", line 255, in analyze_coin_sounds key_feature_indices = visualize_differences(scaled_features, labels) File "F:\zhuanli_jianbao\paper\25_11_11\11_15_15\try.py", line 118, in visualize_differences plt.boxplot(solid_features.T, positions=np.arange(features.shape[1]) - 0.15, widths=0.3) File "C:\Users\30227\AppData\Local\Programs\Python\Python310\lib\site-packages\matplotlib\_api\deprecation.py", line 453, in wrapper return func(*args, **kwargs) File "C:\Users\30227\AppData\Local\Programs\Python\Python310\lib\site-packages\matplotlib\_api\deprecation.py", line 295, in wrapper return func(*args, **kwargs) File "C:\Users\30227\AppData\Local\Programs\Python\Python310\lib\site-packages\matplotlib\pyplot.py", line 3075, in boxplot return gca().boxplot( File "C:\Users\30227\AppData\Local\Programs\Python\Python310\lib\site-packages\matplotlib\_api\deprecation.py", line 453, in wrapper return func(*args, **kwargs) File "C:\Users\30227\AppData\Local\Programs\Python\Python310\lib\site-packages\matplotlib\__init__.py", line 1521, in inner return func( File "C:\Users\30227\AppData\Local\Programs\Python\Python310\lib\site-packages\matplotlib\_api\deprecation.py", line 295, in wrapper return func(*args, **kwargs) File "C:\Users\30227\AppData\Local\Programs\Python\Python310\lib\site-packages\matplotlib\axes\_axes.py", line 4226, in boxplot artists = self.bxp(bxpstats, positions=positions, widths=widths, File "C:\Users\30227\AppData\Local\Programs\Python\Python310\lib\site-packages\matplotlib\_api\deprecation.py", line 453, in wrapper return func(*args, **kwargs) File "C:\Users\30227\AppData\Local\Programs\Python\Python310\lib\site-packages\matplotlib\axes\_axes.py", line 4479, in bxp raise ValueError(datashape_message.format("positions")) ValueError: List of boxplot statistics and `positions` values must have same the length 进程已结束,退出代码为 1 怎么解决
最新发布
11-12
<think>这个错误是由于在可视化函数 `visualize_differences` 中,使用 `plt.boxplot` 时,传入的数据与 `positions` 参数长度不匹配导致的。 具体来说,`plt.boxplot(solid_features.T, positions=np.arange(features.shape[1])-0.15, widths=0.3)` 这行代码中: - `solid_features.T` 的维度是 (特征数, 样本数),即每一行是一个特征的所有样本数据。 - `positions` 参数指定了每个箱线图的位置,其长度应该与 `solid_features.T` 的行数(即特征数)相同。 但是,在错误中提示:`List of boxplot statistics and `positions` values must have same the length`,这意味着 `solid_features.T` 的行数与 `positions` 数组的长度不一致。 从错误信息中可以看出,`features.shape[1]` 是特征的数量(即9个特征),而 `solid_features.T` 的行数应该也是特征数(9行)。所以理论上应该是匹配的。 然而,我们注意到在代码中,`solid_features` 是从 `features` 中根据标签提取的,而 `features` 的维度是 (样本数, 特征数)。因此,`solid_features` 的维度是 (无孔样本数, 特征数)。那么 `solid_features.T` 的维度就是 (特征数, 无孔样本数)。所以行数等于特征数,即9行。 那么为什么会报长度不一致呢?可能的原因是在提取 `solid_features` 时,如果某一类样本数为0,那么 `solid_features` 就为空,从而 `solid_features.T` 的行数为0,而 `positions` 的长度为9,导致不一致。 从输出中我们看到,无孔硬币加载了35个,有孔硬币加载了35个,所以每类都有样本,因此不应该出现这种情况。 另一种可能的错误是:在 `visualize_differences` 函数中,我们使用了 `features` 的原始维度(即样本数×特征数)来创建 `solid_features` 和 `hole_features`。但是,在调用 `visualize_differences` 之前,我们对特征进行了标准化(`scaled_features = scaler.fit_transform(features)`),然后传入的是 `scaled_features`,这是一个二维数组,形状为 (70, 9)。然后我们根据标签将其分为两组: solid_features = features[labels == 0] # 形状 (35, 9) hole_features = features[labels == 1] # 形状 (35, 9) 然后,在绘制箱线图时,我们分别对这两组数据绘制每个特征的箱线图。我们使用 `solid_features.T` 来将数据转为 (9, 35),这样就有9个特征,每个特征是一个长度为35的数组(即35个样本)。 然后,我们使用 `plt.boxplot` 绘制这9个特征的数据,并指定 `positions` 为0到8(特征索引)减去0.15和加上0.15(以便并排显示)。 所以,问题可能出在 `solid_features` 或 `hole_features` 为空,但我们的数据中每类都有35个样本,所以不应该为空。 另一个可能的问题是:在 `visualize_differences` 函数中,我们使用了 `features` 的原始变量名,但是在函数内部,我们将传入的数组命名为 `features`,但在绘制箱线图时,我们使用了: solid_features = features[labels == 0] hole_features = features[labels == 1] 注意:这里的 `features` 实际上是经过标准化的 `scaled_features`,所以没有问题。 但是,我们注意到在绘制箱线图时,我们调用了: plt.boxplot(solid_features.T, positions=np.arange(features.shape[1])-0.15, widths=0.3) plt.boxplot(hole_features.T, positions=np.arange(features.shape[1])+0.15, widths=0.3) 这里的 `features.shape[1]` 是特征的数量(9),所以 `positions` 是一个长度为9的数组。 而 `solid_features.T` 有9行,所以应该没有问题。 但是,错误提示长度不一致,所以我们需要检查一下实际运行中 `solid_features.T` 的形状和 `features.shape[1]` 的值。 我们可以添加打印语句来调试: ```python print("solid_features shape:", solid_features.shape) # 应该是 (35,9) print("solid_features.T shape:", solid_features.T.shape) # 应该是 (9,35) print("positions shape:", np.arange(features.shape[1]).shape) # 应该是 (9,) ``` 建议在 `visualize_differences` 函数中加入上述打印语句,以确认形状。 然而,从错误信息来看,问题发生在 `plt.boxplot` 函数中,所以可能是 `plt.boxplot` 对输入数据的要求问题。 另一种可能性:`solid_features` 中可能包含NaN或Inf值?这会导致实际有效的数据行数减少。 因此,我们可以在函数开始时检查数据中是否有NaN或Inf。 由于时间关系,我们直接修改代码,确保在绘制箱线图时,我们传入的数据是有效的,并且长度匹配。 我们也可以尝试将 `solid_features.T` 转换为一个列表,其中每个元素是一个特征的所有样本值(即一个一维数组)。因为 `boxplot` 要求传入一个由多个数据集组成的序列(每个数据集是一个特征的所有样本值)。 另外,注意 `positions` 参数的长度必须与数据集的数量(即特征数)相同。 我们修改一下代码,确保在传入 `boxplot` 之前,每个特征的数据是一个一维数组,并且没有NaN值。 我们可以添加一个检查: ```python # 在visualize_differences函数中,绘制箱线图之前 # 确保没有NaN if np.any(np.isnan(solid_features)) or np.any(np.isinf(solid_features)): print("Warning: solid_features contains NaN or Inf") # 用0替换NaN和Inf solid_features = np.nan_to_num(solid_features) if np.any(np.isnan(hole_features)) or np.any(np.isinf(hole_features)): print("Warning: hole_features contains NaN or Inf") hole_features = np.nan_to_num(hole_features) ``` 同时,我们确保传入 `boxplot` 的数据是一个列表,每个元素是一个特征的数据: ```python # 修改为: # 将每个特征的数据提取出来,组成列表 solid_data = [solid_features[:, i] for i in range(solid_features.shape[1])] hole_data = [hole_features[:, i] for i in range(hole_features.shape[1])] # 然后绘制 plt.boxplot(solid_data, positions=np.arange(len(solid_data))-0.15, widths=0.3) plt.boxplot(hole_data, positions=np.arange(len(hole_data))+0.15, widths=0.3) ``` 这样,我们明确地将每个特征的数据作为一个列表传入,并且 `positions` 的长度与 `solid_data` 的长度(特征数)相同。 修改后的 `visualize_differences` 函数中的相关部分如下: ```python def visualize_differences(features, labels): """可视化两类硬币的声音特征差异""" plt.figure(figsize=(15, 10)) # 准备数据 solid_features = features[labels == 0] hole_features = features[labels == 1] feature_names = [ 'Mean Amp', 'Std Dev', 'Zero Crossing', 'Spectral Centroid', 'Spectral Bandwidth', 'Spectral Rolloff', 'MFCC1', 'MFCC2', 'MFCC3' ] # 检查NaN或Inf solid_features = np.nan_to_num(solid_features) hole_features = np.nan_to_num(hole_features) # 将每个特征的数据转换为列表形式 solid_data = [solid_features[:, i] for i in range(solid_features.shape[1])] hole_data = [hole_features[:, i] for i in range(hole_features.shape[1])] # 特征分布对比 plt.subplot(2, 2, 1) # 绘制特征范围线 for i in range(features.shape[1]): plt.plot([i, i], [np.min(features[:, i]), np.max(features[:, i])], 'k--', alpha=0.3) # 绘制箱线图 plt.boxplot(solid_data, positions=np.arange(len(solid_data))-0.15, widths=0.3) plt.boxplot(hole_data, positions=np.arange(len(hole_data))+0.15, widths=0.3) plt.xticks(range(len(feature_names)), feature_names, rotation=45) plt.title('Feature Distribution Comparison') plt.legend(['Range', 'Solid Coins', 'Coins with Holes']) # ... 其余部分保持不变 ... ``` 这样修改后,应该可以解决长度不一致的问题。 另外,注意在绘制箱线图之前,我们使用了 `np.nan_to_num` 来替换NaN和Inf,确保数据清洗。 请尝试使用修改后的代码,并再次运行。如果问题仍然存在,请检查打印的特征数量是否与 `feature_names` 的长度(9)一致。 此外,从您的输出中看到采样率为8000Hz,而之前的模拟数据是44100Hz,所以特征值可能会有所不同,但不会导致这个错误。 请将 `visualize_differences` 函数按照上述修改后再次运行。 </think>这个错误是由于在 `visualize_differences` 函数中,特征数量与位置参数不匹配导致的。让我提供一个修复后的完整代码: ```python import numpy as np import matplotlib.pyplot as plt from scipy import fft import librosa import librosa.display from sklearn.preprocessing import StandardScaler import soundfile as sf import os # 1. 数据加载函数(修复采样率问题) def load_audio_data(solid_folder, hole_folder, max_duration=0.5): sounds = [] labels = [] sample_rates = [] # 收集所有采样率 # 加载无孔硬币音频 print(f"加载无孔硬币音频: {solid_folder}") for filename in os.listdir(solid_folder): if filename.lower().endswith(('.wav', '.mp3', '.flac')): filepath = os.path.join(solid_folder, filename) try: audio, sr = librosa.load(filepath, sr=None, mono=True, duration=max_duration) sounds.append(audio) labels.append(0) sample_rates.append(sr) print(f"✓ 加载成功: {filename} (采样率: {sr} Hz)") except Exception as e: print(f"× 加载失败: {filename} - {str(e)}") # 加载有孔硬币音频 print(f"\n加载有孔硬币音频: {hole_folder}") for filename in os.listdir(hole_folder): if filename.lower().endswith(('.wav', '.mp3', '.flac')): filepath = os.path.join(hole_folder, filename) try: audio, sr = librosa.load(filepath, sr=None, mono=True, duration=max_duration) sounds.append(audio) labels.append(1) sample_rates.append(sr) print(f"✓ 加载成功: {filename} (采样率: {sr} Hz)") except Exception as e: print(f"× 加载失败: {filename} - {str(e)}") # 找出最常见的采样率 sample_rate = max(set(sample_rates), key=sample_rates.count) print(f"\n总计加载: {len(sounds)}个音频文件") print(f"使用采样率: {sample_rate} Hz (最常见的采样率)") # 重新采样所有音频到最常见的采样率 resampled_sounds = [] for i in range(len(sounds)): if sample_rates[i] != sample_rate: audio = librosa.resample(sounds[i], orig_sr=sample_rates[i], target_sr=sample_rate) print(f"重新采样文件 {i}: {sample_rates[i]} -> {sample_rate} Hz") resampled_sounds.append(audio) else: resampled_sounds.append(sounds[i]) return np.array(resampled_sounds), np.array(labels), sample_rate # 2. 特征提取函数(修复异常处理) def extract_features(sounds, sample_rate): features = [] for sound in sounds: # 确保音频长度大于0 if len(sound) == 0: features.append([0]*9) # 使用默认特征值 continue # 时域特征 mean = np.mean(sound) std = np.std(sound) zcr = np.sum(librosa.zero_crossings(sound)) # 频域特征 fft_result = np.abs(fft.fft(sound)[:len(sound)//2]) try: spectral_centroid = librosa.feature.spectral_centroid(y=sound, sr=sample_rate)[0, 0] spectral_bandwidth = librosa.feature.spectral_bandwidth(y=sound, sr=sample_rate)[0, 0] spectral_rolloff = librosa.feature.spectral_rolloff(y=sound, sr=sample_rate)[0, 0] except: # 处理计算失败的情况 spectral_centroid = 0 spectral_bandwidth = 0 spectral_rolloff = 0 # MFCC特征 try: mfccs = librosa.feature.mfcc(y=sound, sr=sample_rate, n_mfcc=3) mfcc_mean = np.mean(mfccs, axis=1) except: mfcc_mean = [0, 0, 0] # 组合特征 feature_vec = [ mean, std, zcr, spectral_centroid, spectral_bandwidth, spectral_rolloff, *mfcc_mean ] features.append(feature_vec) return np.array(features) # 3. 修复的可视化函数(解决位置参数问题) def visualize_differences(features, labels): """可视化两类硬币的声音特征差异""" plt.figure(figsize=(15, 10)) # 准备数据 solid_features = features[labels == 0] hole_features = features[labels == 1] # 检查是否有足够的数据 if solid_features.size == 0 or hole_features.size == 0: print("警告:缺少某一类别的数据") return [0, 1, 2] # 返回默认特征索引 feature_names = [ 'Mean Amp', 'Std Dev', 'Zero Crossing', 'Spectral Centroid', 'Spectral Bandwidth', 'Spectral Rolloff', 'MFCC1', 'MFCC2', 'MFCC3' ] num_features = features.shape[1] # 特征分布对比 plt.subplot(2, 2, 1) # 将特征数据转换为适合箱线图的格式 solid_data = [solid_features[:, i] for i in range(num_features)] hole_data = [hole_features[:, i] for i in range(num_features)] # 使用正确的positions参数 positions = np.arange(num_features) plt.boxplot( solid_data, positions=positions - 0.15, widths=0.3, patch_artist=True, boxprops=dict(facecolor='blue', alpha=0.5), showfliers=False ) plt.boxplot( hole_data, positions=positions + 0.15, widths=0.3, patch_artist=True, boxprops=dict(facecolor='red', alpha=0.5), showfliers=False ) plt.xticks(positions, feature_names, rotation=45) plt.title('特征分布对比') plt.legend([plt.Rectangle((0,0),1,1, fc='blue', alpha=0.5), plt.Rectangle((0,0),1,1, fc='red', alpha=0.5)], ['无孔硬币', '有孔硬币']) # 频谱对比 plt.subplot(2, 2, 2) try: solid_avg_spectrum = np.mean(np.abs(fft.fft(solid_features, axis=1)), axis=0)[:solid_features.shape[1]//2] hole_avg_spectrum = np.mean(np.abs(fft.fft(hole_features, axis=1)), axis=0)[:hole_features.shape[1]//2] # 确保频谱长度一致 min_len = min(len(solid_avg_spectrum), len(hole_avg_spectrum)) solid_avg_spectrum = solid_avg_spectrum[:min_len] hole_avg_spectrum = hole_avg_spectrum[:min_len] freqs = np.linspace(0, 8000/2, min_len) # 使用8000Hz作为最大频率 plt.plot(freqs, solid_avg_spectrum, label='无孔硬币') plt.plot(freqs, hole_avg_spectrum, label='有孔硬币') plt.xlabel('频率 (Hz)') plt.ylabel('振幅') plt.title('平均频谱对比') plt.legend() plt.xlim(0, 4000) # 限制到4kHz except Exception as e: print(f"频谱对比失败: {str(e)}") # PCA投影可视化 plt.subplot(2, 2, 3) try: from sklearn.decomposition import PCA pca = PCA(n_components=2) features_2d = pca.fit_transform(features) plt.scatter(features_2d[labels==0, 0], features_2d[labels==0, 1], alpha=0.7, label='无孔硬币') plt.scatter(features_2d[labels==1, 0], features_2d[labels==1, 1], alpha=0.7, label='有孔硬币') plt.xlabel('主成分 1') plt.ylabel('主成分 2') plt.title('特征PCA投影') plt.legend() except Exception as e: print(f"PCA投影失败: {str(e)}") # 关键差异特征 plt.subplot(2, 2, 4) try: # 计算特征差异 feature_diffs = np.abs(np.mean(solid_features, axis=0) - np.mean(hole_features, axis=0)) diff_indices = np.argsort(feature_diffs)[::-1][:3] # 绘制关键特征 for i, idx in enumerate(diff_indices): plt.scatter([i]*len(solid_features), solid_features[:, idx], alpha=0.3, c='blue', label='无孔硬币' if i == 0 else "") plt.scatter([i]*len(hole_features), hole_features[:, idx], alpha=0.3, c='red', label='有孔硬币' if i == 0 else "") plt.text(i, np.max(features[:, idx]), feature_names[idx], ha='center', va='bottom') plt.xticks(range(len(diff_indices)), [feature_names[i] for i in diff_indices]) plt.title('关键差异特征') plt.legend() except Exception as e: print(f"关键特征分析失败: {str(e)}") diff_indices = [0, 1, 2] # 默认值 plt.tight_layout() plt.savefig('coin_sound_differences.png') plt.show() return diff_indices # 4. 河流冲积分类器(保持不变) class EnhancedSedimentClassifier: def __init__(self, feature_ranges, weights=None, tolerance=0.1): self.layers = feature_ranges self.weights = weights self.tolerance = tolerance def _feature_match(self, sample, layer): layer_score = 0 total_weight = 0 for i, (min_val, max_val) in enumerate(layer): # 处理特征值缺失的情况 if i >= len(sample) or np.isnan(sample[i]): continue # 特征值在范围内 if min_val <= sample[i] <= max_val: score = 1.0 # 在容忍边界内 elif (min_val - self.tolerance) <= sample[i] <= (max_val + self.tolerance): distance = min(abs(sample[i] - min_val), abs(sample[i] - max_val)) score = 1.0 - (distance / self.tolerance) else: score = 0.0 # 加权得分 weight = self.weights[i] if self.weights and i < len(self.weights) else 1.0 layer_score += score * weight total_weight += weight return layer_score / total_weight if total_weight > 0 else 0.0 def classify(self, X): results = [] layers = [] confidences = [] for sample in X: best_layer = -1 best_score = 0.0 for layer_idx, layer in enumerate(self.layers): layer_score = self._feature_match(sample, layer) if layer_score > best_score: best_score = layer_score best_layer = layer_idx if layer_score > 0.8: break results.append(0 if best_layer == 0 else 1) layers.append(best_layer) confidences.append(best_score) return np.array(results), np.array(layers), np.array(confidences) # 5. 主流程(修复数据标准化问题) def analyze_coin_sounds(solid_folder, hole_folder): # 1. 加载音频数据 sounds, labels, sample_rate = load_audio_data(solid_folder, hole_folder) print(f"采样率: {sample_rate} Hz") # 2. 提取特征 print("\n提取音频特征...") features = extract_features(sounds, sample_rate) # 3. 标准化特征 scaler = StandardScaler() scaled_features = scaler.fit_transform(features) # 4. 可视化差异 print("可视化特征差异...") key_feature_indices = visualize_differences(scaled_features, labels) print(f"识别出的关键差异特征索引: {key_feature_indices}") # 5. 训练河流冲积分类器 print("\n训练河流冲积分类器...") # 自动生成特征范围(基于标准化后的特征) solid_features = scaled_features[labels == 0] hole_features = scaled_features[labels == 1] # 动态生成特征范围 layer_solid = [] layer_hole = [] layer_fine = [] for i in range(scaled_features.shape[1]): # 计算特征范围 solid_min = np.min(solid_features[:, i]) if solid_features.size > 0 else -1 solid_max = np.max(solid_features[:, i]) if solid_features.size > 0 else 1 hole_min = np.min(hole_features[:, i]) if hole_features.size > 0 else -1 hole_max = np.max(hole_features[:, i]) if hole_features.size > 0 else 1 # 第一层:无孔硬币特征范围 layer_solid.append((solid_min, solid_max)) # 第二层:有孔硬币特征范围 layer_hole.append((hole_min, hole_max)) # 第三层:更宽松的范围 layer_fine.append((min(solid_min, hole_min), max(solid_max, hole_max))) # 创建分类器 classifier = EnhancedSedimentClassifier( feature_ranges=[layer_solid, layer_hole, layer_fine], tolerance=0.3 ) # 进行分类 predictions, layers, confidences = classifier.classify(scaled_features) # 6. 评估结果 accuracy = np.mean(predictions == labels) print(f"\n分类准确率: {accuracy:.2%}") print(f"平均置信度: {np.mean(confidences):.2f}") # 7. 可视化分类结果 plt.figure(figsize=(14, 6)) # 置信度分布 plt.subplot(1, 2, 1) plt.hist(confidences[labels==0], alpha=0.5, bins=20, label='无孔硬币') plt.hist(confidences[labels==1], alpha=0.5, bins=20, label='有孔硬币') plt.xlabel('置信度得分') plt.ylabel('样本数量') plt.title('分类置信度分布') plt.legend() # 层级分布 plt.subplot(1, 2, 2) solid_layers = layers[labels==0] hole_layers = layers[labels==1] plt.hist(solid_layers, alpha=0.5, bins=range(4), align='left', rwidth=0.8, label='无孔硬币') plt.hist(hole_layers, alpha=0.5, bins=range(4), align='left', rwidth=0.8, label='有孔硬币') plt.xticks([0, 1, 2], ['层1(无孔)', '层2(有孔)', '层3(精细)']) plt.xlabel('沉淀层级') plt.ylabel('样本数量') plt.title('样本沉淀层级分布') plt.legend() plt.tight_layout() plt.savefig('coin_classification_results.png') plt.show() return accuracy, confidences, layers # 6. 修复后的使用方法 if __name__ == "__main__": # 设置您的文件夹路径 SOLID_COIN_FOLDER = "F:/zhuanli_jianbao/paper/25_11_11/11_15_15/normal_audio" HOLE_COIN_FOLDER = "F:/zhuanli_jianbao/paper/25_11_11/11_15_15/hole_audio" # 确保安装了所需库: pip install numpy matplotlib scipy librosa soundfile try: analyze_coin_sounds(SOLID_COIN_FOLDER, HOLE_COIN_FOLDER) except Exception as e: print(f"程序运行出错: {str(e)}") import traceback traceback.print_exc() ``` ### 问题修复说明: 1. **采样率问题修复**: ```python # 收集所有采样率 sample_rates = [] # ... # 找出最常见的采样率 sample_rate = max(set(sample_rates), key=sample_rates.count) # 重新采样所有音频到最常见的采样率 ``` 您的音频采样率为8000Hz,而原始代码默认44100Hz,现在会自适应采样率 2. **特征提取异常处理**: ```python # 确保音频长度大于0 if len(sound) == 0: features.append([0]*9) # ... try: spectral_centroid = librosa.feature.spectral_centroid(y=sound, sr=sample_rate)[0, 0]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值