day06-情感分析-主题抽取-语音识别-声音合成-图像识别-
10.情感分析
一个样本一个tuple: (dict: {特征名: 特征值}, 输出)
整个样本集就是一个tuple的list
代码:sent.py
import nltk.corpus as nc #语料库
import nltk.classify as cf #自然语言分类器
import nltk.classify.util as cu #自然语言分类辅助工具
pdata = []
fileids = nc.movie_reviews.fileids('pos') #nltk_data\corpora\movie_reviews目录模块下的pos子目录
for fileid in fileids:#获得pos目录下的各样本文件名
feature = {} #按一个文件构建一个样本
words = nc.movie_reviews.words(fileid) #获得文件名对应文件中的所有单词
for word in words: #将文件中的单词变成由True, 和False构成的字典
feature[word] = True; #即键名为word, 键值为True
pdata.append((feature, 'POSITIVE')) #POSITIVE进行正面评价
ndata = []
fileids = nc.movie_reviews.fileids('neg') #nltk_data\corpora\movie_reviews目录模块下的neg子目录
for fileid in fileids:#获得neg目录下的各样本文件名
feature = {} #按一个文件构建一个样本
words = nc.movie_reviews.words(fileid) #获得文件名对应文件中的所有单词
for word in words: #将文件中的单词变成由True, 和False构成的字典
feature[word] = True; #即键名为word, 键值为True
ndata.append((feature, 'NEGATIVE')) #NEGATIVE进行负面评价
pnumb,nnumb = int(len(pdata)*0.8),int(len(ndata)*0.8)#将80%的正负评价样本作为训练样本
train_data = pdata[:pnumb] + ndata[:nnumb]
test_data = pdata[pnumb:] + ndata[nnumb:] #将20%的正负评价样本作为测试样本
#以上数据准备工作完成,分别准备了80%的训练数据,20%的测试数据
model = cf.NaiveBayesClassifier.train(train_data) #进行训练,返回训练好的模型
ac = cu.accuracy(model,test_data)#同测试数据测试模型的精度.
print(ac)#输出得分情况
tops = model.most_informative_features()#获取最重要的特征
for top in tops[:10]:
print(top[0])#输出最重要特征的名称
reviews =[ #预测数据准备
'It is an amazing movie. ',
'This is a dull movie. I would never recommend it to anyone. ',
'The cinematography is pretty great in this movie. ',
'The direction was terrible and the story was all over the place. ']
sents , probs = [],[]
for review in reviews:
feature = {} #将每句话作为一个样本
words = review.split()
for word in words:
feature[word] = True
pcls = model.prob_classify(feature) #进行预测,获得置信概率矩阵
#print(pcls)
sent = pcls.max() #获得最大置信概率的类别
prob = pcls.prob(sent) #概率值
sents.append(sent)
probs.append(prob)
for review, sent, prob in zip(reviews,sents,probs):
print(review,'-->',sent,'%.2f'%prob)
11.主题抽取
主题识别是一种有监督学习方式
主题抽取是一种无监督学习方式,如自动摘要生成
主题都是与词频有关
基于LDA,隐狄利克雷分布
import gensim.models.ldamodel as gm#主题抽取模块.模型集.主题抽取
import gensim.corpora as gc#主题抽取模块.素材
dic = gc.Dictionary(lines_tokens) #将获得的词干构造词典
line_tokens:词干
model = gm.LdaModel(bow,num_topics=n_topics,id2word=dic,passes=25)
bow:词袋;num_topics:主题数;id2word:通过词典中索引号找词
passes:每个主题的词语数量
topics = model.print_topics(num_topics=n_topics,num_words=4)#获取主题
num_topics:输出的主题数;num_words:每个主题输出的单词数
代码示例:topic.py
import warnings
warnings.filterwarnings('ignore',category=UserWarning)
import nltk.tokenize as tk #分词器
import nltk.corpus as nc #语料库 终止词过滤 或废词 高频,但语义贡献很小的词
import nltk.stem.snowball as sb #思诺博词干提取器
import gensim.models.ldamodel as gm #主题抽取模块.模型集.主题抽取
import gensim.corpora as gc #主题抽取模块.素材
doc = []
with open('../../day01/data/topic.txt','r') as f:
for line in f.readlines():
doc.append(line[:-1])
tokenizer = tk.RegexpTokenizer(r'\w+')#用正则表达式描述分隔符
stopwords = nc.stopwords.words('english') #取英语废词 语料库目录:nltk_data\corpora\stopwords
stemmer = sb.SnowballStemmer('english') #英语词干提取器
lines_tokens = []
for line in doc:
tokens = tokenizer.tokenize(line.lower())
line_tokens = []
for token in tokens:
if token not in stopwords:#如果不是废词
token = stemmer.stem(token) #抽取词干
line_tokens.append(token)
lines_tokens.append(line_tokens)
#以上数据准备主要作用是过滤废词,抽取词干
dic = gc.Dictionary(lines_tokens) #将获得的词干构造词典
bow = []
for line_tokens in lines_tokens:
row = dic.doc2bow(line_tokens) #文档词典到词袋
bow.append(row)#构造词袋
n_topics = 2
model = gm.LdaModel(bow,num_topics=n_topics,id2word=dic,passes=25)
topics = model.print_topics(num_topics=n_topics,num_words=4)#获取主题
print(topics)
十五、语音识别
1.声音的本质是震动,是一个位移关于时间的函数
Signal:s = f(t)
.wav剥削声音文件记录了不同采样时刻的位移
2.通过傅里叶变换,可以将时间域的声音函数分解为一系列不同频率
的正玄函数的叠加,通过频率谱线的特殊分布,建立音频内容和文
本的对应关系,以此作为模型训练的基础。
代码示例:audio.py
import numpy as np
import numpy.fft as nf
import scipy.io.wavfile as wf
import matplotlib.pyplot as mp
sample_rate,sigs = wf.read('../../day01/data/freq.wav') #sample_rate,采样率,noised_sigs信号
sigs = sigs / 2**15 #数据还原
times = np.arange(len(sigs))/sample_rate #获得采样点时间
freqs = nf.fftfreq(sigs.size,1/sample_rate) # sample_rate采样频率的倒数即为采样周期
ffts = nf.fft(sigs) # 进行傅里叶变换,获得复数形式的离散函数组
pows = np.abs(ffts) # 对复数取模,获得能量值
mp.figure('Audio',facecolor='lightgray')
mp.subplot(121)
mp.title('timeDoDomain',fontsize=16)
mp.ylabel('Sigal',fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(times,sigs,label='Audio')
mp.legend()
mp.subplot(122)
mp.title('Freq Domain',fontsize=16)
mp.ylabel('power',fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(freqs[freqs>=0],pows[freqs>=0],label='power')
mp.legend()
mp.tight_layout()
mp.show()
3.梅尔频率倒谱系数(MFCC)
通过与声音内容密切相关的13个特殊频率所对应的能量分布,作为
语音的特征。
特征工程学,专业研究如何抓取事物的特征。
import python_speech_features as sf
mfcc=sf.mfcc(sigs,sample_rate)
sample_rate,采样率,sigs信号
代码示例:mfcc.py
import scipy.io.wavfile as wf
import python_speech_features as sf
import matplotlib.pyplot as mp
#sample_rate,sigs = wf.read('../../day01/data/speeches/training/apple/apple01.wav') #sample_rate,采样率,sigs信号
#sample_rate,sigs = wf.read('../../day01/data/speeches/training/apple/apple07.wav')
sample_rate,sigs = wf.read('../../day01/data/speeches/training/orange/orange01.wav') #sample_rate,采样率,sigs信号
mfcc=sf.mfcc(sigs,sample_rate)
print(mfcc.shape)
mp.matshow(mfcc.T,cmap='gist_rainbow',fignum='MFCC')
mp.title('Sample',fontsize=16)
mp.ylabel('Feature',fontsize=12)
mp.tick_params(which='bothl',top=False,labeltop=False,
labelbottom=True,labelsize=10)
mp.show()
4.语音识别(声音转为文字)
隐马尔科夫模型
GaussianHMM基于正态分布(高斯分布)的隐藏式马尔科夫模型,叫隐马尔科夫模型
是一种生成模型,有输入时,可记录输入输出的关联关系,
无输入时,会自动生成一套数据,生成的数据规则同训练数据的规则一样。
在神经学中叫自编码器,传统机器学习中叫生成模型
如某人看了一本书或一个电影,然后再将主要内容,主要特点复述出来,就是叫隐马尔科夫模型
即凭记忆描述或还原一些感兴趣的事物,就叫隐马尔科夫模型
用统计方法(高斯分布)去发现一个随机特性样本的分布中心.
分布中心是一个特征聚集的地方。
即隐马尔科夫模型主要记忆分布中心的数据
模块安装:
1.下载包https://www.lfd.uci.edu/~gohlke/pythonlibs/
hmmlearn‑0.2.1‑cp37‑cp37m‑win_amd64.whl
2.cd 到下载保存的目录
3.python -m pip install hmmlearn‑0.2.1‑cp37‑cp37m‑win_amd64.whl
接口使用:
import hmmlearn.hmm as hl
models = hl.GaussianHMM(n_components=4,covariance_type='diag',n_iter=1000)
n_components分布中心(隐藏状态)数量;
covariance_type用相关矩阵的diag辅对角线来判定协方差,判断相关性
n_iter最大迭代次数,即反复优化次数
代码示例:spch.py
import os
import warnings
import numpy as np
import scipy.io.wavfile as wf
import python_speech_features as sf
import hmmlearn.hmm as hl
warnings.filterwarnings('ignore',category=DeprecationWarning)
np.seterr(all='ignore')
def search_speeches(directory,speeches):
directory = os.path.normpath(directory) #适应跨需要,将路径规范化
if not os.path.isdir(directory):
raise IOError('目录不存在:'+directory)
for entry in os.listdir(directory):#遍历目录
sep = directory.rfind(os.path.sep)#寻找目录分隔符
label = directory[sep+1:] #获得目录名称
path = os.path.join(directory,entry)
if os.path.isdir(path):
search_speeches(path, speeches)
elif os.path.isfile(path) and path.endswith('.wav'):#endswith('.wav') 判断文件是否以.wav结尾
if label not in speeches:
speeches[label] = []
speeches[label].append(path)
train_speechs={}
search_speeches('../../day01/data/speeches/training',train_speechs)
#print(train_speechs)
train_x,train_y = [],[]
for label,filenames in train_speechs.items():
mfccs = np.array([])
for filename in filenames:
sample_rate , sigs = wf.read(filename)
mfcc = sf.mfcc(sigs,sample_rate)
if len(mfccs) == 0:
mfccs = mfcc
else:
mfccs = np.append(mfccs,mfcc,axis=0) #在行方向追加
train_x.append(mfccs)
train_y.append(label)
#print(len(train_y),len(train_x))
models = {}
for mfccs , label in zip(train_x,train_y):#训练
# n_components分布中心(隐藏状态)数量;covariance_type用相关矩阵的diag辅对角线来判定协方差,判断相关性
#n_iter最大迭代次数,即反复优化次数
model = hl.GaussianHMM(n_components=4,covariance_type='diag',n_iter=1000)
models[label] = model.fit(mfccs)
#开始测试
test_speechs={}
search_speeches('../../day01/data/speeches/testing',test_speechs)
test_x,test_y = [],[]
for label,filenames in train_speechs.items():
mfccs = np.array([])
for filename in filenames:
sample_rate , sigs = wf.read(filename)
mfcc = sf.mfcc(sigs,sample_rate)
if len(mfccs) == 0:
mfccs = mfcc
else:
mfccs = np.append(mfccs,mfcc,axis=0) #在行方向追加
test_x.append(mfccs)
test_y.append(label)
pred_test_y = []
for mfccs in test_x:
best_score,best_label = None,None
for label,model in models.items():
score = model.score(mfccs) #相似度得分
if (best_score is None) or (best_score < score):
best_score,best_label = score,label
pred_test_y.append(best_label)
print(test_y) #实际的单词
print(pred_test_y) #预测出来的单词
5.声音合成(文字转为声音)
代码示例:music.py
import json
import numpy as np
import scipy.io.wavfile as wf
with open('../../day01/data/12.json','r') as f:
freqs = json.loads(f.read())
tones = [#乐谱
('G5',0.5),('A5',0.5),('G5',1.0),('E5',0.5),('D5',0.5),
('E5',0.25),('D5',0.25),('C5',0.5),('A4',0.5),('C5',0.75)
]
sample_rate = 44100
music = np.empty(shape=1)
for tone, duration in tones:
times = np.linspace(0,duration,duration * sample_rate)
sound = np.sin(2*np.pi * freqs[tone] * times)
music = np.append(music,sound)
music *= 2**15
music = music.astype(np.int16)
wf.write('./music.wav',sample_rate,music)
十六、图像识别
1、图像处理
OpenCV,机器视觉,核心是图像特征抽取
模块安装:
pip install opencv-python==3.4.2.16
pip install opencv-contrib-python==3.4.2.16
代码示例:basicCV.py
import cv2 as cv
import numpy as np
original = cv.imread('../../day01/data/forest.jpg')
print(original.shape)#(397, 600, 3) ( 高, 宽,颜色通道 )如果黑白,是二维,没有颜色通道
cv.imshow('photo',original)#显示图片
blue = np.zeros_like(original) #zeros_like,表示填充的0,要与original维度元素类型一致
blue[...,0] = original[...,0] #0是蓝色通道;1 是绿色通道; 2 是红色通道
cv.imshow('blue',blue)
h,w = original.shape[:2] #获取图片的高,宽
l,t = int(w / 4), int(h / 4 )#左上角为原点,获取左,上边界
r,b = int(w*3/4),int(h*3/4)#获取右,底边界
cropped = original[t:b,l:r] #裁剪图片
cv.imshow('cropped',cropped)
scaled1 = cv.resize(original,(int(w/2),int(h/2)),#缩放图片 ,缩放到原来的1/4
interpolation=cv.INTER_LINEAR)#线性颜色平滑,颜色差值,柔和一些
cv.imshow('scaled1',scaled1)
scaled2 = cv.resize(scaled1,None,fx=2,fy=2, #fx=2,fy=2水平和垂直方向放大2倍
interpolation=cv.INTER_LINEAR)
cv.imshow('scaled2',scaled2)
cv.waitKey() #阻塞,等待按键退出图片显示
cv.imwrite('./blue.jpg',blue) #保存图片
2、边缘检测
亮度梯度
可通过聚类或浮雕效果的方式先做预处理
索贝尔梯度:可在水平和垂直方向上单独做索贝尔微分,利用索贝尔矩阵求
偏微分,利用偏微分求梯度。
cv.Sobel(original,cv.CV_64F,水平开关,垂直开关,ksize=) 索贝尔梯度
original要处理的图片;CV_64F,将图片中的数据类型转换为64位浮点数
水平开关,垂直开关:1,打开,0,关闭
如:1,0,表示只做水平梯度
ksize=5 卷积核大小,为5 * 5 矩阵
拉普拉斯边缘识别(拉氏变换)
cv.Laplacian(original,cv.CV_64F)
Canny边缘检测算法(最常用,较好的检测算法)
cv.Canny(original,50,240) 后面两个数值为超参数
50水平方向梯度最值,240垂直方向梯度最值
代码示例:edge.py
import cv2 as cv
original = cv.imread('../../day01/data/chair.jpg',
cv.IMREAD_GRAYSCALE)#IMREAD_GRAYSCALE灰度方式读取
# print(original.shape)
# cv.imshow(' ',original)
#Sobel(original,cv.CV_64F,水平开关,垂直开关)
#CV_64F,将图片中的数据类型转换为64位浮点数
#水平开关,垂直开关:1,打开,0,关闭
#ksize = 5 卷积核大小,为5 * 5 矩阵
hsobel = cv.Sobel(original,cv.CV_64F,1,0,ksize=5) #索贝尔水平梯度cv
#cv.imshow('h',hsobel)
vsobel = cv.Sobel(original,cv.CV_64F,0,1,ksize=5) #索贝尔垂直梯度cv
#cv.imshow('v',vsobel)
sobel = cv.Sobel(original,cv.CV_64F,1,1,ksize=5) #索贝尔水平与垂直梯度cv
#cv.imshow('hv',sobel)
laplacian = cv.Laplacian(original,cv.CV_64F)#拉普拉斯边缘识别(拉氏变换)
#cv.imshow('ls',laplacian)
canny = cv.Canny(original,50,240)#Canny边缘检测算法 水平方向梯度最值,垂直方向梯度最值
cv.imshow('canny',canny)
cv.waitKey()
3.亮度提升
直方图均衡化
代码示例:eq.py
import cv2 as cv
original = cv.imread('../../day01/data/sunrise.jpg')
#cv.imshow('or ',original)
gray = cv.cvtColor(original,cv.COLOR_BGR2GRAY) #转为灰度图片
#cv.imshow('gr ',gray)
grayH = cv.equalizeHist(gray)#直方图均衡化
cv.imshow('grayH',grayH)
#将BGR彩色图片映射到YUV格式,
#YUV也是三维通道数组,最后一位通道0代表亮度,1代表色度,2代表饱和度
yuv = cv.cvtColor(original,cv.COLOR_BGR2YUV)
#0通道均衡化后覆盖原来的0通道
yuv[...,0] = cv.equalizeHist(yuv[...,0]) #0 代表取出亮度通道 ,对亮度通道做均衡化
yuv2bgr = cv.cvtColor(yuv,cv.COLOR_YUV2BGR) #将YUV转为BGR
cv.imshow('YUV2BGR',yuv2bgr)
cv.waitKey()
4.角点检测
平直棱线的交汇点
哈里斯角点检测
cv.cornerHarris(图片,水平方向边缘值,垂直方向边缘值,弧度)
代码示例:corner.py
import cv2 as cv
original = cv.imread('../../day01/data/box.png')
cv.imshow(' ',original)
gray = cv.cvtColor(original,cv.COLOR_BGR2GRAY)
cv.imshow(' ',gray)
#哈里斯角点检测,在水平和垂直方向梯度变化大于7 和 5就是边缘,边缘线改变0,04的弧度就认为是角点
corner = cv.cornerHarris(gray,7,5,0.04)
corner = cv.dilate(corner,None)#滤波,去除干扰
mixture = original.copy()
mixture[corner > corner.max() *0.01] = [0,0,255] #在原图中标准角点为红色
cv.imshow(' ',mixture)
cv.waitKey()
5.特征点检测
STAR方式:
star = cv.xfeatures2d.StarDetector_create()
star.detect(图片的)获得检测点
mixture = original.copy()
cv.drawKeypoints(image,keypoints,outImage,
flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
绘制关键点的函数: cv2.drawKeyPoints(),它可以在关键点的部位绘制一个小圆圈。
如果你设置参数为 cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_就会绘制代表关键点大小的
圆圈甚至可以绘制除关键点的方向。
image:原始图像,可以使三通道或单通道图像;
keypoints:特征点向量,向量内每一个元素是一个KeyPoint对象,包含了特征点的各种属性信息;
outImage:特征点绘制的画布图像,可以是原图像;
color:绘制的特征点的颜色信息,默认绘制的是随机彩色;
flags:特征点的绘制模式,其实就是设置特征点的那些信息需要绘制,那些不需要绘制,有以下几种模式可选:
DEFAULT:只绘制特征点的坐标点,显示在图像上就是一个个小圆点,每个小圆点的圆心坐标都是特征点的坐标。
DRAW_OVER_OUTIMG:函数不创建输出的图像,而是直接在输出图像变量空间绘制,
要求本身输出图像变量就 是一个初始化好了的,size与type都是已经初始化好的变量
NOT_DRAW_SINGLE_POINTS:单点的特征点不被绘制
DRAW_RICH_KEYPOINTS:绘制特征点的时候绘制的是一个个带有方向的圆,
这种方法同时显示图像的坐标,size,和方向,是最能显示特征的一种绘制方式。
keypoints对象包含的信息有:
angle:角度,表示关键点的方向,通过Lowe大神的论文可以知道,为了保证方向不变形,
SIFT算法通过对关键点周围邻域进行梯度运算,求得该点方向。-1为初值。
class_id:当要对图片进行分类时,我们可以用class_id对每个特征点进行区分,
未设定时为-1,需要靠自己设定
octave:代表是从金字塔哪一层提取的得到的数据。
pt:关键点点的坐标
response:响应程度,代表该点强壮大小,更确切的说,是该点角点的程度。
size:该点直径的大小
代码示例:star.py
import cv2 as cv
original = cv.imread('../../day01/data/table.jpg')
cv.imshow(' ',original)
gray = cv.cvtColor(original,cv.COLOR_BGR2GRAY)
cv.imshow(' ',gray)
star = cv.xfeatures2d.StarDetector_create()
keystar = star.detect(gray)
mixture = original.copy()
cv.drawKeypoints(original,keystar,mixture,
flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv.imshow(' ',mixture)
cv.waitKey()
SIFT方式:
sift = cv.xfeatures2d.SIFT_create()
keystar = sift.detect(gray)
代码示例:sift.py
#运行库报错:Set OPENCV_ENABLE_NONFREE CMake option and rebuild the library in function 'cv::xfeatures2d::SIFT::create'
#这里如果运行库报错,需卸载重新安装时指定版本号==3.4.2.16
#如果其他版本,也会报错。
import cv2 as cv
original = cv.imread('../../day01/data/table.jpg')
cv.imshow(' ',original)
gray = cv.cvtColor(original,cv.COLOR_BGR2GRAY)
cv.imshow(' ',gray)
#star = cv.xfeatures2d.StarDetector_create()
sift = cv.xfeatures2d.SIFT_create()
#keystar = star.detect(gray)
keystar = sift.detect(gray)
mixture = original.copy()
#园中的半径,代表偏导方向,与边缘线垂直
cv.drawKeypoints(original,keystar,mixture,
flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv.imshow(' ',mixture)
cv.waitKey()