在Python卷积hypercolumns

如果你是以下一些机器学习的消息,你肯定看到了瑞恩·达尔所做的工作自动彩色化黑客新闻评论reddit的评论)。这个惊人的工作是采用像素hypercolumn从VGG-16网络,以便提取上色图像的信息。SAMIM还使用的网络来处理黑白视频帧和下面产生的惊人的视频:

https://www.youtube.com/watch?v=_MJU8VK2PI4

着色黑白电影与神经网络(由SAMIM视频,网络由Ryan)

但如何做到这一点hypercolumns作品?如何提取他们在这样的各种像素的分类问题使用?这篇文章的主要思想是使用具有Keras和Scikit-学习VGG-16预训练的网络一起,以提取像素hypercolumns并采取目前其上的信息的肤浅的样子。我写这篇文章,因为我还没有发现在Python什么做到这一点,这可能是别人对像素分类,分割等工作真的很有用

Hypercolumns

使用来自细胞神经网络(卷积神经网络)提供许多算法通常使用最后FC(完全连接)层,以便提供至约的某些输入摘录信息。然而,在过去的FC层中的信息可以是太粗糙空间,以允许精确定位(由于maxpooling等的序列),在另一侧中,第一层可以是在空间上精确,但将缺乏语义信息。为了得到两全其美的,的作者hypercolumn纸定义“上方”该像素的像素,因为所有的CNN单元的激活矢量的hypercolumn。

Hypercolumn提取
Hypercolumn提取通过Hypercolumns为对象分割和细粒度本地化

在hypercolumns的提取的第一步是将图像馈送到CNN(卷积神经网络)并提取特征图激活针对图像的每个位置。最棘手的部分是,当特征地图比输入图像更小,例如一个池操作之后,该论文的作者,然后做特征映射的双线性采样,以保持特征地图上输入相同的大小。也有与FC的问题(完全连接)层,因为可以不分离单元仅语义绑在图像的一个像素,所以FC激活被看作1×1的特征的地图,这意味着所有位置股关于hypercolumn的FC部分相同的信息。然后,所有这些激活被连接起来以创建hypercolumn。举例来说,如果我们把VGG-16架构的最大池操作后,仅使用前2卷积层,我们将与大小的hypercolumn:

64个过滤器池之前第一CONV层

+

128个过滤器池之前第二CONV层)=192层的功能

这意味着图像的每个像素将具有192维向量hypercolumn。这hypercolumn真的很有趣,因为它包含关于第一层(在这里我们有很多的空间信息,但很少语义)关于最后几层,也信息(很少的空间信息和大量的语义的)信息。因此,本hypercolumn将大量的像素分类任务一定的帮助,如一个较早的自动着色的提及,因为每个位置hypercolumn携带什么这个像素语义上和空间上代表的信息。这也是上分割任务非常有帮助亚洲金博宝的(你可以看到更多有关原始文件介绍hypercolumn概念)。

一亚洲金博宝切听起来很酷,但我们如何在实践中提取hypercolumns?

VGG-16

Before being able to extract the hypercolumns, we’ll setup the VGG-16 pre-trained network, because you know, the price of a good GPU (I can’t even imagine many of them) here in Brazil is very expensive and I don’t want to sell my kidney to buy a GPU.

VGG16网络架构(由志成燕等人。)
VGG16网络架构(由志成燕等人。)

要设置上Keras预训练VGG-16网络,你需要下载文件的权重从这里(具有大约500MB vgg16_weights.h5文件),然后设置的体系结构和加载使用Keras下载的权重(关于权重文件和体系结构的详细信息这里):

从matplotlib进口pyplot如PLT进口theano进口CV2进口numpy的为NP进口SciPy的从keras.models SP导入顺序从keras.layers.core进口展平,密,差从keras.layers.convolutional进口Convolution2D,MaxPooling2D从keras.layers。Convolutional import ZeroPadding2D from keras.optimizers import SGD from sklearn.manifold import TSNE from sklearn import manifold from sklearn import cluster from sklearn.preprocessing import StandardScaler def VGG_16(weights_path=None): model = Sequential() model.add(ZeroPadding2D((1,1),input_shape=(3,224,224))) model.add(Convolution2D(64, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(64, 3, 3, activation='relu')) model.add(MaxPooling2D((2,2), stride=(2,2))) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(128, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(128, 3, 3, activation='relu')) model.add(MaxPooling2D((2,2), stride=(2,2))) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(256, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(256, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(256, 3, 3, activation='relu')) model.add(MaxPooling2D((2,2), stride=(2,2))) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(512, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(512, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(512, 3, 3, activation='relu')) model.add(MaxPooling2D((2,2), stride=(2,2))) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(512, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(512, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(512, 3, 3, activation='relu')) model.add(MaxPooling2D((2,2), stride=(2,2))) model.add(Flatten()) model.add(Dense(4096, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(4096, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(1000, activation='softmax')) if weights_path: model.load_weights(weights_path) return model

正如你所看到的,这是一个非常简单的代码(与Pytho亚洲金博宝n进口所需要的包一起)申报VGG16架构并加载预训练的权重。在此之后,我们将编译Keras模型:

模型= VGG_16( 'vgg16_weights.h5')SGD = SGD(LR = 0.1,衰减= 1E-6,动量= 0.9,涅斯捷罗夫=真)model.compile(优化= SGD,损耗= 'categorical_crossentropy')

现在,让我们来测试使用图像网络:

im_original = cv2.resize(cv2.imread( 'madruga.jpg'),(224,224))IM = im_original.transpose((2,0,1))IM = np.expand_dims(1M,轴= 0)im_converted= cv2.cvtColor(im_original,cv2.COLOR_BGR2RGB)plt.imshow(im_converted)

图片使用

图片使用

正如我们所看到的,我们加载的图像,固定轴,然后我们就可以像现在送入VGG-16得到的预测:

OUT = model.predict(IM)plt.plot(out.ravel())

预测
预测

正如你所看到的,这些都是SOFTMAX层的最终激活,用类“运动衫,T恤,T恤”的范畴。

提取任意特征图

现在,提取特征地图的激活,我们必须能够提取特征从网络的任意卷积层映射。我们可以通过使用编译Theano功能做到这一点get_output()Keras的方法,如在下面的例子:

get_feature = theano.function([model.layers [0]。输入],model.layers [3] .get_output(列车= FALSE),allow_input_downcast =假)技艺= get_feature(IM)plt.imshow(技艺[0] [2])

特征映射

特征映射

在上面的例子中,我编译Theano函数来获取3层(卷积层)的特征图,然后仅示出第三特征地图。在这里我们可以看到激活的强度。如果我们从功能,最终层激活的地图上,我们可以看到,提取的特征是比较抽象的,一样的眼睛,等看从15卷积层下面这个例子:

get_feature = theano.function([model.layers [0]。输入],model.layers [15] .get_output(列车= FALSE),allow_input_downcast =假)技艺= get_feature(IM)plt.imshow(技艺[0] [13])

更多的语义特征的地图

更多的语义特征映射。

正如你所看到的,这第二个特征图提取更抽象的特点。而且你还可以注意到,当我们前面看到的功能相比,形象似乎更加捉襟见肘,这是因为第一个特征映射具有224×224大小,这其中有56×56,由于各层的缩小操作卷积层之前,这就是为什么我们失去了很多的空间信息。

提取hypercolumns

现在,终于让我们提取层的任意一组的hypercolumns。要做到这一点,我们将定义一个函数来提取这些hypercolumns:

DEF extract_hypercolumn(型号,layer_indexes,实例):层= [model.layers [LI] .get_output(列车=假),用于在layer_indexes LI] get_feature = theano.function([model.layers [0]。输入],层allow_input_downcast =假)feature_maps = get_feature(实例)hypercolumns = []用于feature_maps convmap:用于convmap FMAP [0]:=放大的sp.misc.imresize(FMAP,大小=(224,224),模式= “F”,口译= '双线性')hypercolumns.append(放大的)返回np.asarray(hypercolumns)

我们可以看到,这个功能会想到三个参数:模型本身,将被用于提取hypercolumn功能和将要用于提取hypercolumns图像实例层指标的清单。现在让我们来测试第2卷积层hypercolumn提取:

layers_extract = [3,8] HC = extract_hypercolumn(模型,layers_extract,IM)

就这样,我们提取的每个像素的hypercolumn载体。这个“HC”可变的形状是:(192L,224L,224L),这意味着我们为224×224像素中的每一个(总共50176个像素与每个192 hypercolumn功能)192维hypercolumn。

我们绘制的平均hypercolumns激活每个像素的:

平均= np.average(hc.transpose(1,2,0),轴= 2)plt.imshow(AVE)
Hypercolumn平均层3和8。
Hypercolumn平均层3和8。

广告可以看到,那些第一hypercolumn激活都在寻找像边缘检测,让我们来看看这些hypercolumns看起来像层22和29如何:

layers_extract = [22,29] HC = extract_hypercolumn(模型,layers_extract,1M)平均= np.average(hc.transpose(1,2,0),轴= 2)plt.imshow(AVE)
Hypercolumn平均为层22和29。
Hypercolumn平均为层22和29。

正如我们现在可以看到,功能真多抽象和语义有趣,但与空间信息有点模糊。

请记住,您可以提取使用所有的初始层,并最终层,包括FC层hypercolumns。在这里,我分别提取他们出示他们在可视化图的区别。

简单hypercolumn像素集群

Now, you can do a lot of things, you can use these hypercolumns to classify pixels for some task, to do automatic pixel colorization, segmentation, etc. What I’m going to do here just as an experiment, is to use the hypercolumns (from the VGG-16 layers 3, 8, 15, 22, 29) and then cluster it using KMeans with 2 clusters:

米= hc.transpose(1,2,0).reshape(50176,-1)k均值= cluster.KMeans(n_clusters = 2,max_iter = 300,n_jobs = 5,precompute_distances =真)cluster_labels = k均值.fit_predict(M)imcluster = np.zeros((224224))imcluster = imcluster.reshape((224 * 224))= imcluster cluster_labels plt.imshow(imcluster.reshape(224,224),CMAP = “热”)
k均值聚类使用hypercolumns。
k均值聚类使用hypercolumns。

现在,你可以想像是多么有用hypercolumns可以像关键点提取,分割等,这是一个非常优雅的,简单实用的理念任务。亚洲金博宝

我希望你喜欢它 !

- 基督教S. Perone

引用本文为:基督教S. Perone,“在Python卷积hypercolumns,”在亚洲金博宝未知领域,2016年11月1日,//www.cpetem.com/2016/01/convolutional-hypercolumns-in-python/

深度学习 - 卷积神经网络,并与Python特征提取

卷积神经网络(或ConvNets)的生物激发的MLP的变体,它们具有不同的种类的层,并且每个层不同工作比通常的MLP层不同。如果您有兴趣了解更多关于ConvNets,好的当然是CS231n - 卷积神经Newtorks从视觉上识别。的细胞神经网络的体系结构示于下面的图片:

有规律的神经网络。
有规律的神经网络(从CS231n网站)。
一个ConvNet网络achitecture(从CS231n网站)。
一个ConvNet网络achitecture(从CS231n网站)。

正如你所看到的,ConvNets可与三维体积和这些3D体积的转换。我不会在这个岗位重复整个CS231n教程,所以如果你真的有兴趣,请花时间,然后再继续阅读。

意大利千层面和nolearn

其中一个Python包深学习,我真的很喜欢工作,是千层面nolearn。意大利千层面是基于Theano所以GPU的加速真的会造成很大的差别,以及他们对神经网络建立声明的方式是非常有帮助。该nolearn libary是周围神经网络软件包(包括千层面),可以帮助我们创建神经网络结构的过程中有很多,各层的检查等实用程序的集合

我什么都在这个岗位展示,是如何建立一个简单的ConvNet架构与一些卷积和汇聚层。I’m also going to show how you can use a ConvNet to train a feature extractor and then use it to extract features before feeding them into different models like SVM, Logistic Regression, etc. Many people use pre-trained ConvNet models and then remove the last output layer to extract the features from ConvNets that were trained on ImageNet datasets. This is usually called transfer learning because you can use layers from other ConvNets as feature extractors for different problems, since the first layer filters of the ConvNets works as edge detectors, they can be used as general feature detectors for other problems.

加载MNIST数据集

MNIST数据集是数字分类的最传统的数据集之一。我们将使用它的一个腌版本的Python,但首先,让导入的包,我们将需要使用:

进口matplotlib进口matplotlib.pyplot作为PLT进口matplotlib.cm从进口的urllib进口urlretrieve cPickle的作为泡菜进口OS进口gzip的进口numpy的作为NP进口从lasagne.updates烤宽面条进口层theano进口烤宽面条厘米从nolearn.lasagne进口导入nesterov_momentum NeuralNet从sklearn.metrics nolearn.lasagne进口形象化导入classification_report从sklearn.metrics进口confusion_matrix

正如你所看到的,我们正在绘制一些图像导入matplotlib,一些原生的Python模块下载MNIST数据集,numpy的,theano,烤宽面条,nolearn和模型评估一些scikit学习功能。

在那之后,我们定义MNIST加载函数(这是相当的意大利千层面教程中使用的相同的功能):

DEF load_dataset():URL = 'http://deeplearning.net/data/mnist/mnist.pkl.gz' 文件名= 'mnist.pkl.gz' 如果不是os.path.exists(文件名):打印(“下载MNIST数据集...“)urlretrieve(URL,文件名)与gzip.open(文件名, 'RB')为f:数据=和pickle.load(F)X_train,y_train =数据[0] X_val,y_val =数据[1] X_test,y_test =数据[2] = X_train X_train.reshape(( -  1,1,28,28))X_val = X_val.reshape(( -  1,1,28,28))X_test = X_test.reshape((-1,1,28,28))y_train = y_train.astype(np.uint8)y_val = y_val.astype(np.uint8)y_test = y_test.astype(np.uint8)返回X_train,y_train,X_val,y_val,X_test,y_test

正如你所看到的,我们正在下载MNIST腌制数据集,然后拆开包装成三个不同的数据集:训练,验证和测试。之后,我们重塑图像内容到他们以后准备输入到千层面输入层并且我们也转换numpy的阵列类型UINT8由于GPU / theano数据类型的限制。

在那之后,我们已经准备好装载MNIST数据集并检查:

X_train,y_train,X_val,y_val,X_test,y_test = load_dataset()plt.imshow(X_train [0] [0],CMAP = cm.binary)

此代码以上将输出以下图像(我使用IPython的笔记本):

一个数字MNIST(5中的情况下)的一个例子。
一个数字MNIST(5中的情况下)的一个例子。

ConvNet架构和培训

现在,我们可以定义我们ConvNet架构,然后用GPU / CPU(我有一个非常便宜的GPU,但是它有很大帮助)训练它:亚洲金博宝

NET1 = NeuralNet(层= [( '输入',layers.InputLayer),( 'conv2d1',layers.Conv2DLayer),( 'maxpool1',layers.MaxPool2DLayer),( 'conv2d2',layers.Conv2DLayer),('maxpool2”,layers.MaxPool2DLayer),( 'dropout1',layers.DropoutLayer),( '密',layers.DenseLayer),( 'dropout2',layers.DropoutLayer),( '输出',layers.DenseLayer)],#输入层input_shape =(无,1,28,28),#层conv2d1 conv2d1_num_filters = 32,conv2d1_filter_size =(5,5),conv2d1_nonlinearity = lasagne.nonlinearities.rectify,conv2d1_W = lasagne.init.GlorotUniform(),#层maxpool1maxpool1_pool_size =(2,2),#层conv2d2 conv2d2_num_filters = 32,conv2d2_filter_size =(5,5),conv2d2_nonlinearity = lasagne.nonlinearities.rectify,#层maxpool2 maxpool2_pool_size =(2,2),#dropout1 dropout1_p = 0.5,#密dense_num_units = 256,dense_nonlinearity = lasagne.nonlinearities.rectify,#dropout2 dropout2_p = 0.5,#输出output_nonlinearity = lasagne.nonlinearities.softmax,output_num_units = 10,#优化方法PARAMS更新=未列名terov_momentum,update_learning_rate = 0.01,update_momentum = 0.9,max_epochs = 10,详细= 1,)#列车网络NN = net1.fit(X_train,y_train)

正如你所看到的,在参数我们定义与该层的名称/类型的元组的字典,然后我们定义为这些层的参数。我们在这里的结构是利用两个卷积层用poolings然后完全连接层(致密层)和输出层。也有一些层之间遗失,漏失层为正则该随机设定的输入值为零,以避免过度拟合(见下面的图)。

漏失层效果(从CS231n网站)。
漏失层效果(从CS231n网站)。

调用后培养法,nolearn包会显示我的卑微的GPU我得到下面的结果学习过程中的地位,在我的机器:

#神经网络160362个可学习参数##层信息#名称大小--- -------- -------- 0输入1x28x28 1 conv2d1 32x24x24 2 maxpool1 32x12x12 3 conv2d2 32x8x8 4 maxpool2 32x4x4 5 dropout132x4x4 6密256 7 dropout2 256 8输出10划时代列车损失有效损失火车/ VAL有效ACC DUR ------- ------------ -----------  ----------- --------- --- 1 0.85204 0.16707 5.09977 0.95174 33.71s 2 0.27571 0.10732 2.56896 0.96825 3 33.34s 0.20262 0.08567 2.36524 0.97488 33.51s 4 0.16551 0.07695 2.150810.97705 33.50s 5 0.14173 0.06803 2.08322 0.98061 34.38s 6 0.12519 0.06067 2.06352 0.98239 34.02s 7 0.11077 0.05532 2.00254 0.98427 33.78s 8 0.10497 0.05771 1.81898 0.98248 34.17s 9 0.09881 0.05159 1.91509 0.98407 10 33.80s 0.09264 0.04958 1.86864 0.98526 33.40s

正如你所看到的,到底准确度为0.98526,一个相当不错的表现,适合于10个时期的培训。

预测和混淆矩阵

现在,我们可以用模型来预测整个测试数据集:

preds = net1.predict(X_test)

而且我们还可以绘制一个混淆矩阵检查神经网络分类的性能:

厘米= confusion_matrix(y_test,preds)plt.matshow(厘米)plt.title( '混淆矩阵')plt.colorbar()plt.ylabel( '真标签')plt.xlabel( '预测标签')plt.show()

上面的代码将绘制以下混淆矩阵:

混淆矩阵
混淆矩阵

正如你所看到的,对角线,其中分类更加密集,显示我们分类的良好性能。

过滤器的可视化

我们也可以想像从第一卷积层32层的过滤器:

visualize.plot_conv_weights(net1.layers _ [ 'conv2d1'])

上面的代码将绘制下面以下过滤器:

第一层5x5x32滤波器。
第一层5x5x32滤波器。

正如你所看到的,nolearnplot_conv_weights地块所有过滤器呈现我们指定的层。

Theano层的功能和特征提取

现在是时候创建theano编译功能,将前馈输入数据到结构到层你有兴趣。我要得到输出层,也为输出层前的致密层的功能:

dense_layer = layers.get_output(net1.layers _ [ '密'],确定性=真)output_layer = layers.get_output(net1.layers _ [ '输出'],确定性=真)input_var = net1.layers _ [ '输入']。input_varf_output = theano.function([input_var],output_layer)f_dense = theano.function([input_var],dense_layer)

正如你可以看到,我们有一个叫做现在二人theano功能f_outputf_dense(用于输出和致密层)。请注意,在这里为了让大家层使用称为额外的参数“确定性“,这是为了避免影响我们的前馈通辍学层。

现在,我们可以示例实例转换到输入格式,然后将其馈送到用于输出层theano功能:

实例= X_test [0] [无,:,:]%timeit -n 500 f_output(实例)500个循环,最好的3:858微秒每循环

正如你所看到的,f_output功能需要的858微秒的平均水平。我们也可以绘制实例的输出层激活:

PRED = f_output(实例)N = pred.shape [1] plt.bar(范围(N),pred.ravel())

上面的代码将创建以下情节:

输出层激活。
输出层激活。

正如你所看到的,该数字被认为是数字7,你可以对网络中的任何一层创建theano功能事实上是非常有用的,因为你可以创建一个函数(像我们以前那样),以获得密集的激活亚洲金博宝层(输出层前的一个),你可以使用这些激活的功能和使用你的神经网络没有分类,但作为一个特征提取。对于致密层我们绘制现在256个单位激活:

PRED = f_dense(实例)N = pred.shape [1] plt.bar(范围(N),pred.ravel())

上面的代码将创建下面的情节如下:

致密层激活。
致密层激活。

现在,您可以使用这些256个激活的输出功能,像Logistic回归或SVM线性分类。

我希望你喜欢的教程!

引用本文为:基督教S. Perone,“深度学习 - 卷积神经网络,并与Python特征提取”,在亚洲金博宝未知领域,19/08/2015,//www.cpetem.com/2015/08/convolutional-neural-networks-and-feature-extraction-with-python/

机器学习::文本特征提取(TF-IDF) - 第二部分

阅读本教程的第一部分:文本特征提取(TF-IDF) - 第一部分

这个职位是一个延续在哪里,我们开始学习有关文本特征提取和向量空间模型表示的理论和实践的第一部分。我真的建议你阅读第一部分后一系列以遵循这个第二。

由于很多人喜欢这个教程的第一部分,该第二部分是比第一个长一点。

介绍

在第一篇文章中,我们学会了如何使用长期频以表示在矢量空间的文本信息。然而,与术语频率方法的主要问题是,它大大加快了频繁的条款和规模下降,这比高频方面经验更丰富罕见的条款。基本的直觉是,在许多文件中经常出现的一个术语不太好鉴别,真正有意义的(至少在许多实验测试);这里最重要的问题是:你为什么会在例如分类问题,强调术语,是在你的文档的整个语料库几乎礼物?

在TF-IDF权重来解决这个问题。什么TF-IDF给出的是如何重要的是一个集合中的文档的话,这就是为什么TF-IDF结合本地和全球的参数,因为它考虑到不仅需要隔离的期限,但也文献集内的术语。什么TF-IDF然后做来解决这个问题,是缩小,同时扩大了难得的条件频繁的条款;出现比其他的10倍以上期限不为10倍比它更重要的是,为什么TF-IDF采用对数刻度的做到这一点。

但是,让我们回到我们的定义\ mathrm {TF}(T,d)这实际上是长期的长期计数Ť在文档中d。使用这种简单的词频可能导致我们一样的问题滥用关键字,这是当我们有一个文档中的术语重复以改善上的IR其排名的目的(信息检索)系统,甚至对创建长文档偏见,使他们看起来比他们只是因为手册中出现的高频更重要。

为了克服这个问题,词频\ mathrm {TF}(T,d)上的矢量空间中的文件的通常也归一化。让我们来看看我们是如何规范这一载体。

矢量归

假设我们要正常化术语频矢量\ {VEC V_ {D_4}}我们在本教程的第一部分已经计算。该文件D4从本教程的第一部分中有这样的文字表示:

D4:我们可以看到闪亮的阳光,明亮的阳光下。

和使用该文件的非归一化项频向量空间表示为:

\ {VEC V_ {D_4}} =(0,2,1,0)

为了归一化矢量,是相同的计算单位向量矢量,而他们使用的是“帽子”符号表示:\帽子{V}。的单位矢量的定义\帽子{V}一个向量的\ VEC {V}是:

\的DisplayStyle \帽子{V} = \压裂{\ vec的{V}} {\ | \ vec的{V} \ | _p}

\帽子{V}是单位矢量,或者归一化矢量,所述\ VEC {V}在矢量将被归一化和\ | \ VEC {V} \ | _p是矢量的范数(大小,长度)\ VEC {V}在里面L ^ p空间(别担心,我将所有的解释)。

的单位矢量实际上无非是矢量的归一化版本的更多,是一种载体,其长度为1。

归一化处理(来源:http://processing.org/learning/pvector/)
归一化处理(来源:http://processing.org/learning/pvector/)

但这里的重要问题是如何向量的长度来计算,并明白这一点,你必须了解的动机L ^ p空间,也被称为勒贝格空间

勒贝格空间

多久这个载体?(来源:来源:http://processing.org/learning/pvector/)
多久这个载体?(来源:来源:http://processing.org/learning/pvector/)

通常,一个矢量的长度\ {VEC U】=(U_1,U_2,U_3,\ ldots,u_n)使用计算欧几里得范-一个准则是在矢量空间中分配一个严格正长度或大小于所有矢量的函数- ,其被定义为:

(来源:http://processing.org/learning/pvector/)
(来源:http://processing.org/learning/pvector/)

\ | \ VEC【U} \ |= \ SQRT【U ^ 2_1 + U ^ 2_2 + U ^ 2_3 + \ ldots + U ^ 2_n}

但是,这不是定义长度的唯一途径,这就是为什么你看到(有时)的数p符合规范的符号,就像在了一起\ | \ VEC【U} \ | _p。这是因为它可以被概括为:

\的DisplayStyle \ | \ VEC【U} \ | _p =(\左| U_1 \右| ^ P + \左| U_2 \右| ^ P + \左| U_3 \右| ^ P + \ ldots + \左|u_n \右| ^ p)^ \压裂{1} {p}

并简化为:

\的DisplayStyle \ | \ VEC【U} \ | _p =(\总和\ limits_ {I = 1} ^ {N} \左| \ VEC {U】_i \右| ^ P)^ \压裂{1} {P}

所以,当你阅读有关L2范,你正在阅读关于欧几里得范,具有规范p = 2时用于测量的矢量的长度的最常用标准,通常称为“大小”;其实,当你有一个不合格的长度测量(不p号),你有L2范(欧几里得范数)。

当你阅读一L1范你正在阅读与规范P = 1, 定义为:

\的DisplayStyle \ | \ VEC【U} \ | _1 =(\左| U_1 \右| + \左| U_2 \右| + \左| U_3 \右| + \ ldots + \左| u_n \右|)

这无非是向量的组件的简单相加,也被称为出租汽车距离,也被称为曼哈顿距离。

出租车几何与欧几里得距离:在出租车几何所有三个描绘线具有对于相同的路径具有相同的长度(12)。在欧几里德几何,绿色的线有长度,6 \倍\ SQRT {2} \约8.48,并且是唯一的最短路径。
资源:维基百科::出租车几何

请注意,您也可以使用任何规范正常化的载体,但我们将使用最常用的规范,L2范数,这也是在0.9版本的默认scikits.learn。You can also find papers comparing the performance of the two approaches among other methods to normalize the document vector, actually you can use any other method, but you have to be concise, once you’ve used a norm, you have to use it for the whole process directly involving the norm (即所使用的L1范数的单位矢量是不会具有长度1,如果你要以后采取其L2范数)。

返回矢量归

现在你知道了矢量正常化进程是什么,我们可以尝试一个具体的例子,使用L2范数的过程(我们现在使用正确的术语),以规范我们的矢量\ {VEC V_ {D_4}} =(0,2,1,0)为了得到其单位向量\ {帽子V_ {D_4}}。为了做到这一点,我们将简单的将其插入单位矢量的定义,对其进行评估:

\帽子{V}= \frac{\vec{v}}{\|\vec{v}\|_p} \\ \\  \hat{v_{d_4}} = \frac{\vec{v_{d_4}}}{||\vec{v_{d_4}}||_2} \\ \\ \\  \hat{v_{d_4}} = \frac{(0,2,1,0)}{\sqrt{0^2 + 2^2 + 1^2 + 0^2}} \\ \\  \hat{v_{d_4}} = \frac{(0,2,1,0)}{\sqrt{5}} \\ \\  \small \hat{v_{d_4}} = (0.0, 0.89442719, 0.4472136, 0.0)

这就是它!我们的法矢\ {帽子V_ {D_4}}现在有一个L2范\ | \帽子{V_ {D_4}} \ | _2 = 1.0

请注意,这里我们归我们词频文档向量,但后来我们要做的是,TF-IDF的计算后。

术语频率 - 逆文档频率(TF-IDF)重量

现在你已经了解了矢量归在理论和实践是如何工作的,让我们继续我们的教程。假设你有你的收藏(从教程的第一部分拍摄)在下列文件:

火车文档集:D1:天空是蓝色的。D2:阳光灿烂。测试文档集:D3:在天空,阳光灿烂。D4:我们可以看到闪亮的阳光,明亮的阳光下。

您的文档空间可以那么作为被定义d = \ {D_1,D_2,\ ldots,D_N \}哪里ñ是在你的文集文档的数量,并在我们的情况下,D_ {火车} = \ {D_1,D_2 \}D_ {测试} = \ {D_3,D_4 \}。我们的文档空间的基数被定义\左| {{D_火车}} \右|= 2\左| {{D_测试}} \右|= 2,因为我们只有2两个用于训练和测试文档,但他们显然并不需要有相同的基数。

现在让我们看看,然后是如何IDF(逆文档频率)定义:

\的DisplayStyle \ mathrm {IDF}(T)= \日志{\压裂{\左| d \右|} {1+ \左| \ {d:吨\在d \} \右|}}

哪里\左| \ {d:T \在d \} \右|是个文件数其中术语Ť出现,术语频率函数满足当\ mathrm {TF}(T,d)\ 0 NEQ,我们只加1代入公式,以避免零分。

为TF-IDF式则是:

\ mathrm {TF \ MBOX { - } IDF}(T)= \ mathrm {TF}(T,d)\倍\ mathrm {IDF}(t)的

和该公式具有重要的后果:当你有给定文档中高词频(TF)达到TF-IDF计算的高权重(本地参数)和整个集合中的术语的低文档频率(全局参数)。

现在,让我们计算每个出现在与我们在第一个教程计算词频特征矩阵功能的IDF:

M_ {}列车=  \begin{bmatrix}  0 & 1 & 1 & 1\\  0 & 2 & 1 & 0  \end{bmatrix}

因为我们有4个特点,我们要计算\ mathrm {IDF}(T_1)\ mathrm {IDF}(T_2)\ mathrm {IDF}(t_3处)\ mathrm {IDF}(T_4)

\ mathrm {IDF}(T_1)= \日志{\压裂{\左| d \右|} {1+ \左| \ {d:T_1 \在d \} \右|}} = \日志{\压裂{2} {1}} = 0.69314718

\ mathrm {IDF}(T_2)= \日志{\压裂{\左| d \右|} {1+ \左| \ {d:T_2 \在d \} \右|}} = \日志{\压裂{2} {3}} = -0.40546511

\ mathrm {IDF}(t_3处)= \日志{\压裂{\左| d \右|} {1+ \左| \ {d:t_3处\在d \} \右|}} = \日志{\压裂{2} {3}} = -0.40546511

\ mathrm {IDF}(T_4)= \日志{\压裂{\左| d \右|} {1+ \左| \ {d:T_4 \在d \} \右|}} = \日志{\压裂{2} {2}} = 0.0

这些IDF权重可以由矢量作为表示:

\ {VEC {idf_列车}} =(0.69314718,-0.40546511,-0.40546511,0.0)

现在,我们有我们的词频矩阵(M_ {}列车)和表示我们的矩阵的每个特征的IDF(矢量\ {VEC {idf_列车}}),我们可以计算出我们的TF-IDF权重。我们要做的是矩阵中的每一列的简单乘法M_ {}列车与各自的\ {VEC {idf_列车}}向量维度。要做到这一点,我们可以创建一个正方形对角矩阵M_ {} IDF同时与垂直和水平尺寸等于向量\ {VEC {idf_列车}}尺寸:

M_ {} IDF=   \begin{bmatrix}   0.69314718 & 0 & 0 & 0\\   0 & -0.40546511 & 0 & 0\\   0 & 0 & -0.40546511 & 0\\   0 & 0 & 0 & 0   \end{bmatrix}

然后将它乘到术语频率矩阵,因此最终结果然后可以定义为:

M_ {TF \ MBOX { - } IDF} = M_ {火车} \倍M_ {IDF}

请注意,矩阵乘法是不可交换的,结果A \乘以B会比的结果不同乙\一个时代,这就是为什么M_ {} IDF是对乘法的右侧,以完成每个IDF值到其对应的特征相乘的期望的效果:

\begin{bmatrix}   \mathrm{tf}(t_1, d_1) & \mathrm{tf}(t_2, d_1) & \mathrm{tf}(t_3, d_1) & \mathrm{tf}(t_4, d_1)\\   \mathrm{tf}(t_1, d_2) & \mathrm{tf}(t_2, d_2) & \mathrm{tf}(t_3, d_2) & \mathrm{tf}(t_4, d_2)   \end{bmatrix}   \times   \begin{bmatrix}   \mathrm{idf}(t_1) & 0 & 0 & 0\\   0 & \mathrm{idf}(t_2) & 0 & 0\\   0 & 0 & \mathrm{idf}(t_3) & 0\\   0 & 0 & 0 & \mathrm{idf}(t_4)   \end{bmatrix}   \\ =   \begin{bmatrix}   \mathrm{tf}(t_1, d_1) \times \mathrm{idf}(t_1) & \mathrm{tf}(t_2, d_1) \times \mathrm{idf}(t_2) & \mathrm{tf}(t_3, d_1) \times \mathrm{idf}(t_3) & \mathrm{tf}(t_4, d_1) \times \mathrm{idf}(t_4)\\   \mathrm{tf}(t_1, d_2) \times \mathrm{idf}(t_1) & \mathrm{tf}(t_2, d_2) \times \mathrm{idf}(t_2) & \mathrm{tf}(t_3, d_2) \times \mathrm{idf}(t_3) & \mathrm{tf}(t_4, d_2) \times \mathrm{idf}(t_4)   \end{bmatrix}

现在让我们来看看这个乘法的一个具体的例子:

M_ {TF \ MBOX { - } IDF} = M_ {火车} \倍M_ {IDF}= \\   \begin{bmatrix}   0 & 1 & 1 & 1\\   0 & 2 & 1 & 0   \end{bmatrix}   \times   \begin{bmatrix}   0.69314718 & 0 & 0 & 0\\   0 & -0.40546511 & 0 & 0\\   0 & 0 & -0.40546511 & 0\\   0 & 0 & 0 & 0   \end{bmatrix} \\   =   \begin{bmatrix}   0 & -0.40546511 & -0.40546511 & 0\\   0 & -0.81093022 & -0.40546511 & 0   \end{bmatrix}

最后,我们可以将我们的L2归一化处理的M_ {TF \ MBOX { - }} IDF矩阵。请注意,这正常化“逐行”因为我们要处理矩阵的每一行作为一个分离向量进行归一化,而不是矩阵作为一个整体:

M_ {TF \ MBOX { - } IDF} = \压裂{M_ {TF \ MBOX { - } IDF}} {\ | M_ {TF \ MBOX { - } IDF} \ | _2} = \begin{bmatrix}   0 & -0.70710678 & -0.70710678 & 0\\   0 & -0.89442719 & -0.4472136 & 0   \end{bmatrix}

这就是我们的我们的测试文档集,这实际上是单位向量的集合的漂亮归TF-IDF权重。如果你把矩阵的每一行的L2范数,你会发现它们都具有1的L2范数。

Python的实践

环境中使用Python的v.2.7.2NumPy的1.6.1SciPy的v.0.9.0Sklearn(Scikits.learn)v.0.9

现在,你在等待的部分!在本节中,我将使用Python的使用,以显示TF-IDF计算的每一步Scikit.learn特征提取模块。

第一步是创建我们的训练和测试文档集和计算词频矩阵:

从sklearn.feature_extraction.text进口CountVectorizer train_set =(“天空是蓝色的。”,“阳光灿烂”。)TEST_SET =(“在天空中的太阳是光明的。”,“我们可以看到闪耀的太阳,。明亮的太阳“)count_vectorizer = CountVectorizer()count_vectorizer.fit_transform(train_set)打印 ”词汇“,count_vectorizer.vocabulary#词汇:{ '蓝':0, '太阳':1, '鲜艳':2 '天空':3} freq_term_matrix = count_vectorizer.transform(TEST_SET)打印freq_term_matrix.todense()#[[0 1 1 1]#[0 2 1 0]]

现在,我们有频率项矩阵(称为freq_term_matrix),我们可以实例化TfidfTransformer,这将是负责来计算我们的词频矩阵TF-IDF权重:

从进口sklearn.feature_extraction.text TFIDF TfidfTransformer = TfidfTransformer(NORM = “L2”)tfidf.fit(freq_term_matrix)打印 “IDF:”,tfidf.idf_#IDF:[0.69314718 -0.40546511 -0.40546511 0]

请注意,我所指定的标准为L2,这是可选的(实际上默认为L2范数),但我已经添加了参数,使其明确向你表示,它会使用L2范数。还要注意的是,你可以通过访问称为内部属性看IDF计算权重idf_。现在适合()方法计算矩阵中的IDF上,让我们改造freq_term_matrix到TF-IDF权重矩阵:

tf_idf_matrix = tfidf.transform(freq_term_matrix)打印tf_idf_matrix.todense()#[[0 -0.70710678 -0.70710678 0]#[0 -0.89442719 -0.4472136 0]]

这就是它的tf_idf_matrix其实我们以前M_ {TF \ MBOX { - }} IDF矩阵。您可以通过使用达到相同的效果矢量器类Scikit.learn的这是一个矢量器自动结合CountVectorizerTfidfTransformer给你。看到这个例子要知道如何使用它的文本分类过程。

I really hope you liked the post, I tried to make it simple as possible even for people without the required mathematical background of linear algebra, etc. In the next Machine Learning post I’m expecting to show how you can use the tf-idf to calculate the cosine similarity.

如果你喜欢,随时提出意见和建议,修改等。

引用本文为:基督教S. Perone,“机器学习::文本特征提取(TF-IDF) - 第二部分”,在亚洲金博宝未知领域,03/10/2011,//www.cpetem.com/2011/10/machine-learning-text-feature-extraction-tf-idf-part-ii/

参考

理解逆文档频率:对IDF理论论证

维基百科:: TF-IDF

经典的向量空间模型

Sklearn文本特征提取码

更新

2015年3月13日-格式化,固定图像的问题。
2011 10月3日-添加了有关使用Python示例环境信息