1、什么是一元线性回归

线性:两个变量之间的关系是一次函数,也是数据与数据之间的关系。
回归:人们在测试事物的时候因为客观条件所限,求的都是测试值,而不是真实值,为了无限接近真实值,无限次的进行测量,最后通过这些测量数据计算回归到真实值,这就是回归的由来。
KNN最近邻值是:KNN横纵轴坐标为两个特征,比如身高体重与某种疾病关系。
一元线性回归:只有横轴是特征,纵轴是输出值,比如股价与时间的关系。
通俗的说就是用一个函数去逼近这个真实值

在这里插入图片描述

1.2、线性回归解决什么问题

通过大量样本数据进行处理,可以得出一个 比较符合事物内部规律的y=kx+b,从而对结果进行预测,解决的就是通过已知样本数据,预测未知数据,比如房价进行预测,电影票房预测。

计算k和b的计算公式:

在这里插入图片描述

损失函数(loss function),衡量了误差大小,不断地去优化,找出最优解,平方残差和是最常用的一种方式

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.3、实现一元线性回归

在这里插入图片描述

# 使用boston数据集 
import numpy as np
import matplotlib.pyplot as plt
import sklearn
from sklearn.model_selection import train_test_split
import pandas as pd 

# 加载波士顿房屋数据集
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]

from sklearn.model_selection import train_test_split
# 拆分数据集
x_train,x_test,y_train,y_test = train_test_split(data,target,train_size=0.7,random_state=233)

x_train[:,5].shape,y_train.shape
plt.scatter(x_train[:,5],y_train)

def fit(x,y):
    a_up = np.sum((x-np.mean(x))*(y-np.mean(y)))
    a_bottom = np.sum((x-np.mean(x))**2)
    a = a_up/a_bottom
    b = np.mean(y) - a *np.mean(x)
    return a,b

a,b = fit(x_train[:,5],y_train)
a,b

plt.scatter(x_train[:,5],y_train)
plt.plot(x_train[:,5],a*x_train[:,5]+b,c='r')
plt.show()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.

1.4、使用sklearn实现一元线性回归

from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(x_train[:,5].reshape(-1,1),y_train)
y_predict = lr.predict(x_test[:,5].reshape(-1,1))

plt.scatter(x_test[:,5],y_test)
plt.plot(x_test[:,5],y_predict,c='r')
plt.show()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

2、多元线性回归

参考链接

线性回归是评估自变量x和应变量y之间的一种线性关系,当只有一个自变量称为一元线性回归,多个自变量称为多元线性回归,现实生活中数据都是比较复杂的,比如影响房价的因素往往不止一个,可能还有附近地铁,房间数,层数,建筑年代等诸多因素。不过每个因素对房价影响权重不同,因此我们可以用多个权重来表示多个因素与房屋价格的关系

x:影响因素,即特征。
w:每个x的影响力度。
n:特征的个数。
y^:房屋的预测价格。

在这里插入图片描述

在这里插入图片描述

这样,就可以表示为:

在这里插入图片描述

多元线性回归在空间中,可以表示为一个超平面,去拟合空间中的数据点。
我们的目的就是从现有的数据中,去学习w与b的值。一旦w与b的值确定,就能够确定拟合数据的线性方程,这样就可以对未知的数据x进行预测y(房价)

损失函数:
对于机器学习来讲,就是从已知数据去建立一个模型,使得该模型能够对未知数据进行预测。实际上,机器学习的过程就是确定模型参数的过程。
对于监督学习来说,我们可以通过建立损失函数来实现模型参数的求解,损失函数也称目标函数或代价函数,简单来说就是关于误差的一个函数。损失函数用来衡量模型预测值与真实值之间的差异。机器学习的目标,就是要建立一个损失函数,使得该函数的值最小。
也就是说,损失函数是一个关于模型参数的函数(以模型参数w作为自变量的函数),自变量可能的取值组合通常是无限的,我们的目标,就是要在众多可能的组合中,找到一组最合适的自变量组合,使得损失函数的值最小。
在线性回归中,我们使用平方损失函数(最小二乘法),定义如下:

在这里插入图片描述

2.2、使用sklearn实现多元线性回归

多元线性回归没办法通过画图看出效果,但是可以通过score来获取模型的评分。
注意:多元线性回归是不需要归一化的,学习的是各自维度特征

# 使用boston数据集 
import numpy as np
import matplotlib.pyplot as plt
import sklearn
from sklearn.model_selection import train_test_split
import pandas as pd 

# 加载波士顿房屋数据集
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]

x_train,x_test,y_train,y_test = train_test_split(data,target,test_size=0.3,random_state=233)
lr = LinearRegression()
lr.fit(x_train,y_train)
lr.score(x_test,y_test)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

2.3、MSE

MSE(Mean Squared Error),平均平方差,为所有样本数据误差(真实值与预测值之差)的平方和,然后取均值。越接近0越好,mse越小容易出现过拟合,反之容易欠拟合。

在这里插入图片描述

手动实现

mse = np.sum(((y_test-y_predict)**2)/len(y_test))
mse
  • 1.
  • 2.

使用skleran实现

# 使用sklearn实现
from sklearn.metrics import mean_squared_error
mean_squared_error(y_test,y_predict)
  • 1.
  • 2.
  • 3.

2.4、RMSE

RMSE(Root Mean Squared Error),平均平方误差的平方根,即在MSE的基础上,取平方根。放大了较大误差之间的差距

在这里插入图片描述

#RMSE,先对数据进行了平方然后累加在开方,放大了较大误差之间的差距
rmse = np.sqrt(mse)

# 使用skleran实现
from sklearn.metrics import mean_squared_error
mean_squared_error(y_test,y_predict,squared=False)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

2.5、MAE

MAE(Mean Absolute Error),平均绝对值误差,为所有样本数据误差的绝对值和,然后去均值。真实误差

在这里插入图片描述

# MAE 真是误差
mae = np.sum((np.abs(y_test-y_predict))/len(y_test))

# 使用skleran实现
from sklearn.metrics import mean_absolute_error
mean_absolute_error(y_test,y_predict)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

2.6、R^2

R2为决定系数,用来表示模型拟合性的分值,值越高表示模型拟合性越好,在训练集中,R2的取值范围为[0,1]。在R2的取值范围为[-∞,1]。从公式定义可知,最理想情况,所有的样本数据的预测值与真实值相同,即RSS为0,此时R2为1。

在这里插入图片描述


在这里插入图片描述

r2 = 1 - (np.sum((y_test-y_predict)**2))/(np.sum((y_test-np.mean(y_test))**2))
r2
  • 1.
  • 2.

公式二:消除样本本身取值大小的影响,实现了归一化

在这里插入图片描述

1-mse/np.var(y_test)

# skleran实现
from sklearn.metrics import r2_score
r2_score(y_test,y_predict)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

2.7、模型评价方法总结

总结:MSE计算简单,RMSE和MAE保持了和样本同样的量纲,MSE和MAE适用误差相对明显的时候,大的误差就会有比较大的权重,RMSE针对误差不是很明显的时候,MAE相比MSE更能凸显异常值,在回归模型中损失函数一般使用MAE、MSE、RMSE,性能评估指标一般使用R^2。

3、多项式回归代码实现

对于非线性回归的数据,我们可以使用多项式回归拟合一条曲线。

在这里插入图片描述


在这里插入图片描述

可以明显看到使用直线拟合非线性数据,效果非常不好。

# 多项式回归
x = np.random.uniform(-4,2,size=(100))
y = 2*x**2 + 4*x+3+np.random.randn(100)
X = x.reshape(-1,1)
plt.scatter(x,y)
plt.show()

lr = LinearRegression()
lr.fit(X,y)
y_predict = lr.predict(X)
plt.scatter(x,y)
plt.plot(np.sort(x),y_predict[np.argsort(x)],color='red')
plt.show()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

使用多项式回归拟合

在这里插入图片描述

X_new = np.hstack([X,X**2])
lr = LinearRegression()
lr.fit(X_new,y)
y_predict = lr.predict(X_new)
plt.scatter(x,y)
plt.plot(np.sort(x),y_predict[np.argsort(x)],color='red')
plt.show()+# 输出函数截取
lr.intercept_
# 输出函数特征值
lr.coef_
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

使用sklearn实现

# 使用sklearn实现
from sklearn.preprocessing import PolynomialFeatures
# 最高2次幂
polynomial = PolynomialFeatures(degree=2)
# 转换后的特征
x_poly = polynomial.fit_transform(X)
lr = LinearRegression()
lr.fit(x_poly,y)
y_predict = lr.predict(x_poly)
plt.scatter(x,y)
plt.plot(np.sort(x),y_predict[np.argsort(x)],color='red')
plt.show()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

4、逻辑回归解决分类问题

在这里插入图片描述

误差距离计算方式:

在这里插入图片描述


在这里插入图片描述

在这里插入图片描述

4.2、使用sklearn实现逻辑回归

# 逻辑回归
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_samples=200,# 样本数
    n_features=2,# 特征数
    n_redundant=0,# 冗余特指数
    n_classes=2,# 类型
    n_clusters_per_class=1,# 族设为1
    random_state=1024
)
x.shape,y.shape

x_train,x_test,y_train,y_test = train_test_split(x,y,train_size=0.7,random_state=1024,stratify=y)
plt.scatter(x_train[:,0],x_train[:,1],c=y_train)

from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
clf.fit(x_train,y_train)
clf.score(x_test,y_test)
clf.predict(x_test)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.

4.3、超参数使用

# 超参数
from sklearn.model_selection import GridSearchCV
params = [{
    'penalty':['l2','l1'],# 损失函数正则项
    'C':[0.0001,0.001,0.01,0.1,1,10,100,1000],
    'solver':['liblinear']# 优化算法
},{
    'penalty':['none'],
    'C':[0.0001,0.001,0.01,0.1,1,10,100,1000],
    'solver':['lbfgs']
},{
    'penalty':['elasticnet'],
    'C':[0.0001,0.001,0.01,0.1,1,10,100,1000],
    'l1_ratio':[0,0.25,0.5,0.75,1],
    'solver':['saga'],
    'max_iter':[200]
}]
grid = GridSearchCV(
    estimator=LogisticRegression(),
    param_grid=params,
    n_jobs=-1
)

grid.fit(x,y)
grid.best_score_

grid.best_estimator_.score(x_test,y_test)
grid.best_params_
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.

4.4、多项式逻辑回归

在这里插入图片描述

# 多项式逻辑回归
np.random.seed(0)
X = np.random.normal(0,1,size=(200,2))
y = np.array((X[:,0]**2)+(X[:,1]**2)<2,dtype='int')
x_train,x_test,y_train,y_test = train_test_split(X,y,train_size=0.7,random_state=1024,stratify=y)
plt.scatter(x_train[:,0],x_train[:,1],c=y_train)

from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree=2)
poly.fit(x_train)

x2 = poly.transform(x_train)
x2t = poly.transform(x_test)
clf = LogisticRegression()
clf.fit(x2,y_train)
clf.score(x2,y_train)
clf.score(x2t,y_test)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

4.5、多分类问题OVR

在这里插入图片描述

在这里插入图片描述

# 多分类问题,OVO和OVR
from sklearn import datasets
iris = datasets.load_iris()
x = iris.data
y = iris.target
x_train,x_test,y_train,y_test = train_test_split(x,y,random_state=666)

plt.scatter(x_train[:,0],x_train[:,1],c=y_train)
plt.show()

from sklearn.multiclass import OneVsRestClassifier
ovr = OneVsRestClassifier(clf)
ovr.fit(x_train,y_train)
ovr.score(x_test,y_test)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

4.6、多分类问题OVO

在这里插入图片描述


在这里插入图片描述

# 多分类问题,OVO和OVR
from sklearn import datasets
iris = datasets.load_iris()
x = iris.data
y = iris.target
x_train,x_test,y_train,y_test = train_test_split(x,y,random_state=666)

plt.scatter(x_train[:,0],x_train[:,1],c=y_train)
plt.show()

from sklearn.multiclass import OneVsOneClassifier
ovo = OneVsOneClassifier(clf)
ovo.fit(x_train,y_train)
ovo.score(x_test,y_test)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

在这里插入图片描述

5、优缺点对比

在这里插入图片描述

KNN对比线性算法:
KNN算法:非参数模型、计算量大、数据无假设
线性算法:可解释性好、建模迅速、线性分布