1. 可以使用的支持向量機(SVM)MATLAB程序,最好是和粒子群演算法(PSO)或者遺傳演算法(GA)耦聯的程序,謝謝
http://www.pudn.com/downloads246/sourcecode/others/detail1145908.html
2. C或C++程序編寫的基於向量機的車牌識別
http://www.ilovematlab.cn/thread-123590-1-1.html
我發的貼 右下角聯系
人臉識別的話 找哥吧 matlab中文論壇有很多的
3. 求支持向量機的vc++原代碼
如果是7.0以上版本
>>edit svmtrain
>>edit svmclassify
>>edit svmpredict
function [svm_struct, svIndex] = svmtrain(training, groupnames, varargin)
%SVMTRAIN trains a support vector machine classifier
%
% SVMStruct = SVMTRAIN(TRAINING,GROUP) trains a support vector machine
% classifier using data TRAINING taken from two groups given by GROUP.
% SVMStruct contains information about the trained classifier that is
% used by SVMCLASSIFY for classification. GROUP is a column vector of
% values of the same length as TRAINING that defines two groups. Each
% element of GROUP specifies the group the corresponding row of TRAINING
% belongs to. GROUP can be a numeric vector, a string array, or a cell
% array of strings. SVMTRAIN treats NaNs or empty strings in GROUP as
% missing values and ignores the corresponding rows of TRAINING.
%
% SVMTRAIN(...,'KERNEL_FUNCTION',KFUN) allows you to specify the kernel
% function KFUN used to map the training data into kernel space. The
% default kernel function is the dot proct. KFUN can be one of the
% following strings or a function handle:
%
% 'linear' Linear kernel or dot proct
% 'quadratic' Quadratic kernel
% 'polynomial' Polynomial kernel (default order 3)
% 'rbf' Gaussian Radial Basis Function kernel
% 'mlp' Multilayer Perceptron kernel (default scale 1)
% function A kernel function specified using @,
% for example @KFUN, or an anonymous function
%
% A kernel function must be of the form
%
% function K = KFUN(U, V)
%
% The returned value, K, is a matrix of size M-by-N, where U and V have M
% and N rows respectively. If KFUN is parameterized, you can use
% anonymous functions to capture the problem-dependent parameters. For
% example, suppose that your kernel function is
%
% function k = kfun(u,v,p1,p2)
% k = tanh(p1*(u*v')+p2);
%
% You can set values for p1 and p2 and then use an anonymous function:
% @(u,v) kfun(u,v,p1,p2).
%
% SVMTRAIN(...,'POLYORDER',ORDER) allows you to specify the order of a
% polynomial kernel. The default order is 3.
%
% SVMTRAIN(...,'MLP_PARAMS',[P1 P2]) allows you to specify the
% parameters of the Multilayer Perceptron (mlp) kernel. The mlp kernel
% requires two parameters, P1 and P2, where K = tanh(P1*U*V' + P2) and P1
% > 0 and P2 < 0. Default values are P1 = 1 and P2 = -1.
%
% SVMTRAIN(...,'METHOD',METHOD) allows you to specify the method used
% to find the separating hyperplane. Options are
%
% 'QP' Use quadratic programming (requires the Optimization Toolbox)
% 'LS' Use least-squares method
%
% If you have the Optimization Toolbox, then the QP method is the default
% method. If not, the only available method is LS.
%
% SVMTRAIN(...,'QUADPROG_OPTS',OPTIONS) allows you to pass an OPTIONS
% structure created using OPTIMSET to the QUADPROG function when using
% the 'QP' method. See help optimset for more details.
%
% SVMTRAIN(...,'SHOWPLOT',true), when used with two-dimensional data,
% creates a plot of the grouped data and plots the separating line for
% the classifier.
%
% Example:
% % Load the data and select features for classification
% load fisheriris
% data = [meas(:,1), meas(:,2)];
% % Extract the Setosa class
% groups = ismember(species,'setosa');
% % Randomly select training and test sets
% [train, test] = crossvalind('holdOut',groups);
% cp = classperf(groups);
% % Use a linear support vector machine classifier
% svmStruct = svmtrain(data(train,:),groups(train),'showplot',true);
% classes = svmclassify(svmStruct,data(test,:),'showplot',true);
% % See how well the classifier performed
% classperf(cp,classes,test);
% cp.CorrectRate
%
% See also CLASSIFY, KNNCLASSIFY, QUADPROG, SVMCLASSIFY.
% Copyright 2004 The MathWorks, Inc.
% $Revision: 1.1.12.1 $ $Date: 2004/12/24 20:43:35 $
% References:
% [1] Kecman, V, Learning and Soft Computing,
% MIT Press, Cambridge, MA. 2001.
% [2] Suykens, J.A.K., Van Gestel, T., De Brabanter, J., De Moor, B.,
% Vandewalle, J., Least Squares Support Vector Machines,
% World Scientific, Singapore, 2002.
% [3] Scholkopf, B., Smola, A.J., Learning with Kernels,
% MIT Press, Cambridge, MA. 2002.
%
% SVMTRAIN(...,'KFUNARGS',ARGS) allows you to pass additional
% arguments to kernel functions.
% set defaults
plotflag = false;
qp_opts = [];
kfunargs = {};
setPoly = false; usePoly = false;
setMLP = false; useMLP = false;
if ~isempty(which('quadprog'))
useQuadprog = true;
else
useQuadprog = false;
end
% set default kernel function
kfun = @linear_kernel;
% check inputs
if nargin < 2
error(nargchk(2,Inf,nargin))
end
numoptargs = nargin -2;
optargs = varargin;
% grp2idx sorts a numeric grouping var ascending, and a string grouping
% var by order of first occurrence
[g,groupString] = grp2idx(groupnames);
% check group is a vector -- though char input is special...
if ~isvector(groupnames) && ~ischar(groupnames)
error('Bioinfo:svmtrain:GroupNotVector',...
'Group must be a vector.');
end
% make sure that the data is correctly oriented.
if size(groupnames,1) == 1
groupnames = groupnames';
end
% make sure data is the right size
n = length(groupnames);
if size(training,1) ~= n
if size(training,2) == n
training = training';
else
error('Bioinfo:svmtrain:DataGroupSizeMismatch',...
'GROUP and TRAINING must have the same number of rows.')
end
end
% NaNs are treated as unknown classes and are removed from the training
% data
nans = find(isnan(g));
if length(nans) > 0
training(nans,:) = [];
g(nans) = [];
end
ngroups = length(groupString);
if ngroups > 2
error('Bioinfo:svmtrain:TooManyGroups',...
'SVMTRAIN only supports classification into two groups.\nGROUP contains %d different groups.',ngroups)
end
% convert to 1, -1.
g = 1 - (2* (g-1));
% handle optional arguments
if numoptargs >= 1
if rem(numoptargs,2)== 1
error('Bioinfo:svmtrain:IncorrectNumberOfArguments',...
'Incorrect number of arguments to %s.',mfilename);
end
okargs = {'kernel_function','method','showplot','kfunargs','quadprog_opts','polyorder','mlp_params'};
for j=1:2:numoptargs
pname = optargs{j};
pval = optargs{j+1};
k = strmatch(lower(pname), okargs);%#ok
if isempty(k)
error('Bioinfo:svmtrain:UnknownParameterName',...
'Unknown parameter name: %s.',pname);
elseif length(k)>1
error('Bioinfo:svmtrain:AmbiguousParameterName',...
'Ambiguous parameter name: %s.',pname);
else
switch(k)
case 1 % kernel_function
if ischar(pval)
okfuns = {'linear','quadratic',...
'radial','rbf','polynomial','mlp'};
funNum = strmatch(lower(pval), okfuns);%#ok
if isempty(funNum)
funNum = 0;
end
switch funNum %maybe make this less strict in the future
case 1
kfun = @linear_kernel;
case 2
kfun = @quadratic_kernel;
case {3,4}
kfun = @rbf_kernel;
case 5
kfun = @poly_kernel;
usePoly = true;
case 6
kfun = @mlp_kernel;
useMLP = true;
otherwise
error('Bioinfo:svmtrain:UnknownKernelFunction',...
'Unknown Kernel Function %s.',kfun);
end
elseif isa (pval, 'function_handle')
kfun = pval;
else
error('Bioinfo:svmtrain:BadKernelFunction',...
'The kernel function input does not appear to be a function handle\nor valid function name.')
end
case 2 % method
if strncmpi(pval,'qp',2)
useQuadprog = true;
if isempty(which('quadprog'))
warning('Bioinfo:svmtrain:NoOptim',...
'The Optimization Toolbox is required to use the quadratic programming method.')
useQuadprog = false;
end
elseif strncmpi(pval,'ls',2)
useQuadprog = false;
else
error('Bioinfo:svmtrain:UnknownMethod',...
'Unknown method option %s. Valid methods are ''QP'' and ''LS''',pval);
end
case 3 % display
if pval ~= 0
if size(training,2) == 2
plotflag = true;
else
warning('Bioinfo:svmtrain:OnlyPlot2D',...
'The display option can only plot 2D training data.')
end
end
case 4 % kfunargs
if iscell(pval)
kfunargs = pval;
else
kfunargs = {pval};
end
case 5 % quadprog_opts
if isstruct(pval)
qp_opts = pval;
elseif iscell(pval)
qp_opts = optimset(pval{:});
else
error('Bioinfo:svmtrain:BadQuadprogOpts',...
'QUADPROG_OPTS must be an opts structure.');
end
case 6 % polyorder
if ~isscalar(pval) || ~isnumeric(pval)
error('Bioinfo:svmtrain:BadPolyOrder',...
'POLYORDER must be a scalar value.');
end
if pval ~=floor(pval) || pval < 1
error('Bioinfo:svmtrain:PolyOrderNotInt',...
'The order of the polynomial kernel must be a positive integer.')
end
kfunargs = {pval};
setPoly = true;
case 7 % mlpparams
if numel(pval)~=2
error('Bioinfo:svmtrain:BadMLPParams',...
'MLP_PARAMS must be a two element array.');
end
if ~isscalar(pval(1)) || ~isscalar(pval(2))
error('Bioinfo:svmtrain:MLPParamsNotScalar',...
'The parameters of the multi-layer perceptron kernel must be scalar.');
end
kfunargs = {pval(1),pval(2)};
setMLP = true;
end
end
end
end
if setPoly && ~usePoly
warning('Bioinfo:svmtrain:PolyOrderNotPolyKernel',...
'You specified a polynomial order but not a polynomial kernel');
end
if setMLP && ~useMLP
warning('Bioinfo:svmtrain:MLPParamNotMLPKernel',...
'You specified MLP parameters but not an MLP kernel');
end
% plot the data if requested
if plotflag
[hAxis,hLines] = svmplotdata(training,g);
legend(hLines,cellstr(groupString));
end
% calculate kernel function
try
kx = feval(kfun,training,training,kfunargs{:});
% ensure function is symmetric
kx = (kx+kx')/2;
catch
error('Bioinfo:svmtrain:UnknownKernelFunction',...
'Error calculating the kernel function:\n%s\n', lasterr);
end
% create Hessian
% add small constant eye to force stability
H =((g*g').*kx) + sqrt(eps(class(training)))*eye(n);
if useQuadprog
% The large scale solver cannot handle this type of problem, so turn it
% off.
qp_opts = optimset(qp_opts,'LargeScale','Off');
% X=QUADPROG(H,f,A,b,Aeq,beq,LB,UB,X0,opts)
alpha = quadprog(H,-ones(n,1),[],[],...
g',0,zeros(n,1),inf *ones(n,1),zeros(n,1),qp_opts);
% The support vectors are the non-zeros of alpha
svIndex = find(alpha > sqrt(eps));
sv = training(svIndex,:);
% calculate the parameters of the separating line from the support
% vectors.
alphaHat = g(svIndex).*alpha(svIndex);
% Calculate the bias by applying the indicator function to the support
% vector with largest alpha.
[maxAlpha,maxPos] = max(alpha); %#ok
bias = g(maxPos) - sum(alphaHat.*kx(svIndex,maxPos));
% an alternative method is to average the values over all support vectors
% bias = mean(g(sv)' - sum(alphaHat(:,ones(1,numSVs)).*kx(sv,sv)));
% An alternative way to calculate support vectors is to look for zeros of
% the Lagrangians (fifth output from QUADPROG).
%
% [alpha,fval,output,exitflag,t] = quadprog(H,-ones(n,1),[],[],...
% g',0,zeros(n,1),inf *ones(n,1),zeros(n,1),opts);
%
% sv = t.lower < sqrt(eps) & t.upper < sqrt(eps);
else % Least-Squares
% now build up compound matrix for solver
A = [0 g';g,H];
b = [0;ones(size(g))];
x = A\b;
% calculate the parameters of the separating line from the support
% vectors.
sv = training;
bias = x(1);
alphaHat = g.*x(2:end);
end
svm_struct.SupportVectors = sv;
svm_struct.Alpha = alphaHat;
svm_struct.Bias = bias;
svm_struct.KernelFunction = kfun;
svm_struct.KernelFunctionArgs = kfunargs;
svm_struct.GroupNames = groupnames;
svm_struct.FigureHandles = [];
if plotflag
hSV = svmplotsvs(hAxis,svm_struct);
svm_struct.FigureHandles = {hAxis,hLines,hSV};
end
4. 向量機是什麼(不是問支持向量機)
向量機vector machine是向量計算機的簡稱。
詞霸
vector machine
詞性及解釋
【計】 向量機, 向量計算機
向加工向量機 這種機器採用向量全長的縱向加工方式,每執行一個向量運算都要從頭至尾執行全部分量的運算,操作數或結果向量都直接取自主存或寫入主存。主存的數據傳輸率須按運算部件速度的3~4倍來配置。縱向加工向量機設置交叉訪問的、數量眾多的存儲體和很寬的數據通路,並以超長字為單位進行訪問,以便滿足要求。這樣,就使成本高、主存系統靈活性差,難以實現對繁多的主存向量的高效存取。此外,向量運算的起步時間長,短向量運算速度下降幅度大。
縱橫加工向量機 這種機器採用向量分段縱橫加工方式,並設置有小容量高速度的多個向量運算寄存器。計算向量運算表達式時,每個向量運算每次只執行一段分量。從主存取出的操作數向量和運算產生的中間結果向量,可以逐段存放在向量寄存器中,運算部件主要訪問向量寄存器組。這樣,就能保證運算部件進行高速運算,同時又能減輕主存的負擔,使對主存數據傳輸率的要求比縱向加工下降70%左右。美國的CRAY-1機和中國的757機都屬於這種型式。
軟體與應用 向量機一般配有向量匯編和向量高級語言,供用戶編制能發揮具體向量機速度潛力的向量程序。只有研製和採用向量型並行演算法,使程序中包含的向量運算越多、向量越長,運算速度才會越高。面向各種應用領域的向量的建立,能方便用戶使用和提高向量機的解題效率。向量識別程序是中新開發的一部分,用於編譯時自動識別採用通常串列演算法的源程序中的向量運算成分,並編譯成相應的向量運算目標程序,以提高向量機計算大量現存非向量程序的計算速度。向量識別技術還有待進一步發展和完善,以提高識別水平。
向量計算機的發展方向是多向量機系統或細胞結構向量機。實現前者須在軟體和演算法上取得進展,解決如任務劃分和分派等許多難題;後者則須採用適當的,用硬體自動解決因用戶將分散的主存當作集中式的共存使用而帶來的矛盾,才能構成虛共存的細胞結構向量機。它既具有陣列機在結構上易於擴大並行台數以提高速度的優點,又有向量機使用方便的優點。
參考書目
高慶獅著:《數字計算機系統功能設計導引Ⅱ向量巨型機》,科學出版社,北京,1983
5. c語言常用詞彙及函數有那些
常用詞彙:
1、short:修飾int,短整型數據,可省略被修飾的int。
2、long:修飾int,長整型數據,可省略被修飾的int。
3、long long:修飾int,超長整型數據,可省略被修飾的int。
4、signed:修飾整型數據,有符號數據類型。
5、unsigned:修飾整型數據,無符號數據類型。
6、restrict:用於限定和約束指針,並表明指針是訪問一個數據對象的唯一且初始的方式。
7、return:用在函數體中,返回特定值(如果是void類型,則不返回函數值)。
8、continue:結束當前循環,開始下一輪循環。
9、break:跳出當前循環或switch結構。
10、goto:無條件跳轉語句。
11、if:條件語句,後面不需要放分號。
12、else:條件語句否定分支(與if連用)。
13、switch:開關語句(多重分支語句)。
14、case:開關語句中的分支標記,與switch連用。
15、default:開關語句中的「其他」分支,可選。
常用函數:
1、int isalpha(int ch) 若ch是字母('A'-'Z','a'-'z'),返回非0值,否則返回0。
2、int isalnum(int ch) 若ch是字母('A'-'Z','a'-'z')或數字('0'-'9'),返回非0值,否則返回0。
3、int abs(int i) 返回整型參數i的絕對值。
4、double cabs(struct complex znum) 返回復數znum的絕對值。
5、double fabs(double x) 返回雙精度參數x的絕對值。
6、long labs(long n) 返回長整型參數n的絕對值。
6. 有沒有用c或c++實現svm演算法
林智仁 的libsvm 就是C實現的SVM演算法代碼,回答不能帶鏈接,你去搜一下libsvm就能找到了.你可以找到他的主頁,上面還會有演算法的具體介紹,和libsvm的使用. 這個估計是使用最廣泛的求解svm的工具包. 裡面的代碼都是可以看的.
理論的話,july寫的一篇文章很經典, 搜索 支持向量機通俗導論(理解SVM的三層境界) 就能找到.
另外看樓主是想學習人工智慧演算法的, 附加一個學習神經網路的網路, <神經網路之家> nnetinfo ,專講神經網路的,還有相關視頻.
都是本人學習過程了解到的干貨, 望採納.
7. c語言問題
void sub(int*, int);
int main()
{
int a[]=,i;
int x=0;
for(i=0;i<4;i++)
{
sub(a,x);
printf("%d",x);
}
printf("\n");
}
void sub(int *s, int y)
{
static int t=3;
y=s[t];
t--;
}
是這樣的。
就是靜態變數難理解,靜態變數存儲在全局數據區,只有在第一次調用 sub() 的時候,才會有 t = 3 的初始化,以後再調用就使用上一次調用後 t 的新值,以後同樣使用上一次調用後的值,這個值被稱為保留值。
還有就是,如果不是按指針或引用傳遞,那麼傳遞的是變數的副本,所以雖然,sub() 幾次改了 y 的值,但都不影響 x。
另外,虛機團上產品團購,超級便宜
8. 支持向量機基本原理 matlab程序及其應用
支持向量機
1 簡介
支持向量機基本上是最好的有監督學習演算法了。最開始接觸SVM是去年暑假的時候,老師要求交《統計學習理論》的報告,那時去網上下了一份入門教程,裡面講的很通俗,當時只是大致了解了一些相關概念。這次斯坦福提供的學習材料,讓我重新學習了一些SVM知識。我看很多正統的講法都是從VC 維理論和結構風險最小原理出發,然後引出SVM什麼的,還有些資料上來就講分類超平面什麼的。這份材料從前幾節講的logistic回歸出發,引出了SVM,既揭示了模型間的聯系,也讓人覺得過渡更自然。
2 重新審視logistic回歸
Logistic回歸目的是從特徵學習出一個0/1分類模型,而這個模型是將特性的線性組合作為自變數,由於自變數的取值范圍是負無窮到正無窮。因此,使用logistic函數(或稱作sigmoid函數)將自變數映射到(0,1)上,映射後的值被認為是屬於y=1的概率。
形式化表示就是
假設函數
其中x是n維特徵向量,函數g就是logistic函數。
的圖像是
可以看到,將無窮映射到了(0,1)。
而假設函數就是特徵屬於y=1的概率。
當我們要判別一個新來的特徵屬於哪個類時,只需求 ,若大於0.5就是y=1的類,反之屬於y=0類。
再審視一下 ,發現 只和 有關, >0,那麼 ,g(z)只不過是用來映射,真實的類別決定權還在 。還有當 時, =1,反之 =0。如果我們只從 出發,希望模型達到的目標無非就是讓訓練數據中y=1的特徵 ,而是y=0的特徵 。Logistic回歸就是要學習得到 ,使得正例的特徵遠大於0,負例的特徵遠小於0,強調在全部訓練實例上達到這個目標。
圖形化表示如下:
中間那條線是 ,logistic回顧強調所有點盡可能地遠離中間那條線。學習出的結果也就中間那條線。考慮上面3個點A、B和C。從圖中我們可以確定A是×類別的,然而C我們是不太確定的,B還算能夠確定。這樣我們可以得出結論,我們更應該關心靠近中間分割線的點,讓他們盡可能地遠離中間線,而不是在所有點上達到最優。因為那樣的話,要使得一部分點靠近中間線來換取另外一部分點更加遠離中間線。我想這就是支持向量機的思路和logistic回歸的不同點,一個考慮局部(不關心已經確定遠離的點),一個考慮全局(已經遠離的點可能通過調整中間線使其能夠更加遠離)。這是我的個人直觀理解。
3 形式化表示
我們這次使用的結果標簽是y=-1,y=1,替換在logistic回歸中使用的y=0和y=1。同時將 替換成w和b。以前的 ,其中認為 。現在我們替換 為b,後面替換 為 (即 )。這樣,我們讓 ,進一步 。也就是說除了y由y=0變為y=-1,只是標記不同外,與logistic回歸的形式化表示沒區別。再明確下假設函數
上一節提到過我們只需考慮 的正負問題,而不用關心g(z),因此我們這里將g(z)做一個簡化,將其簡單映射到y=-1和y=1上。映射關系如下:
4 函數間隔(functional margin)和幾何間隔(geometric margin)
給定一個訓練樣本 ,x是特徵,y是結果標簽。i表示第i個樣本。我們定義函數間隔如下:
可想而知,當 時,在我們的g(z)定義中, , 的值實際上就是 。反之亦然。為了使函數間隔最大(更大的信心確定該例是正例還是反例),當 時, 應該是個大正數,反之是個大負數。因此函數間隔代表了我們認為特徵是正例還是反例的確信度。
繼續考慮w和b,如果同時加大w和b,比如在 前面乘個系數比如2,那麼所有點的函數間隔都會增大二倍,這個對求解問題來說不應該有影響,因為我們要求解的是 ,同時擴大w和b對結果是無影響的。這樣,我們為了限制w和b,可能需要加入歸一化條件,畢竟求解的目標是確定唯一一個w和b,而不是多組線性相關的向量。這個歸一化一會再考慮。
剛剛我們定義的函數間隔是針對某一個樣本的,現在我們定義全局樣本上的函數間隔
說白了就是在訓練樣本上分類正例和負例確信度最小那個函數間隔。
接下來定義幾何間隔,先看圖
假設我們有了B點所在的 分割面。任何其他一點,比如A到該面的距離以 表示,假設B就是A在分割面上的投影。我們知道向量BA的方向是 (分割面的梯度),單位向量是 。A點是 ,所以B點是x= (利用初中的幾何知識),帶入 得,
進一步得到
實際上就是點到平面距離。
再換種更加優雅的寫法:
當 時,不就是函數間隔嗎?是的,前面提到的函數間隔歸一化結果就是幾何間隔。他們為什麼會一樣呢?因為函數間隔是我們定義的,在定義的時候就有幾何間隔的色彩。同樣,同時擴大w和b,w擴大幾倍, 就擴大幾倍,結果無影響。同樣定義全局的幾何間隔
5 最優間隔分類器(optimal margin classifier)
回想前面我們提到我們的目標是尋找一個超平面,使得離超平面比較近的點能有更大的間距。也就是我們不考慮所有的點都必須遠離超平面,我們關心求得的超平面能夠讓所有點中離它最近的點具有最大間距。形象的說,我們將上面的圖看作是一張紙,我們要找一條折線,按照這條折線折疊後,離折線最近的點的間距比其他折線都要大。形式化表示為:
這里用 =1規約w,使得 是幾何間隔。
到此,我們已經將模型定義出來了。如果求得了w和b,那麼來一個特徵x,我們就能夠分類了,稱為最優間隔分類器。接下的問題就是如何求解w和b的問題了。
由於 不是凸函數,我們想先處理轉化一下,考慮幾何間隔和函數間隔的關系, ,我們改寫一下上面的式子:
這時候其實我們求的最大值仍然是幾何間隔,只不過此時的w不受 的約束了。然而這個時候目標函數仍然不是凸函數,沒法直接代入優化軟體里計算。我們還要改寫。前面說到同時擴大w和b對結果沒有影響,但我們最後要求的仍然是w和b的確定值,不是他們的一組倍數值,因此,我們需要對 做一些限制,以保證我們解是唯一的。這里為了簡便我們取 。這樣的意義是將全局的函數間隔定義為1,也即是將離超平面最近的點的距離定義為 。由於求 的最大值相當於求 的最小值,因此改寫後結果為:
這下好了,只有線性約束了,而且是個典型的二次規劃問題(目標函數是自變數的二次函數)。代入優化軟體可解。
到這里發現,這個講義雖然沒有像其他講義一樣先畫好圖,畫好分類超平面,在圖上標示出間隔那麼直觀,但每一步推導有理有據,依靠思路的流暢性來推導出目標函數和約束。
接下來介紹的是手工求解的方法了,一種更優的求解方法。
6 拉格朗日對偶(Lagrange ality)
先拋開上面的二次規劃問題,先來看看存在等式約束的極值問題求法,比如下面的最優化問題:
目標函數是f(w),下面是等式約束。通常解法是引入拉格朗日運算元,這里使用 來表示運算元,得到拉格朗日公式為
L是等式約束的個數。
然後分別對w和 求偏導,使得偏導數等於0,然後解出w和 。至於為什麼引入拉格朗日運算元可以求出極值,原因是f(w)的dw變化方向受其他不等式的約束,dw的變化方向與f(w)的梯度垂直時才能獲得極值,而且在極值處,f(w)的梯度與其他等式梯度的線性組合平行,因此他們之間存在線性關系。(參考《最優化與KKT條件》)
然後我們探討有不等式約束的極值問題求法,問題如下:
我們定義一般化的拉格朗日公式
這里的 和 都是拉格朗日運算元。如果按這個公式求解,會出現問題,因為我們求解的是最小值,而這里的 已經不是0了,我們可以將 調整成很大的正值,來使最後的函數結果是負無窮。因此我們需要排除這種情況,我們定義下面的函數:
這里的P代表primal。假設 或者 ,那麼我們總是可以調整 和 來使得 有最大值為正無窮。而只有g和h滿足約束時, 為f(w)。這個函數的精妙之處在於 ,而且求極大值。
因此我們可以寫作
這樣我們原來要求的min f(w)可以轉換成求 了。
我們使用 來表示 。如果直接求解,首先面對的是兩個參數,而 也是不等式約束,然後再在w上求最小值。這個過程不容易做,那麼怎麼辦呢?
我們先考慮另外一個問題
D的意思是對偶, 將問題轉化為先求拉格朗日關於w的最小值,將 和 看作是固定值。之後在 求最大值的話:
這個問題是原問題的對偶問題,相對於原問題只是更換了min和max的順序,而一般更換順序的結果是Max Min(X) <= MinMax(X)。然而在這里兩者相等。用 來表示對偶問題如下:
下面解釋在什麼條件下兩者會等價。假設f和g都是凸函數,h是仿射的(affine, )。並且存在w使得對於所有的i, 。在這種假設下,一定存在 使得 是原問題的解, 是對偶問題的解。還有 另外, 滿足庫恩-塔克條件(Karush-Kuhn-Tucker, KKT condition),該條件如下:
所以如果 滿足了庫恩-塔克條件,那麼他們就是原問題和對偶問題的解。讓我們再次審視公式(5),這個條件稱作是KKT al complementarity條件。這個條件隱含了如果 ,那麼 。也就是說, 時,w處於可行域的邊界上,這時才是起作用的約束。而其他位於可行域內部( 的)點都是不起作用的約束,其 。這個KKT雙重補足條件會用來解釋支持向量和SMO的收斂測試。
這部分內容思路比較凌亂,還需要先研究下《非線性規劃》中的約束極值問題,再回頭看看。KKT的總體思想是將極值會在可行域邊界上取得,也就是不等式為0或等式約束里取得,而最優下降方向一般是這些等式的線性組合,其中每個元素要麼是不等式為0的約束,要麼是等式約束。對於在可行域邊界內的點,對最優解不起作用,因此前面的系數為0。
7 最優間隔分類器(optimal margin classifier)
重新回到SVM的優化問題:
我們將約束條件改寫為:
從KKT條件得知只有函數間隔是1(離超平面最近的點)的線性約束式前面的系數 ,也就是說這些約束式 ,對於其他的不在線上的點( ),極值不會在他們所在的范圍內取得,因此前面的系數 .注意每一個約束式實際就是一個訓練樣本。
看下面的圖:
實線是最大間隔超平面,假設×號的是正例,圓圈的是負例。在虛線上的點就是函數間隔是1的點,那麼他們前面的系數 ,其他點都是 。這三個點稱作支持向量。構造拉格朗日函數如下:
注意到這里只有 沒有 是因為原問題中沒有等式約束,只有不等式約束。
下面我們按照對偶問題的求解步驟來一步步進行,
首先求解 的最小值,對於固定的 , 的最小值只與w和b有關。對w和b分別求偏導數。
並得到
將上式帶回到拉格朗日函數中得到,此時得到的是該函數的最小值(目標函數是凸函數)
代入後,化簡過程如下:
最後得到
由於最後一項是0,因此簡化為
這里我們將向量內積 表示為
此時的拉格朗日函數只包含了變數 。然而我們求出了 才能得到w和b。
接著是極大化的過程 ,
前面提到過對偶問題和原問題滿足的幾個條件,首先由於目標函數和線性約束都是凸函數,而且這里不存在等式約束h。存在w使得對於所有的i, 。因此,一定存在 使得 是原問題的解, 是對偶問題的解。在這里,求 就是求 了。
如果求出了 ,根據 即可求出w(也是 ,原問題的解)。然後
即可求出b。即離超平面最近的正的函數間隔要等於離超平面最近的負的函數間隔。
關於上面的對偶問題如何求解,將留給下一篇中的SMO演算法來闡明。
這里考慮另外一個問題,由於前面求解中得到
我們通篇考慮問題的出發點是 ,根據求解得到的 ,我們代入前式得到
也就是說,以前新來的要分類的樣本首先根據w和b做一次線性運算,然後看求的結果是大於0還是小於0,來判斷正例還是負例。現在有了 ,我們不需要求出w,只需將新來的樣本和訓練數據中的所有樣本做內積和即可。那有人會說,與前面所有的樣本都做運算是不是太耗時了?其實不然,我們從KKT條件中得到,只有支持向量的 ,其他情況 。因此,我們只需求新來的樣本和支持向量的內積,然後運算即可。這種寫法為下面要提到的核函數(kernel)做了很好的鋪墊。這是上篇,先寫這么多了。
7 核函數(Kernels)
考慮我們最初在「線性回歸」中提出的問題,特徵是房子的面積x,這里的x是實數,結果y是房子的價格。假設我們從樣本點的分布中看到x和y符合3次曲線,那麼我們希望使用x的三次多項式來逼近這些樣本點。那麼首先需要將特徵x擴展到三維 ,然後尋找特徵和結果之間的模型。我們將這種特徵變換稱作特徵映射(feature mapping)。映射函數稱作 ,在這個例子中
我們希望將得到的特徵映射後的特徵應用於SVM分類,而不是最初的特徵。這樣,我們需要將前面 公式中的內積從 ,映射到 。
至於為什麼需要映射後的特徵而不是最初的特徵來參與計算,上面提到的(為了更好地擬合)是其中一個原因,另外的一個重要原因是樣例可能存在線性不可分的情況,而將特徵映射到高維空間後,往往就可分了。(在《數據挖掘導論》Pang-Ning Tan等人著的《支持向量機》那一章有個很好的例子說明)
將核函數形式化定義,如果原始特徵內積是 ,映射後為 ,那麼定義核函數(Kernel)為
到這里,我們可以得出結論,如果要實現該節開頭的效果,只需先計算 ,然後計算 即可,然而這種計算方式是非常低效的。比如最初的特徵是n維的,我們將其映射到 維,然後再計算,這樣需要 的時間。那麼我們能不能想辦法減少計算時間呢?
先看一個例子,假設x和z都是n維的,
展開後,得
這個時候發現我們可以只計算原始特徵x和z內積的平方(時間復雜度是O(n)),就等價與計算映射後特徵的內積。也就是說我們不需要花 時間了。
現在看一下映射函數(n=3時),根據上面的公式,得到
也就是說核函數 只能在選擇這樣的 作為映射函數時才能夠等價於映射後特徵的內積。
再看一個核函數
對應的映射函數(n=3時)是
更一般地,核函數 對應的映射後特徵維度為 。(這個我一直沒有理解)。
由於計算的是內積,我們可以想到IR中的餘弦相似度,如果x和z向量夾角越小,那麼核函數值越大,反之,越小。因此,核函數值是 和 的相似度。
再看另外一個核函數
這時,如果x和z很相近( ),那麼核函數值為1,如果x和z相差很大( ),那麼核函數值約等於0。由於這個函數類似於高斯分布,因此稱為高斯核函數,也叫做徑向基函數(Radial Basis Function 簡稱RBF)。它能夠把原始特徵映射到無窮維。
既然高斯核函數能夠比較x和z的相似度,並映射到0到1,回想logistic回歸,sigmoid函數可以,因此還有sigmoid核函數等等。
下面有張圖說明在低維線性不可分時,映射到高維後就可分了,使用高斯核函數。
來自Eric Xing的slides
注意,使用核函數後,怎麼分類新來的樣本呢?線性的時候我們使用SVM學習出w和b,新來樣本x的話,我們使用 來判斷,如果值大於等於1,那麼是正類,小於等於是負類。在兩者之間,認為無法確定。如果使用了核函數後, 就變成了 ,是否先要找到 ,然後再預測?答案肯定不是了,找 很麻煩,回想我們之前說過的
只需將 替換成 ,然後值的判斷同上。
9. 跪求支持向量機分類c語言下的源程序的例子
你就等待畢不了業吧!