数据分析与机器学习之线性回归与逻辑回归(六)

一 机器学习分类

  • 有监督学习

    1 概述: 主要用于决策支持,它利用有标识的历史数据进行训练,以实现对新数据的表示的预测

    2 分类: 分类计数预测的数据对象是离散的。如短信是否为垃圾短信,用户是否喜欢电子产品

    ​ 比如: K近邻、朴素贝叶斯、决策树、SVM

    3 回归: 回归技术预测的数据对象是连续值, 例如温度变化或时间变化。包括一元回归和多元回

    ​ 归,线性回归和非线性回归: 例如 线性回归、逻辑回归、岭回归

  • 无监督学习

    1 概述: 数据无标识, 主要用于知识发现,在历史数据中发现隐藏的模式或内在结构

    2 聚类: 聚类算法用于在数据中寻找隐藏的模式或分组。例如: K-means

  • 半监督学习

    1 概述: 在半监督学习方式下,训练数据有部分被标识部分没有被标识,这种模型首先需要学习数据的内在结构,以便合理的组织数据来进行预测。算法上,包括一些对常用监督式学习算法的延伸,这些算法首先试图对未标识数据进行建模,在此基础上再对标识的数据进行预测

二 线性回归数学原理

\[\theta^T: 特征权重的转置, \theta原本表示一维列矩阵,转置为一维行矩阵,X是一维列矩阵,此时\theta^T x代表行乘列的数值 \]

回归问题误差原理及公式推导

\[\theta^Tx^{(i)} 表示预测值, y^{(i)}表示真实值,两者之间存在误差\epsilon^{(i)} \]

\[L(\theta) 似然函数: \theta^Tx^{(i)}要想越接近与y^{(i)},代表求和概率P应该越大越好 \]

矩阵求导过程省略,公式太多,都是笔记本上推导的

线性回归代码实现原理

#导包
import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets  #导入数据集
%matplotlib inline

构造线性回归类

#构造类
class LinearRegression():
    #初始化
    def __init__(self):
        self.w = None
    
    #进行训练
    def fit(self,X,y):
        print(X.shape)  #(422, 1)
        X = np.insert(X,0,1,axis=1)  #在列中新增x0 = 1的操作类似插入数据
        print(X.shape)  #(422, 2)
        print(X)
        X_ = np.linalg.inv(X.T.dot(X)) #x的转置dot(x)再取逆操作 
        self.w = X_.dot(X.T).dot(y) #再dot(x的转置)dot(y)
        
    #进行预测
    def predict(self,X):
        X = np.insert(X,0,1,axis=1)
        y_pred = X.dot(self.w)
        return y_pred

预测值与测试值平方求均值

#将预测与预测值power2次方
def mean_squared_error(y_true,y_pred):
    mse = np.mean(np.power(y_true-y_pred,2))
    return mse

主函数执行

def main():
    #生成训练/测试数据
    diabetes = datasets.load_diabetes()
    X = diabetes.data[:,np.newaxis,2]
    print(X.shape)  #(442, 1)
    x_train,x_test = X[:-20],X[-20:]
    y_train,y_test = diabetes.target[:-20],diabetes.target[-20:]
    
    #线性回归数据导入:训练 预测
    clf = LinearRegression()
    clf.fit(x_train,y_train)
    y_pred = clf.predict(x_test)
    print(mean_squared_error(y_test,y_pred))
    
    #绘制图形
    plt.scatter(x_test[:,0],y_test,color='black')
    plt.plot(x_test[:,0],y_pred,color='blue',linewidth=3)
    plt.show()

三 逻辑斯蒂回归

逻辑斯蒂原理代码

import matplotlib.pyplot as plt
import pandas as pd
pga = pd.read_csv('../Desktop/pga.csv')

#数据标准归一化处理
pga.distance = (pga.distance - pga.distance.mean()) / pga.distance.std()
pga.accuracy = (pga.accuracy - pga.accuracy.mean()) / pga.accuracy.std()
pga.head()

plt.scatter(pga.distance,pga.accuracy)
plt.xlabel('distance')
plt.ylabel('accurancy')
plt.show()

目标函数的构建

\[h_\theta(x) = \theta x + \theta_0 预测函数 \]

#目标函数(损失函数)
def cost(theta0,theta1,x,y):
    J=0
    m = len(x)
    for i in range(m):
        h = theta1*x[i] + theta0  #对应公式 h(x)值
        J += (h-y[i])**2  #目标函数 J = (h(x) - y)**2
    J /= (2*m)
    return J
print(cost(0,1,pga.distance,pga.accuracy))  #1.599438422599817

theta0 = 100
theta1s = np.linspace(-3,2,100)
costs = []
for theta1 in theta1s:
    costs.append(cost(theta0,theta1,pga.distance,pga.accuracy))
print(theta1s.shape)  #(100,)
plt.plot(theta1s,costs)
plt.show()

接下里我们采用梯度下降法原理解析这类问题

#梯度下降解决问题
import numpy as np
from mpl_toolkits.mplot3d.axes3d import Axes3D  #导入3D包
import matplotlib.pyplot as plt
%matplotlib inline

theta0s = np.linspace(-2,2,100)
theta1s = np.linspace(-2,2,100)
COST = np.empty(shape=(100,100))  #空白填充(100,100)的数组
print(COST.shape)  #(100, 100)

TOS,TIS = np.meshgrid(theta0s,theta1s)
print(TOS.shape,TIS.shape)  #  (100, 100) (100, 100)

#将标准归一化的数据替换新的数组并绘制
for i in range(100):
    for j in range(100):
        COST[i,j] = cost(TOS[0,i],TIS[j,0],pga.distance,pga.accuracy)
print(COST.shape)  #(100, 100)

fig2 = plt.figure()
ax = fig2.gca(projection='3d')
ax.plot_surface(X=TOS,Y=TIS,Z=COST)
plt.show()

#梯度下降实现原理:  对theta1与theta0进行求偏导值
#对theta1值进行求偏导值
def partial_cost_theta1(theta0,theta1,x,y):
    h = theta0 + theta1*x  #预测函数
    diff = (h-y) *x   # 对theta1进行求偏导  (h(x) - y) * x
    partial = diff.sum()/(x.shape[0])  #进行求和并除以样本数量
    return partial
partial1 = partial_cost_theta1(0,5,pga.distance,pga.accuracy)
print(partial1)

#对theta0进行求偏导值
def partial_cost_theta0(theta0,theta1,x,y):
    h = theta0 + theta1*x   #预测函数
    diff = (h-y)      #对theta0求偏导  (h(x) - y)
    partial = diff.sum() / (x.shape[0])  #进行求和并除以样本数量
    return partial

partial0 = partial_cost_theta0(1,1,pga.distance,pga.accuracy)
print(partial0)

#输出
5.5791338540719
1.0000000000000104

使用梯度下降迭代更新值

#梯度下降迭代更新值  alpha=0.1代表默认步长
def gradient_descent(x,y,alpha=0.1,theta0=0,theta1=0):
    max_epochs = 1000   #迭代次数1000  
    counter = 0
    c = cost(theta1,theta0,pga.distance,pga.accuracy)
    costs = [c]
    convergence_thres = 0.00001  #定义下降趋势设置临界值精度
    cprev = c+ 10
    theta0s = [theta0]
    theta1s = [theta1]
    #判断目标函数值大于临界精度或者小于迭代次数,继续迭代
    while (np.abs(cprev-c) > convergence_thres) and (counter < max_epochs):
        cprev = c
        update0 = alpha*partial_cost_theta0(theta0,theta1,x,y)  #alpha乘以 theta0求的偏导值
        update1 = alpha*partial_cost_theta1(theta0,theta1,x,y)  #alpha乘以 theta1求的偏导值
        #更新theta值,梯度下降
        theta0 -= update0
        theta1 -= update1
        #添加到列表中
        theta0s.append(theta0)
        theta1s.append(theta1)
        #计算新的cost值
        c = cost(theta0,theta1,pga.distance,pga.accuracy)
        costs.append(c)
        counter += 1
    return {'theta0':theta0,'theta1':theta1,'costs':costs}

#实现当迭代次数越多,计算的目标函数cost值越低并趋于平缓,从而实现找到目标函数趋近的最低值
print('theta1=',gradient_descent(pga.distance,pga.accuracy)['theta1'])
descend = gradient_descent(pga.distance,pga.accuracy,alpha=0.01)
plt.scatter(range(len(descend['costs'])),descend['costs'])
plt.xlabel('costs_len')
plt.ylabel('costs')
plt.show()

#输出
theta1= -0.5984131176478865

posted @ 2018-07-23 14:49  诚实善良小郎君  阅读(922)  评论(0编辑  收藏  举报