回归算法_回归算法的优缺点 - CSDN
精华内容
参与话题
  • 回归算法与分类算法都属于监督学习算法,不同的是,分类算法中标签是一些离散值,代表不同的分类,而回归算法中,标签是一些连续值,回归算法需要训练得到样本特征到这些连续标签之间的映射。 1.线性回归 2.局部加权...

    机器学习算法——回归算法总结(一)

    回归算法与分类算法都属于监督学习算法,不同的是,分类算法中标签是一些离散值,代表不同的分类,而回归算法中,标签是一些连续值,回归算法需要训练得到样本特征到这些连续标签之间的映射。
    1.线性回归
    2.局部加权回归
    3.岭回归
    4.Lasso回归
    5.CART回归树

    一 线性回归:
    线性回归是一类重要的回归问题,在线性回归中,目标值和特征之间存在线性相关的关系
    在这里插入图片描述
    1 基本的线性回归
    线性回归模型 一般有如下的线性回归方程:
    y = b + i=1nwixi\displaystyle\sum_{i=1}^{n}w_ix_i 其中b为偏置 ,wiw_i为回归系数。对于上式令 x0x_0 =1 可以写成 y=i=0nwixi\displaystyle\sum_{i=0}^{n}w_ix_i
    2 线性回归模型的损失函数
    线性回归的评价是指如何度量预测值与标签之间的接近程度。线性回归模型的损失函数可以是绝对损失和平方损失
    其中,绝对损失为 l = |y - yy^*| 其中yy^*为预测值,且y=i=0nwixiy^*=\displaystyle\sum_{i=0}^{n}w_ix_i
    平方损失函数:l = (yy)2(y - y^*)^2
    由于平方损失处处可导,通常使用平方误差作为线性回归模型的损失函数。
    假设有m个样本,每个样本有n-1个特征,则平方误差可表示为:
    l=0.5*i=1m(y(i)j=0n1wjxj(i))2\displaystyle\sum_{i=1}^{m}(y^{(i)}-\displaystyle\sum_{j=0}^{n-1}w_jx_{j}^{(i)})^2
    对于平方误差损失函数,线性回归的求解就是希望求得平方误差的最小值。

    3 线性回归的最小二乘法
    预测函数可以用矩阵的方式表示:Y = WX其损失函数可以表示为:
    YXW)T(YXW)(Y - XW)^T(Y -XW)
    对 w进行求导,得XT(YXW)X^T(Y-XW) 令其为零 可得 W=(XTX)1XTYW^*=(X^TX)^{-1}X^TY
    利用python实现最小二乘法十分简单:

    import numpy as np
    def least_square(feature,label):
    	w = (feature.T *feature).I * feature.T * label
    	return w
    

    这中方法前提是要矩阵(XTX)(X^TX)是满秩矩阵,其逆矩阵才存在

    4 牛顿法求解回归系数w(重要)

    牛顿法的基本思想是利用迭代点xkx_k处的一介导数(梯度)和二阶导数(Hessen矩阵)对目标函数进行二次函数近似,然后把二次函数的极小值点作为新的迭代点,并不断重复这一个过程,知道求得满足精度的近似极小值。

    基本牛顿法是一种基于导数的方法,它每一步的迭代方向都是沿着当前点的函数值下降方向。
    对于一维的情况,对于一个需要求解的优化问题f(x),求其极值得问题,可以转换为导函数f`(x)=0.
    对函数f(x)进行泰勒展开到二阶
    f(x)=f(xk)+f(xk)(xxk)+0.5f(xk)(xxk)2f(x)= f(x_k)+f'(x_k)(x-x_k)+0.5f''(x_k)(x-x_k)^2
    对其求导(对x求导)得到:
    f(xk)+f(xk)(xxk)f'(x_k) + f''(x_k)(x-x_k)=0 得到 x=xkf(xk)f(xk)x = x_k - \frac{f'(x_k)}{f''(x_k)}
    这就是牛顿法的更新公式。
    基本牛顿法流程:
    1.给定终止误差值 0<ε<1 初始点x0x_0,令k=0;
    2.计算gk=f(xk)g_k= ▽f(x_k),若||gkg_k||<= ε,则停止,输出 x=xkx^* = x_k
    3.计算Gk=2f(xk)G_k = ▽^2f(x_k)并求解线性方程组Gkd=gkG_kd = -g_k得解 dkd_k
    4.令 xk+1=xk+dkk=k+1x_{k+1}=x_k + d_k k = k+1 转2

    基本牛顿法的优点是收敛速度快,局部二阶收敛性,但是缺点是需要初始点需要足够靠近极小点,否则算法可能不收敛。
    在这里插入图片描述
    全局牛顿法相对于基本牛顿法其实就是引入了一个搜索步长,这个步长的确定也是通过线性搜索得到的。(具体可参考董晓辉的优化方法那本书)
    牛顿法需要计算Hessen矩阵的逆矩阵,计算量太大,可以利用拟牛顿法法拟牛顿法核心是找一个矩阵近似代替Hessen矩阵的逆矩阵

    二 局部加权线性回归
    当数据的全局线性回归的性质不是那么完美时,线性回归中可能出现欠拟合问题。局部加权回归可以解决这种情况。
    在这里插入图片描述
    局部加权回归执行以下步骤:
    1.针对给定的查询点xx,寻找使iw(i)(y(i)θTx(i))2\displaystyle\sum_{i}w(i)(y^{(i)}-\theta^Tx^{(i)})^2取最小的θ\theta
    2.给出预测结果θTx\theta^Tx
    这里的ww称为权值,是一个非负数,直观上看,如果对于某个i,w(i)i,w(i)取值较大,则在计算θ\theta取值时,我们将尽可能的减小(y(i)θTx(i))2(y^{(i)}-\theta^Tx^{(i)})^2项的取值(精确拟合);反之,如果w(i)w(i)取值较小,则(y(i)θTx(i))2(y^{(i)}-\theta^Tx^{(i)})^2所得到的误差项将足够小二忽略不计。
    局部加权回归采用的是给预测点附近的每一个点赋予一定的权重,
    此时的回归系数可以表示为: W=(XTMX)1XTMYW = (X^TMX)^{-1}X^TMY M是每个点的权重
    LWLR使用核函数来对附近的点赋予更高的权重,常用的有高斯核,对应的权重为
    M(i,i)=exp(XiX22k2)M(i,i)=exp(\frac{||X^i-X||^{2}}{-2k^2})
    其中 x是查询点,xix_i是第i个训练样本,k是可调参数,控制训练点到查询点的权重衰减速率。
    易看出,对于给定的查询点x,权值的大小与训练样本x(i)相对于x的位置密切相关:
    1)如果x(i)距离x很近,则ω(i)将取靠近1的值;
    2)如果x(i)距离x很远,则ω(i)将取到0附近。
    注意:尽管权值函数的样子看起来很像高斯分布的概率密度函数,但是这个函数跟高斯分布并没有直接联系,另外ω(i)并不是随机变量,也并不服从高斯分布,它只是一个样子恰好类似钟形的曲线
    这样的权重矩阵只含对角元素。

    def lwlr(testpoint,xArr,yArr,k=1.0):
    	xMat= mat(xArr)
    	yMat= mat(yArr)
    	m= shape(xMat)[0]
    	weights=mat(eye((m)))
    	for j in range(m):
    		diffMat = testpoint -xMat[j,:]
    		weights[j,j]=exp(diffMat*diffMat.T /(-2.0 *k**2)
    		xTx = xMat.T * (weights*xMat)
    		if linalg.det(xTX)==0.0:
    			print "This matrix is singular ,can not to inverse"
    			return
    	w = xTx.I *(xMat.T *(weights*yMat)
    	return testpoint * w	
    

    局部加权回归算法中,核函数的k值时唯一可调参数,当k值变小时,离测试点较远的点的权重会指数级减小,此时拟合数据的能力会变强。
    局部加权线性回归算法中,我们对测试点附近的每一个点赋予一定的权重,在这个子集上基于最小均方差来进行普通的回归。
    函数中的τ称作带宽(bandwidth)(或波长)参数,它控制了权值随距离下降的速率。如果τ取值较小,则会得到一个较窄的钟形曲线,这意味着离给定查询点x较远的训练样本x(i)的权值(对查询点x附近训练样本的拟合的影响)将下降的非常快;而τ较大时,则会得到一个较为平缓的曲线,于是查询点附近的训练样本的权重随距离而下降的速度就会相对比较慢。
    值得注意的是,这是一个非参数算法,我们在使用这个方法时,是针对给定的查询点x进行计算,也就是每当我们对于一个给定的x做出预测时,都需要根据整个训练集重新进行拟合运算,如果训练集很大而查询很频繁的话,这个算法的代价将非常高。关于提高这个算法的效率,可以参考Andrew Moore关于KD-Tree的工作。
    局部线性回归算法的问题在于,对于每一个要查询的点,都要重新依据整个数据集计算一个线性回归模型出来,这样使得计算代价极高。

    展开全文
  • 几种常用回归算法的比较

    万次阅读 多人点赞 2018-08-27 11:00:54
    type introduce example k-nearest neighbors ... 原理:是一种常用的监督学习方法,给定测试样本,基于某种距离度量找出训练集中与其最靠近的k个训练样本,然后基于这k个“邻居”的...

    type

    introduce

    example

    k-nearest neighbors

    原理:是一种常用的监督学习方法,给定测试样本,基于某种距离度量找出训练集中与其最靠近的k个训练样本,然后基于这k个“邻居”的信息来进行预测。

    判定方法:

    (1)在分类任务中的可使用“投票法”,即选择这k个样本中出现最多的类别标记作为预测结果;

    (2)在回归任务中可使用“平均法”,即将这k个样本的标记平均值作为预测结果。

    (3)还可以根据距离远近,对样本进行加权,实现加权平均或加权投票。

    (二)注意点:

    1、距离度量方法不同,找到的“近邻”也可能有显著区别,进而导致分类结果不同。通常是用欧式距离,即平方和开根号。

    2、k在其中是一个相当重要的参数,k取值不同时,分类结果会有显著不同。

    优点:适合对稀有事件进行分类(例如当流失率很低时,比如低于0.5%,构造流失预测模型)

    特别适合于多分类问题(multi-modal,对象具有多个类别标签),例如根据基因特征来判断其功能分类,kNN比SVM的表现要好

    理论成熟,思想简单,既可以用来做分类也可以用来做回归;

    可用于非线性分类;

    训练时间复杂度为O(n);

    对数据没有假设,准确度高,对outlier不敏感;

    缺点:

    计算量大;

    样本不平衡问题(即有些类别的样本数量很多,而其它样本的数量很少);

    需要大量的内存。

    #1.导入:

    分类问题:

    from sklearn.neighbors import KNeighborsClassifier

    回归问题:

    from sklearn.neighbors import KNeighborsRegressor

     

    #2.创建模型

    knnclf = KNeighborsClassifier(n_neighbors=5)

    knnrgr = KNeighborsRegressor(n_neighbors=3)

     

    #3.训练

    knnclf.fit(X_train,y_train)

     

    #4.预测

    y_pre = knnclf.predict(x_test)

    LinearRegression

    数理统计中回归分析,用来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法,其表达形式为y = w'x+e,其中只有一个自变量的情况称为简单回归,多个自变量的情况叫多元回归

    回归说明它的响应是定量(quantitative)的,而不是定性(qualitative)的。

    适用数据类型:数值型和标称型

    优点:结果易于理解,计算不复杂

    缺点:对非线性的数据拟合不好

              当特征冗余,即如果存在多重共线性时,线性回归就不太稳定

    损失函数: 对于线性回归模型,将模型与数据点之间的距离差之和做为衡量匹配好坏的标准,误差越小,匹配程度越大

    #1.导入from sklearn.linear_model import LinearRegression

    #2.创建模型

    line = LinearRegression()

    #3.训练

    line.fit(X_train,y_train)

    #4.预测

    y_pre= line.predict(x_test)

    Ridge

    原理:岭回归是一种专用于共线性数据分析的有偏估计回归方法,实质上是一种改良的最小二乘估计法,通过放弃最小二乘法的无偏性,以损失部分信息、降低精度为代价,获得回归系数更为符合实际、更可靠的回归方法,对病态数据的耐受性远远强于最小二乘法。

    缺点:通常岭回归方程的R平方值会稍低于普通回归分析,但回归系数的显著性往往明显高于普通回归,在存在共线性问题和病态数据偏多的研究中有较大的实用价值。

    适用情况:主要适用于过拟合严重或各变量之间存在多重共线性的时候

    1.岭回归可以解决特征数量比样本量多的问题

    2.岭回归作为一种缩减算法可以判断哪些特征重要或者不重要,有点类似于降维的效果

    3.缩减算法可以看作是对一个模型增加偏差的同时减少方差

    #1.导入from sklearn.linear_model import Ridge

    #2.创建模型# alpha就是缩减系数lambda# 如果把alpha设置为0,就是普通线性回归

    ridge = Ridge(alpha=.5)

    #3.训练#4.预测

    X = [[0,0],[0,0],[1,1]]

    y = [0,.1,1]

    clf.fit(X,y)

    print(clf.coef_)

    print(clf.intercept_)

    Lasso

    最小绝对值收敛和选择算子、套索算法。该方法是一种压缩估计。它通过构造一个罚函数得到一个较为精炼的模型,使得它压缩一些系数,同时设定一些系数为零。因此保留了子集收缩的优点,是一种处理具有复共线性数据的有偏估计

    Lasso 的基本思想是在回归系数的绝对值之和小于一个常数的约束条件下,使残差平方和最小化,从而能够产生某些严格等于0 的回归系数,得到可以解释的模型。将Lasso应用于回归,可以在参数估计的同时实现变量的选择,较好的解决回归分析中的多重共线性问题,并且能够很好的解释结果.

    #1.导入from sklearn.linear_model import Lasso

    #2.创建模型

    las = Lasso(alpha=0.0001)

    #3.训练

    #4.预测

    DecisionTreeRegressor

    决策树是是一个监督式学习方法,主要用于分类和回归,是一个树结构(可以是二叉树或非二叉树)。其每个非叶节点表示一个特征属性上的测试,每个分支代表这个特征属性在某个值域上的输出,而每个叶节点存放一个类别。使用决策树进行决策的过程就是从根节点开始,测试待分类项中相应的特征属性,并按照其值选择输出分支,直到到达叶子节点,将叶子节点存放的类别作为决策结果。

    决策树是一种典型的分类方法,首先对数据进行处理,利用归纳算法生成可读的规则和决策树,然后使用决策对新数据进行分析。本质上决策树是通过一系列规则对数据进行分类的过程。

    可以毫无压力地处理特征间的交互关系并且是非参数化的,因此不必担心异常值或者数据是否线性可分

    决策树优势:

    1、计算简单,易于理解,可解释性强;

    2、比较适合处理有缺失属性的样本;

    3、能够处理不相关的特征;

    4、在相对短的时间内能够对大型数据源做出可行且效果良好的结果。

    决策树劣势:

    1、可能会建立过于复杂的规则,即过拟合。

    2、决策树有时候是不稳定的,因为数据微小的变动,可能生成完全不同的决策树。

    3、实际决策树学习算法是基于试探性算法,例如在每个节点实现局部最优值的贪心算法。 这样的算法是无法保证返回一个全局最优的决策树。可以通过随机选择特征和样本训练多个决策树来缓解这个问题。

    4、有些问题学习起来非常难,因为决策树很难表达。如:异或问题、奇偶校验或多路复用器问题

    5、如果有些因素占据支配地位,决策树是有偏的。因此建议在拟合决策树之前先平衡数据的影响因子。

    6、不支持在线学习,于是在新样本到来后,决策树需要全部重建

    #Import Library

    #Import other necessary libraries like pandas, numpy...

    from sklearn import tree

    #Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset

    # Create tree object

    model = tree.DecisionTreeClassifier(criterion='gini') # for classification, here you can change the algorithm as gini or entropy (information gain) by default it is gini

    # model = tree.DecisionTreeRegressor() for regression

    # Train the model using the training sets and check score

    model.fit(X, y)

    model.score(X, y)

    #Predict Output

    predicted= model.predict(x_test)

    SVR

    支持向量回归(support vector regression)是支持向量机(SVM)的重要的应用分支.

    SVR回归,就是找到一个回归平面,让一个集合的所有数据到该平面的距离最近

    1.导入模块

    import numpy as np

    import pandas as pd

    from pandas import Series,DataFrame

    import matplotlib.pyplot as plt

    %matplotlib inline

    import sklearn.datasets as datasets

    #支持向量回归

    from sklearn.svm import SVR

     

    2.生成训练数据

    x = np.linspace(-np.pi,np.pi,60)

    y = np.sin(x)

    #数据加噪

    y[::3]+=0.5-np.random.random(20)

    X_train = x.reshape(-1,1)

    Y_train = y

     

    3.创建支持向量回归模型

    svr_linear = SVR(kernel='linear')

    svr_rbf = SVR(kernel='rbf')

    svr_poly = SVR(kernel='poly')

     

    4.训练数据

    svr_linear.fit(X_train,Y_train)

    svr_rbf.fit(X_train,Y_train)

    svr_poly.fit(X_train,Y_train)

     

    5.与测试数据

    #获取预测数据自变量范围

    xmin,xmax = X_train.min(),X_train.max()

    x_test = np.arange(xmin,xmax,0.01).reshape(-1,1)

    #获取预测数据

    linear_y_pre = svr_linear.predict(x_test)

    rbf_y_pre = svr_rbf.predict(x_test)

    poly_y_pre = svr_poly.predict(x_test)

     

    6.绘图

    results = [linear_y_pre,rbf_y_pre,poly_y_pre]

    titles = ['Linear','rbf','poly']

    plt.figure(figsize=(12,12))

    for i,result in enumerate(results):

    plt.subplot(3,1,i+1)

    plt.scatter(X_train,Y_train)

    plt.plot(x_test,result,color='orange')

    plt.title(titles[i])

    Logistic回归(逻辑回归)

    实际中最常用的就是二分类的Logistic回归,用于分类

    Logistic回归本质上是线性回归,只是在特征到结果的映射中加入了一层函数映射,即先把特征线性求和,然后使用函数g(z)将最为假设函数来预测。g(z)可以将连续值映射到0和1上。

    Logistic回归的主要用途:

    •寻找危险因素:寻找某一疾病的危险因素等; 

    •预测:根据模型,预测在不同的自变量情况下,发生某病或某种情况的概率有多大; 

    •判别:实际上跟预测有些类似,也是根据模型,判断某人属于某病或属于某种情况的概率有多大,也就是看一下这个人有多大的可能性是属于某病。

    Logistic回归主要在流行病学中应用较多,比较常用的情形是探索某疾病的危险因素,根据危险因素预测某疾病发生的概率,等等

    其损失函数的目的是增加对分类影响较大的数据点的权重,减少与分类关系较小的数据点的权重

    优点:

    1、预测结果是界于0和1之间的概率;

    2、可以适用于连续性和类别性自变量;

    3、容易使用和解释;

    缺点:

    1、当特征空间很大时,逻辑回归的性能不是很好;

    2、容易欠拟合,一般准确度不太高;

    3、不能很好地处理大量多类特征或变量;只能处理两分类问题(在此基础上衍生出来的Softmax可以用于多分类),且必须线性可分;

    4、预测结果呈“S”型,因此从log(odds)log(odds)向概率转化的过程是非线性的,在两端随着log(odds)log(odds)值的变化,概率变化很小,边际值太小,slopeslope太小,而中间概率的变化很大,很敏感。 导致很多区间的变量变化对目标概率的影响没有区分度,无法确定阀值;

    5、对于非线性特征,需要进行转换;

    # -*- coding:utf-8 -*-

    import numpy as np

    import matplotlib.pyplot as plt

    import random

    def text2num(string):

        str_list = string.replace("\n", " ").split(" ")

        while '' in str_list:

            str_list.remove('')

        num_list = [float(i) for i in str_list]

        return num_list

    def sigmoid(x):

        return 1.0 / (1 + np.exp(-x))

    def data_plot(data_list, weight):

        x_data = [list(i[0:2]) for i in data_list if i[2] == 0.0]

        y_data = [list(i[0:2]) for i in data_list if i[2] == 1.0]

        x_data = np.reshape(x_data, np.shape(x_data))

        y_data = np.reshape(y_data, np.shape(y_data))

        linear_x = np.arange(-4, 4, 1)

        linear_y = (-weight[0] - weight[1] * linear_x) / weight[2]

        print(linear_y)

        plt.figure(1)

        plt.scatter(x_data[:, 0], x_data[:, 1], c='r')

        plt.scatter(y_data[:, 0], y_data[:, 1], c='g')

        print(linear_x)

        print(linear_y.tolist()[0])

        plt.plot(linear_x, linear_y.tolist()[0])

        plt.show()

    def grad_desc(data_mat, label_mat, rate, times):

        data_mat = np.mat(data_mat)

        label_mat = np.mat(label_mat)

        m,n = np.shape(data_mat)

        weight = np.ones((n, 1))

        for i in range(times):

            h = sigmoid(data_mat * weight)

            error = h - label_mat

            weight = weight - rate * data_mat.transpose() * error

        return weight

    def random_grad_desc(data_mat, label_mat, rate, times):

        data_mat = np.mat(data_mat)

        m,n = np.shape(data_mat)

        weight = np.ones((n, 1))

        for i in range(times):

            for j in range(m):

                h = sigmoid(data_mat[j] * weight)

                error = h - label_mat[j]

                weight = weight - rate * data_mat[j].transpose() * error

        return weight

    def improve_random_grad_desc(data_mat, label_mat, times):

        data_mat = np.mat(data_mat)

        m,n = np.shape(data_mat)

        weight = np.ones((n, 1))

        for i in range(times):

            index_data = [i for i in range(m)]

            for j in range(m):

                rate = 0.0001 + 4 / (i + j + 1)

                index = random.sample(index_data, 1)

                h = sigmoid(data_mat[index] * weight)

                error = h - label_mat[index]

                weight = weight - rate * data_mat[index].transpose() * error

                index_data.remove(index[0])

        return weight

    def main():

        file = open("/Users/chenzu/Documents/code-machine-learning/data/LR", "rb")

        file_lines = file.read().decode("UTF-8")

        data_list = text2num(file_lines)

        data_len = int(len(data_list) / 3)

        data_list = np.reshape(data_list, (data_len, 3))

        data_mat_temp = data_list[:, 0:2]

        data_mat = []

        for i in data_mat_temp:

            data_mat.append([1, i[0], i[1]])

        print(data_mat)

        label_mat = data_list[:, 2:3]

        #梯度下降求参数

        weight = improve_random_grad_desc(data_mat, label_mat, 500)

        print(weight)

        data_plot(data_list, weight)

    if __name__ == '__main__':

        main()

     

    朴素贝叶斯

    优点:

    朴素贝叶斯模型发源于古典数学理论,有着坚实的数学基础,以及稳定的分类效率;

    对小规模的数据表现很好,能个处理多分类任务,适合增量式训练;

    对缺失数据不太敏感,算法也比较简单,常用于文本分类。

    缺点:

    需要计算先验概率;

    分类决策存在错误率;

    对输入数据的表达形式很敏感。

    import numpy as np
     
    class NativeBayes:
        def __init__(self):
            # log(P(Y)), Y = 0,1
            self.log_label_0_ratio = 0
            self.log_label_1_ratio = 0 
            # array of feature weights
            self.weights = None     
            # log value of feat vector
            self.log_label_0_vec = None
            self.log_label_1_vec = None
            
        def fit(self, data_set, labels, weights):
            self.weights = weights
            data_mat = np.array(data_set)
            data_num = len(data_mat)
            feat_num = len(data_mat[0])
            label_1_ratio = sum(labels) / float(data_num)
            label_0_ratio = 1 - label_1_ratio     
            self.log_label_1_ratio = np.log(label_1_ratio)
            self.log_label_0_ratio = np.log(label_0_ratio)    
            # using Laplace smoothing, initialization with alpha = 1
            label_1_feat_array = np.ones(feat_num)
            label_0_feat_array = np.ones(feat_num)
            label_1_feat_sum = float(feat_num)
            label_0_feat_sum = float(feat_num)       
            for i in range(data_num):
                if labels[i] == 0:
                    label_0_feat_array += data_mat[i]
                    label_0_feat_sum += sum(data_mat[i])
                else:
                    label_1_feat_array += data_mat[i]
                    label_1_feat_sum += sum(data_mat[i])
            self.log_label_0_vec = np.log(label_0_feat_array / label_0_feat_sum)
            self.log_label_1_vec = np.log(label_1_feat_array / label_1_feat_sum)  
            return self
        
        def predict(self, data):
            p0 = sum(self.log_label_0_vec * data * self.weights) + self.log_label_0_ratio
            p1 = sum(self.log_label_1_vec * data * self.weights) + self.log_label_1_ratio
            if p0 > p1:
                return 0
            else:
                return 1

     

    展开全文
  • 机器学习之回归算法

    千次阅读 2018-06-29 16:52:16
    回归算法是机器学习中最常见也是使用最广的一个算法,回归算法主要有线性回归和逻辑回归2种。下面我将分别介绍线性回归和逻辑回归。1线性回归 线性回归是有监督学习的一种算法,科学的介绍这里就不做说明了。通俗的...

    回归算法是机器学习中最常见也是使用最广的一个算法,回归算法主要有线性回归和逻辑回归2种。下面我将分别介绍线性回归和逻辑回归。

    1线性回归

        线性回归是有监督学习的一种算法,科学的介绍这里就不做说明了。通俗的说,就是根据数据集中的特征(X),找到一个合适的线或是面。。来拟合我们的数据集标签(Y)。

        假设我们有一个简单的数据集,里面每个样本都有2个特征,我们根据线性回归算法,找到一个平面来拟合这个数据集中的标签。如下的方程

        

    也可以将方程转化成矩阵形式

        

    而我们要做的就是找到里面的权重值 θ,使得对于每个样本


    中ε(误差)值最小。

    重点来了~~我们这里的误差是相对独立的而且具有相同的分布,服从均值为0方差为σ2的高斯分布!!!

    所以我们将误差ε  带入高斯函数



    这里我们要使用似然函数,来找到这些参数,使得跟我们的数据组合后恰好是真实值的最大可能性。

    加入似然函数后如下


    因为是一个连乘的结构,不好计算,我们在式子两边去对数,在不改变性质的情况下简化计算。


    简化展开后如下


    我们要使得上面的式子最大,则需要这式子最小。

    最终,我们找到了一个损失函数,

       

    这个函数也叫最小二乘法。

    以上的推导就是线性回归这个损失函数的由来。

    接下来我们要做的就是采用梯度下降法,迭代计算得到最终我们需要的一组θ。。。。

    后续的具体方法比如采用什么样的梯度下降法(批量梯度下降,随机梯度下降,小批量梯度下降)

    以及学习率的选择,(这里不详细介绍机器学习里面的基本知识。)这里不做介绍。

    2 逻辑回归

        逻辑回归是经典的二分类算法。

    这我们也是介绍逻辑回归损失函数的推导

    首先一个就是sigmoid函数


    这个函数的作用说白了就是将线性值映射成概率值

    因此,我们的预测函数为


    在分类任务中如果


    那么


    对于二分类任务,预测结果不是0,就是1.因此有最后的整合函数


    同样的我们采用似然函数


    还是对两边取对数


    此时是获取最大值,我们引入

    ,使得获取最大值的结果变成获取最小值

    紧接着,就是对其求导,

    最终简化的结果为


    最后还是进行常规的参数迭代更新。

    这里就不做详细介绍了

    下面,我们用python实现一个   基于梯度下降的逻辑回归实例

    ------------------------------------------------------------------------------------------------------------------------------

    我们将建立一个逻辑回归模型来预测一个学生是否被大学录取。假设你是一个大学系的管理员,你想根据两次考试的结果来决定每个申请人的录取机会。你有以前的申请人的历史数据,你可以用它作为逻辑回归的训练集。对于每一个培训例子,你有两个考试的申请人的分数和录取决定。为了做到这一点,我们将建立一个分类模型,根据考试成绩估计入学概率。

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    path = 'H:\data\LogiReg_data.txt'
    pdData = pd.read_csv(path, header=None, names=['Exam 1', 'Exam 2', 'Admitted'])#导入数据
    pdData.head()

    #数据显示
    positive = pdData[pdData['Admitted'] == 1] # returns the subset of rows such Admitted = 1, i.e. the set of *positive* examples
    negative = pdData[pdData['Admitted'] == 0] # returns the subset of rows such Admitted = 0, i.e. the set of *negative* examples
    fig, ax = plt.subplots(figsize=(10,5))
    ax.scatter(positive['Exam 1'], positive['Exam 2'], s=30, c='g', marker='o', label='Admitted')
    ax.scatter(negative['Exam 1'], negative['Exam 2'], s=30, c='r', marker='x', label='Not Admitted')
    ax.legend()
    ax.set_xlabel('Exam 1 Score')
    ax.set_ylabel('Exam 2 Score')


    要完成的模块

    • sigmoid : 映射到概率的函数

    • model : 返回预测结果值

    • cost : 根据参数计算损失

    • gradient : 计算每个参数的梯度方向

    • descent : 进行参数更新

    • accuracy: 计算精度

    sigmoid 函数

        
    def sigmoid(z):
        return 1 / (1 + np.exp(-z))
    def model(X, theta):
        return sigmoid(np.dot(X, theta.T))
    #向元数据插入一列全1
    pdData.insert(0, 'Ones', 1) # in a try / except structure so as not to return an error if the block si executed several times
    #创建权重值
    theta = np.zeros([1, 3])

    损失函数

    def cost(X, y, theta):
        left = np.multiply(-y, np.log(model(X, theta)))
        right = np.multiply(1 - y, np.log(1 - model(X, theta)))
        return np.sum(left - right) / (len(X))

    可以先计算一次

    cost(X, y, theta)
    0.6931471805599453

    计算梯度

    def gradient(X, y, theta):
        grad = np.zeros(theta.shape)
        error = (model(X, theta)- y).ravel()
        for j in range(len(theta.ravel())): #for each parmeter
            term = np.multiply(error, X[:,j])
            grad[0, j] = np.sum(term) / len(X)
        
        return grad

    Gradient descent

    比较3中不同梯度下降方法


    STOP_ITER = 0 #按次数停止
    STOP_COST = 1 #按损失值停止
    STOP_GRAD = 2 #按梯度值停止
    
    def stopCriterion(type, value, threshold):
        #设定三种不同的停止策略
        if type == STOP_ITER:        return value > threshold
        elif type == STOP_COST:      return abs(value[-1]-value[-2]) < threshold
        elif type == STOP_GRAD:      return np.linalg.norm(value) < threshold
    import numpy.random
    #洗牌
    def shuffleData(data):
        np.random.shuffle(data)
        cols = data.shape[1]
        X = data[:, 0:cols-1]
        y = data[:, cols-1:]
        return X, y
    import time
    
    def descent(data, theta, batchSize, stopType, thresh, alpha):
        #梯度下降求解
        
        init_time = time.time()
        i = 0 # 迭代次数
        k = 0 # batch
        X, y = shuffleData(data)
        grad = np.zeros(theta.shape) # 计算的梯度
        costs = [cost(X, y, theta)] # 损失值
    
        
        while True:
            grad = gradient(X[k:k+batchSize], y[k:k+batchSize], theta)
            k += batchSize #取batch数量个数据
    
            if k >= n: 
                k = 0 
                X, y = shuffleData(data) #重新洗牌
            theta = theta - alpha*grad # 参数更新
            costs.append(cost(X, y, theta)) # 计算新的损失
            i += 1 
    
            if stopType == STOP_ITER:       value = i
            elif stopType == STOP_COST:     value = costs
            elif stopType == STOP_GRAD:     value = grad
            if stopCriterion(stopType, value, thresh): break
        
        return theta, i-1, costs, grad, time.time() - init_time

    def runExpe(data, theta, batchSize, stopType, thresh, alpha):
        #import pdb; pdb.set_trace();
        theta, iter, costs, grad, dur = descent(data, theta, batchSize, stopType, thresh, alpha)
        name = "Original" if (data[:,1]>2).sum() > 1 else "Scaled"
        name += " data - learning rate: {} - ".format(alpha)
        if batchSize==n: strDescType = "Gradient"
        elif batchSize==1:  strDescType = "Stochastic"
        else: strDescType = "Mini-batch ({})".format(batchSize)
        name += strDescType + " descent - Stop: "
        if stopType == STOP_ITER: strStop = "{} iterations".format(thresh)
        elif stopType == STOP_COST: strStop = "costs change < {}".format(thresh)
        else: strStop = "gradient norm < {}".format(thresh)
        name += strStop
        print ("***{}\nTheta: {} - Iter: {} - Last cost: {:03.2f} - Duration: {:03.2f}s".format(
            name, theta, iter, costs[-1], dur))
        fig, ax = plt.subplots(figsize=(12,4))
        ax.plot(np.arange(len(costs)), costs, 'r')
        ax.set_xlabel('Iterations')
        ax.set_ylabel('Cost')
        ax.set_title(name.upper() + ' - Error vs. Iteration')
        return theta

    不同的停止策略

    设定迭代次数

    #选择的梯度下降方法是基于所有样本的
    n=100
    runExpe(orig_data, theta, n, STOP_ITER, thresh=5000, alpha=0.000001)

    根据损失值停止


    runExpe(orig_data, theta, n, STOP_COST, thresh=0.000001, alpha=0.001)

    根据梯度变化停止


    runExpe(orig_data, theta, n, STOP_GRAD, thresh=0.05, alpha=0.001)

    对比不同的梯度下降方法

    Stochastic descent 随机梯度下降

    runExpe(orig_data, theta, 1, STOP_ITER, thresh=5000, alpha=0.001)

    降低学习率减小梯度爆炸

    runExpe(orig_data, theta, 1, STOP_ITER, thresh=15000, alpha=0.000002)

    Mini-batch descent 小批量梯度下降

    runExpe(orig_data, theta, 16, STOP_ITER, thresh=15000, alpha=0.001)

    浮动仍然比较大,我们来尝试下对数据进行标准化 将数据按其属性(按列进行)减去其均值,然后除以其方差。最后得到的结果是,对每个属性/每列来说所有数据都聚集在0附近,方差值为1

    from sklearn import preprocessing as pp
    
    scaled_data = orig_data.copy()
    scaled_data[:, 1:3] = pp.scale(orig_data[:, 1:3])
    
    runExpe(scaled_data, theta, n, STOP_ITER, thresh=5000, alpha=0.001)

    精度


    #设定阈值
    def predict(X, theta):
        return [1 if x >= 0.5 else 0 for x in model(X, theta)]
    scaled_X = scaled_data[:, :3]
    y = scaled_data[:, 3]
    predictions = predict(scaled_X, theta)
    correct = [1 if ((a == 1 and b == 1) or (a == 0 and b == 0)) else 0 for (a, b) in zip(predictions, y)]
    accuracy = (sum(map(int, correct)) % len(correct))
    print ('accuracy = {0}%'.format(accuracy))
    补充。上例中用到的数据集下载请点击连接 数据集

    至此,简单的介绍了机器学习中的回归算法。这里我只是针对那些我学习中容易出错或是不太理解的地方进行说明。并不是针对这个算法进行详细的解释。如果对于这个算法一点都不了解的,建议先补充相关的知识。








    展开全文
  • 机器学习中【回归算法】详解

    万次阅读 多人点赞 2019-01-15 16:30:50
    关注微信公众号【Microstrong】,我写过四年Android代码,了解前端、熟悉后台,现在研究方向是机器学习、深度学习!一起来学习,一起来进步,一起来交流吧! ...amp;mid=2247483935&amp;idx=1&...

    关注微信公众号【Microstrong】,我写过四年Android代码,了解前端、熟悉后台,现在研究方向是机器学习、深度学习!一起来学习,一起来进步,一起来交流吧!

    本文同步更新在我的微信公众号里,地址:https://mp.weixin.qq.com/s?__biz=MzI5NDMzMjY1MA==&mid=2247483935&idx=1&sn=5e1c55c764ae3443734b3d6d13a110e9&chksm=ec65339adb12ba8ceb875f2dffd29723d975a61ab9af127b4e00e708f177da4abe4ff2e88a96#rd

     

    回归问题:主要用于预测数值型数据,典型的回归例子:数据拟合曲线。

     

    一、线性回归

     

    (1)线性回归的定义:

     

    线性回归需要一个线性模型,属于监督学习,因此方法和监督学习应该是一样的,先给定一个训练集,根据这个训练集学习出一个线性函数,然后测试这个函数是否足够拟合训练集数据,然后挑选出最好的线性函数。

    需要注意两点:

    A.因为是线性回归,所以学习到的函数为线性函数,即直线函数;

    B.因为是单变量,因此只有一个x;(这里我们只讨论单变量线性回归)

     

    (2)单变量线性回归模型

     

    我们能够给出单变量线性回归模型:

     

     

    这里,X为特征,h(x)为hypothesis。

    举个例子:

    我们想要根据房子的大小,预测房子的价格,给定如下数据集:

     

    我们根据以上的数据集画在图上,如下图所示:

     

    我们需要根据这些点拟合出一条直线,使得costFunction最小。拟合出的直线大概如下图所示:

     

     

    从上面的过程中,我们肯定有一个疑问,怎么样能够看出线性函数拟合的好不好呢?

    答案是我们需要使用到Cost Function(代价函数),代价函数越小,说明我们线性回归的越好,和训练数据拟合的越好。(有关代价函数还请读者自行学习)

     

    二、逻辑回归(Logistic Regression)

     

     

    逻辑回归虽然名字中有“回归”,但实际却是一种分类学习方法,它将数据拟合到一个logit函数或者是logistic函数中,从而能够完成对事件发生的概率进行预测。

     

     (1)逻辑回归出现的背景:

     

    线性回归能对连续值结果进行预测,而现实生活中常见的另一类问题是分类问题。最简单的情况是:是与否的二分类问题。比如说:医生需要需要判断病人是否患癌症,银行要判断一个人的信用程度是否达到可以给他发信用卡的程度,邮件收件箱要自动对邮件分类为正常邮件和垃圾邮件等等。

     

    当然,我们最直接的想法是,既然能够用线性回归预测出连续值的结果,那根据结果设定一个阈值应该可以结果分类问题。事实上,对于很标准的情况,确定是可以的,这里我们套用Andrew Ng老师的课件中的例子,下图中X为数据点肿瘤的大小,Y为观测结果是否是恶性肿瘤。通过构建线性回归模型,如所示,构建线性回归模型后,我们设定一个阈值0.5,预测>=0.5的这些点为恶性肿瘤,而<0.5为良性肿瘤。下图是我们构建的一个线性回归模型,可以很好的把恶性肿瘤和良性肿瘤分隔开。

     

     

    但是在很多实际的情况下,我们需要学习的分类数据并没有这么准确,比如说上面这个肿瘤的例子,如果突然有一个噪点数据出现,如下图所示:

     

    那我们的线性逻辑回归模型,就不那么适用了并且你设定的阈值0.5也就失效了,如下图所示。而在现实生活分类问题的数据中,会比例子中的这个更为复杂,这个时候我们借助线性回归和阈值的方式,已经很难完成一个表现良好的分类器了。

     

     

    在这样的场景下,逻辑回归就诞生了。它的核心思想是,如果线性回归的结果输出是一个连续值,而值的范围是无法限定的,那么我们有没有办法把这个结果映射为可以帮助我们判断的结果呢。而如果输出的结果是(0,1)的一个概率值,那么这个问题就能很清楚的解决了。

     

    (2)逻辑回归基本的知识点:

     

     

    Logistic回归虽然名字里带“回归”,但是它实际上是一种分类方法,主要用于两分类问题(即输出只有两种,分别代表两个类别),所以利用了Logistic函数(或称为Sigmoid函数),函数形式为:

     

     

    我们来画出sigmoid函数图像,如下图所示:

     

     从函数图上可以看出,函数y=g(z)在z=0的时候取值为1/2,而随着z逐渐变小,函数值趋于0,z逐渐变大的同时函数值逐渐趋于1,而这正是一个概率的范围。所以我们定义线性回归的预测函数为Y=WTX,那么逻辑回归的输出Y= g(WTX),其中y=g(z)函数正是上述sigmoid函数(或者简单叫做S形函数)。这就是逻辑回归中的预测输出函数。

     

    有了预测输出函数,我们考虑一下,为什么逻辑回归就能做到分类问题?其实是逻辑回归根据我们的样本点获得这些数据的判定边界。那什么是判定边界呢?你可以简单理解为是用以对不同类别的数据分割的边界,边界的两旁应该是不同类别的数据。我们在二维直角坐标系中,来看看具体的判定边界是什么样子:

    可能是这个样子:

     

    还可能是这个样子:

    或者是这个样子:

     

    我们来思考一个问题:逻辑回归是如何根据样本点获得这些判定边界呢?

    根据sigmoid函数,我们发现:

    当g(z)≥0.5时, z≥0;对于=g(θTX)≥0.5, 则θTX≥0, 此时意味着预估y=1;

    反之,当预测y = 0时,θTX<0;所以我们认为θTX=0是一个决策边界,当它大于0或小于0时,逻辑回归模型分别预测不同的分类结果。

     

    先看第一个例子

    ,其中θ0 ,θ1 ,θ2分别取-3, 1, 1。则当−3+X1+X2≥0时, y = 1; 则X1+X2=3是一个决策边界,图形表示如下,刚好把图上的两类点区分开来:

    上边的例子是一个线性的决策边界,当hθ(x)更复杂的时候,我们可以得到非线性的决策边界,例如:

     

    这时当x12+x22≥1时,我们判定y=1,这时的决策边界是一个圆形,如下图所示:

     

     

    所以我们发现,理论上说,只要我们的设计足够合理,准确的说是g(θTX)中θTX足够复杂,我们能在不同的情形下,拟合出不同的判定边界,从而把不同的样本点分隔开来。

    判定边界详细介绍和项目实践例子:

    线性判定Python实践例子  地址:http://blog.csdn.net/program_developer/article/details/79163466

    非线性判定边界Python实践例子 地址:http://blog.csdn.net/program_developer/article/details/79190616 

     

    (3)逻辑回归的代价函数

     

    对于线性边界的情况,边界形式如下:

     

    构造预测函数为:

    函数的值有特殊的含义,它表示结果取1的概率,因此对于输入x分类结果为类别1和类别0的概率分别为:

     

    下面我们根据(1)式,推导出我们的代价函数

    (1)式综合起来可以写成:

     

    然后取似然函数为:

    因为在同一θ处取得极值,因此我们接着取对数似然函数为:

     

    交叉熵代价函数(cross-entropy)

    最大似然估计就是求使取最大值时的θ,其实这里可以使用梯度上升法求解,求得的θ就是要求的最佳参数。但是,在Andrew Ng的课程中将取为下式,即:

     

    因为乘了一个负的系数-1/m,所以取最小值时的θ为要求的最佳参数。

     

    我们在来看看,梯度下降法求的最小值θ更新过程:

     

     

    最终θ更新过程可以写成:

     

    补充知识点: 

    三、总结

    至此,我们把机器学习中的回归算法知识点进行了一个总结。我们再来总结一下线性回归和逻辑回归的区别和联系:

    (1)Linear Regression: 输出一个标量 wx+b,这个值是连续值,所以可以用来处理回归问题。

    (2)Logistic Regression:把上面的 wx+b 通过 sigmoid函数映射到(0,1)上,并划分一个阈值,大于阈值的分为一类,小于等于分为另一类,可以用来处理二分类问题。

    (3)更进一步:对于N分类问题,则是先得到N组w值不同的 wx+b,然后归一化,比如用 softmax函数,最后变成N个类上的概率,可以处理多分类问题。

    Reference:

    http://blog.csdn.net/han_xiaoyang/article/details/49123419

    http://blog.csdn.net/pakko/article/details/37878837

    分类与回归区别是什么? -穆文的回答 - 知乎

    https://www.zhihu.com/question/21329754/answer/151216012

    coursera上吴恩达《机器学习》第三周课程

     

    展开全文
  • 回归算法

    千次阅读 2020-03-03 00:09:31
    1. 什么是回归算法 回归算法是监督型算法的一种,通过利用测试集数据来建立模型,再利用这个模型训练集中的数据进行处理的算法。线性回归旨在寻找到一根线,这个线到到达所有样本点的距离的和是最小的。常用在预测...
  • 回归分析算法

    千次阅读 2018-10-29 21:21:07
    回归”名词的由来 1889年,英国著名统计学家Francils Galton在研究父代与子代身高之间的关系时发现:身材较高的父母,他们的孩子也较高,但这些孩子的平均身高并没有他们的父母的平均身高高;身材较矮的父母,他们...
  • 一个是想买米10,我想在各个平台发布,希望各位帅哥美女支持一下,多多少少支持一下,另为一个是想将十大经典算法的推导以及思路清清楚楚的理下,希望这整期教程对大家有帮助,第一期咱们讲线性回归。这期不似之前的...
  • ML之回归预测:机器学习中的各种Regression回归算法、关键步骤配图 目录 机器学习中的各种回归算法 1、回归算法代码 2、各种回归算法 3、各种回归算法大PK 机器学习中的各种回归算法 1、回归...
  • logistic回归和回归算法
  • 算法】局部加权回归(Lowess)

    万次阅读 多人点赞 2020-04-19 22:24:00
    一、简介 1.1 预测问题 1.2 平滑问题 二、算法讲解 2.1 算法思想 2.2 参数讲解 2.3 权值函数 ...对于预测问题,回归中最简单的线性回归,是以线性的方法拟合出数据的趋势。但是对于有周期性,波动性的...
  • 机器学习之非线性回归算法(Non-linear Regression)属于有监督的回归(Regression)学习算法。很多场合线性模型无法很好的拟合目标数据曲线,这就需要引入非线性回归模式。非线性回归(Non-linear Regression)算法就是将...
  • 分类&回归算法-随机森林

    万次阅读 2015-11-03 14:46:13
    在得到森林之后,当有一个新的输入样本进入的时候,就让森林中的每一棵决策树分别进行一下判断,看看这个样本应该属于哪一类(对于分类算法),然后看看哪一类被选择最多,就预测这个样本为那一类。 算法思想解释:...
  • ML之回归预测:利用13种机器学习算法对Boston(波士顿房价)数据集【13+1,506】进行回归预测(房价预测)+预测新数据得分 导读 本文章基于前边的一篇文章,对13种机器学习的回归模型性能比较以后,然后利用各个模型对...
  • 【机器学习】非线性回归算法分析

    万次阅读 2018-01-18 08:05:08
    我们上文深入本质了解了机器学习基础线性回归算法后,本文继续研究非线性回归。非线性回归在机器学习中并非热点,并且较为小众,且其应用范畴也不如其他广。鉴于此,我们本文也将较为简单的介绍,并不会深入展开。非...
  • 机器学习算法--逻辑回归原理介绍

    万次阅读 多人点赞 2016-11-13 21:16:54
    本博文针对逻辑回归的原理进行了介绍:逻辑回归就是这样的一个过程:面对一个回归或者分类问题,建立代价函数,然后通过优化方法迭代求解出最优的模型参数,然后测试验证我们这个求解的模型的好坏。Logistic回归虽然...
  • ML之LoR:逻辑回归LoR算法的简介、应用、经典案例之详细攻略 目录 逻辑回归LoR算法的简介 逻辑回归LoR算法的应用 1、逻辑回归可视化 逻辑回归LoR算法的经典案例 逻辑回归LoR算法的简介 逻辑回归最...
  • 3. 回归:有监督学习,学习结果将产生几个函数,通过函数产生连续的结果,数据对象是连续值;   聚类 聚类算法是无监督学习的一种算法,也就是说,并没有一批已经打好标签的数据供机器训练模型。因此该算法用于...
  • 线性回归算法原理及实现

    万次阅读 2018-04-05 16:32:15
    我们来看看最简单的线性回归,基于标准的线性回归,可以扩展出更多的线性回归算法,比如基于核函数的局部加权线性回归,lasso等。希望了解的可以查阅相关的资料。下面来看看最基本的线性回归的原理。根据线性代数,...
  • CART回归算法过程

    千次阅读 2018-10-15 12:27:52
    CART决策树算法是一种分类及回归算法,既可以用于分类,也可以用于回归。但是在李航老师的《统计学习方法》一书中,并没有详细介绍回归树,更多的是介绍分类树,所以有必要对CART回归树进行简单介绍,有利于对CART...
  • 人工智能之机器学习常见算法

    万次阅读 多人点赞 2019-04-11 11:18:17
    摘要之前一直对机器学习很感兴趣,一直没时间去研究,今天刚好是周末,有时间去各大技术论坛看看,刚好看到一篇关于机器学习不错的文章,在这里就分享给大家了....很多时候困惑人们都是,很多算法是一类算法,而有
1 2 3 4 5 ... 20
收藏数 164,195
精华内容 65,678
关键字:

回归算法