一、基于内容的图像检索
在大型数据库上,CBIR(Content-Based Image Retrieval,基于内容的图像检索)技术用于检索在视觉上具有相似性的图像。这样返回的图像可以是颜色相似,纹理相似,图像中的物体或场景相似;总之,基本上可以是这些图像自身共有的任何信息。
对于高层查询,比如寻找相似的物体,将查询图像与数据库中所有的图像进行完全比较(比如用特征匹配)往往是不可行的。在数据库很大的情况下,这样的查询方式会消耗过多时间。在过去的几年里,研究者成功地引入文本挖掘技术到CBIR中处理问题,使在数百万图像中搜索具有相似内容的图像成为可能。
从文本挖掘中获取灵感——矢量空间模型
矢量空间模型是用于表示和搜索文本文档的模型。我们将看到,它基本上可以应用于任何对象类型,包括图像。该名字来源于用矢量来表示文本文档,这些矢量是有文本词频直方图构成的。换句话说,矢量包含了每个单词出现的次数,而且在其他别的地方包含很多0元素。由于其忽略了单词出现的顺序及位置,该模型也被称为BOW表示模型。
通过单词计算来构建文档直方图向量v,从而建立文档索引。通常,在单词计数时会忽略掉一些常用词,如“这”“和”“是”等,这些常用词称为停用词。由于每篇文档长度不同,故除以直方图总和将向量归一化成单位长度。对于直方图向量中的每个元素,一般根据每个单词的重要性来赋予相应的权重。通常,数据集(或语料库)中一个单词的重要性来赋予相应的权重。通常,数据集(或语料库)中一个单词的重要性与它在文档中出现的次数成正比,而与它在语料库中出现的次数为反比。
最常用的权重是tf-idf(term frequency-inverse document frequency,词频-逆向文档频率),单词w在文档d中的词频是:
nw是单词w在文档d中出现的次数。为了归一化,将nw除以整个文档中单词的总数。
逆向文档频率为:
|D|是在语料库D中文档的数目,分母是语料库中包含单词w的文档数d。将两者相乘可以得到矢量v中对应元素的tf-idf权重。
用python3实现tf-idf算法:
from collections import defaultdict
import math
import operator
"""
函数说明:创建数据样本
Returns:
dataset:实验样本切分的词条
classvec:类别标签向量
"""
def loadDataSet():
dataset = [['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'], # 切分的词条
['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
['stop', 'posting', 'stupid', 'worthless', 'garbage'],
['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
classvec = [0, 1, 0, 1, 0, 1] # 类别标签向量,1代表好,0代表不好
return dataset, classvec
"""
函数说明:特征选择TF-IDF算法
Parameters:
list_words:词列表
Returns:
dict_feature_select:特征选择词字典
"""
def feature_select(list_words):
# 总词频统计
doc_frequency = defaultdict(int)
for word_list in list_words:
for i in word_list:
doc_frequency[i] += 1
# 计算每个词的TF值
word_tf = {} # 存储每个单词的tf值
for i in doc_frequency:
word_tf[i] = doc_frequency[i] / sum(doc_frequency.values())
# 计算每个词的IDF值
doc_num = len(list_words)
word_idf = {} # 存储每个词的idf值
word_doc = defaultdict(int)
for i in doc_frequency:
for j in list_words:
if i in j:
word_doc[i] += 1
for i in doc_frequency:
word_idf[i] = math.log(doc_num / (word_doc[i]+1))
# 计算每个词的TF*IDF的值
word_tf_idf = {}
for i in doc