Python搭建SVM
目录
1.线性分类器
2.损失函数 Loss function
多类支持向量机损失(Multiclass Support Vector Machine Loss)
损失函数(Softmax分类器):
3.正则化(Regularization)
4.总结如下:
5.部分代码及其解释
6.全部代码
从SVM开始才算真正步入机器学习了,之前的KNN只能算是公式应用,毕竟没有损失函数,没有权重优化怎么能称之为学习呢?
SVM的知识包括几个主要方面评分函数、损失函数、正则化以及梯度下降。
从整个过程来看:
1.初始化权重,训练数据点乘权重得到评分矩阵;
2.根据评分矩阵和损失函数公式来求得损失值,并对损失值进行正则化,来减小大的权重参数对损失值影响;
3.利用梯度下降方法对损失值来进行迭代,通过损失值来调整权值参数达到最优。
1.线性分类器
W被称为权重(weights),b被称为偏差向量(bias vector)
举例:xi=32*32*3*1 [3072 x 1]的列向量;W=10*3072 W的每一行对应一个类的分类器
那么xi的大小就变成[3073x1],而不是[3072x1]了,多出了包含常量1的1个维度。W大小就是[10x3073]了。W中多出来的这一列对应的就是偏差值b
把权重和偏差放到一个矩阵(如图1所示),我们就只需要学习一个权重矩阵,而不用去学习两个分别装着权重和偏差的矩阵了。
图1
所得的结果就是想要得到的评分矩阵(具体例子如图2所示)
图2
每一行相当于一个分类器,第一行就是cat的分类器,得分分别是第一幅图cat得分是3.2,第二幅图cat得分是4.9。
2.损失函数 Loss function
多类支持向量机损失(Multiclass Support Vector Machine Loss)
第i个数据的多类SVM的损失函数为
第i个数据中包含图像xi的像素和代表正确类别的标签yi 。评分函数输入像素数据,然后通过公式 来计算不同分类类别的分值。这里我们将分值简写为 。比如,针对第j个类别的得分就是第j个元素:sj=f(xi,W)j。yi 表示正确的得分,针对第i个数据的多类SVM的损失函数定义如下:
关于0的阀值:max(0,-)函数,它常被称为折叶损失(hinge loss)。有时候会听到人们使用平方折叶损失SVM(即L2-SVM),它使用的是max(0,-)2,将更强烈(平方地而不是线性地)地惩罚过界的边界值。
不使用平方是更标准的版本,但是在某些数据集中,平方折叶损失会工作得更好,可以通过交叉验证来决定到底使用哪个。
在上述例子中,Syi ,分别是3.2,4.9,-3.1。
L1=max(0,5.1-3.2+1)+ max(0,-1.7-3.2+1)
L2=…
举例来说,在CIFAR-10中,我们有一个N=50000的训练集,每个图像有D=32x32x3=3072个像素,而K=10,这是因为图片被分为10个不同的类别(狗,猫,汽车等)。定义评分函数为: ,该函数是原始图像像素到分类分值的映射。
损失函数(Softmax分类器):
第i个数据的Softmax分类器的损失函数为
Softmax分类器就可以理解为逻辑回归分类器面对多个分类的一般化归纳。SVM将输出 作为每个分类的评分(因为无定标,所以难以直接解释)。与SVM不同,Softmax的输出(归一化的分类概率)更加直观,并且从概率上可以解释。
在Softmax分类器中,函数映射保持不变,但将这些评分值视为每个分类的未归一化的对数概率,并且将折叶损失(hinge loss)替换为交叉熵损失(cross-entropy loss)。公式如下:
normalize 意思是归一化也就是公式中的
这一步操作使得各个概率加起来的和为1。
在实际使用中,SVM和Softmax经常是相似的:通常说来,两种分类器的表现差别很小,不同的人对于哪个分类器更好有不同的看法。相对于Softmax分类器,SVM更加“局部目标化(local objective)”,这既可以看做是一个特性,也可以看做是一个劣势。考虑一个评分是[10, -2, 3]的数据,其中第一个分类是正确的。那么一个SVM()会看到正确分类相较于不正确分类,已经得到了比边界值还要高的分数,它就会认为损失值是0。SVM对于数字个体的细节是不关心的:如果分数是[10, -100, -100]或者[10, 9, 9],对于SVM来说没设么不同,只要满足超过边界值等于1,那么损失值就等于0。
3.正则化(Regularization)
L1 regularization:
L2 regularization:
最常用的正则化惩罚是L2范式,L2范式通过对所有参数进行逐元素的平方惩罚来抑制大数值的权重。
完整的多类SVM损失函数:
它由两个部分组成:数据损失(data loss),即所有样例的的平均损失,以及正则化损失(regularization loss)。将其展开完整公式是:
引入了L2惩罚后,SVM们就有了最大边界(max margin)这一良好性质
其中最好的性质就是对大数值权重进行惩罚,可以提升其泛化能力,因为这就意味着没有哪个维度能够独自对于整体分值有过大的影响。
∆ 在绝大多数情况下设为 都是安全的。
4.数据预处理
mean_image=np.mean(X_train,axis=0)#计算每一列特征的平均值,共32*32*3个特征
X_train-=mean_image
X_dev-=mean_image
X_test-=mean_image
X_val-=mean_imageX_train=np.hstack([X_train,np.ones((X_train.shape[0],1))])
X_dev=np.hstack([X_dev,np.ones((X_dev.shape[0],1))])
X_test=np.hstack([X_test,np.ones((X_test.shape[0],1))])
X_val=np.hstack([X_val,np.ones((X_val.shape[0],1))])
对每个特征减去平均值来中心化数据是非常重要的,该步骤意味着根据训练集中所有的图像计算出一个平均图像值,这样图像的像素值就大约分布在[-127, 127]之间了。下一个常见步骤是,让所有数值分布的区间变为[-1, 1],零均值的中心化。
后面这段代码应该就是之前在线性分类器中提到的,那么xi的大小就变成[3073x1],而不是[3072x1]了,多出了包含常量1的1个维度。np.hstack的意思是将数据按列堆叠起来。
5.总结如下:
定义了从图像像素映射到不同类别的分类评分的评分函数。
在本节中,评分函数是一个基于权重W和偏差b的线性函数。
与kNN分类器不同,参数方法的优势在于一旦通过训练学习到了参数,就可以将训练数据丢弃了。同时该方法对于新的测试数据的预测非常快,因为只需要与权重W进行一个矩阵乘法运算。
介绍了偏差技巧,让我们能够将偏差向量和权重矩阵合二为一,然后就可以只跟踪一个矩阵。
定义了损失函数(介绍了SVM和Softmax线性分类器最常用的2个损失函数)。损失函数能够衡量给出的参数集与训练集数据真实类别情况之间的一致性。在损失函数的定义中可以看到,对训练集数据做出良好预测与得到一个足够低的损失值这两件事是等价的。
5.部分代码及其解释
以下图为例子举例来解释向量法求损失函数和权重
def svm_loss_vectorized(W, X, y, reg):loss = 0.0dW = np.zeros(W.shape) # initialize the gradient as zeroscores = X.dot(W) #=[[3.2,5.1,-1.7],[1.3,4.9,2.0].[2.2,2.5,-3.1]]num_classes = W.shape[1] #=3scores_correct = scores[np.arange(num_train), y] # np.arange(num_train)=[1,2,3] y=[1,2,3], scores_correct=[3.2,4.9,-3.1]scores_correct = np.reshape(scores_correct, (num_train, 1)) # scores_correct=3*1=[[3.2],[4.9],[-3.1]]margins = scores - scores_correct + 1.0 #=[[1,2.9,-5.9],[-2.6,1,-1.9],[6.3,6.6,1]]margins[np.arange(num_train), y] = 0.0#margins[[1,2,3],[1,2,3]]=0.0,margins=[[0,2.9,-5.9],[-2.6,0,-1.9],[6.3,6.6,0]]margins[margins <= 0] = 0.0 #margins=[[0,2.9,0],[0,0,0],[6.3,6.6,0]]loss += np.sum(margins) / num_train #loss=2.9+6.3+6.6=15.8loss += 0.5 * reg * np.sum(W * W) #正则化 0.5*reg是正则化系数margins[margins > 0] = 1.0 # margins=[[0,1,0],[0,0,0],[1,1,0]]row_sum = np.sum(margins, axis=1) #row_sum=[2,0,2]margins[np.arange(num_train), y] = -row_sum #margins=[[-2,1,0],[0,0,0],[1,1,-2]]dW += np.dot(X.T, margins)/num_train + reg * Wreturn loss, dW
learning_rates=[1.75e-7,1.25e-7,2e-7,1.5e-7,0.75e-7]
regularization_strengths = [3e4,3.5e4,4e4,4.5e4,5e4,3.25e4,3.75e4,4.25e4,4.75e4]
学习率和正则化参数就从这些数据中遍历,两两组合,最后选取交叉验证准确率最高的一组参数来作为预测测试集的参数 。
# -*- coding: utf-8 -*-
import pickle as p
import numpy as np
import osdef load_CIFAR_batch(filename):""" 载入cifar数据集的一个batch """with open(filename, 'rb') as f:datadict = p.load(f, encoding='latin1')X = datadict['data']Y = datadict['labels']X = X.reshape(10000, 3, 32, 32).transpose(0, 2, 3, 1).astype("float")Y = np.array(Y)return X, Ydef load_CIFAR10(ROOT):""" 载入cifar全部数据 """xs = []ys = []for b in range(1, 6):f = os.path.join(ROOT, 'data_batch_%d' % (b,))X, Y = load_CIFAR_batch(f)xs.append(X) #将所有batch整合起来ys.append(Y)Xtr = np.concatenate(xs) #使变成行向量,最终Xtr的尺寸为(50000,32*32*3)Ytr = np.concatenate(ys)del X, YXte, Yte = load_CIFAR_batch(os.path.join(ROOT, 'test_batch'))return Xtr, Ytr, Xte, Yteimport numpy as np
import matplotlib.pyplot as plt# 载入CIFAR-10数据集
cifar10_dir = 'datasets/cifar-10-batches-py'
X_train, y_train, X_test, y_test = load_CIFAR10(cifar10_dir)# 看看数据集中的一些样本:每个类别展示一些
print('Training data shape: ', X_train.shape)
print('Training labels shape: ', y_train.shape)
print('Test data shape: ', X_test.shape)
print('Test labels shape: ', y_test.shape)num_train=40000
num_validation=1000
num_test=1000
num_dev=50
在进行测试时,读取了全部50000个样本数据和10000个测试数据,单选择了其中40000(样本数据)作为训练数据,1000(样本数据)作为交叉验证数据,1000(测试数据)作为测试数据,正常理论上应该是8:1:1的数据分布,不过测试集数量少一点问题也不大。看一下最终测试数据,准确率貌似还不错,至此SVM就算基本理解透彻了,梯度计算那里还是有些问题,接下去再去好好学习。
lr 7.500000e-08 reg 3.000000e+04 train accuracy: 0.376450 val accracy: 0.358400
lr 7.500000e-08 reg 3.250000e+04 train accuracy: 0.381950 val accracy: 0.361400
lr 7.500000e-08 reg 3.500000e+04 train accuracy: 0.382025 val accracy: 0.365800
lr 7.500000e-08 reg 3.750000e+04 train accuracy: 0.374625 val accracy: 0.355600
lr 7.500000e-08 reg 4.000000e+04 train accuracy: 0.371850 val accracy: 0.355000
lr 7.500000e-08 reg 4.250000e+04 train accuracy: 0.381125 val accracy: 0.364800
lr 7.500000e-08 reg 4.500000e+04 train accuracy: 0.373275 val accracy: 0.354400
lr 7.500000e-08 reg 4.750000e+04 train accuracy: 0.379900 val accracy: 0.362600
lr 7.500000e-08 reg 5.000000e+04 train accuracy: 0.376075 val accracy: 0.357800
lr 1.250000e-07 reg 3.000000e+04 train accuracy: 0.377375 val accracy: 0.362000
lr 1.250000e-07 reg 3.250000e+04 train accuracy: 0.375225 val accracy: 0.360800
lr 1.250000e-07 reg 3.500000e+04 train accuracy: 0.375675 val accracy: 0.359200
lr 1.250000e-07 reg 3.750000e+04 train accuracy: 0.372925 val accracy: 0.354600
lr 1.250000e-07 reg 4.000000e+04 train accuracy: 0.373200 val accracy: 0.355800
lr 1.250000e-07 reg 4.250000e+04 train accuracy: 0.375825 val accracy: 0.355600
lr 1.250000e-07 reg 4.500000e+04 train accuracy: 0.374375 val accracy: 0.352800
lr 1.250000e-07 reg 4.750000e+04 train accuracy: 0.370075 val accracy: 0.351200
lr 1.250000e-07 reg 5.000000e+04 train accuracy: 0.366825 val accracy: 0.351800
lr 1.500000e-07 reg 3.000000e+04 train accuracy: 0.376625 val accracy: 0.358200
lr 1.500000e-07 reg 3.250000e+04 train accuracy: 0.372375 val accracy: 0.359800
lr 1.500000e-07 reg 3.500000e+04 train accuracy: 0.371750 val accracy: 0.357800
lr 1.500000e-07 reg 3.750000e+04 train accuracy: 0.372925 val accracy: 0.356600
lr 1.500000e-07 reg 4.000000e+04 train accuracy: 0.375975 val accracy: 0.360800
lr 1.500000e-07 reg 4.250000e+04 train accuracy: 0.377725 val accracy: 0.363200
lr 1.500000e-07 reg 4.500000e+04 train accuracy: 0.363225 val accracy: 0.348400
lr 1.500000e-07 reg 4.750000e+04 train accuracy: 0.373600 val accracy: 0.354400
lr 1.500000e-07 reg 5.000000e+04 train accuracy: 0.371425 val accracy: 0.352200
lr 1.750000e-07 reg 3.000000e+04 train accuracy: 0.377325 val accracy: 0.363600
lr 1.750000e-07 reg 3.250000e+04 train accuracy: 0.375100 val accracy: 0.357400
lr 1.750000e-07 reg 3.500000e+04 train accuracy: 0.371375 val accracy: 0.352600
lr 1.750000e-07 reg 3.750000e+04 train accuracy: 0.371575 val accracy: 0.355000
lr 1.750000e-07 reg 4.000000e+04 train accuracy: 0.370800 val accracy: 0.349200
lr 1.750000e-07 reg 4.250000e+04 train accuracy: 0.372600 val accracy: 0.361400
lr 1.750000e-07 reg 4.500000e+04 train accuracy: 0.354825 val accracy: 0.341600
lr 1.750000e-07 reg 4.750000e+04 train accuracy: 0.356025 val accracy: 0.340000
lr 1.750000e-07 reg 5.000000e+04 train accuracy: 0.364875 val accracy: 0.351400
lr 2.000000e-07 reg 3.000000e+04 train accuracy: 0.373575 val accracy: 0.354600
lr 2.000000e-07 reg 3.250000e+04 train accuracy: 0.381775 val accracy: 0.365000
lr 2.000000e-07 reg 3.500000e+04 train accuracy: 0.364675 val accracy: 0.353400
lr 2.000000e-07 reg 3.750000e+04 train accuracy: 0.363400 val accracy: 0.349800
lr 2.000000e-07 reg 4.000000e+04 train accuracy: 0.367050 val accracy: 0.340800
lr 2.000000e-07 reg 4.250000e+04 train accuracy: 0.359325 val accracy: 0.340000
lr 2.000000e-07 reg 4.500000e+04 train accuracy: 0.368375 val accracy: 0.347800
lr 2.000000e-07 reg 4.750000e+04 train accuracy: 0.365100 val accracy: 0.352400
lr 2.000000e-07 reg 5.000000e+04 train accuracy: 0.364225 val accracy: 0.349000
best_val_accuracy: 0.365800
test_accuracy: 0.383400
plt.plot(loss_history)
plt.title(u"carve of loss")
plt.xlabel('num_iters')
plt.ylabel('loss')
plt.show()
6.全部代码
SVM.py
import numpy as np
class MulticlassSupportVector(object):def __init__(self): self.W = Noneself.shape=Nonedef train(self, X, y, learning_rate=1e-3, reg=1e-5, num_iters=200, batch_size=200, verbose=True): #注意这里传递的参数设置num_train, dim = X.shape# assume y takes values 0...K-1 where K is number of classesnum_classes = np.max(y) + 1 if self.W is None:# lazily initialize Wself.W = 0.001 * np.random.randn(dim, num_classes) # 初始化W# Run stochastic gradient descent(Mini-Batch) to optimize Wloss_history = []for it in range(num_iters): #每次随机取batch的数据来进行梯度下降X_batch = Noney_batch = None# Sampling with replacement is faster than sampling without replacement.sample_index = np.random.choice(num_train, batch_size, replace=False)X_batch = X[sample_index, :] # batch_size by Dy_batch = y[sample_index] # 1 by batch_size# evaluate loss and gradientloss, grad = svm_loss_vectorized(self.W,X_batch, y_batch, reg)loss_history.append(loss)# perform parameter updateself.W += -learning_rate * gradif verbose and it % 100 == 0:print ('Iteration %d / %d: loss %f' % (it, num_iters, loss))return loss_historydef predict(self, X): y_pred = np.zeros(X.shape[1]) # 1 by Ny_pred = np.argmax(X.dot(self.W), axis=1) #预测直接找到最后y最大的那个值return y_preddef svm_loss_vectorized(W, X, y, reg):loss = 0.0dW = np.zeros(W.shape) # initialize the gradient as zeroscores = X.dot(W) # N by Cnum_train = X.shape[0]num_classes = W.shape[1]scores_correct = scores[np.arange(num_train), y] # 1 by Nscores_correct = np.reshape(scores_correct, (num_train, 1)) # N by 1margins = scores - scores_correct + 1.0 # N by Cmargins[np.arange(num_train), y] = 0.0margins[margins <= 0] = 0.0loss += np.sum(margins) / num_trainloss += 0.5 * reg * np.sum(W * W)# compute the gradientmargins[margins > 0] = 1.0row_sum = np.sum(margins, axis=1) # 1 by Nmargins[np.arange(num_train), y] = -row_sum dW += np.dot(X.T, margins)/num_train + reg * W # D by Creturn loss, dWdef svm_loss_naive(W, X, y, reg):"""Inputs:- W: A numpy array of shape (D, C) containing weights.- X: A numpy array of shape (N, D) containing a minibatch of data.- y: A numpy array of shape (N,) containing training labels; y[i] = c means that X[i] has label c, where 0 <= c < C.- reg: (float) regularization strengthReturns a tuple of:- loss as single float- gradient with respect to weights W; an array of same shape as W"""dW = np.zeros(W.shape) # initialize the gradient as zero# compute the loss and the gradientnum_classes = W.shape[1]num_train = X.shape[0]loss = 0.0for i in range(num_train): scores = X[i].dot(W) correct_class_score = scores[y[i]]for j in range(num_classes):if j == y[i]: #根据公式,正确的那个不用算continuemargin = scores[j] - correct_class_score + 1 # note delta = 1if margin > 0:loss += margindW[:, y[i]] += -X[i, :] # 根据公式:∇Wyi Li = - xiT(∑j≠yi1(xiWj - xiWyi +1>0)) + 2λWyi dW[:, j] += X[i, :] # 根据公式: ∇Wj Li = xiT 1(xiWj - xiWyi +1>0) + 2λWj , (j≠yi)# Right now the loss is a sum over all training examples, but we want it# to be an average instead so we divide by num_train.loss /= num_traindW /= num_train# Add regularization to the loss.loss += 0.5 * reg * np.sum(W * W)dW += reg * Wreturn loss, dW
SVMexercise.py
# -*- coding: utf-8 -*-
import pickle as p
import numpy as np
import osdef load_CIFAR_batch(filename):""" 载入cifar数据集的一个batch """with open(filename, 'rb') as f:datadict = p.load(f, encoding='latin1')X = datadict['data']Y = datadict['labels']X = X.reshape(10000, 3, 32, 32).transpose(0, 2, 3, 1).astype("float")Y = np.array(Y)return X, Ydef load_CIFAR10(ROOT):""" 载入cifar全部数据 """xs = []ys = []for b in range(1, 6):f = os.path.join(ROOT, 'data_batch_%d' % (b,))X, Y = load_CIFAR_batch(f)xs.append(X) #将所有batch整合起来ys.append(Y)Xtr = np.concatenate(xs) #使变成行向量,最终Xtr的尺寸为(50000,32*32*3)Ytr = np.concatenate(ys)del X, YXte, Yte = load_CIFAR_batch(os.path.join(ROOT, 'test_batch'))return Xtr, Ytr, Xte, Yteimport numpy as np
import matplotlib.pyplot as plt# 载入CIFAR-10数据集
cifar10_dir = 'datasets/cifar-10-batches-py'
X_train, y_train, X_test, y_test = load_CIFAR10(cifar10_dir)# 看看数据集中的一些样本:每个类别展示一些
print('Training data shape: ', X_train.shape)
print('Training labels shape: ', y_train.shape)
print('Test data shape: ', X_test.shape)
print('Test labels shape: ', y_test.shape)num_train=40000
num_validation=1000
num_test=1000
num_dev=50mask=range(num_train,num_train+num_validation)
X_val=X_train[mask]
y_val=y_train[mask]mask=range(num_train)
X_train=X_train[mask]
y_train=y_train[mask]mask=np.random.choice(num_train,num_dev,replace=False)
X_dev=X_train[mask]
y_dev=y_train[mask]mask=range(num_test)
X_test=X_test[mask]
y_test=y_test[mask]X_train=np.reshape(X_train,(X_train.shape[0],-1))
X_dev=np.reshape(X_dev,(X_dev.shape[0],-1))
X_val=np.reshape(X_val,(X_val.shape[0],-1))
X_test=np.reshape(X_test,(X_test.shape[0],-1))print('Training data shape: ', X_train.shape)
print('Training labels shape: ', y_train.shape)
print('Test data shape: ', X_test.shape)
print('Test labels shape: ', y_test.shape)#首先训练数据,计算图像的平均值
mean_image=np.mean(X_train,axis=0)#计算每一列特征的平均值,共32*32*3个特征
print(mean_image[:10]) #查看指定特征的数据
plt.figure(figsize=(4,4)) #指定画框框图的大小
plt.imshow(mean_image.reshape((32,32,3)).astype('uint8')) #将平均值可视化
#plt.show()X_train-=mean_image
X_dev-=mean_image
X_test-=mean_image
X_val-=mean_imageX_train=np.hstack([X_train,np.ones((X_train.shape[0],1))])
X_dev=np.hstack([X_dev,np.ones((X_dev.shape[0],1))])
X_test=np.hstack([X_test,np.ones((X_test.shape[0],1))])
X_val=np.hstack([X_val,np.ones((X_val.shape[0],1))])import SVM
learning_rates=[1.75e-7,1.25e-7,2e-7,1.5e-7,0.75e-7]
regularization_strengths = [3e4,3.5e4,4e4,4.5e4,5e4,3.25e4,3.75e4,4.25e4,4.75e4]
results={}
best_val=-1
best_svm = None
for rate in learning_rates:for regular in regularization_strengths:svm=SVM.MulticlassSupportVector()svm.train(X_train, y_train, learning_rate=rate, reg=regular, num_iters=1500)y_train_pred=svm.predict(X_train)accuracy_train = np.mean(y_train==y_train_pred)y_val_pred=svm.predict(X_val)accuracy_val = np.mean(y_val==y_val_pred)results[(rate,regular)] = (accuracy_train,accuracy_val)if (best_val < accuracy_val):best_val = accuracy_valbest_svm = svm
for lr,reg in sorted(results):train_accuracy,val_accuracy = results[(lr,reg)]print('lr %e reg %e train accuracy: %f val accracy: %f'%(lr,reg,train_accuracy,val_accuracy))
print('best_val_accuracy: %f'%(best_val))
y_tset_pred = best_svm.predict(X_test)
acc_test = np.mean(y_test == y_tset_pred)
print('test_accuracy: %f'%(acc_test))
Python搭建SVM相关推荐
- python系统-基于Python搭建Django后台管理系统
一个好的项目数据库管理后台是必须的,今天代码君教大家搭建Django网站后台,当然做网站后台的前提是需要有Python以及Django的开发环境,至于如何搭建这些开发环境,请查看我的上一篇文章 Mac ...
- 运行python需要网吗-python搭建网站(想学Python有什么建议吗?)
python求助!建立并输出一个字典,其键是ASCII码0-127,其值为对应的字符. 题主你好, 代码: {key: chr(key) for key in range(0,128)} 测试截图如下 ...
- Python【算法中心 01】Web框架Django入门(安装+项目创建+应用创建+服务启动)Python搭建算法中心后台实例分享
Django 官网 有详细的使用说明,这里只做简单记录. 1.起因 Java 项目用到了 Python 的类库,使用jython-standalone在 idea 里可以调用,但是部署时模块无法找到, ...
- python代理池_用Python搭建一个简单的代理池
其实每次爬东西的时候,特怕IP被封,所以每次都要把时间延迟设置得长一点...这次用Python搭建一个简单的代理池.获取代理IP,然后验证其有效性.不过结果好像不是很理想,为什么西刺代理的高匿代理都能 ...
- python运维脚本部署jdk_基于Java/Python搭建Web UI自动化环境
Java搭建UI自动化测试环境 下载JDK8 https://www.cnblogs.com/thloveyl/p/12378124.html 配置Java环境 1.解压Jdk压缩包 2.配置环境变量 ...
- python搭建web服务器_Python搭建简单的web服务器
Python搭建简单的web服务器 1.win+R输入cmd打开命令行 2.通过 cd 进入到你保存 HTML 文件的目录.例如:H:\D3\d3 输入 cd\ 指令进入到C盘的根目录.(CD(更改目 ...
- 零基础小白10分钟用Python搭建小说网站!网友:我可以!
都说Python什么都能做,本来我是不信的!直到我在CSDN站内看到了一件真事儿:一位博主贴出了自己10分钟用Python搭建小说网站的全过程!全程只用了2步操作,简直太秀了!!-- 第一步:爬取小说 ...
- 技术实践:教你用Python搭建gRPC服务
摘要:gRPC是一个高性能.通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf序列化协议开发,且支持众多开发语言. 本文分享自华为云社区& ...
- python仿真搭建_mock搭建——python——搭建一个简单的mock服务——简单版本
1.无聊的背景.起源: 如今的业务系统越来越复杂庞大,各个功能直接的调用也是多如牛毛,但如果在联调的时候,恰好被调的接口正在开发,怎么办? 傻傻的等么,不存在的!这时会搭建一些server来进行moc ...
最新文章
- 2022-2028年中国出版业投资分析及前景预测报告(全卷)
- sentry日志管理系统安装以及使用教程
- 安全类链接,https
- 异常处理——上传文件到HDFS,put: `.': No such file or directory
- 机器学习算法优缺点改进总结
- ubuntu 配置 静态ip
- php字段验证规则,详解ThinkPHP中自动验证及验证规则
- lnmp mysql主从_LNMP linux下mysql主从复制 _好机友
- Client访问Tomcat简单流程(Struts2)
- mac搭建svn服务器文件被锁定,MAC搭建SVN服务器并配置Cornerstone
- C++ 链表结构的常用操作(单链表)
- linux ipc信号量
- Python语音转文字、音频切割、语音识别
- 在Windows里面使用binwalk工具分离图片
- 马步站桩---快速健身法
- 2017.8.18总结3-沙耶的玩偶
- 防止其他域名指向你的服务器的一种方法
- 循环队列front==rear
- matlab中饼图绘制程序,MATLAB中绘制二维饼图的函数是(? ? ) (1.5分)
- RabbitMQ 高级指南:从配置、使用到高可用集群搭建
热门文章
- matlab边角网间接平差计算,12.2测边网与边角网间接平差
- android开发股票数据接口,股票数据接口-股票数据接口api
- java俄罗斯方块英文书籍_Java版俄罗斯方块
- 1 、(5分)短信中提取号码
- Jenkins升级大坑-插件问题
- Android 12 Watchdog(4) Trace生成过程
- 《增强现实:原理、算法与应用》读书笔记(5)运动恢复结构(上)初始化、相机位姿估计、集束调整
- SlidesJS基本使用方法
- Crack:Aspose.Slides for .NET 22.12.x
- Linux平台上DPDK入门指南(二)