当前位置:首页 » 编程语言 » python去噪

python去噪

发布时间: 2022-07-13 19:01:39

python绘折线图(数据很多)很难看

数据使用前要清洗,去除无效数据。
如果这些数据都是有效数据,只是你不想显示那些过份异常的数据,那么,就进行去噪处理。
去噪分两步:检测噪点,噪点修正。
对于整体连续,总体范围大的数据集,最简单的检测噪点的办法就是邻值法,对于第n取相邻的k个值:p[n-k,],p[n-k+1]...p[n-1]

对它们加权平均,得到标准点,上下浮动一定范围,如果p[k]不在这个范围内就是异常点
对应的噪点修正可以使用类似的过程,局部噪点回归法。
这些一般来说都不是很实现的东西,对于数据集结构的不同,没有必要做成通用的包,所以你只有自己实现。

② 怎样用python实现图像去噪

#coding:utf-8
importsys,os
fromPILimportImage,ImageDraw

#二值数组
t2val={}
deftwoValue(image,G):
foryinxrange(0,image.size[1]):
forxinxrange(0,image.size[0]):
g=image.getpixel((x,y))
ifg>G:
t2val[(x,y)]=1
else:
t2val[(x,y)]=0

#降噪
#根据一个点A的RGB值,与周围的8个点的RBG值比较,设定一个值N(0<N<8),当A的RGB值与周围8个点的RGB相等数小于N时,此点为噪点
#G:Integer图像二值化阀值
#N:Integer降噪率0<N<8
#Z:Integer降噪次数
#输出
#0:降噪成功
#1:降噪失败
defclearNoise(image,N,Z):

foriinxrange(0,Z):
t2val[(0,0)]=1
t2val[(image.size[0]-1,image.size[1]-1)]=1

forxinxrange(1,image.size[0]-1):
foryinxrange(1,image.size[1]-1):
nearDots=0
L=t2val[(x,y)]
ifL==t2val[(x-1,y-1)]:
nearDots+=1
ifL==t2val[(x-1,y)]:
nearDots+=1
ifL==t2val[(x-1,y+1)]:
nearDots+=1
ifL==t2val[(x,y-1)]:
nearDots+=1
ifL==t2val[(x,y+1)]:
nearDots+=1
ifL==t2val[(x+1,y-1)]:
nearDots+=1
ifL==t2val[(x+1,y)]:
nearDots+=1
ifL==t2val[(x+1,y+1)]:
nearDots+=1

ifnearDots<N:
t2val[(x,y)]=1

defsaveImage(filename,size):
image=Image.new("1",size)
draw=ImageDraw.Draw(image)

forxinxrange(0,size[0]):
foryinxrange(0,size[1]):
draw.point((x,y),t2val[(x,y)])

image.save(filename)

image=Image.open("d:/1.jpg").convert("L")
twoValue(image,100)
clearNoise(image,4,1)
saveImage("d:/5.jpg",image.size)

③ python pil 怎么去掉验证码线条

一、验证码识别的概念

机器识别图片主要的三个步骤为消去背景、切割字符、识别字符。而现有的字符验证码也针对这三个方面来设计强壮的验证码。

以下简图帮助大家理解验证码识别的流程:

二、处理流程

其中最为关键的就是好图像处理这一步了。图像处理功能模块包括图像的灰度化、二值化、离散噪声点的去除、倾斜度校正、字符的切割、图像的归一化等图像处理技术 。

1、 图像的灰度化
由于 256 色的位图的调色板内容比较复杂,使得图像处理的许多算法都没有办法展开,因此有必要对它进行灰度处理。所谓灰度图像就是图像的每一个像素的 R、G、B 分量的值是相等的。彩色图像的每个像素的 R、G、B 值是不相同的,所以显示出红绿蓝等各种颜色。灰度图像没有这些颜色差异,有的只是亮度上的不同。灰度值大的像素点比较亮(像素值最大为 255,为白色),反之比较暗(像素值最小为 0,为黑色)。图像灰度化有各种不同的算法,比较直接的一种就是给像素的 RGB 值各自一个加权系数,然后求和;同时还要对调色板表项进行相应的处理。

2、 图像的二值化
要注意的是,最后得到的结果一定要归一到 0-255 之内。因为这是每个字节表示
图像数据的极限。

3、 去噪
图像可能在生成、传输或者采集过程中夹带了噪声,去噪声是图像处理中常用的手法。通常去噪声用滤波的方法,比如中值滤波、均值滤波。但是那样的算法不适合用在处理字符这样目标狭长的图像中,因为在滤波的过程中很有可能会去掉字符本身的像素。

一个采用的是去除杂点的方法来进行去噪声处理的。具体算法如下:扫描整个图像,当发现一个黑色点的时候,就考察和该黑色点间接或者直接相连接的黑色点的个数有多少,如果大于一定的值,那就说明该点不是离散点,否则就是离散点,把它去掉。在考察相连的黑色点的时候用的是递归的方法。此处,我简单的用python实现了,大家可以参考以下。

#coding=utf-8"""
creat time:2015.09.14
"""import cv2import numpy as npfrom matplotlib import pyplot as pltfrom PIL import Image,ImageEnhance,ImageFilter

img_name = '2+.png'#去除干扰线im = Image.open(img_name)#图像二值化enhancer = ImageEnhance.Contrast(im)
im = enhancer.enhance(2)
im = im.convert('1')
data = im.getdata()
w,h = im.size#im.show()black_point = 0for x in xrange(1,w-1): for y in xrange(1,h-1):
mid_pixel = data[w*y+x] #中央像素点像素值
if mid_pixel == 0: #找出上下左右四个方向像素点像素值
top_pixel = data[w*(y-1)+x]
left_pixel = data[w*y+(x-1)]
down_pixel = data[w*(y+1)+x]
right_pixel = data[w*y+(x+1)] #判断上下左右的黑色像素点总个数
if top_pixel == 0:
black_point += 1
if left_pixel == 0:
black_point += 1
if down_pixel == 0:
black_point += 1
if right_pixel == 0:
black_point += 1
if black_point >= 3:
im.putpixel((x,y),0) #print black_point
black_point = 0im.show()041424344

原验证码:

4、分割
图像中一般会含有多个数字,识别的时候只能根据每个字符的特征来进行判断,所以还要进行字符切割的工作。这一步工作就是把图像中的字符独立的切割出来。

具体的算法如下:

第一步,先自下而上对图像进行逐行扫描直至遇到第一个黑色的像素点。记录下来。然后再自上而下对图像进行逐行扫描直至找到第一个黑色像素,这样就找到图像大致的高度范围。

第二步,在这个高度范围之内再自左向右逐列进行扫描,遇到第一个黑色像素时认为是字符切割的起始位置,然后继续扫描,直至遇到有一列中没有黑色像素,则认为这个字符切割结束,然后继续扫描,按照上述的方法一直扫描直至图像的最右端。这样就得到了每个字符的比较精确宽度范围。

第三步,在已知的每个字符比较精确的宽度范围内,按照第一步的方法,分别进行自上而下和自下而上的逐行扫描来获取每个字符精确的高度范围。

5、 图像的归一化
因为采集的图像中字符大小有可能存在较大的差异,或者是经过切割后的字符尺寸不统一,而相对来说,统一尺寸的字符识别的标准性更强,准确率自然也更高,归一化图像就是要把原来各不相同的字符统一到同一尺寸,在系统实现中是统一到同一高度,然后根据高度来调整字符的宽度。具体算法如下:先得到原来字符的高度,跟系统要求的高度做比较,得出要变换的系数,然后根据得到的系数求得变换后应有得宽度。在得到宽度和高度之后,把新图像里面的点按照插值的方法映射到原图像中。

不少人认为把每个字符图像归一化为 5×9 像素的二值图像是最理想的,因为图像的尺寸越小,识别速度就越高,网络训练也越快。而实际上,相对于要识别的字符图像, 5×9 像素图太小了。归一化后,图像信息丢失了很多,这时进行图像识别,准确率不高。实验证明,将字符图像归一化为 10×18 像素的二值图像是现实中是比较理想的,达到了识别速度快和识别准确率高的较好的平衡点。

三、识别

图像识别包括特征提取、样本训练和识别三大块内容。

验证码识别其中最为关键的就是去噪和分割,这对你的训练和识别的精度都有着很大的影响。这里只讲了大致的流程,其中每个细节都有很多工作要做,这里码字也很难讲清楚,大家可以以这个流程为主线,一步步的实现,最终也就能完成你的需求。

④ python里的问题 ,pywt.dwt(signal,'db1','sym')这个函数

噪声能获取吗?好吧。你可以试试减一减。不过你的测试用例不太对。 尽量用有规律的数据去做。

比如你可以做一个正弦函数,再人为的加上一点点扰动。再做小波变换看看。另外数据要多些。太短的数据看不出效果来。

至于变换后是两个4,我想等你数据弄多些就明白了。 数据多些,就容易做图。你把变换后的数据变成图形,画出来。可以用EXCEL来画。

这样一对比就明白变换后的两个4数组是什么数据。 然后你就可以针对性的处理。取得噪声也是可以的。

通常来讲噪声是没有规律的。 但是不排除它是另外一种规律迭加上去的。 试试看。

⑤ python sklearn主成分分析法 各个特征向量是啥意思

主成分分析(PCA)是一种基于变量协方差矩阵对数据进行压缩降维、去噪的有效方法。
PCA的思想是将n维特征映射到k维上(k<n),这k维特征称为主元,是旧特征的线性组合,这些线性组合最大化样本方差,尽量使新的k个特征互不相关。

⑥ 声线年龄层怎么划分

从EDA、音频预处理到特征工程和数据建模的完整源代码演示
大多数人都熟悉如何在图像、文本或表格数据上运行数据科学项目。 但处理音频数据的样例非常的少见。 在本文中,将介绍如何在机器学习的帮助下准备、探索和分析音频数据。 简而言之:与其他的形式(例如文本或图像)类似我们需要将音频数据转换为机器可识别的格式。
音频数据的有趣之处在于您可以将其视为多种不同的模式:
· 可以提取高级特征并分析表格数据等数据。
· 可以计算频率图并分析图像数据等数据。
· 可以使用时间敏感模型并分析时间序列数据等数据。
· 可以使用语音到文本模型并像文本数据一样分析数据。
在本文中,我们将介绍前三种方法。 首先看看音频数据的实际样子。

音频数据的格式

虽然有多个 Python 库可以处理音频数据,但我们推荐使用 librosa。 让我们加载一个 MP3 文件并绘制它的内容。
# Import librosa
import librosa
# Loads mp3 file with a specific sampling rate, here 16kHz
y, sr = librosa.load("c4_sample-1.mp3", sr=16_000)
# Plot the signal stored in 'y'
from matplotlib import pyplot as plt
import librosa.display
plt.figure(figsize=(12, 3))
plt.title("Audio signal as waveform")
librosa.display.waveplot(y, sr=sr);
这里看到的是句子的波形表示。
1、波形 - 信号的时域表示
之前称它为时间序列数据,但现在我们称它为波形? 当只看这个音频文件的一小部分时,这一点变得更加清晰。 下图显示了与上面相同的内容,但这次只有 62.5 毫秒。
我们看到的是一个时间信号,它以不同的频率和幅度在值 0 附近振荡。该信号表示气压随时间的变化,或扬声器膜(或耳膜)的物理位移 . 这就是为什么这种对音频数据的描述也称为波形的原因。
频率是该信号振荡的速度。 低频例如 60 Hz 可能是低音吉他的声音,而鸟儿的歌声可能是 8000 Hz 的更高频率。 我们人类语言通常介于两者之间。
要知道这个信号在单位时间内从连续信号中提取并组成离散信号的采样个数,我们使用赫兹(Hz)来表示每秒的采样个数。 16'000 或 16k Hz表示美标采集了16000次。 我们在上图中可以看到的 1'000 个时间点代表了 62.5 毫秒(1000/16000 = 0.0625)的音频信号。
2、傅里叶变换——信号的频域表示
虽然之前的可视化可以告诉我们什么时候发生了(即 2 秒左右似乎有很多波形信号),但它不能真正告诉我们它发生的频率。 因为波形向我们显示了有关时间的信息,所以该信号也被称为信号的时域表示。
可以使用快速傅立叶变换,反转这个问题并获得关于存在哪些频率的信息,同时丢弃掉关于时间的信息。 在这种情况下,信号表示被称为信号的频域表示。
让我们看看之前的句子在频域中的表现。
import scipy
import numpy as np
# Applies fast fourier transformation to the signal and takes absolute values
y_freq = np.abs(scipy.fftpack.fft(y))
# Establishes all possible frequency
# (dependent on the sampling rate and the length of the signal)
f = np.linspace(0, sr, len(y_freq))
# Plot audio signal as frequency information.
plt.figure(figsize=(12, 3))
plt.semilogx(f[: len(f) // 2], y_freq[: len(f) // 2])
plt.xlabel("Frequency (Hz)")
plt.show();
可以在此处看到大部分信号在 ~100 到 ~1000 Hz 之间(即 10² 到 10³ 之间)。 另外,似乎还有一些从 1'000 到 10'000 Hz 的内容。
3、频谱图
我们并不总是需要决定时域或频域。 使用频谱图同时表示这两个领域中的信息,同时将它们的大部差别保持在最低限度。 有多种方法可以创建频谱图,但在本文中将介绍常见的三种。
3a 短时傅里叶变换 (STFT)
这时是之前的快速傅立叶变换的小型改编版本,即短时傅立叶变换 (STFT), 这种方式是以滑动窗口的方式计算多个小时间窗口(因此称为“短时傅立叶”)的 FFT。
import librosa.display
# Compute short-time Fourier Transform
x_stft = np.abs(librosa.stft(y))
# Apply logarithmic dB-scale to spectrogram and set maximum to 0 dB
x_stft = librosa.amplitude_to_db(x_stft, ref=np.max)
# Plot STFT spectrogram
plt.figure(figsize=(12, 4))
librosa.display.specshow(x_stft, sr=sr, x_axis="time", y_axis="log")
plt.colorbar(format="%+2.0f dB")
plt.show();
与所有频谱图一样,颜色代表在给定时间点给定频率的量(响度/音量)。 +0dB 是最响亮的,-80dB 接近静音。 在水平 x 轴上我们可以看到时间,而在垂直 y 轴上我们可以看到不同的频率。
3b 梅尔谱图
作为 STFT 的替代方案,还可以计算基于 mel 标度的梅尔频谱图。 这个尺度解释了我们人类感知声音音高的方式。 计算 mel 标度,以便人类将由 mel 标度中的 delta 隔开的两对频率感知为具有相同的感知差异。
梅尔谱图的计算与 STFT 非常相似,主要区别在于 y 轴使用不同的刻度。
# Compute the mel spectrogram
x_mel = librosa.feature.melspectrogram(y=y, sr=sr)
# Apply logarithmic dB-scale to spectrogram and set maximum to 0 dB
x_mel = librosa.power_to_db(x_mel, ref=np.max)
# Plot mel spectrogram
plt.figure(figsize=(12, 4))
librosa.display.specshow(x_mel, sr=sr, x_axis="time", y_axis="mel")
plt.colorbar(format="%+2.0f dB")
plt.show();
与 STFT 的区别可能不太明显,但如果仔细观察,就会发现在 STFT 图中,从 0 到 512 Hz 的频率在 y 轴上占用的空间比在 mel 图中要大得多 .
3c 梅尔频率倒谱系数 (MFCC)
梅尔频率倒谱系数 (MFCC) 是上面梅尔频谱图的替代表示。 MFCC 相对于 梅尔谱图的优势在于特征数量相当少(即独特的水平线标度),通常约为 20。
由于梅尔频谱图更接近我们人类感知音高的方式,并且 MFCC 只有少数几个分量特征,所以大多数机器学习从业者更喜欢 使用MFCC 以“图像方式”表示音频数据。 但是对于某些问题,STFT、mel 或波形表示可能会更好。
让我们继续计算 MFCC 并绘制它们。
# Extract 'n_mfcc' numbers of MFCCs components (here 20)
x_mfccs = librosa.feature.mfcc(y, sr=sr, n_mfcc=20)
# Plot MFCCs
plt.figure(figsize=(12, 4))
librosa.display.specshow(x_mfccs, sr=sr, x_axis="time")
plt.colorbar()
plt.show();

数据清洗

现在我们更好地理解了音频数据的样子,让我们可视化更多示例。
在这四个示例中,我们可以收集到有关此音频数据集的更多问题:
· 大多数录音在录音的开头和结尾都有一段较长的静默期(示例 1 和示例 2)。 这是我们在“修剪”时应该注意的事情。
· 在某些情况下,由于按下和释放录制按钮,这些静音期会被“点击”中断(参见示例 2)。
· 一些录音没有这样的静音阶段,即一条直线(示例 3 和 4)。
· 在收听这些录音时,有大量背景噪音。
为了更好地理解这在频域中是如何表示的,让我们看一下相应的 STFT 频谱图。
当听录音时,可以观察到样本 3 具有覆盖多个频率的不同背景噪声,而样本 4 中的背景噪声相当恒定。 这也是我们在上图中看到的。 样本 3 在整个过程中都非常嘈杂,而样本 4 仅在几个频率上(即粗水平线)有噪声。 我们不会详细讨论如何消除这种噪音,因为这超出了本文的范围。
但是让我们研究一下如何消除此类噪音并修剪音频样本的“捷径”。 虽然使用自定义过滤函数的更手动的方法可能是从音频数据中去除噪声的最佳方法,但在我们的例子中,将推荐使用实用的 python 包 noiserece。
import noiserece as nr
from scipy.io import wavfile
# Loop through all four samples
for i in range(4):
# Load audio file
fname = "c4_sample-%d.mp3" % (i + 1)
y, sr = librosa.load(fname, sr=16_000)
# Remove noise from audio sample
reced_noise = nr.rece_noise(y=y, sr=sr, stationary=False)
# Save output in a wav file as mp3 cannot be saved to directly
wavfile.write(fname.replace(".mp3", ".wav"), sr, reced_noise)
聆听创建的 wav 文件,可以听到噪音几乎完全消失了。 虽然我们还引入了更多的代码,但总的来说我们的去噪方法利大于弊。
对于修剪步骤,可以使用 librosa 的 .effects.trim() 函数。每个数据集可能需要一个不同的 top_db 参数来进行修剪,所以最好进行测试,看看哪个参数值好用。 在这个的例子中,它是 top_db=20。
# Loop through all four samples
for i in range(4):
# Load audio file
fname = "c4_sample-%d.wav" % (i + 1)
y, sr = librosa.load(fname, sr=16_000)
# Trim signal
y_trim, _ = librosa.effects.trim(y, top_db=20)
# Overwrite previous wav file
wavfile.write(fname.replace(".mp3", ".wav"), sr, y_trim)
现在让我们再看一下清理后的数据。
看样子好多了

特征提取

数据是干净的,应该继续研究可以提取的特定于音频的特征了。
1、开始检测
通过观察一个信号的波形,librosa可以很好地识别一个新口语单词的开始。
# Extract onset timestamps of words
onsets = librosa.onset.onset_detect(
y=y, sr=sr, units="time", hop_length=128, backtrack=False)
# Plot onsets together with waveform plot
plt.figure(figsize=(8, 3))
librosa.display.waveplot(y, sr=sr, alpha=0.2, x_axis="time")
for o in onsets:
plt.vlines(o, -0.5, 0.5, colors="r")
plt.show()
# Return number of onsets
number_of_words = len(onsets)
print(f"{number_of_words} onsets were detected in this audio signal.")
>>> 7 onsets were detected in this audio signal
2、录音的长度
与此密切相关的是录音的长度。录音越长,能说的单词就越多。所以计算一下录音的长度和单词被说出的速度。
ration = len(y) / sr
words_per_second = number_of_words / ration
print(f"""The audio signal is {ration:.2f} seconds long,
with an average of {words_per_second:.2f} words per seconds.""")
>>> The audio signal is 1.70 seconds long,
>>> with an average of 4.13 words per seconds.
3、节奏
语言是一种非常悦耳的信号,每个人都有自己独特的说话方式和语速。因此,可以提取的另一个特征是说话的节奏,即在音频信号中可以检测到的节拍数。
# Computes the tempo of a audio recording
tempo = librosa.beat.tempo(y, sr, start_bpm=10)[0]
print(f"The audio signal has a speed of {tempo:.2f} bpm.")
>>> The audio signal has a speed of 42.61 bpm.
4、基频
基频是周期声音出现时的最低频率。在音乐中也被称为音高。在之前看到的谱图图中,基频(也称为f0)是图像中最低的亮水平条带。而在这个基本音之上的带状图案的重复称为谐波。
为了更好地说明确切意思,下面提取基频,并在谱图中画出它们。
# Extract fundamental frequency using a probabilistic approach
f0, _, _ = librosa.pyin(y, sr=sr, fmin=10, fmax=8000, frame_length=1024)
# Establish timepoint of f0 signal
timepoints = np.linspace(0, ration, num=len(f0), endpoint=False)
# Plot fundamental frequency in spectrogram plot
plt.figure(figsize=(8, 3))
x_stft = np.abs(librosa.stft(y))
x_stft = librosa.amplitude_to_db(x_stft, ref=np.max)
librosa.display.specshow(x_stft, sr=sr, x_axis="time", y_axis="log")
plt.plot(timepoints, f0, color="cyan", linewidth=4)
plt.show();
在 100 Hz 附近看到的绿线是基本频率。 但是如何将其用于特征工程呢? 可以做的是计算这个 f0 的具体特征。
# Computes mean, median, 5%- and 95%-percentile value of fundamental frequency
f0_values = [
np.nanmean(f0),
np.nanmedian(f0),
np.nanstd(f0),
np.nanpercentile(f0, 5),
np.nanpercentile(f0, 95),
]
print("""This audio signal has a mean of {:.2f}, a median of {:.2f}, a
std of {:.2f}, a 5-percentile at {:.2f} and a 95-percentile at {:.2f}.""".format(*f0_values))
>>> This audio signal has a mean of 81.98, a median of 80.46, a
>>> std of 4.42, a 5-percentile at 76.57 and a 95-percentile at 90.64.
除以上说的技术意外,还有更多可以探索的音频特征提取技术,这里就不详细说明了。

音频数据集的探索性数据分析 (EDA)

现在我们知道了音频数据是什么样子以及如何处理它,让我们对它进行适当的 EDA。 首先下载一个数据集Kaggle 的 Common Voice 。 这个 14 GB 的大数据集只是来自 Mozilla 的 +70 GB 大数据集的一个小的快照。 对于本文这里的示例,将只使用这个数据集的大约 9'000 个音频文件的子样本。
看看这个数据集和一些已经提取的特征。
1、特征分布调查
目标类别年龄和性别的类别分布。
目标类别分布是不平衡的
下一步,让我们仔细看看提取的特征的值分布。
除了 words_per_second,这些特征分布中的大多数都是右偏的,因此可以从对数转换中获益。
import numpy as np
# Applies log1p on features that are not age, gender, filename or words_per_second
df = df.apply(
lambda x: np.log1p(x)
if x.name not in ["age", "gender", "filename", "words_per_second"]
else x)
# Let's look at the distribution once more
df.drop(columns=["age", "gender", "filename"]).hist(
bins=100, figsize=(14, 10))
plt.show();
好多了,但有趣的是 f0 特征似乎都具有双峰分布。 让我们绘制与以前相同的内容,但这次按性别分开。
正如怀疑的那样,这里似乎存在性别效应! 但也可以看到,一些 f0 分数(这里特别是男性)比应有的低和高得多。 由于特征提取不良,这些可能是异常值。 仔细看看下图的所有数据点。
# Plot sample points for each feature indivially
df.plot(lw=0, marker=".", subplots=True, layout=(-1, 3),
figsize=(15, 7.5), markersize=2)
plt.tight_layout()
plt.show();
鉴于特征的数量很少,而且有相当漂亮的带有明显尾部的分布,可以遍历它们中的每一个,并逐个特征地确定异常值截止阈值。
2、特征的相关性
下一步,看看所有特征之间的相关性。 但在这样做之前需要对非数字目标特征进行编码。 可以使用 scikit-learn 的 OrdinalEncoder 来执行此操作,但这可能会破坏年龄特征中的正确顺序。 因此在这里手动进行映射。
# Map age to appropriate numerical value
df.loc[:, "age"] = df["age"].map({
"teens": 0,
"twenties": 1,
"thirties": 2,
"fourties": 3,
"fifties": 4,
"sixties": 5})
# Map gender to corresponding numerical value
df.loc[:, "gender"] = df["gender"].map({"male": 0, "female": 1})
现在可以使用 pandas 的 .corr() 函数和 seaborn 的 heatmap() 来更深入地了解特征相关性。
import seaborn as sns
plt.figure(figsize=(8, 8))
df_corr = df.corr() * 100
sns.heatmap(df_corr, square=True, annot=True, fmt=".0f",
mask=np.eye(len(df_corr)), center=0)
plt.show();
非常有趣!提取的 f0 特征似乎与性别目标有相当强的关系,而年龄似乎与任何其他的特征都没有太大的相关性。
3、频谱图特征
目前还没有查看实际录音。 正如之前看到的,有很多选择(即波形或 STFT、mel 或 mfccs 频谱图)。
音频样本的长度都不同,这意味着频谱图也会有不同的长度。 因此为了标准化所有录音,首先要将它们剪切到正好 3 秒的长度:太短的样本会被填充,而太长的样本会被剪掉。
一旦计算了所有这些频谱图,我们就可以继续对它们执行一些 EDA! 而且因为看到“性别”似乎与录音有特殊的关系,所以分别可视化两种性别的平均梅尔谱图,以及它们的差异。
男性说话者的平均声音低于女性。 这可以通过差异图中的较低频率(在红色水平区域中看到)的更多强度来看出。

模型选择

现在已经可以进行建模了。我们有多种选择。关于模型,我们可以……
· 训练我们经典(即浅层)机器学习模型,例如 LogisticRegression 或 SVC。
· 训练深度学习模型,即深度神经网络。
· 使用 TensorflowHub 的预训练神经网络进行特征提取,然后在这些高级特征上训练浅层或深层模型
而我们训练的数据是
· CSV 文件中的数据,将其与频谱图中的“mel 强度”特征相结合,并将数据视为表格数据集
· 单独的梅尔谱图并将它们视为图像数据集
· 使用TensorflowHub现有模型提取的高级特征,将它们与其他表格数据结合起来,并将其视为表格数据集
当然,有许多不同的方法和其他方法可以为建模部分创建数据集。因为我们没有使用全量的数据,所以在本文我们使用最简单的机器学习模型。

经典(即浅层)机器学习模型

这里使用EDA获取数据,与一个简单的 LogisticRegression 模型结合起来,看看我们能在多大程度上预测说话者的年龄。除此以外还使用 GridSearchCV 来探索不同的超参数组合,以及执行交叉验证。
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import RobustScaler, PowerTransformer, QuantileTransformer
from sklearn.decomposition import PCA
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV
# Create pipeline
pipe = Pipeline(
[
("scaler", RobustScaler()),
("pca", PCA()),
("logreg", LogisticRegression(class_weight="balanced")),
]
)
# Create grid
grid = {
"scaler": [RobustScaler(), PowerTransformer(), QuantileTransformer()],
"pca": [None, PCA(0.99)],
"logreg__C": np.logspace(-3, 2, num=16),
}
# Create GridSearchCV
grid_cv = GridSearchCV(pipe, grid, cv=4, return_train_score=True, verbose=1)
# Train GridSearchCV
model = grid_cv.fit(x_tr, y_tr)
# Collect results in a DataFrame
cv_results = pd.DataFrame(grid_cv.cv_results_)
# Select the columns we are interested in
col_of_interest = [
"param_scaler",
"param_pca",
"param_logreg__C",
"mean_test_score",
"mean_train_score",
"std_test_score",
"std_train_score",
]
cv_results = cv_results[col_of_interest]
# Show the dataframe sorted according to our performance metric
cv_results.sort_values("mean_test_score", ascending=False)
作为上述 DataFrame 输出的补充,还可以将性能得分绘制为探索的超参数的函数。 但是因为使用了有多个缩放器和 PCA ,所以需要为每个单独的超参数组合创建一个单独的图。
在图中,可以看到总体而言模型的表现同样出色。 当降低 C 的值时,有些会出现更快的“下降”,而另一些则显示训练和测试(这里实际上是验证)分数之间的差距更大,尤其是当我们不使用 PCA 时。
下面使用 best_estimator_ 模型,看看它在保留的测试集上的表现如何。
# Compute score of the best model on the withheld test set
best_clf = model.best_estimator_
best_clf.score(x_te, y_te)
>>> 0.4354094579008074
这已经是一个很好的成绩了。 但是为了更好地理解分类模型的表现如何,可以打印相应的混淆矩阵。
虽然该模型能够检测到比其他模型更多的 20 岁样本(左混淆矩阵),但总体而言,它实际上在对 10 岁和 60 岁的条目进行分类方面效果更好(例如,准确率分别为 59% 和 55%)。

总结

在这篇文章中,首先看到了音频数据是什么样的,然后可以将其转换成哪些不同的形式,如何对其进行清理和探索,最后如何将其用于训练一些机器学习模型。如果您有任何问题,请随时发表评论。
最后本文的源代码在这里下载:
https://www.overfit.cn/post/
作者:Michael Notter

热点内容
mysql解压后 发布:2024-05-13 21:05:43 浏览:341
mac如何给文件夹加密 发布:2024-05-13 20:25:50 浏览:352
路由器和远程访问 发布:2024-05-13 19:49:44 浏览:213
ftp五个转换步骤是什么 发布:2024-05-13 19:45:15 浏览:835
页面显示源码 发布:2024-05-13 19:27:42 浏览:741
视频站配什么服务器 发布:2024-05-13 19:12:48 浏览:466
mc驱动编译教学 发布:2024-05-13 19:11:12 浏览:440
r9s怎么关闭应用加密 发布:2024-05-13 19:02:57 浏览:535
末并的算法 发布:2024-05-13 18:38:03 浏览:406
java入门视频教学 发布:2024-05-13 18:37:48 浏览:449