机器学习篇(2)——最小二乘法

作者: 飘涯 | 来源:发表于2018-03-05 20:56 被阅读118次

    前言:主要介绍了从最小二乘法到

    • 概念

    顾名思义,线性模型就是可以用线性组合进行预测的函数,如图:

    image.png
    公式如下:
    image.png
    image.png
    误差是独立同分布的,服从均值为0,方差为某定值s2的高斯分布。
    原因:中心极限定理
    实际问题中,很多随机现象可以看做众多因素的独立影响的综合反应,往往服从正态分布
    写出损失函数:
    image.png
    求解:
    image.png
    求得的杰刚好和线性代数中的解相同
    • 最小二乘法

    用投影矩阵可以解决线代中方程组无解的方法就是最小二乘法,其解和上述解一样

    image.png
    例子:用最小二乘法预测家用功率和电流之间的关系
    数据来源:http://archive.ics.uci.edu/ml/datasets/Individual+household+electric+power+consumption
    代码如下:
    from sklearn.model_selection import train_test_split
    import numpy as np
    import pandas as pd
    from pandas import DataFrame
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    import time
    #防止中文乱码
    mpl.rcParams['font.sans-serif']=[u'simHei']
    mpl.rcParams['axes.unicode_minus']=False
    #加载数据
    path = "household_power_consumption_1000.txt"
    df = pd.read_csv(path,sep=";",low_memory=False)
    
    #功率和电流之间的关系
    X = df.iloc[:,2:4]
    Y = df.iloc[:,5]
    #数据集划分两个参数test_size表示怎么划分,random_state固定随机种子类似于在执行random模块时候,给一个随机种子random.seed(0),之后每次运行的随机数不会改变
    x_train,x_test,y_train,y_test=train_test_split(X,Y,test_size=0.2,random_state=0)
    #转化为矩阵形式,进行最小二乘法运算,即矩阵的运算
    x1 = np.mat(x_train)
    y1 = np.mat(y_train).reshape(-1,1)#转化为一列-1表示一后面1列为标准
    #带入最小二乘公式求θ
    theat = (x1.T*x1).I*x1.T*y1
    print(theat)
    #对测试集进行训练
    y_hat = np.mat(x_test)*theat
    #画图看看,预测值和实际值比较200个预测值之间的比较
    t = np.arange(len(x_test))
    plt.figure()
    plt.plot(t,y_test,"r-",label=u'真实值')
    plt.plot(t,y_hat,"g-",label=u'预测值')
    # plt.legend(loc = 'lower right')
    plt.title(u"线性回归预测功率与电流之间的关系", fontsize=20)
    plt.grid(b=True)
    plt.show()
    

    输出结果:θ=[[4.20324605], [1.36676171]]
    预测结果:


    image.png

    其中”from sklearn.model_selection import train_test_split“中的数据划分模块可以用底层代码实现,实现如下:

    import random
    import csv
    def loadDataset(fileName,split,trainingSet=[],textSet=[]):
        with open(fileName, "r") as f:
            reader = csv.reader(f)
            data = list(reader)
            for x in range(len(data) - 1):
                for y in range(4):
                    data[x][y] = float(data[x][y])
                if random.random() < split:
                    trainingSet.append(data[x])
                else:
                    textSet.append(data[x])
            return trainingSet,textSet
    trainingSet,textSet=loadDataset("irisdata.csv",0.7)
    print(trainingSet)
    print(textSet)
    

    调用sklearn实现代码如下:

    from sklearn.model_selection import train_test_split
    from sklearn.linear_model import LinearRegression
    from sklearn.preprocessing import StandardScaler
    import numpy as np
    import pandas as pd
    from pandas import DataFrame
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    import time
    #加载数据
    path="household_power_consumption_1000.txt"
    df = pd.read_csv(path,sep=";")
    #数据处理,包括,清除空数据
    df1=df.replace("?",np.nan)
    data = df1.dropna(axis=0,how="any")
    #把数据中的字符串转化为数字
    def data_formate(x):
        t = time.strptime(' '.join(x), '%d/%m/%Y %H:%M:%S')
        return (t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec)
    X = data.iloc[:,0:2]
    x = X.apply(lambda x:pd.Series(data_formate(x)),axis=1)
    y = data.iloc[:,4]
    #数据分集
    x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=0)
    #标准化
    ss = StandardScaler()
    x_train=ss.fit_transform(x_train)
    x_test=ss.transform(x_test)
    #模型训练
    lr = LinearRegression()
    lr.fit(x_train,y_train)
    y_pridect=lr.predict(x_test)
    #输出参数
    print("模型的系数(θ):",lr.coef_)
    print("模型的截距:",lr.intercept_)
    print("训练集上R2:",lr.score(x_train, y_train))
    print("测试集上R2:",lr.score(x_test, y_test))
    mse = np.average((y_pridect-y_test)**2)
    rmse = np.sqrt(mse)
    print("rmse:",rmse)
    #画图
    t=np.arange(len(y_test))
    plt.figure(facecolor='w')#建一个画布,facecolor是背景色
    plt.plot(t, y_test, 'r-', linewidth=2, label='真实值')
    plt.plot(t, y_pridect, 'g-', linewidth=2, label='预测值')
    plt.legend(loc = 'upper left')#显示图例,设置图例的位置
    plt.title("线性回归预测时间和功率之间的关系", fontsize=20)
    plt.grid(b=True)#加网格
    plt.show()
    

    注意: LinearRegression返回的参数,有θ,截距,正确率,以及rmse
    数据一般需要标准化,用StandardScaler
    结果如下:模型的系数(θ): [ 0.00000000e+00 8.88178420e-16 -6.08846044e+00 -4.01611493e+00
    -4.41741494e-01 0.00000000e+00]
    模型的截距: 10.463250000000013
    训练集上R2: 0.2648347024910076
    测试集上R2: 0.13627227933073027
    rmse: 4.766714115205903


    image.png

    关于R2的概念,他是衡量数据集是否为线性的依据。叫判定系数、拟合优度,决定系数。
    参数解释的原文如下:

    The coefficient R^2 is defined as (1 - u/v), where u is the regression sum of squares ((y_true - y_pred) ** 2).sum() and v is the residual sum of squares ((y_true - y_true.mean()) ** 2).sum().


    image.png

    模型模拟的越好,越接近于一

    相关文章

      网友评论

        本文标题:机器学习篇(2)——最小二乘法

        本文链接:https://www.haomeiwen.com/subject/uaiqfftx.html