机器学习2---线性模型

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/aBIT_Tu/article/details/82228850

LDA的代码可参见:https://blog.csdn.net/yt71656/article/details/45199603

来补充代码,萌新写的,也没有经过整理,只是为了熟悉思路,大神轻喷。

线性回归,python3。使用的数据是吴恩达的机器学习数据。

import numpy as np
import matplotlib.pyplot as plt

A = np.zeros((97,2),dtype=float)    #先创建一个 3x3的全零方阵A,并且数据的类型设置为float浮点型
 
f = open('\ex1data1.txt')               #打开数据文件文件
lines = f.readlines()           #把全部数据文件读到一个列表lines中
A_row = 0                       #表示矩阵的行,从0行开始
for line in lines:              #把lines中的数据逐行读取出来
    list = line.strip('\n').split(' ')      #处理逐行数据:strip表示把头尾的'\n'去掉,split表示以空格来分割行数据,然后把处理后的行数据返回到list列表中
    A[A_row:] = list[0:2]                    #把处理后的数据放到方阵A中。list[0:3]表示列表的0,1,2列数据放到矩阵A中的A_row行
    A_row+=1                                #然后方阵A的下一行接着读

x=A[:,0]
y=A[:,1]



# y = th1 + th2*x
th1=0
th2=1
N=20

m=len(A)
rl=0.02
sumt=[]  # 记录代价函数取值
for i in range(N):    ## 优化10次
    sum=0
    sum1=0
    sum2=0
    for j in range(m):
        sum1=sum1+th1+th2*x[j]-y[j]   # th1
        sum2=sum2+(th1+th2*x[j]-y[j])*x[j]   # th2
        sum=sum+(th1+th2*x[j]-y[j])**2
    if (sum/m)<0.1:
        break
    sumt.append(sum/m)
        
    sum1=sum1/m
    sum2=sum2/m
    th1=th1-rl*sum1
    th2=th2-rl*sum2
    
print(th1,'+',th2,'x')

#绘制散点图,examDf.jt为X轴,examDf.hk为Y轴
plt.scatter(x,y,color = 'darkgreen',label = "Exam Data")
 
#添加图的标签(x轴,y轴)
plt.xlabel("x")#设置X轴标签
plt.ylabel("y")#设置Y轴标签

x1 = np.linspace(0, 25, 100)
y1 = th1+th2*x1
plt.plot(x1, y1, color="blue")
plt.show()#显示图像

plt.xlabel("n")#设置X轴标签  次数
plt.ylabel("J")#设置Y轴标签  代价函数
N1 = np.linspace(0, N, N)
plt.plot(N1, sumt, color="blue")
plt.show()#显示图像

运行结果:

中间的蓝色直线是拟合直线,其实看起来不太好,毕竟也只跑了20次。

代价函数的一个图像,横坐标是学习次数,可以看到是下降趋势。

小tips:

(1)一定要动手啊~

(2)有时候其实不是算法思路的问题,也不是代码的问题(简洁性、优美之类的除外),就是取值的问题,多看看大神的代码真的有帮助。

多元线性回归分析的代码,数据是自己做的(3个输入变量,一个输出变量),这次是基于向量的思想在写程序,比之前用循环的程序能简洁些,哈哈哈~

# -*- coding: utf-8 -*-
"""
Created on Thu Nov  1 15:10:44 2018

@author: user
"""

import numpy as np
import matplotlib.pyplot as plt

# 生成随机数
x=np.random.random([1,100])*5

x0=np.ones([1,100])
x1=x
x2=np.multiply(x,x)    # 矩阵元素做点乘
x3=np.multiply(x2,x)
x1=x1+np.random.random([1,100])-0.5
x2=x2+np.random.random([1,100])-0.5
x3=x3+np.random.random([1,100])-0.5
X=np.vstack((x0,x1,x2,x3))   # 按列合并,即将矩阵直接放在下面;np.hstack是按行合并
y=2*x0+3*x1+4*x2+5*x3    # m=100, n=3


# 求解 y=th0+th1*x1+th2*x2+th3*x3 中的参数th

# 初始化 
m=100 # 100个样本
n=3  # 3个输入变量(特征)
ths=np.array([0,1,0,1]).reshape([4,1])
lr=0.00065
N=50  # 迭代次数
Co=[]
T=np.zeros([n+1,1])

# 梯度下降法训练参数
for iter in range(N):
    cost=0
    for j in range(n+1):
        mm=X[j,:]
        mm=np.mat(mm)
        a=np.dot(ths.T,X)   # 矩阵做乘法
        b=np.dot(a,mm.T)
        c=np.dot(y,mm.T)
        T[j,0]=b-c
    ths=ths-lr*T/m
    for i in range(m):
        a=np.dot(ths.T,np.mat(X[:,i]).T)
        cost=cost+(a[0,0]-y[0,i])**2 
    Co.append(cost)
    
plt.xlabel("n")#设置X轴标签  次数
plt.ylabel("J")#设置Y轴标签  代价函数
N1 = np.linspace(0, N, N)
plt.plot(N1, Co, color="blue")
plt.show()#显示图像
    
    

运行的代价函数结果:

感觉这个结果很佛性。。。其实参数结果还可以,设置初始值是个大学问。。。

小tip:

(1)矩阵的乘法要分清楚:*和dot() 不一样。

(2)变量命名要看清楚,这个当时调了好久,后来发现是名字重复了。。。。。当时的心情,本来想去吃饭的。。。

(3)正则化,下次可以用上。

罗杰斯特回归

两个代码,后期会修改比对:

import numpy as np
import math
import matplotlib.pyplot as plt

# 读入数据
A = np.zeros((100,3),dtype=float)    
 
f = open('。。。')               #打开数据文件文件
lines = f.readlines()           #把全部数据文件读到一个列表lines中
A_row = 0                       #表示矩阵的行,从0行开始
for line in lines:              #把lines中的数据逐行读取出来
    list = line.strip('\n').split(' ')      #处理逐行数据:strip表示把头尾的'\n'去掉,split表示以空格来分割行数据,然后把处理后的行数据返回到list列表中
    A[A_row:] = list[0:3]                    #把处理后的数据放到方阵A中。list[0:3]表示列表的0,1,2列数据放到矩阵A中的A_row行
    A_row+=1                                #然后方阵A的下一行接着读

x=A[:,0:2]
y=A[:,2]
x=np.mat(x)
x=x.T
y=np.mat(y)
y=y.T


# 初始化参数
ths=np.array([1,1],dtype=float)
ths=np.mat(ths).T
m=len(y)
N=10
lr=0.001
J=[]

def mysigmoid(x):      
    h=1/(1+np.vectorize(math.exp)(-x))
    return h

# 训练参数
for it in range(N):
    sum1= np.vectorize(math.log)(mysigmoid(-ths.T*x))*y+np.vectorize(math.log)(1-mysigmoid(-ths.T*x))*(1-y)
    temp= mysigmoid(-ths.T*x)
    sum2= x* (temp.T-y)
    J.append(-sum1[0,0]/m)
    dths= sum2/m
    ths=ths-lr*dths
    
plt.xlabel("n")#设置X轴标签  次数
plt.ylabel("J")#设置Y轴标签  代价函数
N1 = np.linspace(0, N, N)
plt.plot(N1, J, color="blue")
plt.show()#显示图像


H=mysigmoid(-ths.T*x)

# -*- coding: utf-8 -*-
"""
Created on Mon Nov  5 17:16:00 2018

@author: user
"""

import numpy as np
 
 
class LogisticRegression:
    """
    Logistic Regression:逻辑回归
    Author:CommissarMa
    """
 
    def __init__(self, m, n, X, y, alpha, iterThreshold):
        """
        构造函数:初始化成员变量
        :param m: 记录数量(int)
        :param n: 特征数量(int)
        :param X: 记录矩阵(n*m)(float)
        :param y: 类别向量(1*m)(取值范围:0或1)
        :param alpha: 更新速率(float)
        :param iterThreshold: 梯度下降迭代停止条件(float)
        :var w: 参数向量(n*1)(float)
        :var b: 参数(float)
        """
        self.m = m
        self.n = n
        self.X = X
        self.y = y
        self.alpha = alpha
        self.iterThreshold = iterThreshold
        self.w = np.ones((n, 1))
        self.b = 0
        return
 
    def train(self):
        """
        训练:使用数据进行训练,使用梯度下降进行迭代使得损失值不断下降直到小于设定的迭代停止条件
        :return:训练完成后得到最优的w和b
        """
        JLast = -1  # 用来存放上一次迭代的损失值。用-1是因为损失值>=0
        count = 0  # 迭代次数
        while True:
            count += 1
            J = 0  # 损失值
            dw = np.zeros((self.n, 1))  # a对w的导数(n*1)
            db = 0  # a对b的导数
            Z = np.dot(self.w.T, self.X) + self.b  # Z=wT*X+b
            a = 1 / (1 + np.exp(-Z))  # Sigmoid函数
            J += -(np.dot(self.y, np.log(a).T) + np.dot(1 - self.y, np.log(1 - a).T))  # 损失函数的计算
            dz = a - self.y  # a对z的导数(m*1)
            dw += np.dot(self.X, dz.T)
            db += np.sum(dz, axis=1)
            J /= self.m  # 平均损失
            dw /= self.m
            db /= self.m
            self.w -= self.alpha * dw
            self.b -= self.alpha * db
            print("第" + str(count) + "次梯度下降的损失值J:" + str(J))
            if (np.abs(J - JLast) < self.iterThreshold and JLast > 0) or count>200:
                break
            JLast = J
        return self.w, self.b
 
    def predict(self, x):
        """
        预测:对新的记录进行预测,给出预测的类别
        :param x:需要进行预测的一条记录(n*1)
        :return:如果预测出的概率大于0.5就返回类别1,小于等于0.5就返回类别0
        """
        result = np.dot(self.w.T, x) + self.b
        result = 1 / (1 + np.exp(-result))
        if result > 0.5:
            return 1
        else:
            return 0
 
 
if __name__ == '__main__':
    
    A = np.zeros((100,3),dtype=float)    
    f = open('。。。')               #打开数据文件文件
    lines = f.readlines()           #把全部数据文件读到一个列表lines中
    A_row = 0                       #表示矩阵的行,从0行开始
    for line in lines:              #把lines中的数据逐行读取出来
        list = line.strip('\n').split(' ')      #处理逐行数据:strip表示把头尾的'\n'去掉,split表示以空格来分割行数据,然后把处理后的行数据返回到list列表中
        A[A_row:] = list[0:3]                    #把处理后的数据放到方阵A中。list[0:3]表示列表的0,1,2列数据放到矩阵A中的A_row行
        A_row+=1
    x=A[:,:2]
    m,n=np.shape(x)
    X=x.reshape([n,m])
    y=A[:,2]
    
    alpha = 0.001  # 设置更新速率
    iterThreshold = 0.00001  # 设置迭代停止条件
    lr = LogisticRegression(m, n, X, y, alpha, iterThreshold)
    lr.train()
    print(lr.predict(np.array([np.random.rand(1), np.random.rand(1)])))
    print(help(LogisticRegression))

猜你喜欢

转载自blog.csdn.net/aBIT_Tu/article/details/82228850