diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2c48e9a --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +## Core latex/pdflatex auxiliary files: +*.aux +*.lof +*.log +*.lot +*.fls +*.out +*.toc +*.fmt +*.fot +*.cb +*.cb2 + + +## MAC +.DS_Store + +## PyCharm +*.idea/*.iml + +# auxiliary python files +*.pyc \ No newline at end of file diff --git a/README.md b/README.md index 49f9246..206b184 100644 --- a/README.md +++ b/README.md @@ -6,39 +6,39 @@ MachineLearning 一些常见的机器学习算法的实现代码,本人学习过程中做的总结,资历尚浅,如有错误请不吝指出。 -##目录介绍 +## 目录介绍 - **DeepLearning Tutorials** - 这个文件夹下包含一些深度学习算法的实现代码,以及具体的应用实例,包含: + 这个文件夹下包含一些深度学习算法的实现代码,以及具体的应用实例,包含: - [dive_into _keras](https://github.com/wepe/MachineLearning/tree/master/DeepLearning%20Tutorials/dive_into_keras) Keras使用进阶。介绍了怎么保存训练好的CNN模型,怎么将CNN用作特征提取,怎么可视化卷积图。[文章链接](http://blog.csdn.net/u012162613/article/details/45581421), 更多进阶使用方法:[gist](https://gist.github.com/wepe/a05ad572dca002046de443061909ff7a) + [dive_into _keras](https://github.com/wepe/MachineLearning/tree/master/DeepLearning%20Tutorials/dive_into_keras) Keras使用进阶。介绍了怎么保存训练好的CNN模型,怎么将CNN用作特征提取,怎么可视化卷积图。[文章链接](http://blog.csdn.net/u012162613/article/details/45581421), 更多进阶使用方法:[gist](https://gist.github.com/wepe/a05ad572dca002046de443061909ff7a) - [keras_usage](https://github.com/wepe/MachineLearning/tree/master/DeepLearning%20Tutorials/keras_usage) 介绍了一个简单易用的深度学习框架keras,用经典的Mnist分类问题对该框架的使用进行说明,训练一个CNN,总共不超过30行代码。[文章链接](http://blog.csdn.net/u012162613/article/details/45397033) + [keras_usage](https://github.com/wepe/MachineLearning/tree/master/DeepLearning%20Tutorials/keras_usage) 介绍了一个简单易用的深度学习框架keras,用经典的Mnist分类问题对该框架的使用进行说明,训练一个CNN,总共不超过30行代码。[文章链接](http://blog.csdn.net/u012162613/article/details/45397033) - [FaceRecognition_CNN(olivettifaces)](https://github.com/wepe/MachineLearning-Demo/tree/master/DeepLearning%20Tutorials/FaceRecognition_CNN(olivettifaces)) + [FaceRecognition_CNN(olivettifaces)](https://github.com/wepe/MachineLearning-Demo/tree/master/DeepLearning%20Tutorials/FaceRecognition_CNN(olivettifaces)) 将卷积神经网络CNN应用于人脸识别的一个demo,人脸数据库采用olivettifaces,CNN模型参考LeNet5,基于python+theano+numpy+PIL实现。详细介绍这个demo的文章:[文章链接](http://blog.csdn.net/u012162613/article/details/43277187) - [cnn_LeNet](https://github.com/wepe/MachineLearning-Demo/tree/master/DeepLearning%20Tutorials/cnn_LeNet) CNN卷积神经网络算法的实现,模型为简化版的LeNet,应用于MNIST数据集(手写数字),来自于DeepLearning.net上的一个教程,基于python+theano,我用了中文将原始的代码进行详细的解读,并简单总结了CNN算法,相应的文章发在:[文章链接](http://blog.csdn.net/u012162613/article/details/43225445) + [cnn_LeNet](https://github.com/wepe/MachineLearning-Demo/tree/master/DeepLearning%20Tutorials/cnn_LeNet) CNN卷积神经网络算法的实现,模型为简化版的LeNet,应用于MNIST数据集(手写数字),来自于DeepLearning.net上的一个教程,基于python+theano,我用了中文将原始的代码进行详细的解读,并简单总结了CNN算法,相应的文章发在:[文章链接](http://blog.csdn.net/u012162613/article/details/43225445) - [mlp](https://github.com/wepe/MachineLearning-Demo/tree/master/DeepLearning%20Tutorials/mlp) 多层感知机算法的实现,代码实现了最简单的三层感知机,并应用于MNIST数据集,来自DeepLearning.net上的一个教程,基于python+theano,我写了一篇文章总结介绍了MLP算法,同时用中文详细解读了原始的代码:[文章链接](http://blog.csdn.net/u012162613/article/details/43221829) + [mlp](https://github.com/wepe/MachineLearning-Demo/tree/master/DeepLearning%20Tutorials/mlp) 多层感知机算法的实现,代码实现了最简单的三层感知机,并应用于MNIST数据集,来自DeepLearning.net上的一个教程,基于python+theano,我写了一篇文章总结介绍了MLP算法,同时用中文详细解读了原始的代码:[文章链接](http://blog.csdn.net/u012162613/article/details/43221829) - [Softmax_sgd(or logistic_sgd)](https://github.com/wepe/MachineLearning-Demo/tree/master/DeepLearning%20Tutorials/Softmax_sgd(or%20logistic_sgd)) Softmax回归算法的实现,应用于MNIST数据集,基于Python+theano,来自DeepLearning.net上的一个教程,基于python+theano,我写了一篇文章介绍了Softmax回归算法,同时用中文详细解读了原始的代码:[文章链接](http://blog.csdn.net/u012162613/article/details/43157801) + [Softmax_sgd(or logistic_sgd)](https://github.com/wepe/MachineLearning-Demo/tree/master/DeepLearning%20Tutorials/Softmax_sgd(or%20logistic_sgd)) Softmax回归算法的实现,应用于MNIST数据集,基于Python+theano,来自DeepLearning.net上的一个教程,基于python+theano,我写了一篇文章介绍了Softmax回归算法,同时用中文详细解读了原始的代码:[文章链接](http://blog.csdn.net/u012162613/article/details/43157801) - **PCA** - 基于python+numpy实现了主成份分析PCA算法,这里详细地介绍了PCA算法,以及代码开发流程:[文章链接](http://blog.csdn.net/u012162613/article/details/42177327) + 基于python+numpy实现了主成份分析PCA算法,这里详细地介绍了PCA算法,以及代码开发流程:[文章链接](http://blog.csdn.net/u012162613/article/details/42177327) - **kNN** - 基于python+numpy实现了K近邻算法,并将其应用在MNIST数据集上,详细的介绍:[文章链接](http://blog.csdn.net/u012162613/article/details/41768407) + 基于python+numpy实现了K近邻算法,并将其应用在MNIST数据集上,详细的介绍:[文章链接](http://blog.csdn.net/u012162613/article/details/41768407) - **logistic regression** - - 基于C++以及线性代数库Eigen实现的logistic回归,[代码](https://github.com/wepe/MachineLearning/tree/master/logistic%20regression/use_cpp_and_eigen) + - 基于C++以及线性代数库Eigen实现的logistic回归,[代码](https://github.com/wepe/MachineLearning/tree/master/logistic%20regression/use_cpp_and_eigen) - - 基于python+numpy实现了logistic回归(二类别),详细的介绍:[文章链接](http://blog.csdn.net/u012162613/article/details/41844495) + - 基于python+numpy实现了logistic回归(二类别),详细的介绍:[文章链接](http://blog.csdn.net/u012162613/article/details/41844495) - **ManifoldLearning** @@ -48,6 +48,11 @@ MachineLearning [libsvm liblinear-usage](https://github.com/wepe/MachineLearning/tree/master/SVM/libsvm%20liblinear-usage) 对使用广泛的libsvm、liblinear的使用方法进行了总结,详细介绍:[文章链接](http://blog.csdn.net/u012162613/article/details/45206813) + [SVM by SMO](./SVM/SVM_by_SMO) - 用SMO实现了SVM + + [SVM by QP](./SVM/SVM_by_QP) - 用二次编程(QP)实现了SVM + + - **GMM** GMM和k-means作为EM算法的应用,在某种程度有些相似之处,不过GMM明显学习出一些概率密度函数来,结合相关理解写成python版本,详细介绍:[文章链接](http://blog.csdn.net/gugugujiawei/article/details/45583051) @@ -64,8 +69,12 @@ MachineLearning 朴素贝叶斯算法的理论推导,以及三种常见模型(多项式模型,高斯模型,伯努利模型)的介绍与编程实现(基于Python,Numpy)。[文章链接](http://blog.csdn.net/u012162613/article/details/48323777) -##Contributor +- **Ridge and Kernel Ridge** + + 介绍了Ridge回归和它的Kernel版本。[代码](./Ridge/kernel_ridge/kernel_ridge.py) + +## Contributor - [wepon](https://github.com/wepe) - [Gogary](https://github.com/enjoyhot) - +- [Locky](https://github.com/junlulocky) diff --git a/Ridge/README.md b/Ridge/README.md new file mode 100644 index 0000000..6e786a3 --- /dev/null +++ b/Ridge/README.md @@ -0,0 +1,18 @@ +Ridge and Kernel Ridge +====================== + +## Ridge + +TODO + +## Kernel Ridge + +See [run_kernel_ridge.py](./run_kernel_ridge.py) for an example for Kernel Ridge + +## Contributor + +- [junlulocky](https://github.com/junlulocky) + +## Reference + +- Welling, Max. "Kernel ridge Regression." Max Welling's Classnotes in Machine Learning (2013): 1-3. \ No newline at end of file diff --git a/Ridge/kernel_ridge/kernel_ridge.py b/Ridge/kernel_ridge/kernel_ridge.py new file mode 100644 index 0000000..6abec91 --- /dev/null +++ b/Ridge/kernel_ridge/kernel_ridge.py @@ -0,0 +1,90 @@ +import scipy as sp +from numpy.linalg import inv +import numpy as np +from scipy import linalg + + +class KernelRidge(): + """ + Simple implementation of a Kernel Ridge Regression using the + closed form for training. + Doc: https://www.ics.uci.edu/~welling/classnotes/papers_class/Kernel-Ridge.pdf + """ + + def __init__(self, kernel_type='linear', C=1.0, gamma=5.0): + """ + :param kernel_type: Kernel type to use in training. + 'linear' use linear kernel function. + 'quadratic' use quadratic kernel function. + 'gaussian' use gaussian kernel function + :param C: Value of regularization parameter C + :param gamma: parameter for gaussian kernel or Polynomial kernel + """ + self.kernels = { + 'linear': self.kernel_linear, + 'quadratic': self.kernel_quadratic, + 'gaussian': self.kernel_gaussian + } + self.kernel_type = kernel_type + self.kernel = self.kernels[self.kernel_type] + self.C = C + self.gamma = gamma + + # Define kernels + def kernel_linear(self, x1, x2): + return np.dot(x1, x2.T) + + def kernel_quadratic(self, x1, x2): + return (np.dot(x1, x2.T) ** 2) + + def kernel_gaussian(self, x1, x2, gamma=5.0): + gamma = self.gamma + return np.exp(-linalg.norm(x1 - x2) ** 2 / (2 * (gamma ** 2))) + + def compute_kernel_matrix(self, X1, X2): + """ + compute kernel matrix (gram matrix) give two input matrix + """ + + # sample size + n1 = X1.shape[0] + n2 = X2.shape[0] + + # Gram matrix + K = np.zeros((n1, n2)) + for i in range(n1): + for j in range(n2): + K[i, j] = self.kernel(X1[i], X2[j]) + + return K + + + def fit(self, X, y): + """ + training KRR + :param X: training X + :param y: training y + :return: alpha vector, see document TODO + """ + K = self.compute_kernel_matrix(X, X) + + self.alphas = sp.dot(inv(K + self.C * np.eye(np.shape(K)[0])), + y.transpose()) + + return self.alphas + + def predict(self, x_train, x_test): + """ + + :param x_train: DxNtr array of Ntr train data points + with D features + :param x_test: DxNte array of Nte test data points + with D features + :return: y_test, D2xNte array + """ + + k = self.compute_kernel_matrix(x_test, x_train) + + y_test = sp.dot(k, self.alphas) + return y_test.transpose() + diff --git a/Ridge/kernel_ridge/kernel_ridge.pyc b/Ridge/kernel_ridge/kernel_ridge.pyc new file mode 100644 index 0000000..6116f24 Binary files /dev/null and b/Ridge/kernel_ridge/kernel_ridge.pyc differ diff --git a/Ridge/kernel_ridge/run_kernel_ridge.py b/Ridge/kernel_ridge/run_kernel_ridge.py new file mode 100644 index 0000000..4d614d3 --- /dev/null +++ b/Ridge/kernel_ridge/run_kernel_ridge.py @@ -0,0 +1,61 @@ +import csv, os, sys +import numpy as np +from kernel_ridge import KernelRidge +filepath = os.path.dirname(os.path.abspath(__file__)) + +def readData(filename, header=True): + data, header = [], None + with open(filename, 'rb') as csvfile: + spamreader = csv.reader(csvfile, delimiter=',') + if header: + header = spamreader.next() + for row in spamreader: + data.append(row) + return (np.array(data), np.array(header)) + +def calc_mse(y, y_hat): + return np.nanmean(((y - y_hat) ** 2)) + +def test_main(filename='small_data/iris-virginica.txt', C=1.0, kernel_type='linear'): + # Load data + (data, _) = readData('%s/%s' % (filepath, filename), header=False) + data = data.astype(float) + + # Split data + X, y = data[:,0:-1], data[:,-1].astype(int) + y = y[np.newaxis,:] + print X.shape + print y.shape + + + + # fit our model + model = KernelRidge(kernel_type='gaussian', C=0.1, gamma=5.0) + model.fit(X, y) + y_hat = model.predict(x_train=X, x_test=X) + mse = calc_mse(y, y_hat) # Calculate accuracy + print("mse of KRR:\t%.3f" % (mse)) + + # fit linear model for test + from sklearn import linear_model + ls = linear_model.LinearRegression() + ls.fit(X, y[0,:]) + y_ls = ls.predict(X) + mse = calc_mse(y, y_ls) + print("mse of LS (from sklearn):\t%.3f" % (mse)) + + # fit KRR from sklearn for test + from sklearn.kernel_ridge import KernelRidge as KR2 + kr2 = KR2(kernel='rbf', gamma=5, alpha=10) + kr2.fit(X, y[0, :]) + y_krr = kr2.predict(X) + mse = calc_mse(y, y_krr) + print("mse of KRR (from sklearn):\t%.3f" % (mse)) + + + + + +if __name__ == '__main__': + + test_main(filename='./small_data/iris-slwc.txt') diff --git a/Ridge/kernel_ridge/small_data/iris-slwc.txt b/Ridge/kernel_ridge/small_data/iris-slwc.txt new file mode 100755 index 0000000..685db1a --- /dev/null +++ b/Ridge/kernel_ridge/small_data/iris-slwc.txt @@ -0,0 +1,150 @@ +5.9,3,1 +6.9,3.1,1 +6.6,2.9,1 +4.6,3.2,-1 +6,2.2,1 +4.7,3.2,-1 +6.5,3,1 +5.8,2.7,1 +6.7,3.1,1 +6.7,2.5,1 +5.1,3.7,-1 +5.1,3.8,-1 +5.7,3,1 +6.1,3,1 +4.9,3.1,-1 +5,3.4,-1 +5,3.4,-1 +5.7,2.8,1 +5,3.3,-1 +7.2,3.2,1 +5.9,3,1 +6.5,3,1 +5.7,4.4,-1 +5.5,2.5,1 +4.9,2.5,1 +5,3.5,-1 +5.5,2.3,1 +4.6,3.1,-1 +7.2,3,1 +6.8,3.2,1 +5.4,3.9,-1 +5,3.2,-1 +5.7,2.5,1 +5.8,2.6,1 +5.1,2.5,1 +5.6,2.5,1 +5.8,2.7,1 +5.1,3.8,-1 +6.3,2.3,1 +6.3,2.5,1 +5.6,3,1 +6.1,3,1 +6.8,3,1 +7.3,2.9,1 +5.6,2.7,1 +4.8,3,-1 +7.1,3,1 +5.7,2.6,1 +5.3,3.7,-1 +5.7,3.8,-1 +5.7,2.9,1 +5.6,2.8,1 +4.4,3,-1 +6.3,3.3,1 +5.4,3.4,-1 +6.3,3.4,1 +6.9,3.1,1 +7.7,3,1 +6.1,2.8,1 +5.6,2.9,1 +6.1,2.6,1 +6.4,2.7,1 +5,3.5,-1 +5.1,3.3,-1 +5.6,3,1 +5.4,3,1 +5.8,2.8,1 +4.9,3.1,-1 +4.6,3.6,-1 +5.2,3.4,-1 +7.9,3.8,1 +7.7,2.6,1 +6.1,2.8,1 +5.5,3.5,-1 +4.6,3.4,-1 +4.7,3.2,-1 +4.4,2.9,-1 +6.2,2.8,1 +4.8,3,-1 +6,2.9,1 +6.2,3.4,1 +5,2.3,1 +6.4,3.2,1 +6.3,2.9,1 +6.7,3,1 +5,2,1 +5.9,3.2,1 +6.7,3.3,1 +5.4,3.9,-1 +6.3,2.7,1 +4.8,3.4,-1 +4.4,3.2,-1 +6.4,3.2,1 +6.2,2.2,1 +6,2.2,1 +7.4,2.8,1 +4.9,2.4,1 +7,3.2,1 +5.5,2.4,1 +6.3,3.3,1 +6.8,2.8,1 +6.1,2.9,1 +6.5,3.2,1 +6.7,3.3,1 +6.7,3.1,1 +4.8,3.4,-1 +4.9,3,-1 +6.9,3.2,1 +4.5,2.3,-1 +4.3,3,-1 +5.2,2.7,1 +5,3.6,-1 +6.4,2.9,1 +5.2,3.5,-1 +5.8,2.7,1 +5.5,4.2,-1 +7.6,3,1 +6.3,2.8,1 +6.4,3.1,1 +6.3,2.5,1 +5.8,2.7,1 +5,3,-1 +6.7,3.1,1 +6,2.7,1 +5.1,3.5,-1 +4.8,3.1,-1 +5.7,2.8,1 +5.1,3.8,-1 +6.6,3,1 +6.4,2.8,1 +5.2,4.1,-1 +6.4,2.8,1 +7.7,2.8,1 +5.8,4,-1 +4.9,3.1,-1 +5.4,3.7,-1 +5.1,3.5,-1 +6,3.4,1 +6.5,3,1 +5.5,2.4,1 +7.2,3.6,1 +6.9,3.1,1 +6.2,2.9,1 +6.5,2.8,1 +6,3,1 +5.4,3.4,-1 +5.5,2.6,1 +6.7,3,1 +7.7,3.8,1 +5.1,3.4,-1 diff --git a/Ridge/kernel_ridge/small_data/iris-versicolor.txt b/Ridge/kernel_ridge/small_data/iris-versicolor.txt new file mode 100755 index 0000000..b09508e --- /dev/null +++ b/Ridge/kernel_ridge/small_data/iris-versicolor.txt @@ -0,0 +1,150 @@ +5.1,3.5,1.4,0.2,-1 +4.9,3,1.4,0.2,-1 +4.7,3.2,1.3,0.2,-1 +4.6,3.1,1.5,0.2,-1 +5,3.6,1.4,0.2,-1 +5.4,3.9,1.7,0.4,-1 +4.6,3.4,1.4,0.3,-1 +5,3.4,1.5,0.2,-1 +4.4,2.9,1.4,0.2,-1 +4.9,3.1,1.5,0.1,-1 +5.4,3.7,1.5,0.2,-1 +4.8,3.4,1.6,0.2,-1 +4.8,3,1.4,0.1,-1 +4.3,3,1.1,0.1,-1 +5.8,4,1.2,0.2,-1 +5.7,4.4,1.5,0.4,-1 +5.4,3.9,1.3,0.4,-1 +5.1,3.5,1.4,0.3,-1 +5.7,3.8,1.7,0.3,-1 +5.1,3.8,1.5,0.3,-1 +5.4,3.4,1.7,0.2,-1 +5.1,3.7,1.5,0.4,-1 +4.6,3.6,1,0.2,-1 +5.1,3.3,1.7,0.5,-1 +4.8,3.4,1.9,0.2,-1 +5,3,1.6,0.2,-1 +5,3.4,1.6,0.4,-1 +5.2,3.5,1.5,0.2,-1 +5.2,3.4,1.4,0.2,-1 +4.7,3.2,1.6,0.2,-1 +4.8,3.1,1.6,0.2,-1 +5.4,3.4,1.5,0.4,-1 +5.2,4.1,1.5,0.1,-1 +5.5,4.2,1.4,0.2,-1 +4.9,3.1,1.5,0.1,-1 +5,3.2,1.2,0.2,-1 +5.5,3.5,1.3,0.2,-1 +4.9,3.1,1.5,0.1,-1 +4.4,3,1.3,0.2,-1 +5.1,3.4,1.5,0.2,-1 +5,3.5,1.3,0.3,-1 +4.5,2.3,1.3,0.3,-1 +4.4,3.2,1.3,0.2,-1 +5,3.5,1.6,0.6,-1 +5.1,3.8,1.9,0.4,-1 +4.8,3,1.4,0.3,-1 +5.1,3.8,1.6,0.2,-1 +4.6,3.2,1.4,0.2,-1 +5.3,3.7,1.5,0.2,-1 +5,3.3,1.4,0.2,-1 +6.3,3.3,6,2.5,-1 +5.8,2.7,5.1,1.9,-1 +7.1,3,5.9,2.1,-1 +6.3,2.9,5.6,1.8,-1 +6.5,3,5.8,2.2,-1 +7.6,3,6.6,2.1,-1 +4.9,2.5,4.5,1.7,-1 +7.3,2.9,6.3,1.8,-1 +6.7,2.5,5.8,1.8,-1 +7.2,3.6,6.1,2.5,-1 +6.5,3.2,5.1,2,-1 +6.4,2.7,5.3,1.9,-1 +6.8,3,5.5,2.1,-1 +5.7,2.5,5,2,-1 +5.8,2.8,5.1,2.4,-1 +6.4,3.2,5.3,2.3,-1 +6.5,3,5.5,1.8,-1 +7.7,3.8,6.7,2.2,-1 +7.7,2.6,6.9,2.3,-1 +6,2.2,5,1.5,-1 +6.9,3.2,5.7,2.3,-1 +5.6,2.8,4.9,2,-1 +7.7,2.8,6.7,2,-1 +6.3,2.7,4.9,1.8,-1 +6.7,3.3,5.7,2.1,-1 +7.2,3.2,6,1.8,-1 +6.2,2.8,4.8,1.8,-1 +6.1,3,4.9,1.8,-1 +6.4,2.8,5.6,2.1,-1 +7.2,3,5.8,1.6,-1 +7.4,2.8,6.1,1.9,-1 +7.9,3.8,6.4,2,-1 +6.4,2.8,5.6,2.2,-1 +6.3,2.8,5.1,1.5,-1 +6.1,2.6,5.6,1.4,-1 +7.7,3,6.1,2.3,-1 +6.3,3.4,5.6,2.4,-1 +6.4,3.1,5.5,1.8,-1 +6,3,4.8,1.8,-1 +6.9,3.1,5.4,2.1,-1 +6.7,3.1,5.6,2.4,-1 +6.9,3.1,5.1,2.3,-1 +5.8,2.7,5.1,1.9,-1 +6.8,3.2,5.9,2.3,-1 +6.7,3.3,5.7,2.5,-1 +6.7,3,5.2,2.3,-1 +6.3,2.5,5,1.9,-1 +6.5,3,5.2,2,-1 +6.2,3.4,5.4,2.3,-1 +5.9,3,5.1,1.8,-1 +7,3.2,4.7,1.4,1 +6.4,3.2,4.5,1.5,1 +6.9,3.1,4.9,1.5,1 +5.5,2.3,4,1.3,1 +6.5,2.8,4.6,1.5,1 +5.7,2.8,4.5,1.3,1 +6.3,3.3,4.7,1.6,1 +4.9,2.4,3.3,1,1 +6.6,2.9,4.6,1.3,1 +5.2,2.7,3.9,1.4,1 +5,2,3.5,1,1 +5.9,3,4.2,1.5,1 +6,2.2,4,1,1 +6.1,2.9,4.7,1.4,1 +5.6,2.9,3.6,1.3,1 +6.7,3.1,4.4,1.4,1 +5.6,3,4.5,1.5,1 +5.8,2.7,4.1,1,1 +6.2,2.2,4.5,1.5,1 +5.6,2.5,3.9,1.1,1 +5.9,3.2,4.8,1.8,1 +6.1,2.8,4,1.3,1 +6.3,2.5,4.9,1.5,1 +6.1,2.8,4.7,1.2,1 +6.4,2.9,4.3,1.3,1 +6.6,3,4.4,1.4,1 +6.8,2.8,4.8,1.4,1 +6.7,3,5,1.7,1 +6,2.9,4.5,1.5,1 +5.7,2.6,3.5,1,1 +5.5,2.4,3.8,1.1,1 +5.5,2.4,3.7,1,1 +5.8,2.7,3.9,1.2,1 +6,2.7,5.1,1.6,1 +5.4,3,4.5,1.5,1 +6,3.4,4.5,1.6,1 +6.7,3.1,4.7,1.5,1 +6.3,2.3,4.4,1.3,1 +5.6,3,4.1,1.3,1 +5.5,2.5,4,1.3,1 +5.5,2.6,4.4,1.2,1 +6.1,3,4.6,1.4,1 +5.8,2.6,4,1.2,1 +5,2.3,3.3,1,1 +5.6,2.7,4.2,1.3,1 +5.7,3,4.2,1.2,1 +5.7,2.9,4.2,1.3,1 +6.2,2.9,4.3,1.3,1 +5.1,2.5,3,1.1,1 +5.7,2.8,4.1,1.3,1 diff --git a/Ridge/kernel_ridge/small_data/iris-virginica.txt b/Ridge/kernel_ridge/small_data/iris-virginica.txt new file mode 100755 index 0000000..b2a701b --- /dev/null +++ b/Ridge/kernel_ridge/small_data/iris-virginica.txt @@ -0,0 +1,150 @@ +5.1,3.5,1.4,0.2,1 +4.9,3,1.4,0.2,1 +4.7,3.2,1.3,0.2,1 +4.6,3.1,1.5,0.2,1 +5,3.6,1.4,0.2,1 +5.4,3.9,1.7,0.4,1 +4.6,3.4,1.4,0.3,1 +5,3.4,1.5,0.2,1 +4.4,2.9,1.4,0.2,1 +4.9,3.1,1.5,0.1,1 +5.4,3.7,1.5,0.2,1 +4.8,3.4,1.6,0.2,1 +4.8,3,1.4,0.1,1 +4.3,3,1.1,0.1,1 +5.8,4,1.2,0.2,1 +5.7,4.4,1.5,0.4,1 +5.4,3.9,1.3,0.4,1 +5.1,3.5,1.4,0.3,1 +5.7,3.8,1.7,0.3,1 +5.1,3.8,1.5,0.3,1 +5.4,3.4,1.7,0.2,1 +5.1,3.7,1.5,0.4,1 +4.6,3.6,1,0.2,1 +5.1,3.3,1.7,0.5,1 +4.8,3.4,1.9,0.2,1 +5,3,1.6,0.2,1 +5,3.4,1.6,0.4,1 +5.2,3.5,1.5,0.2,1 +5.2,3.4,1.4,0.2,1 +4.7,3.2,1.6,0.2,1 +4.8,3.1,1.6,0.2,1 +5.4,3.4,1.5,0.4,1 +5.2,4.1,1.5,0.1,1 +5.5,4.2,1.4,0.2,1 +4.9,3.1,1.5,0.1,1 +5,3.2,1.2,0.2,1 +5.5,3.5,1.3,0.2,1 +4.9,3.1,1.5,0.1,1 +4.4,3,1.3,0.2,1 +5.1,3.4,1.5,0.2,1 +5,3.5,1.3,0.3,1 +4.5,2.3,1.3,0.3,1 +4.4,3.2,1.3,0.2,1 +5,3.5,1.6,0.6,1 +5.1,3.8,1.9,0.4,1 +4.8,3,1.4,0.3,1 +5.1,3.8,1.6,0.2,1 +4.6,3.2,1.4,0.2,1 +5.3,3.7,1.5,0.2,1 +5,3.3,1.4,0.2,1 +7,3.2,4.7,1.4,1 +6.4,3.2,4.5,1.5,1 +6.9,3.1,4.9,1.5,1 +5.5,2.3,4,1.3,1 +6.5,2.8,4.6,1.5,1 +5.7,2.8,4.5,1.3,1 +6.3,3.3,4.7,1.6,1 +4.9,2.4,3.3,1,1 +6.6,2.9,4.6,1.3,1 +5.2,2.7,3.9,1.4,1 +5,2,3.5,1,1 +5.9,3,4.2,1.5,1 +6,2.2,4,1,1 +6.1,2.9,4.7,1.4,1 +5.6,2.9,3.6,1.3,1 +6.7,3.1,4.4,1.4,1 +5.6,3,4.5,1.5,1 +5.8,2.7,4.1,1,1 +6.2,2.2,4.5,1.5,1 +5.6,2.5,3.9,1.1,1 +5.9,3.2,4.8,1.8,1 +6.1,2.8,4,1.3,1 +6.3,2.5,4.9,1.5,1 +6.1,2.8,4.7,1.2,1 +6.4,2.9,4.3,1.3,1 +6.6,3,4.4,1.4,1 +6.8,2.8,4.8,1.4,1 +6.7,3,5,1.7,1 +6,2.9,4.5,1.5,1 +5.7,2.6,3.5,1,1 +5.5,2.4,3.8,1.1,1 +5.5,2.4,3.7,1,1 +5.8,2.7,3.9,1.2,1 +6,2.7,5.1,1.6,1 +5.4,3,4.5,1.5,1 +6,3.4,4.5,1.6,1 +6.7,3.1,4.7,1.5,1 +6.3,2.3,4.4,1.3,1 +5.6,3,4.1,1.3,1 +5.5,2.5,4,1.3,1 +5.5,2.6,4.4,1.2,1 +6.1,3,4.6,1.4,1 +5.8,2.6,4,1.2,1 +5,2.3,3.3,1,1 +5.6,2.7,4.2,1.3,1 +5.7,3,4.2,1.2,1 +5.7,2.9,4.2,1.3,1 +6.2,2.9,4.3,1.3,1 +5.1,2.5,3,1.1,1 +5.7,2.8,4.1,1.3,1 +6.3,3.3,6,2.5,-1 +5.8,2.7,5.1,1.9,-1 +7.1,3,5.9,2.1,-1 +6.3,2.9,5.6,1.8,-1 +6.5,3,5.8,2.2,-1 +7.6,3,6.6,2.1,-1 +4.9,2.5,4.5,1.7,-1 +7.3,2.9,6.3,1.8,-1 +6.7,2.5,5.8,1.8,-1 +7.2,3.6,6.1,2.5,-1 +6.5,3.2,5.1,2,-1 +6.4,2.7,5.3,1.9,-1 +6.8,3,5.5,2.1,-1 +5.7,2.5,5,2,-1 +5.8,2.8,5.1,2.4,-1 +6.4,3.2,5.3,2.3,-1 +6.5,3,5.5,1.8,-1 +7.7,3.8,6.7,2.2,-1 +7.7,2.6,6.9,2.3,-1 +6,2.2,5,1.5,-1 +6.9,3.2,5.7,2.3,-1 +5.6,2.8,4.9,2,-1 +7.7,2.8,6.7,2,-1 +6.3,2.7,4.9,1.8,-1 +6.7,3.3,5.7,2.1,-1 +7.2,3.2,6,1.8,-1 +6.2,2.8,4.8,1.8,-1 +6.1,3,4.9,1.8,-1 +6.4,2.8,5.6,2.1,-1 +7.2,3,5.8,1.6,-1 +7.4,2.8,6.1,1.9,-1 +7.9,3.8,6.4,2,-1 +6.4,2.8,5.6,2.2,-1 +6.3,2.8,5.1,1.5,-1 +6.1,2.6,5.6,1.4,-1 +7.7,3,6.1,2.3,-1 +6.3,3.4,5.6,2.4,-1 +6.4,3.1,5.5,1.8,-1 +6,3,4.8,1.8,-1 +6.9,3.1,5.4,2.1,-1 +6.7,3.1,5.6,2.4,-1 +6.9,3.1,5.1,2.3,-1 +5.8,2.7,5.1,1.9,-1 +6.8,3.2,5.9,2.3,-1 +6.7,3.3,5.7,2.5,-1 +6.7,3,5.2,2.3,-1 +6.3,2.5,5,1.9,-1 +6.5,3,5.2,2,-1 +6.2,3.4,5.4,2.3,-1 +5.9,3,5.1,1.8,-1 diff --git a/SVM/SVM_by_QP/README.md b/SVM/SVM_by_QP/README.md new file mode 100644 index 0000000..c385ed9 --- /dev/null +++ b/SVM/SVM_by_QP/README.md @@ -0,0 +1,7 @@ +# SVM Python + +This is an example of SVM implementation by Python based on cvxopt. + +The quadratic programming function, please refer to http://cvxopt.org/userguide/coneprog.html?highlight=qp#cvxopt.solvers.qp + +The theory of SVM, please refer to the four SVM slides included in this project. diff --git a/SVM/SVM_by_QP/SVCQP.py b/SVM/SVM_by_QP/SVCQP.py new file mode 100644 index 0000000..e4eb8fb --- /dev/null +++ b/SVM/SVM_by_QP/SVCQP.py @@ -0,0 +1,100 @@ +import numpy as np +from numpy import linalg +import cvxopt +import cvxopt.solvers + +## define kenrel functions +def linear_kernel(x1, x2): + return np.dot(x1, x2) + +def polynomial_kernel(x, y, p=3): + return (1 + np.dot(x, y)) ** p + +def gaussian_kernel(x, y, sigma=5.0): + return np.exp(-linalg.norm(x-y)**2 / (2 * (sigma ** 2))) +## end define kernel functions + +class SVM(object): + """ + Suppoet vector classification by quadratic programming + """ + + def __init__(self, kernel=linear_kernel, C=None): + """ + + :param kernel: kernel types, should be in the kernel function list above + :param C: + """ + self.kernel = kernel + self.C = C + if self.C is not None: self.C = float(self.C) + + def fit(self, X, y): + n_samples, n_features = X.shape + + # Gram matrix + K = np.zeros((n_samples, n_samples)) + for i in range(n_samples): + for j in range(n_samples): + K[i,j] = self.kernel(X[i], X[j]) + + P = cvxopt.matrix(np.outer(y,y) * K) + q = cvxopt.matrix(np.ones(n_samples) * -1) + A = cvxopt.matrix(y, (1,n_samples)) + b = cvxopt.matrix(0.0) + + if self.C is None: + G = cvxopt.matrix(np.diag(np.ones(n_samples) * -1)) + h = cvxopt.matrix(np.zeros(n_samples)) + else: + tmp1 = np.diag(np.ones(n_samples) * -1) + tmp2 = np.identity(n_samples) + G = cvxopt.matrix(np.vstack((tmp1, tmp2))) + tmp1 = np.zeros(n_samples) + tmp2 = np.ones(n_samples) * self.C + h = cvxopt.matrix(np.hstack((tmp1, tmp2))) + + # solve QP problem, DOC: http://cvxopt.org/userguide/coneprog.html?highlight=qp#cvxopt.solvers.qp + solution = cvxopt.solvers.qp(P, q, G, h, A, b) + + # Lagrange multipliers + a = np.ravel(solution['x']) + + # Support vectors have non zero lagrange multipliers + sv = a > 1e-5 + ind = np.arange(len(a))[sv] + self.a = a[sv] + self.sv = X[sv] + self.sv_y = y[sv] + print "%d support vectors out of %d points" % (len(self.a), n_samples) + + # Intercept + self.b = 0 + for n in range(len(self.a)): + self.b += self.sv_y[n] + self.b -= np.sum(self.a * self.sv_y * K[ind[n],sv]) + self.b /= len(self.a) + + # Weight vector + if self.kernel == linear_kernel: + self.w = np.zeros(n_features) + for n in range(len(self.a)): + self.w += self.a[n] * self.sv_y[n] * self.sv[n] + else: + self.w = None + + def project(self, X): + if self.w is not None: + return np.dot(X, self.w) + self.b + else: + y_predict = np.zeros(len(X)) + for i in range(len(X)): + s = 0 + for a, sv_y, sv in zip(self.a, self.sv_y, self.sv): + s += a * sv_y * self.kernel(X[i], sv) + y_predict[i] = s + return y_predict + self.b + + def predict(self, X): + return np.sign(self.project(X)) + diff --git a/SVM/SVM_by_QP/doc/.DS_Store b/SVM/SVM_by_QP/doc/.DS_Store new file mode 100644 index 0000000..0e8d47c Binary files /dev/null and b/SVM/SVM_by_QP/doc/.DS_Store differ diff --git a/SVM/SVM_by_QP/doc/Reference/SVM_Dual.pdf b/SVM/SVM_by_QP/doc/Reference/SVM_Dual.pdf new file mode 100644 index 0000000..45ea20c Binary files /dev/null and b/SVM/SVM_by_QP/doc/Reference/SVM_Dual.pdf differ diff --git a/SVM/SVM_by_QP/doc/Reference/SVM_Kernel.pdf b/SVM/SVM_by_QP/doc/Reference/SVM_Kernel.pdf new file mode 100644 index 0000000..59b66ed Binary files /dev/null and b/SVM/SVM_by_QP/doc/Reference/SVM_Kernel.pdf differ diff --git a/SVM/SVM_by_QP/doc/Reference/SVM_Primal.pdf b/SVM/SVM_by_QP/doc/Reference/SVM_Primal.pdf new file mode 100644 index 0000000..3dcb620 Binary files /dev/null and b/SVM/SVM_by_QP/doc/Reference/SVM_Primal.pdf differ diff --git a/SVM/SVM_by_QP/doc/Reference/SVM_SoftMargin.pdf b/SVM/SVM_by_QP/doc/Reference/SVM_SoftMargin.pdf new file mode 100644 index 0000000..f611bda Binary files /dev/null and b/SVM/SVM_by_QP/doc/Reference/SVM_SoftMargin.pdf differ diff --git a/SVM/SVM_by_QP/doc/SVM_quick_doc.pdf b/SVM/SVM_by_QP/doc/SVM_quick_doc.pdf new file mode 100644 index 0000000..88dbcdf Binary files /dev/null and b/SVM/SVM_by_QP/doc/SVM_quick_doc.pdf differ diff --git a/SVM/SVM_by_QP/testSVM.py b/SVM/SVM_by_QP/testSVM.py new file mode 100644 index 0000000..fc3ec3a --- /dev/null +++ b/SVM/SVM_by_QP/testSVM.py @@ -0,0 +1,153 @@ +from SVCQP import * +import pylab as pl + +def gen_lin_separable_data(): + # generate training data in the 2-d case + mean1 = np.array([0, 2]) + mean2 = np.array([2, 0]) + cov = np.array([[0.8, 0.6], [0.6, 0.8]]) + X1 = np.random.multivariate_normal(mean1, cov, 100) + y1 = np.ones(len(X1)) + X2 = np.random.multivariate_normal(mean2, cov, 100) + y2 = np.ones(len(X2)) * -1 + return X1, y1, X2, y2 + +def gen_non_lin_separable_data(): + mean1 = [-1, 2] + mean2 = [1, -1] + mean3 = [4, -4] + mean4 = [-4, 4] + cov = [[1.0,0.8], [0.8, 1.0]] + X1 = np.random.multivariate_normal(mean1, cov, 50) + X1 = np.vstack((X1, np.random.multivariate_normal(mean3, cov, 50))) + y1 = np.ones(len(X1)) + X2 = np.random.multivariate_normal(mean2, cov, 50) + X2 = np.vstack((X2, np.random.multivariate_normal(mean4, cov, 50))) + y2 = np.ones(len(X2)) * -1 + return X1, y1, X2, y2 + +def gen_lin_separable_overlap_data(): + # generate training data in the 2-d case + mean1 = np.array([0, 2]) + mean2 = np.array([2, 0]) + cov = np.array([[1.5, 1.0], [1.0, 1.5]]) + X1 = np.random.multivariate_normal(mean1, cov, 100) + y1 = np.ones(len(X1)) + X2 = np.random.multivariate_normal(mean2, cov, 100) + y2 = np.ones(len(X2)) * -1 + return X1, y1, X2, y2 + +def split_train(X1, y1, X2, y2): + X1_train = X1[:90] + y1_train = y1[:90] + X2_train = X2[:90] + y2_train = y2[:90] + X_train = np.vstack((X1_train, X2_train)) + y_train = np.hstack((y1_train, y2_train)) + return X_train, y_train + +def split_test(X1, y1, X2, y2): + X1_test = X1[90:] + y1_test = y1[90:] + X2_test = X2[90:] + y2_test = y2[90:] + X_test = np.vstack((X1_test, X2_test)) + y_test = np.hstack((y1_test, y2_test)) + return X_test, y_test + +def plot_margin(X1_train, X2_train, clf): + def f(x, w, b, c=0): + # given x, return y such that [x,y] in on the line + # w.x + b = c + return (-w[0] * x - b + c) / w[1] + + pl.plot(X1_train[:,0], X1_train[:,1], "ro") + pl.plot(X2_train[:,0], X2_train[:,1], "bo") + pl.scatter(clf.sv[:,0], clf.sv[:,1], s=100, c="g") + + # w.x + b = 0 + a0 = -4; a1 = f(a0, clf.w, clf.b) + b0 = 4; b1 = f(b0, clf.w, clf.b) + pl.plot([a0,b0], [a1,b1], "k") + + # w.x + b = 1 + a0 = -4; a1 = f(a0, clf.w, clf.b, 1) + b0 = 4; b1 = f(b0, clf.w, clf.b, 1) + pl.plot([a0,b0], [a1,b1], "k--") + + # w.x + b = -1 + a0 = -4; a1 = f(a0, clf.w, clf.b, -1) + b0 = 4; b1 = f(b0, clf.w, clf.b, -1) + pl.plot([a0,b0], [a1,b1], "k--") + + pl.axis("tight") + pl.show() + +def plot_contour(X1_train, X2_train, clf): + pl.plot(X1_train[:,0], X1_train[:,1], "ro") + pl.plot(X2_train[:,0], X2_train[:,1], "bo") + pl.scatter(clf.sv[:,0], clf.sv[:,1], s=100, c="g") + + X1, X2 = np.meshgrid(np.linspace(-6,6,50), np.linspace(-6,6,50)) + X = np.array([[x1, x2] for x1, x2 in zip(np.ravel(X1), np.ravel(X2))]) + Z = clf.project(X).reshape(X1.shape) + pl.contour(X1, X2, Z, [0.0], colors='k', linewidths=1, origin='lower') + pl.contour(X1, X2, Z + 1, [0.0], colors='grey', linewidths=1, origin='lower') + pl.contour(X1, X2, Z - 1, [0.0], colors='grey', linewidths=1, origin='lower') + + pl.axis("tight") + pl.show() + +def test_linear(): + X1, y1, X2, y2 = gen_lin_separable_data() + X_train, y_train = split_train(X1, y1, X2, y2) + X_test, y_test = split_test(X1, y1, X2, y2) + + clf = SVM() + clf.fit(X_train, y_train) + + y_predict = clf.predict(X_test) + correct = np.sum(y_predict == y_test) + print "%d out of %d predictions correct" % (correct, len(y_predict)) + + plot_margin(X_train[y_train==1], X_train[y_train==-1], clf) + +def test_non_linear(): + X1, y1, X2, y2 = gen_non_lin_separable_data() + X_train, y_train = split_train(X1, y1, X2, y2) + X_test, y_test = split_test(X1, y1, X2, y2) + + # X_train = np.load('inputClf/X_train.npy') + # y_train = np.load('inputClf/y_train.npy') + # X_test = np.load('inputClf/X_test.npy') + # y_test = np.load('inputClf/y_test.npy') + clf = SVM(gaussian_kernel, C=1) + clf.fit(X_train, y_train) + + y_predict = clf.predict(X_test) + correct = np.sum(y_predict == y_test) + print "%d out of %d predictions correct" % (correct, len(y_predict)) + + plot_contour(X_train[y_train==1], X_train[y_train==-1], clf) + +def test_soft(): + X1, y1, X2, y2 = gen_lin_separable_overlap_data() + X_train, y_train = split_train(X1, y1, X2, y2) + X_test, y_test = split_test(X1, y1, X2, y2) + + + + clf = SVM(C=0.1) + clf.fit(X_train, y_train) + + y_predict = clf.predict(X_test) + correct = np.sum(y_predict == y_test) + print "%d out of %d predictions correct" % (correct, len(y_predict)) + + plot_contour(X_train[y_train==1], X_train[y_train==-1], clf) + + +if __name__ == "__main__": + + test_non_linear() + #test_soft() \ No newline at end of file diff --git a/SVM/SVM_by_SMO/README.md b/SVM/SVM_by_SMO/README.md new file mode 100755 index 0000000..c624620 --- /dev/null +++ b/SVM/SVM_by_SMO/README.md @@ -0,0 +1,33 @@ +# SVM + +Simple implementation of a Support Vector Classification using the Sequential Minimal Optimization (SMO) algorithm for +training. + +## Supported python versions: +* Python 2.7 +* Python 3.4 + +## Python package dependencies +* Numpy + +# Documentation + +Setup model (following parameters are default) + +```python + +from SVCSMO import SVCSMO +model = SVCSMO(max_iter=10000, kernel_type='linear', C=1.0, epsilon=0.001) +``` + +Train model + +```python +model.fit(X, y) +``` + +Predict new observations + +```python +y_hat = model.predict(X_test) +``` diff --git a/SVM/SVM_by_SMO/SVCSMO.py b/SVM/SVM_by_SMO/SVCSMO.py new file mode 100755 index 0000000..108cf0c --- /dev/null +++ b/SVM/SVM_by_SMO/SVCSMO.py @@ -0,0 +1,114 @@ +from __future__ import division, print_function +from numpy import linalg +import os +import numpy as np +import random as rnd +filepath = os.path.dirname(os.path.abspath(__file__)) + +class SVCSMO(): + """ + Simple implementation of a Support Vector Classification using the + Sequential Minimal Optimization (SMO) algorithm for training. + """ + def __init__(self, max_iter=10000, kernel_type='linear', C=1.0, epsilon=0.001, sigma=5.0): + """ + :param max_iter: maximum iteration + :param kernel_type: Kernel type to use in training. + 'linear' use linear kernel function. + 'quadratic' use quadratic kernel function. + 'gaussian' use gaussian kernel function + :param C: Value of regularization parameter C + :param epsilon: Convergence value. + :param sigma: parameter for gaussian kernel + """ + self.kernels = { + 'linear' : self.kernel_linear, + 'quadratic' : self.kernel_quadratic, + 'gaussian' : self.kernel_gaussian + } + self.max_iter = max_iter + self.kernel_type = kernel_type + self.C = C + self.epsilon = epsilon + self.sigma = sigma + def fit(self, X, y): + # Initialization + n, d = X.shape[0], X.shape[1] + alpha = np.zeros((n)) + kernel = self.kernels[self.kernel_type] + count = 0 + while True: + count += 1 + alpha_prev = np.copy(alpha) + for j in range(0, n): + i = self.get_rnd_int(0, n-1, j) # Get random int i~=j + x_i, x_j, y_i, y_j = X[i,:], X[j,:], y[i], y[j] + k_ij = kernel(x_i, x_i) + kernel(x_j, x_j) - 2 * kernel(x_i, x_j) + if k_ij == 0: + continue + alpha_prime_j, alpha_prime_i = alpha[j], alpha[i] + (L, H) = self.compute_L_H(self.C, alpha_prime_j, alpha_prime_i, y_j, y_i) + + # Compute model parameters + self.w = self.calc_w(alpha, y, X) + self.b = self.calc_b(X, y, self.w) + + # Compute E_i, E_j + E_i = self.E(x_i, y_i, self.w, self.b) + E_j = self.E(x_j, y_j, self.w, self.b) + + # Set new alpha values + alpha[j] = alpha_prime_j + float(y_j * (E_i - E_j))/k_ij + alpha[j] = max(alpha[j], L) + alpha[j] = min(alpha[j], H) + + alpha[i] = alpha_prime_i + y_i*y_j * (alpha_prime_j - alpha[j]) + + # Check convergence + diff = np.linalg.norm(alpha - alpha_prev) + if diff < self.epsilon: + break + + if count >= self.max_iter: + print("Iteration number exceeded the max of %d iterations" % (self.max_iter)) + return + # Compute final model parameters + self.b = self.calc_b(X, y, self.w) + if self.kernel_type == 'linear': + self.w = self.calc_w(alpha, y, X) + # Get support vectors + alpha_idx = np.where(alpha > 0)[0] + support_vectors = X[alpha_idx, :] + return support_vectors, count + def predict(self, X): + return self.h(X, self.w, self.b) + def calc_b(self, X, y, w): + b_tmp = y - np.dot(w.T, X.T) + return np.mean(b_tmp) + def calc_w(self, alpha, y, X): + return np.dot(alpha * y, X) + # Prediction + def h(self, X, w, b): + return np.sign(np.dot(w.T, X.T) + b).astype(int) + # Prediction error + def E(self, x_k, y_k, w, b): + return self.h(x_k, w, b) - y_k + def compute_L_H(self, C, alpha_prime_j, alpha_prime_i, y_j, y_i): + if(y_i != y_j): + return (max(0, alpha_prime_j - alpha_prime_i), min(C, C - alpha_prime_i + alpha_prime_j)) + else: + return (max(0, alpha_prime_i + alpha_prime_j - C), min(C, alpha_prime_i + alpha_prime_j)) + def get_rnd_int(self, a,b,z): + i = z + while i == z: + i = rnd.randint(a,b) + return i + # Define kernels + def kernel_linear(self, x1, x2): + return np.dot(x1, x2.T) + def kernel_quadratic(self, x1, x2): + return (np.dot(x1, x2.T) ** 2) + def kernel_gaussian(self, x1, x2, sigma=5.0): + if self.sigma: + sigma = self.sigma + return np.exp(-linalg.norm(x1-x2)**2 / (2 * (sigma ** 2))) diff --git a/SVM/SVM_by_SMO/SVCSMO.pyc b/SVM/SVM_by_SMO/SVCSMO.pyc new file mode 100644 index 0000000..80afb58 Binary files /dev/null and b/SVM/SVM_by_SMO/SVCSMO.pyc differ diff --git a/SVM/SVM_by_SMO/small_data/iris-slwc.txt b/SVM/SVM_by_SMO/small_data/iris-slwc.txt new file mode 100755 index 0000000..685db1a --- /dev/null +++ b/SVM/SVM_by_SMO/small_data/iris-slwc.txt @@ -0,0 +1,150 @@ +5.9,3,1 +6.9,3.1,1 +6.6,2.9,1 +4.6,3.2,-1 +6,2.2,1 +4.7,3.2,-1 +6.5,3,1 +5.8,2.7,1 +6.7,3.1,1 +6.7,2.5,1 +5.1,3.7,-1 +5.1,3.8,-1 +5.7,3,1 +6.1,3,1 +4.9,3.1,-1 +5,3.4,-1 +5,3.4,-1 +5.7,2.8,1 +5,3.3,-1 +7.2,3.2,1 +5.9,3,1 +6.5,3,1 +5.7,4.4,-1 +5.5,2.5,1 +4.9,2.5,1 +5,3.5,-1 +5.5,2.3,1 +4.6,3.1,-1 +7.2,3,1 +6.8,3.2,1 +5.4,3.9,-1 +5,3.2,-1 +5.7,2.5,1 +5.8,2.6,1 +5.1,2.5,1 +5.6,2.5,1 +5.8,2.7,1 +5.1,3.8,-1 +6.3,2.3,1 +6.3,2.5,1 +5.6,3,1 +6.1,3,1 +6.8,3,1 +7.3,2.9,1 +5.6,2.7,1 +4.8,3,-1 +7.1,3,1 +5.7,2.6,1 +5.3,3.7,-1 +5.7,3.8,-1 +5.7,2.9,1 +5.6,2.8,1 +4.4,3,-1 +6.3,3.3,1 +5.4,3.4,-1 +6.3,3.4,1 +6.9,3.1,1 +7.7,3,1 +6.1,2.8,1 +5.6,2.9,1 +6.1,2.6,1 +6.4,2.7,1 +5,3.5,-1 +5.1,3.3,-1 +5.6,3,1 +5.4,3,1 +5.8,2.8,1 +4.9,3.1,-1 +4.6,3.6,-1 +5.2,3.4,-1 +7.9,3.8,1 +7.7,2.6,1 +6.1,2.8,1 +5.5,3.5,-1 +4.6,3.4,-1 +4.7,3.2,-1 +4.4,2.9,-1 +6.2,2.8,1 +4.8,3,-1 +6,2.9,1 +6.2,3.4,1 +5,2.3,1 +6.4,3.2,1 +6.3,2.9,1 +6.7,3,1 +5,2,1 +5.9,3.2,1 +6.7,3.3,1 +5.4,3.9,-1 +6.3,2.7,1 +4.8,3.4,-1 +4.4,3.2,-1 +6.4,3.2,1 +6.2,2.2,1 +6,2.2,1 +7.4,2.8,1 +4.9,2.4,1 +7,3.2,1 +5.5,2.4,1 +6.3,3.3,1 +6.8,2.8,1 +6.1,2.9,1 +6.5,3.2,1 +6.7,3.3,1 +6.7,3.1,1 +4.8,3.4,-1 +4.9,3,-1 +6.9,3.2,1 +4.5,2.3,-1 +4.3,3,-1 +5.2,2.7,1 +5,3.6,-1 +6.4,2.9,1 +5.2,3.5,-1 +5.8,2.7,1 +5.5,4.2,-1 +7.6,3,1 +6.3,2.8,1 +6.4,3.1,1 +6.3,2.5,1 +5.8,2.7,1 +5,3,-1 +6.7,3.1,1 +6,2.7,1 +5.1,3.5,-1 +4.8,3.1,-1 +5.7,2.8,1 +5.1,3.8,-1 +6.6,3,1 +6.4,2.8,1 +5.2,4.1,-1 +6.4,2.8,1 +7.7,2.8,1 +5.8,4,-1 +4.9,3.1,-1 +5.4,3.7,-1 +5.1,3.5,-1 +6,3.4,1 +6.5,3,1 +5.5,2.4,1 +7.2,3.6,1 +6.9,3.1,1 +6.2,2.9,1 +6.5,2.8,1 +6,3,1 +5.4,3.4,-1 +5.5,2.6,1 +6.7,3,1 +7.7,3.8,1 +5.1,3.4,-1 diff --git a/SVM/SVM_by_SMO/small_data/iris-versicolor.txt b/SVM/SVM_by_SMO/small_data/iris-versicolor.txt new file mode 100755 index 0000000..b09508e --- /dev/null +++ b/SVM/SVM_by_SMO/small_data/iris-versicolor.txt @@ -0,0 +1,150 @@ +5.1,3.5,1.4,0.2,-1 +4.9,3,1.4,0.2,-1 +4.7,3.2,1.3,0.2,-1 +4.6,3.1,1.5,0.2,-1 +5,3.6,1.4,0.2,-1 +5.4,3.9,1.7,0.4,-1 +4.6,3.4,1.4,0.3,-1 +5,3.4,1.5,0.2,-1 +4.4,2.9,1.4,0.2,-1 +4.9,3.1,1.5,0.1,-1 +5.4,3.7,1.5,0.2,-1 +4.8,3.4,1.6,0.2,-1 +4.8,3,1.4,0.1,-1 +4.3,3,1.1,0.1,-1 +5.8,4,1.2,0.2,-1 +5.7,4.4,1.5,0.4,-1 +5.4,3.9,1.3,0.4,-1 +5.1,3.5,1.4,0.3,-1 +5.7,3.8,1.7,0.3,-1 +5.1,3.8,1.5,0.3,-1 +5.4,3.4,1.7,0.2,-1 +5.1,3.7,1.5,0.4,-1 +4.6,3.6,1,0.2,-1 +5.1,3.3,1.7,0.5,-1 +4.8,3.4,1.9,0.2,-1 +5,3,1.6,0.2,-1 +5,3.4,1.6,0.4,-1 +5.2,3.5,1.5,0.2,-1 +5.2,3.4,1.4,0.2,-1 +4.7,3.2,1.6,0.2,-1 +4.8,3.1,1.6,0.2,-1 +5.4,3.4,1.5,0.4,-1 +5.2,4.1,1.5,0.1,-1 +5.5,4.2,1.4,0.2,-1 +4.9,3.1,1.5,0.1,-1 +5,3.2,1.2,0.2,-1 +5.5,3.5,1.3,0.2,-1 +4.9,3.1,1.5,0.1,-1 +4.4,3,1.3,0.2,-1 +5.1,3.4,1.5,0.2,-1 +5,3.5,1.3,0.3,-1 +4.5,2.3,1.3,0.3,-1 +4.4,3.2,1.3,0.2,-1 +5,3.5,1.6,0.6,-1 +5.1,3.8,1.9,0.4,-1 +4.8,3,1.4,0.3,-1 +5.1,3.8,1.6,0.2,-1 +4.6,3.2,1.4,0.2,-1 +5.3,3.7,1.5,0.2,-1 +5,3.3,1.4,0.2,-1 +6.3,3.3,6,2.5,-1 +5.8,2.7,5.1,1.9,-1 +7.1,3,5.9,2.1,-1 +6.3,2.9,5.6,1.8,-1 +6.5,3,5.8,2.2,-1 +7.6,3,6.6,2.1,-1 +4.9,2.5,4.5,1.7,-1 +7.3,2.9,6.3,1.8,-1 +6.7,2.5,5.8,1.8,-1 +7.2,3.6,6.1,2.5,-1 +6.5,3.2,5.1,2,-1 +6.4,2.7,5.3,1.9,-1 +6.8,3,5.5,2.1,-1 +5.7,2.5,5,2,-1 +5.8,2.8,5.1,2.4,-1 +6.4,3.2,5.3,2.3,-1 +6.5,3,5.5,1.8,-1 +7.7,3.8,6.7,2.2,-1 +7.7,2.6,6.9,2.3,-1 +6,2.2,5,1.5,-1 +6.9,3.2,5.7,2.3,-1 +5.6,2.8,4.9,2,-1 +7.7,2.8,6.7,2,-1 +6.3,2.7,4.9,1.8,-1 +6.7,3.3,5.7,2.1,-1 +7.2,3.2,6,1.8,-1 +6.2,2.8,4.8,1.8,-1 +6.1,3,4.9,1.8,-1 +6.4,2.8,5.6,2.1,-1 +7.2,3,5.8,1.6,-1 +7.4,2.8,6.1,1.9,-1 +7.9,3.8,6.4,2,-1 +6.4,2.8,5.6,2.2,-1 +6.3,2.8,5.1,1.5,-1 +6.1,2.6,5.6,1.4,-1 +7.7,3,6.1,2.3,-1 +6.3,3.4,5.6,2.4,-1 +6.4,3.1,5.5,1.8,-1 +6,3,4.8,1.8,-1 +6.9,3.1,5.4,2.1,-1 +6.7,3.1,5.6,2.4,-1 +6.9,3.1,5.1,2.3,-1 +5.8,2.7,5.1,1.9,-1 +6.8,3.2,5.9,2.3,-1 +6.7,3.3,5.7,2.5,-1 +6.7,3,5.2,2.3,-1 +6.3,2.5,5,1.9,-1 +6.5,3,5.2,2,-1 +6.2,3.4,5.4,2.3,-1 +5.9,3,5.1,1.8,-1 +7,3.2,4.7,1.4,1 +6.4,3.2,4.5,1.5,1 +6.9,3.1,4.9,1.5,1 +5.5,2.3,4,1.3,1 +6.5,2.8,4.6,1.5,1 +5.7,2.8,4.5,1.3,1 +6.3,3.3,4.7,1.6,1 +4.9,2.4,3.3,1,1 +6.6,2.9,4.6,1.3,1 +5.2,2.7,3.9,1.4,1 +5,2,3.5,1,1 +5.9,3,4.2,1.5,1 +6,2.2,4,1,1 +6.1,2.9,4.7,1.4,1 +5.6,2.9,3.6,1.3,1 +6.7,3.1,4.4,1.4,1 +5.6,3,4.5,1.5,1 +5.8,2.7,4.1,1,1 +6.2,2.2,4.5,1.5,1 +5.6,2.5,3.9,1.1,1 +5.9,3.2,4.8,1.8,1 +6.1,2.8,4,1.3,1 +6.3,2.5,4.9,1.5,1 +6.1,2.8,4.7,1.2,1 +6.4,2.9,4.3,1.3,1 +6.6,3,4.4,1.4,1 +6.8,2.8,4.8,1.4,1 +6.7,3,5,1.7,1 +6,2.9,4.5,1.5,1 +5.7,2.6,3.5,1,1 +5.5,2.4,3.8,1.1,1 +5.5,2.4,3.7,1,1 +5.8,2.7,3.9,1.2,1 +6,2.7,5.1,1.6,1 +5.4,3,4.5,1.5,1 +6,3.4,4.5,1.6,1 +6.7,3.1,4.7,1.5,1 +6.3,2.3,4.4,1.3,1 +5.6,3,4.1,1.3,1 +5.5,2.5,4,1.3,1 +5.5,2.6,4.4,1.2,1 +6.1,3,4.6,1.4,1 +5.8,2.6,4,1.2,1 +5,2.3,3.3,1,1 +5.6,2.7,4.2,1.3,1 +5.7,3,4.2,1.2,1 +5.7,2.9,4.2,1.3,1 +6.2,2.9,4.3,1.3,1 +5.1,2.5,3,1.1,1 +5.7,2.8,4.1,1.3,1 diff --git a/SVM/SVM_by_SMO/small_data/iris-virginica.txt b/SVM/SVM_by_SMO/small_data/iris-virginica.txt new file mode 100755 index 0000000..b2a701b --- /dev/null +++ b/SVM/SVM_by_SMO/small_data/iris-virginica.txt @@ -0,0 +1,150 @@ +5.1,3.5,1.4,0.2,1 +4.9,3,1.4,0.2,1 +4.7,3.2,1.3,0.2,1 +4.6,3.1,1.5,0.2,1 +5,3.6,1.4,0.2,1 +5.4,3.9,1.7,0.4,1 +4.6,3.4,1.4,0.3,1 +5,3.4,1.5,0.2,1 +4.4,2.9,1.4,0.2,1 +4.9,3.1,1.5,0.1,1 +5.4,3.7,1.5,0.2,1 +4.8,3.4,1.6,0.2,1 +4.8,3,1.4,0.1,1 +4.3,3,1.1,0.1,1 +5.8,4,1.2,0.2,1 +5.7,4.4,1.5,0.4,1 +5.4,3.9,1.3,0.4,1 +5.1,3.5,1.4,0.3,1 +5.7,3.8,1.7,0.3,1 +5.1,3.8,1.5,0.3,1 +5.4,3.4,1.7,0.2,1 +5.1,3.7,1.5,0.4,1 +4.6,3.6,1,0.2,1 +5.1,3.3,1.7,0.5,1 +4.8,3.4,1.9,0.2,1 +5,3,1.6,0.2,1 +5,3.4,1.6,0.4,1 +5.2,3.5,1.5,0.2,1 +5.2,3.4,1.4,0.2,1 +4.7,3.2,1.6,0.2,1 +4.8,3.1,1.6,0.2,1 +5.4,3.4,1.5,0.4,1 +5.2,4.1,1.5,0.1,1 +5.5,4.2,1.4,0.2,1 +4.9,3.1,1.5,0.1,1 +5,3.2,1.2,0.2,1 +5.5,3.5,1.3,0.2,1 +4.9,3.1,1.5,0.1,1 +4.4,3,1.3,0.2,1 +5.1,3.4,1.5,0.2,1 +5,3.5,1.3,0.3,1 +4.5,2.3,1.3,0.3,1 +4.4,3.2,1.3,0.2,1 +5,3.5,1.6,0.6,1 +5.1,3.8,1.9,0.4,1 +4.8,3,1.4,0.3,1 +5.1,3.8,1.6,0.2,1 +4.6,3.2,1.4,0.2,1 +5.3,3.7,1.5,0.2,1 +5,3.3,1.4,0.2,1 +7,3.2,4.7,1.4,1 +6.4,3.2,4.5,1.5,1 +6.9,3.1,4.9,1.5,1 +5.5,2.3,4,1.3,1 +6.5,2.8,4.6,1.5,1 +5.7,2.8,4.5,1.3,1 +6.3,3.3,4.7,1.6,1 +4.9,2.4,3.3,1,1 +6.6,2.9,4.6,1.3,1 +5.2,2.7,3.9,1.4,1 +5,2,3.5,1,1 +5.9,3,4.2,1.5,1 +6,2.2,4,1,1 +6.1,2.9,4.7,1.4,1 +5.6,2.9,3.6,1.3,1 +6.7,3.1,4.4,1.4,1 +5.6,3,4.5,1.5,1 +5.8,2.7,4.1,1,1 +6.2,2.2,4.5,1.5,1 +5.6,2.5,3.9,1.1,1 +5.9,3.2,4.8,1.8,1 +6.1,2.8,4,1.3,1 +6.3,2.5,4.9,1.5,1 +6.1,2.8,4.7,1.2,1 +6.4,2.9,4.3,1.3,1 +6.6,3,4.4,1.4,1 +6.8,2.8,4.8,1.4,1 +6.7,3,5,1.7,1 +6,2.9,4.5,1.5,1 +5.7,2.6,3.5,1,1 +5.5,2.4,3.8,1.1,1 +5.5,2.4,3.7,1,1 +5.8,2.7,3.9,1.2,1 +6,2.7,5.1,1.6,1 +5.4,3,4.5,1.5,1 +6,3.4,4.5,1.6,1 +6.7,3.1,4.7,1.5,1 +6.3,2.3,4.4,1.3,1 +5.6,3,4.1,1.3,1 +5.5,2.5,4,1.3,1 +5.5,2.6,4.4,1.2,1 +6.1,3,4.6,1.4,1 +5.8,2.6,4,1.2,1 +5,2.3,3.3,1,1 +5.6,2.7,4.2,1.3,1 +5.7,3,4.2,1.2,1 +5.7,2.9,4.2,1.3,1 +6.2,2.9,4.3,1.3,1 +5.1,2.5,3,1.1,1 +5.7,2.8,4.1,1.3,1 +6.3,3.3,6,2.5,-1 +5.8,2.7,5.1,1.9,-1 +7.1,3,5.9,2.1,-1 +6.3,2.9,5.6,1.8,-1 +6.5,3,5.8,2.2,-1 +7.6,3,6.6,2.1,-1 +4.9,2.5,4.5,1.7,-1 +7.3,2.9,6.3,1.8,-1 +6.7,2.5,5.8,1.8,-1 +7.2,3.6,6.1,2.5,-1 +6.5,3.2,5.1,2,-1 +6.4,2.7,5.3,1.9,-1 +6.8,3,5.5,2.1,-1 +5.7,2.5,5,2,-1 +5.8,2.8,5.1,2.4,-1 +6.4,3.2,5.3,2.3,-1 +6.5,3,5.5,1.8,-1 +7.7,3.8,6.7,2.2,-1 +7.7,2.6,6.9,2.3,-1 +6,2.2,5,1.5,-1 +6.9,3.2,5.7,2.3,-1 +5.6,2.8,4.9,2,-1 +7.7,2.8,6.7,2,-1 +6.3,2.7,4.9,1.8,-1 +6.7,3.3,5.7,2.1,-1 +7.2,3.2,6,1.8,-1 +6.2,2.8,4.8,1.8,-1 +6.1,3,4.9,1.8,-1 +6.4,2.8,5.6,2.1,-1 +7.2,3,5.8,1.6,-1 +7.4,2.8,6.1,1.9,-1 +7.9,3.8,6.4,2,-1 +6.4,2.8,5.6,2.2,-1 +6.3,2.8,5.1,1.5,-1 +6.1,2.6,5.6,1.4,-1 +7.7,3,6.1,2.3,-1 +6.3,3.4,5.6,2.4,-1 +6.4,3.1,5.5,1.8,-1 +6,3,4.8,1.8,-1 +6.9,3.1,5.4,2.1,-1 +6.7,3.1,5.6,2.4,-1 +6.9,3.1,5.1,2.3,-1 +5.8,2.7,5.1,1.9,-1 +6.8,3.2,5.9,2.3,-1 +6.7,3.3,5.7,2.5,-1 +6.7,3,5.2,2.3,-1 +6.3,2.5,5,1.9,-1 +6.5,3,5.2,2,-1 +6.2,3.4,5.4,2.3,-1 +5.9,3,5.1,1.8,-1 diff --git a/SVM/SVM_by_SMO/testSVM-SMO.py b/SVM/SVM_by_SMO/testSVM-SMO.py new file mode 100755 index 0000000..2fe1929 --- /dev/null +++ b/SVM/SVM_by_SMO/testSVM-SMO.py @@ -0,0 +1,67 @@ +from __future__ import division, print_function +import csv, os, sys +import numpy as np +from SVCSMO import SVCSMO +filepath = os.path.dirname(os.path.abspath(__file__)) + +def readData(filename, header=True): + data, header = [], None + with open(filename, 'rb') as csvfile: + spamreader = csv.reader(csvfile, delimiter=',') + if header: + header = spamreader.next() + for row in spamreader: + data.append(row) + return (np.array(data), np.array(header)) + +def calc_acc(y, y_hat): + idx = np.where(y_hat == 1) + TP = np.sum(y_hat[idx] == y[idx]) + idx = np.where(y_hat == -1) + TN = np.sum(y_hat[idx] == y[idx]) + return float(TP + TN)/len(y) + +def calc_mse(y, y_hat): + return np.nanmean(((y - y_hat) ** 2)) + +def test_main(filename='data/iris-virginica.txt', C=1.0, kernel_type='linear', epsilon=0.001): + # Load data + (data, _) = readData('%s/%s' % (filepath, filename), header=False) + data = data.astype(float) + + # Split data + X, y = data[:,0:-1], data[:,-1].astype(int) + + # Initialize model + model = SVCSMO() + + # Fit model + support_vectors, iterations = model.fit(X, y) + + # Support vector count + sv_count = support_vectors.shape[0] + + # Make prediction + y_hat = model.predict(X) + + # Calculate accuracy + acc = calc_acc(y, y_hat) + mse = calc_mse(y, y_hat) + + print("Support vector count: %d" % (sv_count)) + print("bias:\t\t%.3f" % (model.b)) + print("w:\t\t" + str(model.w)) + print("accuracy:\t%.3f" % (acc)) + print("mse:\t%.3f" % (mse)) + print("Converged after %d iterations" % (iterations)) + +if __name__ == '__main__': + param = {} + param['filename'] = './small_data/iris-slwc.txt' + param['C'] = 0.1 + param['kernel_type'] = 'linear' + param['epsilon'] = 0.001 + + + test_main(**param) +