一、线性回归核心思想和原理
1、一元回归
用一个一元线性函数(y = kx+b)去拟合训练数据,从而达到预测同等分布规律的预测数据的目的;
一元线性回归用公式来表达就是:
2、多元线性回归
用一个多元函数(y = w0+w1 * x1+w2 * x2+…+wn*xn)拟合现有数据,从而对同样分布规律的数据进行预测。
3、多项式回归
用一个多项式函数(y = ax^2+bx+c)拟合现有数据,从而对同样分布规律的数据进行预测。
我们不直接对多项式函数求解参数,而是将多项式函数通过换元的方式变成多元线性回归问题
二、逻辑回归核心思想和原理
逻辑回归实际上是做的分类问题,只能进行二分类(多分类问题可以变换成二分类问题)。逻辑回归是在特征空间中找到一条曲线将数据划分成不同的类别。
用sigmoid函数将数据分布在0-1之间
s
i
g
m
o
i
d
(
t
)
=
1
1
+
e
−
t
sigmoid(t) = \frac{1}{1+e^{-t}}
sigmoid(t)=1+e−t1
整个过程用公式表达就是
原本的回归函数为
f
(
x
)
=
W
T
X
逻辑回归需要利用
s
i
g
m
o
i
d
函数将所有数据分布在
0
−
1
之间
ρ
=
s
i
g
m
o
i
d
(
W
T
X
)
=
1
1
+
e
−
t
y
^
=
{
1
,
ρ
≥
0.5
0
,
ρ
<
0.5
损失函数:
−
y
l
o
g
(
ρ
)
−
(
1
−
y
)
l
o
g
(
1
−
ρ
)
原本的回归函数为f(x)=W^TX\\ 逻辑回归需要利用sigmoid函数将所有数据分布在0-1之间\\ \rho=sigmoid(W^TX)=\frac{1}{1+e^{-t}}\\ \hat{y}= \begin{cases} 1,\quad &\rho\geq 0.5 \\ 0,\quad &\rho<0.5 \end{cases} \\ 损失函数:-ylog(\rho)-(1-y)log(1-\rho)
原本的回归函数为f(x)=WTX逻辑回归需要利用sigmoid函数将所有数据分布在0−1之间ρ=sigmoid(WTX)=1+e−t1y^={1,0,ρ≥0.5ρ<0.5损失函数:−ylog(ρ)−(1−y)log(1−ρ)
训练过程:将逻辑回归函数的预测值放入sigmoid函数中,然后得到一个0-1之间的概率值,然后计算和真值的损失,因为该损失函数下,并不存在一个显性解,所以逻辑回归利用梯度下降算法得到最优参数
预测过程:首先利用sigmoid函数将逻辑回归函数的预测值转到0-1之间,然后根据分类阈值判定该预测值属于哪一个类别
多项式逻辑回归,同样进行换元,转换成多元线性逻辑回归即可
三、线性回归模型评价指标
MSE((mean square error)、RMSE(root square error)、MAE(mean absolute error)、R^2(Coefficient of determination)
M
S
E
=
1
n
∑
i
=
i
n
(
y
i
−
f
(
x
i
)
)
2
R
M
S
E
=
1
n
∑
i
=
i
n
(
y
i
−
f
(
x
i
)
)
2
M
A
E
=
1
n
∣
y
i
−
f
(
x
i
)
∣
R
2
=
1
−
∑
i
=
1
n
(
y
i
−
f
(
x
i
)
)
2
∑
i
=
1
n
(
y
i
−
y
‾
)
2
MSE=\frac{1}{n}\sum_{i=i}^{n} (y_i-f(x_i))^2\\ RMSE = \sqrt{\frac{1}{n}\sum_{i=i}^{n} (y_i-f(x_i))^2}\\ MAE=\frac{1}{n}|y_i-f(x_i)|\\ R^2=1-\frac{\sum_{i=1}^{n}(y_i-f(x_i))^2}{\sum_{i=1}^{n}(y_i-\overline{y})^2}
MSE=n1i=i∑n(yi−f(xi))2RMSE=n1i=i∑n(yi−f(xi))2MAE=n1∣yi−f(xi)∣R2=1−∑i=1n(yi−y)2∑i=1n(yi−f(xi))2
R-squared含义
R-squared为1,表明模型所有的预测都和真值相同,理想情况
R-squared为0,一种情况是模型预测的结果都为平均值,
R-squared为负数,表面模型效果很差
R-squared的取值范围为负无穷到1
四、一元线性回归、多元线性回归、多项式回归代码实现
1、一元线性回归和多元线性回归的实现以及模型评价,针对Boston房价数据集
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 加载波士顿房屋数据集
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]
data.shape,target.shape
# 实现一元回归,自己来实现
X = data[:,5]
y = target
X = X[y<50]
y = y[y<50]
plt.scatter(X,y,c='b')
# 划分数据集
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,train_size=0.7,shuffle=True)
X_train.shape,y_test.shape
# 求解一元线性函数的参数的函数,利用最小二乘法
def get_param_monotone(X,y):
X_mean = np.mean(X)
y_mean = np.mean(y)
a = (np.sum((X-X_mean)*(y-y_mean)))/np.sum((X-X_mean)**2)
b = y_mean-a*X_mean
return a,b
a,b = get_param_monotone(X_train,y_train)
#在训练集上画出来看一下
plt.subplot(221)
plt.scatter(X_train,y_train,c='b')
plt.plot(X_train,a*X_train+b,color='r')
plt.title('train_data')
# 在测试集上进行测试看看,并试试评价指标
plt.subplot(222)
plt.scatter(X_test,y_test,c='b')
plt.plot(X_test,a*X_test+b,color='r')
plt.title('test_data')
plt.show()
# 用sklearn实现一元线性回归
from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(X_train.reshape(-1,1),y_train)
y_predict = lin_reg.predict(X_test.reshape(-1,1))
mse = (np.sum((y_predict-y_test)**2))/len(X_test)
lin_reg.score(X_test.reshape(-1,1),y_test)
# 调用sklearn实现多元回归
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error as mae
from sklearn.metrics import r2_score
X = data
y = target
X_train,X_test,y_train,y_test = train_test_split(X,y,train_size=0.7,random_state=233)
lin_reg = LinearRegression()
lin_reg.fit(X_train,y_train)
y_predict_multi = lin_reg.predict(X_test)
mae(y_test,y_predict_multi)
r2_score(y_test,y_predict_multi)
2、多项式回归
import numpy as np
import matplotlib.pyplot as plt
# 创建一个多项式数据
np.random.seed(233)
np.random.randn?
X = np.random.randn(100)
y = np.array(2*X**2+3*X+4)+np.random.randn(100)
# 画图看看数据分布
plt.scatter(X,y)
# 利用sklearn实现多项式回归
from sklearn.preprocessing import PolynomialFeatures
from sklearn.model_selection import train_test_split
# 划分数据集,并进行特征升维
X_train,X_test,y_train,y_test = train_test_split(X,y,train_size=0.7,shuffle=True)
poly = PolynomialFeatures(degree=2)
X_train_poly = poly.fit_transform(X_train.reshape(-1,1))
X_test_poly = poly.fit_transform(X_test.reshape(-1,1))
len(X_train_poly),len(X_test_poly)
from sklearn.linear_model import LinearRegression
lig = LinearRegression()
lig.fit(X_train_poly,y_train)
y_predict = lig.predict(X_test_poly)
lig.score(X_test_poly,y_test)
# 在测试集上看一下效果
plt.scatter(X_test,y_test)
plt.plot(np.sort(X_test),y_predict[np.argsort(X_test)],color='r')
plt.show()
PS:PolynomialFeatures(degree=2),这里面参数degree应该根据特征分布特性来定,所以在选取该参数前最好可视化一下数据,来估计degree
五、逻辑回归、多项式逻辑回归代码实现
1、线性逻辑回归
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification
X,y = make_classification(
n_classes=2,
n_features=2,
n_samples=2000,
n_redundant=0
)
X,y
# 划分数据集
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,shuffle=True)
plt.subplot(121)
plt.scatter(X_train[:,0],X_train[:,1],c=y_train)
plt.subplot(122)
plt.scatter(X_test[:,0],X_test[:,1],c=y_test)
# 使用逻辑回归拟合数据
from sklearn.linear_model import LogisticRegression
lgg = LogisticRegression()
lgg.fit(X_train,y_train)
lgg.predict(X_test)
lgg.score(X_test,y_test)
# 对数据进行归一化后,对模型正确性的影响
from sklearn.preprocessing import StandardScaler
std = StandardScaler()
std.fit(X_train)
X_train_std = std.transform(X_train)
X_test_std = std.transform(X_test)
lgg_2 = LogisticRegression()
lgg_2.fit(X_train_std,y_train)
lgg_2.score(X_test_std,y_test)
2、多项式逻辑回归
import numpy as np
import matplotlib.pyplot as plt
# 制作数据及划分
from sklearn.model_selection import train_test_split
X = np.random.normal(0,1,size=(500,2)) # 正态分布
y = np.array([np.sum(x**2)<2 for x in X],dtype='int')
plt.scatter(X[:,0],X[:,1],c=y)
X_train,X_test,y_train,y_test = train_test_split(X,y,train_size=0.8,shuffle=True)
# 实现多项式逻辑回归
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree=2)
poly.fit(X_train)
X_train_poly = poly.transform(X_train)
X_test_poly = poly.transform(X_test)
from sklearn.linear_model import LogisticRegression
lgg = LogisticRegression()
lgg.fit(X_train_poly,y_train)
y_predict=lgg.predict(X_test_poly)
lgg.score(X_test_poly,y_test)
# 在测试集上画图看一下结果
plt.subplot(121)
plt.scatter(X_test[:,0],X_test[:,1],c=y_test)
plt.subplot(122)
plt.scatter(X_test[:,0],X_test[:,1],c=y_predict)
plt.show()
六、多分类策略
1、OneVsOne
将多分类问题拆分为多个二分类问题
N
分类问题拆分为
C
(
n
k
)
个二分类问题
N分类问题拆分为C\binom{n}{k}个二分类问题
N分类问题拆分为C(kn)个二分类问题
然后对每个分类结果都进行投票,出现次数最多的类别则为最终模型预测的结果。
在模型训练阶段,需要分别训练N*(N-1)/2个二分类器,对于每个二分类器只使用该对应类别的数据,直到训练完所有的二分类器;
在模型测试阶段,对于一个新数据,该新数据输入到每个二分类器中,然后该数据只会被该分类器判定为正类和负类,类别数最多的类别则作为模型的最终的判定结果。
2、OneVsRest
将多分类问题看成是一个类别+其他类别的二分类问题,N分类问题拆分成N个二分类问题,最终概率最大的类别则为模型的预测结果。
在模型的训练过程中,模型将数据划分为一个正类的数据和其他所有类别组成的负类数据集,然后进行训练,这样训练N个二分类器;
在模型的测试阶段,对于一个新数据,N个训练好的二分类器同该数据进行判断,最终取分类概率最大的那个类别作为模型的预测结果。
3、代码
import numpy as np
from sklearn.datasets import load_iris
iris = load_iris()
from sklearn.model_selection import train_test_split
data = iris.data
target = iris.target
X_train,X_test,y_train,y_test = train_test_split(data,target,test_size=0.7,shuffle=True)
# 利用OneVsOne进行分类
from sklearn.multiclass import OneVsOneClassifier
from sklearn.linear_model import LogisticRegression
lgg = LogisticRegression()
ovo = OneVsOneClassifier(lgg)
ovo.fit(X_train,y_train)
ovo.score(X_test,y_test)
# 利用OneVsRest进行多分类
from sklearn.multiclass import OneVsRestClassifier
ovr = OneVsRestClassifier(lgg)
ovr.fit(X_train,y_train)
ovr.score(X_test,y_test)
结果:OneVsOne分类精度更高,但是需要训练的分类器数量更多,计算量更大。
七、线性算法优缺点及使用条件
线性算法的可解释性很好,参数有其数学含义,但是线性算法作了一个假设,就是数据的分布要符合线性规律。
适用于具有线性分布的特点,或者通过特征工程能够将转换为线性分布的数据。