OpenCV与机器学习:使用opencv和sklearn实现线性回归

前言

线性回归是一种统计分析方法,用于确定两种或两种以上变量之间相互依赖的定量关系。在统计学中,线性回归利用线性回归方程(最小二乘函数)对一个或多个自变量(特征值)和因变量(目标值)之间的关系进行建模。

线性回归主要分为一元线性回归和多元线性回归。一元线性回归涉及两个变量,其关系可以用一条直线近似表示。而多元线性回归则涉及两个或两个以上的自变量,因变量和自变量之间是线性关系。线性回归的目标是找到一个数学公式,能够尽可能完美地组合所有自变量,以接近目标值。

线性回归

生成数据

一般来说我们会借助sklearn当中的linear_model来实现线性回归,我们首先生成一个可以用于线性回归的数据。

python 复制代码
import numpy as np

x = np.linspace(0, 10, 100)
y_hat = x * 5 + 5
np.random.seed(42)
y = x * 5 + 20 * (np.random.rand(x.size) - 0.5) + 5

其中x是数据,而y_hat是我们希望回归得到的回归值(由于这里是自己生成数据,所以这个值我们是知道的,处理现实问题时,这个值我们一般是不知道的)。y是采用随机数生成的用于训练的标签值,我们通过x和y进行线性回归,最终目的是回归出y_hat。

画图展示数据

为了更好的展现效果,下面我们使用matplotlib画一下图

python 复制代码
import matplotlib.pyplot as plt

plt.style.use('ggplot')
plt.figure(figsize=(10, 6))
plt.plot(x, y_hat, linewidth=4)
plt.plot(x, y, 'x')
plt.xlabel('x')
plt.ylabel('y')

其中蓝色的点代表的就是数据,而红色的直线就是我们经过线性回归应当得到的结果(最终结果有可能会有些偏差,但一般和这条红线相近)

划分数据并训练

依旧是借助sklearn中的model_selection.train_test_split对数据集进行划分

python 复制代码
from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=42)

使用sklearn进行回归 使用sklearn的训练十分的简单,如果熟悉sklearn可以发现,这个过程非常符合sklearn的使用风格。

python 复制代码
from sklearn import linear_model

linreg = linear_model.LinearRegression()
linreg.fit(x_train.reshape(-1, 1), y_train.reshape(-1, 1))
y_sklearn = linreg.predict(x.reshape(-1, 1))

使用OpenCV进行回归 我们可以借助cv2.fitLine用一条线拟合。该函数可以取下列参数: points:这是一条直线必须拟合的点集。 distType:这是M-估计所使用的距离。 param:这是数值参数(C),用于某些类型的距离。我们将 其保持为0,这样就可以选择一个最优值。 reps:这是原点到直线的距离准确率。0.01是reps的一个不错的 默认值。 aeps:这是角度的准确率。0.01是aeps的一个不错的默认值。

我们以distTypeOptions来暂存distType可以取的各种参数。

python 复制代码
import cv2

distTypeOptions = [cv2.DIST_L2,\
                   cv2.DIST_L1,\
                   cv2.DIST_L12,\
                   cv2.DIST_FAIR,\
                   cv2.DIST_WELSCH,\
                   cv2.DIST_HUBER
                  ]

为了更加方便的观察不同参数的不同效果,我们直接设置参数后拟合并显示。distTypeLabels对应的就是不同参数的图例,用于标识使用的参数,colors则是设置显示的颜色,points是通过列表推导的方式获得数据和标签相匹配的一对对元组。

python 复制代码
distTypeLabels = ['DIST_L2', 'DIST_L1', 'DIST_L12',
                   'DIST_FAIR', 'DIST_WELSCH','DIST_HUBER']

colors = ['g', 'c', 'm', 'y', 'k', 'b']
points = np.array([(xi, yi) for xi, yi in zip(x_train, y_train)])

cv2.fitLine并没有直接用于预测的函数,返回的是vxl, vyl, xl, yl,通过计算才可以得出预测结果。

python 复制代码
plt.figure(figsize=(10, 6))
plt.plot(x, y_hat, linewidth=2, label='Ideal')
plt.plot(x, y, 'x', label='Data')
for i in range(len(colors)):
    distType = distTypeOptions[i]
    distTypeLabel = distTypeLabels[i]
    c = colors[i]
    [vxl, vyl, xl, yl] = cv2.fitLine(np.array(points, dtype=np.int32), distType, 0, 0.01, 0.01)
    y_cv = [vyl[0]/vxl[0] * (xi -xl[0]) + yl[0] for xi in x]
    plt.plot(x, y_cv, c=c, linewidth=2, label=distTypeLabel)

随后我们也将sklearn的图像画上去,进行对比

python 复制代码
y_sklearn = list(y_sklearn.reshape(1, -1)[0])
plt.plot(x, list(y_sklearn), c='0.5', linewidth=2, label='Scikit-Learn API')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc='upper left')

可以看出,虽然差距不大,但sklearn的表现效果最佳。

相关推荐
程序员正茂19 小时前
Android studio中初步使用OpenCV库
android·opencv
小保CPP1 天前
OpenCV C++将多张图像合并为webp动图
c++·人工智能·opencv·计算机视觉
小保CPP1 天前
OpenCV C++提取webp动图里的图片
c++·人工智能·opencv·计算机视觉
深度研习笔记2 天前
OpenCV工业视觉实战11|多线程解耦+视频流稳流+推理加速,彻底解决卡顿阻塞,实现毫秒级工业实时检测
人工智能·opencv·计算机视觉
深度研习笔记2 天前
OpenCV工业视觉进阶14|SQLite违规数据库存储+历史记录查询+Excel报表导出,完成项目商用数据闭环(验收必备)
数据库·opencv·sqlite
C++ 老炮儿的技术栈3 天前
OpenCV 实现社保卡透视矫正:Hough 直线提取四角并转正证件图像
c语言·c++·人工智能·opencv·算法·计算机视觉·c
深度研习笔记3 天前
OpenCV工业视觉实战09|项目EXE打包+工控机无环境部署+后台常驻运行,彻底脱离Python环境,完成项目最终交付
python·opencv·webpack
深度研习笔记3 天前
OpenCV工业视觉实战06|ROI区域截取+局部精细化检测,锁定作业区域、屏蔽无效背景,大幅提升YOLO检测准确率
人工智能·opencv·yolo
fai厅的秃头姐!3 天前
OpenCV-基础篇
人工智能·opencv·计算机视觉
丨白色风车丨3 天前
OpenCV 基于 HSV 颜色空间实时颜色分割(摄像头蓝色识别)
人工智能·opencv·计算机视觉·hsv颜色识别·python计算机视觉