机器学习 --- 线性回归

简介: 机器学习 --- 线性回归

今天我们来开始入门机器学习,简单介绍一下线性回归模型


image.png

image.png

这几天一直有人问我拟合数据的问题,还有预测模型等问题,所以就想来开始一下这个我一直在准备的专栏--机器学习


线性回归是线性模型,例如,假设输入变量(x)和单个输出变量(y)之间存在线性关系的模型。


更具体地,可以根据输入变量(x)的线性组合来计算输出变量(y)。

所以我们希望算法学习假设的参数,以便能够建立方程进行预测 该方程以特征和参数作为输入,并预测其值作为输出。


要弄明白线性回归就要从背后的数学原理开始讲起


1.数学原理


从初中我们就开始接触方程,一开始是简单的y=kx+b,到后来越来越复杂。初中时有没有碰到这样一类问题呢?题目给出了一大堆商场每天的销售数量和利润让你从中得到函数去估计未来某个销售数量的利润。又或者是大学做大物实验画图的时候,老师总会说描点画线的要求是画一条直线,使每个点均匀的分布在这条直线的两边,且到直线的距离最短。那什么样的直线才是最适合的来预测这些数据特征(属性的)曲线呢?这就需要讲讲线性模型了。


首先是最基本的表达形式

image.png


其中X是自变量的各个属性,θ是参数

image.png

 然后就是最重要的就是怎么才能使参数最优,也就是损失率降到最小。 这就需要谈谈损失率和损失函数了,在这里我们选择的损失函数是均方误差


image.png


有了损失函数那我们还要想办法使误差最小。怎么求一个函数的最小值呢,就需要另外一个很重要的算法,叫梯度下降。

梯度下降:梯度下降是一种用来寻找最小损失函数的迭代优化算法。查找局部最小损失函数使用梯度下降算法,以当前点函数的负梯度的一定比例的步数进行逼近。

下图表示我们从函数高点出发找到局部最小值的步骤。


image.png


函数的负梯度理解起来就是损失函数求导的负方向


image.png


然后每次更新的步长就是我们说的学习率,这样就可以通过迭代求出损失函数的最小值了,从而就得到了最优参数解。


这里有个问题,就是梯度下降容易陷入局部最小值而不是全局最小值,这就涉及到随机梯度下降等优化算法了,而且还有过拟合从而失去泛化能力


代码实现部分


首先是最基本的线性拟合方法

image.png


就拿帮别人做的个作业来举例子


import pandas as pd
import numpy as np
import math
from scipy.optimize import leastsq
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False 
#导入数据
#平方英尺
x=[150,200,250,300,350,400,600]
#房价
y=[6450,7450,8450,9450,11450,15450,18450]
#训练集和测试集
x_train=np.array(x[0:5])
y_train=np.array(y[0:5])
x_test=np.array(x[5:7])
y_test=np.array(y[5:7])
def fun(p,x):
    k,b=p
    return k*x+b
# 误差函数
def error(p,x,y):
    return np.sqrt((fun(p,x)-y)**2)
#只用前五个数据进行预测
p0=[100,2]
para=leastsq(error,p0,args=(x_train,y_train))
k,b=para[0]
print("拟合的方程为:y={}x+{}".format(k,b))
#绘制拟合直线
plt.figure(figsize=(8,6))
plt.scatter(x,y,color="red",label="Point",linewidth=3)
X=np.linspace(100,700,1000)
Y=k*X+b
plt.plot(X,Y,color="orange",label="拟合直线",linewidth=2)
plt.xlabel('平方英尺')
plt.ylabel('房价')
plt.legend()
plt.show()
复制代码


image.png


#画误差图
err1=[]
for i in range(len(x_train)):
    err1.append(k*x_train[i]+b-y_train[i])
plt.figure(figsize=(10, 7))
plt.title('误差图')
plt.plot(x_train,err1,'r',label='error', linewidth=3)
plt.xlabel('x')
plt.ylabel('error')
plt.show()

image.png


然后自己仿着sklearn的线性模型写段代码,构建属于自己的线性模型训练器这里用到的数据集是2017年世界幸福指数和GPD的数据,可以在kaggle上下载,链接如下www.kaggle.com/unsdsn/worl…然后我们通过GDP指数去预测人们的幸福指数


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
#导入数据
data = pd.read_csv('2017.csv')
#查看数据集
data.info()
data.head(10)
复制代码


image.png


image.png

#画出每一个属性的分布直方图
histohrams = data.hist(grid=False, figsize=(10, 10))

image.png

#切分训练集和测试集
#分出80%训练集,20%测试集
#这里没有用到sklearn的train_test_split
train_data = data.sample(frac=0.8)
test_data = data.drop(train_data.index)
x_train = train_data[['Economy..GDP.per.Capita.']].values
y_train = train_data[['Happiness.Score']].values
x_test = test_data[['Economy..GDP.per.Capita.']].values
y_test = test_data[['Happiness.Score']].values
#绘制出散点图
plt.scatter(x_train, y_train, label='Training Dataset')
plt.scatter(x_test, y_test, label='Test Dataset')
plt.xlabel('Economy..GDP.per.Capita.')
plt.ylabel('Happiness.Score')
plt.title('Countries Happines')
plt.legend()
plt.show()

image.png

然后就是一些正则化防止过拟合的函数和归一化的函数了,这里就不贴了


#开始自己动手写一个线性回归模型
class self_LinearRegression:
    def __init__(self, data, labels, polynomial_degree=0, sinusoid_degree=0, normalize_data=True):
        (data_processed,features_mean,features_deviation)=prepare_for_training(data, polynomial_degree, sinusoid_degree, normalize_data)
        self.data = data_processed
        self.labels = labels
        self.features_mean = features_mean
        self.features_deviation = features_deviation
        self.polynomial_degree = polynomial_degree
        self.sinusoid_degree = sinusoid_degree
        self.normalize_data = normalize_data
        num_features = self.data.shape[1]
        self.theta = np.zeros((num_features, 1))
    #训练
    def train(self, alpha, lambda_param=0, num_iterations=500):
        cost_history = self.gradient_descent(alpha, lambda_param, num_iterations)
        return self.theta, cost_history
    #梯度下降
    def gradient_descent(self, alpha, lambda_param, num_iterations):
        cost_history = []
        for _ in range(num_iterations):
            self.gradient_step(alpha, lambda_param)
            cost_history.append(self.cost_function(self.data, self.labels, lambda_param))
        return cost_history
    def gradient_step(self, alpha, lambda_param):
        num_examples = self.data.shape[0]
        predictions = self_LinearRegression.hypothesis(self.data, self.theta)
        delta = predictions - self.labels
        reg_param = 1 - alpha * lambda_param / num_examples
        theta = self.theta
        theta = theta * reg_param - alpha * (1 / num_examples) * (delta.T @ self.data).T
        theta[0] = theta[0] - alpha * (1 / num_examples) * (self.data[:, 0].T @ delta).T
        self.theta = theta
    #损失率
    def get_cost(self, data, labels, lambda_param):
        data_processed = prepare_for_training(
            data,
            self.polynomial_degree,
            self.sinusoid_degree,
            self.normalize_data,
        )[0]
        return self.cost_function(data_processed, labels, lambda_param)
    def cost_function(self, data, labels, lambda_param):
        num_examples = data.shape[0]
        delta = self_LinearRegression.hypothesis(data, self.theta) - labels
        theta_cut = self.theta[1:, 0]
        reg_param = lambda_param * (theta_cut.T @ theta_cut)
        cost = (1 / 2 * num_examples) * (delta.T @ delta + reg_param)
        return cost[0][0]
    #预测
    def predict(self, data):
        data_processed = prepare_for_training(
            data,
            self.polynomial_degree,
            self.sinusoid_degree,
            self.normalize_data,
        )[0]
        predictions = self_LinearRegression.hypothesis(data_processed, self.theta)
        return predictions
    @staticmethod
    def hypothesis(data, theta):
        predictions = data @ theta
        return predictions
复制代码
#现在开始训练自己做的线性回归模型
num_iterations = 500  #设置迭代次数
learning_rate = 0.01   #学习率
regularization_param = 0 #正则化参数
polynomial_degree = 0
sinusoid_degree = 0 
linear_regression = self_LinearRegression(x_train, y_train, polynomial_degree, sinusoid_degree)
(theta, cost_history) = linear_regression.train(learning_rate,regularization_param,num_iterations)
#输出训练的损失率
print('最初损失率: {:.2f}'.format(cost_history[0]))
print('最优损失率: {:.2f}'.format(cost_history[-1]))
#输出模型参数
theta_table = pd.DataFrame({'自己的线性模型参数': theta.flatten()})
theta_table.head()


image.png

用自己写的模型训练得到的线性回归方程为:y=5.383319*x+0.892002


#画出梯度下降
plt.plot(range(num_iterations), cost_history)
plt.xlabel('迭代次数')
plt.ylabel('损失率')
plt.title('损失率梯度下降图')
plt.show()


image.png

#用自己构建的模型去进行预测,绘制出模型预测直线
predictions_num = 100
x_predictions = np.linspace(x_train.min(), x_train.max(), predictions_num).reshape(predictions_num, 1)
y_predictions = linear_regression.predict(x_predictions)
plt.scatter(x_train, y_train, label='训练数据')
plt.scatter(x_test, y_test, label='测试数据')
plt.plot(x_predictions, y_predictions, 'r', label='预测直线')
plt.xlabel('Economy..GDP.per.Capita.')
plt.ylabel('Happiness.Score')
plt.title('Countries Happines')
plt.legend()
plt.show()


image.png


后用sklrean的LinearRegression也来训练预测一下


#用sklearn构建线性回归模型
from sklearn.linear_model import LinearRegression
#创建模型
liner = LinearRegression()
#拟合模型
liner.fit(x_train,y_train)
#预测
y_predictions = liner.predict(x_predictions)
plt.scatter(x_train, y_train, label='训练数据')
plt.scatter(x_test, y_test, label='测试数据')
plt.plot(x_predictions, y_predictions, 'r', label='预测直线')
plt.xlabel('Economy..GDP.per.Capita.')
plt.ylabel('Happiness.Score')
plt.title('Countries Happines')
plt.legend()
plt.show()
print("斜率为:",liner.coef_)
print("截距为:",liner.intercept_)
复制代码



image.png

目录
相关文章
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
机器学习之线性回归与逻辑回归【完整房价预测和鸢尾花分类代码解释】
机器学习之线性回归与逻辑回归【完整房价预测和鸢尾花分类代码解释】
|
2月前
|
机器学习/深度学习 算法 TensorFlow
机器学习算法简介:从线性回归到深度学习
【5月更文挑战第30天】本文概述了6种基本机器学习算法:线性回归、逻辑回归、决策树、支持向量机、随机森林和深度学习。通过Python示例代码展示了如何使用Scikit-learn、statsmodels、TensorFlow库进行实现。这些算法在不同场景下各有优势,如线性回归处理连续值,逻辑回归用于二分类,决策树适用于规则提取,支持向量机最大化类别间隔,随机森林集成多个决策树提升性能,而深度学习利用神经网络解决复杂模式识别问题。理解并选择合适算法对提升模型效果至关重要。
192 4
|
2月前
|
机器学习/深度学习 数据采集 人工智能
【机器学习】解释什么是线性回归?
【5月更文挑战第15天】【机器学习】解释什么是线性回归?
|
11天前
|
机器学习/深度学习 数据采集 算法
【机器学习】线性回归:以房价预测为例
【机器学习】线性回归:以房价预测为例
57 1
|
17天前
|
机器学习/深度学习 数据可视化 算法
【阿旭机器学习实战】【29】产品广告投放实战案例---线性回归
【阿旭机器学习实战】【29】产品广告投放实战案例---线性回归
|
9天前
|
机器学习/深度学习 算法 数据格式
机器学习线性回归——概念梳理及非线性拟合
机器学习线性回归——概念梳理及非线性拟合
5 0
|
2月前
|
机器学习/深度学习 Python
利用Python实现一个简单的机器学习模型:线性回归详解
利用Python实现一个简单的机器学习模型:线性回归详解
41 2
|
16天前
|
机器学习/深度学习 存储 算法
【机器学习】深入探索机器学习:线性回归算法的原理与应用
【机器学习】深入探索机器学习:线性回归算法的原理与应用
25 0
|
17天前
|
机器学习/深度学习 算法
【阿旭机器学习实战】【31】股票价格预测案例--线性回归
【阿旭机器学习实战】【31】股票价格预测案例--线性回归
|
2月前
|
机器学习/深度学习 数据采集 人工智能
【机器学习】非线性回归与线性回归有何不同?
【5月更文挑战第19天】【机器学习】非线性回归与线性回归有何不同?