前言
总的来说,机器学习的问题可以分为两大类:分类和回归,不管是分类还是回归,其本质是一样的,都是对输入做出预测,并且都是监督学习。说白了,就是根据特征,分析输入的内容,判断它的类别,或者预测其值。在分类问题上,这几年已经有很多文献比较了常见的机器学习方法,比如:
Do we Need Hundreds of Classiers to Solve Real World Classification Problems?
Comparison of 14 different families of classication algorithms on 115 binary datasets
而在回归问题上,哪些方法的性能表现通常比较好呢?
一、预备工作
常见的机器学习算法
- 回归算法:回归算法是试图采用对误差的衡量来探索因变量(目标)和自变量(预测器)之间的关系的一类算法。回归算法是统计机器学习的利器,通常用于预测分析。例如,司机的鲁莽驾驶与道路交通事故数量之间的关系,最好的研究方法就是回归。 常见的回归算法包括:线性回归(Linear Regression)(又称最小二乘法问题),逻辑回归(Logistic Regression),岭回归(Ridge Regression)。
- 聚类算法:聚类,就像回归一样,有时候是描述一类问题,有时候是一类算法。聚类算法通常按照中心点或者分层的方式对输入数据进行归并。所以的聚类算法都试图找到数据的内在结构,以便按照最大的共同点将数据进行归类。常见的聚类算法包括 K-Means算法以及期望最大化算法(Expectation Maximization,EM)。
- 基于实例的算法:基于实例的算法常常用来对决策问题建立模型,这样的模型常常先选取一批样本数据,然后根据某些近似性把新数据与样本数据进行比较。通过这种方式来寻找最佳的匹配。因此,基于实例的算法常常也被称为“赢家通吃”学习或者“基于记忆的学习”。常见的算法包括 k-Nearest Neighbor(KNN)。
- 决策树学习:决策树算法根据数据的属性采用树状结构建立决策模型, 决策树模型常常用来解决分类和回归问题。常见的算法包括:分类及回归树(Classification And Regression Tree,CART),ID3 (Iterative Dichotomiser 3), 随机森林(Random Forest)etc。
- 贝叶斯方法:贝叶斯方法算法是基于贝叶斯定理的一类算法,主要用来解决分类和回归问题。常见算法有朴素贝叶斯算法。
- 基于核的算法:基于核的算法中最著名的莫过于支持向量机(SVM)了。基于核的算法把输入数据映射到一个高阶的向量空间,在这些高阶向量空间里,有些分类或者回归问题能够更容易的解决。常见的基于核的算法包括:支持向量机(Support Vector Machine,SVM), 径向基函数(Radial Basis Function,RBF),以及线性判别分析(Linear Discriminate Analysis,LDA)等。
- 人工神经网络:人工神经网络算法模拟生物神经网络,是一类模式匹配算法。通常用于解决分类和回归问题。人工神经网络是机器学习的一个庞大的分支,有几百种不同的算法。(其中深度学习就是其中的一类算法),重要的人工神经网络算法包括:感知器神经网络(Perceptron Neural Network), 反向传递(Back Propagation),Hopfield网络,自组织映射(Self-Organizing Map, SOM)。学习矢量量化(Learning Vector Quantization, LVQ)。
二、回归算法
1.线性回归
线性回归仅适用于对线性可分离的数据建模,通过不同的系数权重 a i a_i ai 来标注不同特征变量 X i X_i Xi 的权重,在因变量(Y)和一个或多个自变量(X)之间建立线性方程:
Y
=
a
1
∗
X
1
+
a
2
∗
X
2
+
.
.
.
.
.
.
a
n
∗
X
n
+
b
Y = a_1 *X_1+ a_2 * X_2 +......a_n*X_n+b
Y=a1∗X1+a2∗X2+......an∗Xn+b
其中
a
n
a_n
an是系数,
X
n
X_n
Xn是变量,b是偏差。
接下来通过分析只有一个特征变量的简单线性回归来抛砖引玉:
2.简单线性回归
对于只有一个特征
x
x
x 和一个标记
y
y
y 的简单线性回归,有线性方程:
y
=
a
x
+
b
y=ax+b
y=ax+b
则对于每个样本点
x
i
x_i
xi,预测值如下。其中
y
^
\hat{y}
y^ 表示预测值,读作
y
y
y head ,右上角的i表示样本索引。
y
^
(
i
)
=
a
x
(
i
)
+
b
\hat{y}^{(i)} = ax^{(i)} + b
y^(i)=ax(i)+b
我们希望预测值和真实值之间的差距尽量小。一般用欧氏距离来衡量。下式称为损失函数(Loss Function):
∑
i
=
1
m
(
y
(
i
)
−
y
^
(
i
)
)
2
\sum_{i=1}^{m} (y^{(i)} - \hat{y}^{(i)}) ^2
i=1∑m(y(i)−y^(i))2
通过分析不同的问题,我们需要确定问题的损失函数。而通过最优化损失函数,获得机器学习的模型参数几乎是所有的参数学习算法的套路。那么这个问题是一个典型的最小二乘法问题,即最小化误差的平方。推导可得以下公式:
a
=
∑
i
=
1
m
(
x
(
i
)
−
x
ˉ
)
(
y
(
i
)
−
y
ˉ
)
∑
i
=
1
m
(
x
(
i
)
−
x
ˉ
)
2
,
b
=
y
ˉ
−
a
x
ˉ
a = \frac{\sum_{i=1}^{m}(x^{(i)}-\bar{x})(y^{(i)} - \bar{y})}{\sum_{i=1}^{m}(x^{(i)}-\bar{x})^2}, b=\bar{y}-a\bar{x}
a=∑i=1m(x(i)−xˉ)2∑i=1m(x(i)−xˉ)(y(i)−yˉ),b=yˉ−axˉ
衡量线性回归模型好坏有多个标准,均方误差(Mean Squared Error)、均方根误差(Root Mean Squared Error)、平均绝对误差(Mean Absolute Error)等。一般使用MSE,即均方误差。
M
S
E
=
1
m
∑
i
=
1
m
(
y
t
e
s
t
(
i
)
−
y
^
t
e
s
t
(
i
)
)
2
MSE = \frac{1}{m} \sum_{i=1}^{m}(y^{(i)}_{test}-\hat{y}^{(i)}_{test})^2
MSE=m1i=1∑m(ytest(i)−y^test(i))2
均方根误差:
R
M
S
E
=
M
S
E
RMSE = \sqrt{MSE}
RMSE=MSE
平均绝对误差:
M
A
E
=
1
m
∑
i
=
1
m
∣
y
t
e
s
t
(
i
)
−
y
^
t
e
s
t
(
i
)
∣
MAE = \frac{1}{m}\sum_{i=1}^{m}|y^{(i)}_{test}-\hat{y}^{(i)}_{test}|
MAE=m1i=1∑m∣ytest(i)−y^test(i)∣
代码如下:
# -*- coding:utf-8 -*-
"""
@author:starlee
@time:2021/9/13 17:58
"""
import numpy as np
class SimpleLinearRegression:
def __init__(self):
"""初始化Simple Linear Regression 模型"""
self.a_ = None
self.b_ = None
def fit(self, x_train, y_train):
"""根据训练数据集x_train,y_train训练Simple Linear Regression 模型"""
assert x_train.nidm == 1, \
"Simple Linear Regressor can only solve single feature training data."
assert len(x_train) == len(y_train), \
"the size of x_train must be equal to the size of y_train"
x_mean = np.mean(x_train)
y_mean = np.mean(y_train)
"""进行向量化可以加快训练速度"""
"""dot函数用于矩阵乘法"""
num = (x_train - x_mean).dot(y_train - y_mean)
d = (x_train - x_mean).dot(x_train - x_mean)
self.a_ = num/d
self.b_ = y_mean - self.a_ * x_mean
return self
def predict(self, x_predict):
"""给定待预测数据集x_predict, 返回表示x_predict的结果向量"""
assert x_predict.ndim == 1, \
"Simeple Linear Regressor can only solve single feature training data."
assert self.a_ is not None and self.b_ is not None, \
"must fit before predict!"
return np.array([self._predict(x) for x in x_predict])
def _predict(self, x_single):
"""给定单个待预测数据x_single, 返回x_single的预测结果值"""
return self.a_ * x_single + self.b_
def __repr__(self):
return "SimpleLinearRegression()"