机器学习(一)------- 线性回归(Linear regression )

发现网上有很多的原理讲解,其实这个大家都差不多会的,很少有提供代码参考的,我这里python直接实现出来,后面还会实现神经网络,回归树和其他类型的机器学习算法

先来一篇小试牛刀,个人表达能力不是很好,大家见谅

简要说下自己的理解:

训练一个Linear Regression,给定一组特征值([x1,x2,x3,x4,...,xn]) 和 对应的结果 y,目标就是得到一个模型W权重向量

图一

图一表示原始训练数据集(当然训练规模 远比这个大,这里只是图形化理解下)

把图一扩充一列全为1,然后用训练出来的权重w(怎么训练下面会说到)和矩阵相乘可以预测结果,这里是用原数据集和训练出来的w来为以后计算模型的代价,当然给定一组新的数据,你就能用w来预测结果了。

图二用权重计算y值

图三原数据的y值

上图表达的是通用形式

在这个例子中,我们的预测模型就是Hypothesis,未正则化的代价函数J,后面是使用正则化来消除过拟合(什么叫过拟合,举个例子,简单的说就是,在训练集上的表现太好了可以看成100%正确预测训练集,就是你训练的模型,在原数据集上进行,预测结果是100%正确。那么就存在一个问题,本来一些干扰值本身就是干扰项,而你的模型却不能排除,那么在以后的数据集上你就会预测错误。换句话说,你不能很好容错率。我们希望有好的推广能力,而不拘泥于仅仅的训练集)

注意是要同时更新theta所有值

上图中J不能预防过拟合,所以用下图中的公式

我们的目标是要是的J尽量等于0,相当于保证不过你和的情况下,让在数据集犯的错误尽可能的少。

注意观察预测函数的表达形式,theta0的系数为0,为了J的求导的统一形式,所以为X数据集填上一列1

所以上图为我实现的形式,代码为J就是代价函数,注意正则化theta是不包括theta0的(具体理解我是用极限法理解的,如果lambda很大,那么所有的theta都很小,留下theta0才能保证正确,可以这样理解,theta0定义了一个基本调子,类似一个平均水平的意思,然后其他theta进行微调)

<pre name="code" class="python">def countCostFunc(X, y, theta, lamb):
    #X为训练集,y表示训练集上的lable,theta表示权重,lamb是正则常数
    #注意这里的X,theta都经过了扩充,X增加了一列1,theta增加了theta0,这主要是为了向量的统一运算
    m, n = np.shape(X)  #X矩阵行m,列n
    h = np.dot(X,  theta) #举证相乘
    regtheta = np.copy(theta)#深拷贝,因为,python是引用,
    regtheta[0,0] = 0
    J = ((np.dot((h-y).transpose(), (h - y))  +  lamb * np.dot(regtheta.transpose(), regtheta) )/ float(2 * m))
    grad = (1  / float(m)) * (np.dot(X.transpose(),  h-y) +  lamb * regtheta)  #对所有theta求导,这个就是J函数对theta分别求导后,然后变成一个列向量
    return J, grad

#theta多了theta0但是X还没有增加1列,用训练出来的模型,预测结果
def predict(X, theta):
    X = np.array(X)
    m,n = np.shape(X)
    X = np.hstack([np.ones((m, 1)), X]) #为X增加一列1
    h = np.dot(X, theta)
    return h

下面python代码为例子,实现一个完整的Linear Regression,原理通过代码阐述,注意下文中的theta也就是前面说到的w权重

生成简易的数据集,考虑好像简单形象化,并没有使用80M的数据集,而是临时生成简易的数据集。代码如下

一些导入的文件和库,具体说明看后面,python2.7

#coding=utf-8
import numpy as np
import grandDescent
import costFunction
import loadData
import predict
import write2File
import rmse
import os
import random
import matplotlib.pyplot as plt
from pylab import plot,show
from scipy import stats

生成数据集 横轴为X,纵坐标为y

def handle_data_self():
    X_train = np.array([0,1,2,3,4,5,6,7,8,9]).reshape(10, 1)
    y_train = np.array([0,2,3,4,5,6,7,4,9,10]).reshape(10, 1)
    X_cross = np.copy(X_train)
    y_cross = np.copy(y_train)
    X_test = np.array([0,1,2,3,4,5,6,7,8,9, 10,11,23,1]).reshape(14,1)
    plt.scatter(X_train, y_train, color="Red")
    # plt.show()
    return X_train,y_train,X_cross,y_cross,X_test

最后贴出主程序如下main.py

<pre name="code" class="python">#coding=utf-8
import numpy as np  #系统库
import grandDescent
import costFunction
import loadData
import predict
import write2File
import rmse
import os  #库
import random #库
import matplotlib.pyplot as plt #库

def regression_simple(X, y, X1, y1, option):
    alpha = float(option["alpha"])
    maxCycles = int(option["maxCycle"])
    lamb = float(option["lamb"])
    save = bool(option["saveRecord"])
    add = bool(option["add"])
    optGoal = option["optGoal"]
    methods = option["method"]
    thetaPath = option["thetaWritePath"] if option.has_key("thetaWritePath") else None
    m,n = np.shape(X)
    J_train = None
    theta = None
    if methods == "stocGradDescent":
        J_train, theta = grandDescent.stocGradDescent(np.copy(X), y, maxCycles, alpha, lamb)
    elif methods == "grandDescent":
        J_train, theta = grandDescent.grandDescent(np.copy(X),  y, maxCycles, alpha, lamb)
    J_cross = costFunction.countCostFunc(np.hstack([np.ones((X1.shape[0], 1)), X1]), y1, theta, lamb)
    rmseResult = rmse.countrmse(np.copy(X1),y1,theta) #后面都是保存一些东西
    if save and thetaPath:
        if not add and os.path.exists(thetaPath):
            os.remove(thetaPath)
        file_object = None
        if not add:
            file_object = open(thetaPath, 'w')
        elif os.path.exists(thetaPath):
            file_object = open(thetaPath, 'a')
        else:
            file_object = open(thetaPath, 'w')
        file_object.write("J_traincost=>"+ str(J_train) + ",J_crosscost=>" + str(J_cross[0]) +  ",alpha=>" + str(alpha) + ",lamb=>" +  str(lamb) + ", Cycles=>"+ str(maxCycles) + ", rmse=>" + str(rmseResult) + "\n" + ",theata==>"+str(theta.transpose()) + "\n")
        file_object.close()
    J = None
    if optGoal == "J_train":
        J = J_train
    elif optGoal == "J_cross":
        J = J_cross
    elif optGoal == "rmse":
        J = rmseResult
    else:
        print "optGoal fault!!!"
    return J, theta

def handle_data_self():
    X_train = np.array([0,1,2,3,4,5,6,7,8,9]).reshape(10, 1)
    y_train = np.array([0,2,3,4,5,6,7,4,9,10]).reshape(10, 1)
    X_cross = np.copy(X_train)
    y_cross = np.copy(y_train)
    X_test = np.array([0,1,2,3,4,5,6,7,8,9, 10,11,23,1]).reshape(14,1)
    plt.scatter(X_train, y_train, color="Red")
    plt.show()
    return X_train,y_train,X_cross,y_cross,X_test

if __name__ == "__main__":
    print "load data..."
    X_train, y_train, X_cross, y_cross, X_test = handle_data_self()
    print "load data finished"
    print "进入traing..."
    action = "regression_grandDescent"
    J = None
    theta = None
    if action == "regression_grandDescent":
        option = {"maxCycle": 400, "alpha": 0.05, "lamb": 0.001, "saveRecord": 1,
                  "thetaWritePath": "./thetaSave.txt", "add":1, "optGoal":"J_train",
                  "method": "grandDescent"}
        J, theta = regression_simple(X_train.copy(), y_train.copy(), X_cross.copy(), y_cross.copy(), option)
        plt.plot(X_train, predict.predict(X_train, theta), color="Green")
        plt.show()

    print "完成traing"

    if action == "regression_grandDescent" or action == "regression_grandDescentWithBestAlphaAndLamb" or action == "regression_stocGradDescent":
        y_pre = predict.predict(X_test, theta)
        write2File.savePrediction(y_pre, path="sample_submission.csv")
    print "预测完毕","保存结果至sample_submission.csv"



其中
X_train, y_train, X_cross, y_cross, X_test = handle_data_self()

这里分别是,原始数据集X,原始数据集y,交叉验证集X,交叉验证y,检测集X

原始数据集X:就是给你的训练样本的特征值,注意这里还没添加X0为一,后面会在其他地方加上,为什么要加一列,是为了统一后面的导数计算,


grandDescent.py文件
<pre name="code" class="python">#coding=utf-8

import numpy as np
import operator
import copy
import math
import costFunction

def grandDescent(X, y, maxCycles, alpha, lamb):
    m,n = np.shape(X)
    theta = np.zeros((n + 1, 1))
    X = np.hstack([np.ones((m,1)), X])
    J = 0
    for i in range(maxCycles):
        J, grad = costFunction.countCostFunc(np.copy(X), y, np.copy(theta), lamb)
        #print "J的第",i+1,"次==>" ,J
        theta = theta - alpha * grad
    return J, theta

costFunction.py文件
<pre name="code" class="python">#coding=utf-8

import numpy as np
import operator
import copy
import math

def countCostFunc(X, y, theta, lamb):
    m, n = np.shape(X)
    h = np.dot(X,  theta)
    regtheta = np.copy(theta)
    regtheta[0,0] = 0
    J = ((np.dot((h-y).transpose(), (h - y))  +  lamb * np.dot(regtheta.transpose(), regtheta) )/ float(2 * m))
    grad = (1  / float(m)) * (np.dot(X.transpose(),  h-y) +  lamb * regtheta)
    return J, grad

rmse.py 文件
#coding=utf-8

import numpy as np
import operator
import copy
import math
import costFunction

def countrmse(X, y, theta):
    m,n = np.shape(X)
    theta = theta
    #扩展1
    X = np.hstack([np.ones((m,1)), X])
    h = np.dot(X , theta)
    #按列求和
    sumDiffY = np.dot((h - y).transpose(), (h - y))
    J = sumDiffY / float(m)
    #print np.shape(J)
    return math.sqrt(J)
predict.py文件
#coding=utf-8
import numpy as np
import costFunction

#theta多了theta0但是X还没有增加1列
def predict(X, theta):
    X = np.array(X)
    m,n = np.shape(X)
    X = np.hstack([np.ones((m, 1)), X])
    h = np.dot(X, theta)
    return h

write2File.py文件

def savePrediction(y_pre, path):
    file_object = open(path, 'w')
    file_object.write("Id,reference\n")
    for i in range(len(y_pre)):
        file_object.write(str(i) + "," + str(y_pre[i][0]) + "\n")






最红结果如下:红点表示预测原来的数据集,绿色的线表示用训练出来的额theta计算的结果

本文主要是用python,采用梯度下降的方法实现了正则化的Linear Regression

总结一些重要的地方,

1我这里没进行数据的预处理,因为各个特征值得数量级要保持一样。有两种方法,

第一种一般会采用把所有的数据集的变为均值为0,方差为1(x= (x - 这一列均值)/这一列标准差 )

第二种变为-0.5到+0.5之间(x=(x-min)/(max-min) 对每列求得最小值和最大值,然后对每个值这样处理),

2.增加数据集一列1,theta增加theta0,是为了能统一计算梯度,而不用对theta0特殊计算

3.除了梯度下降(小规模数据)

还有随机梯度下降(适合大规模数据,比如上G的量,未演示出来,如果需要,后面会给出)

采用线性代数直接求X*theat = y的方法( 这种方法有特定条件限制,一般不采用),下图解决不可逆问题,但是由于矩阵求逆在矩阵很大的时候,计算误差很大,所以一般不采用

4正则化是使用的L2平方,这样好计算导数, 还有更好的L1,采用绝对值,效果更好 但是不好计算导数,所以这里没涉及

5这里只是两个theta0和theta1, 略微大一点都有上万的,预测值都是采用线性加权的方法

6另外关键的是,alpha和lambda的设定,都是经验值,alpha

一般你可是尝试一下组合

alphas = [0.1, 0.05, 0.01, 0.005, 0.001, 0.0005, 0.0001]
maxCycles = 200
lambs = [100,10,1,0.1,0.01, 0.001]

7并行化处理还没涉及,因为工业化必要分布式的,在有限的时间中训练出来,线性模型简单,预测速度快,仍然是一个主流算法

时间: 2024-10-09 00:27:43

机器学习(一)------- 线性回归(Linear regression )的相关文章

Stanford机器学习---第二讲. 多变量线性回归 Linear Regression with multiple variable

原文:http://blog.csdn.net/abcjennifer/article/details/7700772 本栏目(Machine learning)包括单参数的线性回归.多参数的线性回归.Octave Tutorial.Logistic Regression.Regularization.神经网络.机器学习系统设计.SVM(Support Vector Machines 支持向量机).聚类.降维.异常检测.大规模机器学习等章节.所有内容均来自Standford公开课machine

机器学习 Machine Learning(by Andrew Ng)----第二章 单变量线性回归(Linear Regression with One Variable)

第二章 单变量线性回归(Linear Regression with One Variable) <模型表示(Model Representation)>                                                             <代价函数(Cost Function)>                                                          <梯度下降(Gradient Descent)

机器学习 (一) 单变量线性回归 Linear Regression with One Variable

文章内容均来自斯坦福大学的Andrew Ng教授讲解的Machine Learning课程,本文是针对该课程的个人学习笔记,如有疏漏,请以原课程所讲述内容为准.感谢博主Rachel Zhang和 JerryLead 的个人笔记,为我做个人学习笔记提供了很好的参考和榜样. § 1.  单变量线性回归 Linear Regression with One Variable 1. 代价函数Cost Function 在单变量线性回归中,已知有一个训练集有一些关于x.y的数据(如×所示),当我们的预测值

机器学习笔记01:线性回归(Linear Regression)和梯度下降(Gradient Decent)

最近在Coursera上看吴大神的Machine Learning,感觉讲的真的很棒.所以觉得应该要好好做做笔记,一方面是加强自己对ML中一些方法的掌握程度和理解,另一方面也能方便自己或者同样爱好ML的同学. 线性回归(Linear Regression) 线性回归(Linear Regression)应该是机器学习中最基本的东西了.所谓回归,想必大家在高中时期的课程里面就接触过,给定一系列离散的点(x0,y0),求一条直线 f(x)=ax+b 以使得最小.在machine learning 中

Stanford公开课机器学习---2.单变量线性回归(Linear Regression with One Variable)

单变量线性回归(Linear Regression with One Variable) 2.1 模型表达(Model Representation) m 代表训练集中实例的数量 x 代表特征/输入变量 y 代表目标变量/输出变量 (x,y) 代表训练集中的实例 (x(i),y(i) ) 代表第 i 个观察实例 h 代表学习算法的解决方案或函数也称为假设(hypothesis) 单变量线性回归:只含有一个特征/输入变量 x hθ=θ0+θ1x 2.2 代价函数(Cost Function) 目标

机器学习方法(一):线性回归Linear regression

开一个机器学习方法科普系列,也做基础回顾之用.学而时习之. content: linear regression, Ridge, Lasso Logistic Regression, Softmax Kmeans, GMM, EM, Spectral Clustering Dimensionality Reduction: PCA.LDA.Laplacian Eigenmap. LLE. Isomap(修改前面的blog) SVM C3.C4.5 Apriori,FP PageRank minH

机器学习方法:回归(一):线性回归Linear regression

开一个机器学习方法科普系列:做基础回想之用.学而时习之:也拿出来与大家分享.数学水平有限,仅仅求易懂,学习与工作够用.周期会比較长.由于我还想写一些其它的,呵呵. content: linear regression, Ridge, Lasso Logistic Regression, Softmax Kmeans, GMM, EM, Spectral Clustering Dimensionality Reduction: PCA.LDA.Laplacian Eigenmap. LLE. Is

Ng第二课:单变量线性回归(Linear Regression with One Variable)

二.单变量线性回归(Linear Regression with One Variable) 2.1  模型表示 2.2  代价函数 2.3  代价函数的直观理解 2.4  梯度下降 2.5  梯度下降的直观理解 2.6  梯度下降的线性回归 2.7  接下来的内容 2.1  模型表示 之前的房屋交易问题为例,假使我们回归问题的训练集(Training Set)如下表所示: 我们将要用来描述这个回归问题的标记如下: m                代表训练集中实例的数量 x          

多元线性回归(Linear Regression with multiple variables)与最小二乘(least squat)

1.线性回归介绍 X指训练数据的feature,beta指待估计得参数. 详细见http://zh.wikipedia.org/wiki/%E4%B8%80%E8%88%AC%E7%BA%BF%E6%80%A7%E6%A8%A1%E5%9E%8B 使用最小二乘法拟合的普通线性回归是数据建模的基本方法. 令最小二乘项的偏导为0(为0时RSS项最小),求Beta估计值,得到最小二乘的向量形式. 最小二乘其实就是找出一组参数beta使得训练数据到拟合出的数据的欧式距离最小.如下图所示,使所有红点(训练

Machine_learning_cs229线性回归 Linear regression(2)

这篇博客针对的AndrewNg在公开课中未讲到的,线性回归梯度下降的学习率进行讨论,并且结合例子讨论梯度下降初值的问题. 线性回归梯度下降中的学习率 上一篇博客中我们推导了线性回归,并且用梯度下降来求解线性回归中的参数.但是我们并没有考虑到学习率的问题. 我们还是沿用之前对于线性回归形象的理解:你站在山顶,环顾四周,寻找一个下山最快的方向走一小步,然后再次环顾四周寻找一个下山最快的方向走一小步,在多次迭代之后就会走到最低点.那么在这个理解中,学习率其实是什么呢?学习率就是你走的步子有多长. 所以