python机器学习逻辑回归算法

一、Sigmoid/Logistic函数:
我们定义逻辑回归的预测函数为ℎ𝜃(𝑥) = 𝑔(𝜃𝑇𝑥) ,
其中g(x)函数是sigmoid函数。
注意此处𝜃,x都是列向量;

二、决策边界:
1、𝜃 = [-3; 1; 1] x = [0; x1; x2]
在这里插入图片描述
2、𝜃 = [-1; 0; 0; 1; 1] x = [0; x1; x2; x12; x22]
在这里插入图片描述
3、这是更复杂的逻辑边界:
在这里插入图片描述
三、逻辑回归的代价函数:
1、其中y代表真实值,ℎ𝜃(𝑥)代表预测值;该代价函数也是一个凸函数,故而可以利用梯度下降法求解全局最小值
在这里插入图片描述
或者简化为如下形式:
𝐶𝑜𝑠𝑡(ℎ𝜃(𝑥), 𝑦) = −𝑦𝑙𝑜𝑔(ℎ𝜃(𝑥)) − (1−𝑦)𝑙𝑜𝑔(1−ℎ𝜃(𝑥))
2、代价函数的导数:
在这里插入图片描述
在这里插入图片描述
3、梯度下降法的伪代码描述:
在这里插入图片描述
四、多分类问题:
通过划定不止一个决策边界:
在这里插入图片描述
五、正确率/召回率/F1指标:
1、定义:
正确率:就是检索出来的条目有多少是正确的;
召回率:就是所有正确的条目有多少被检索出来了。
F1值=2∗(正确率∗召回率)/(正确率+召回率)。 是综合上面二个指标的评估指标。
这几个指标的取值都在0-1之间,数值越接近于1,效果越好。
2、分析:
我们希望检索结果Precision越高越好,同时Recall也越高越好,但事实上这两者在某些情况下有矛盾的。
比如极端情况下,我们只搜索出了一个结果,且是准确的,那么Precision就是100%,但是Recall就很低;
而如果我们把所有结果都返回,那么比如Recall是100%,但是Precision就会很低。

六、代码展示:
相关代码
my_first_logistic_linear.py:

import matplotlib.pyplot as plt
import numpy as np
#用来评估模型性能
from sklearn.metrics import classification_report
from sklearn import preprocessing
#是否对数据进行标准化处理
scale = True
#载入数据:
data = np.genfromtxt("LR-testSet.csv",delimiter=",")
x_data = data[:,:-1]
#给x_data添加偏置项,即线性逻辑回归中的截距
#np.concatenate(a,b)的功能是对矩阵进行扩充
#axis=0是沿Y轴进行扩充,b放置在A的下面
#axis=1是沿X轴进行扩充
x_data = np.concatenate((np.ones((100,1)), x_data), axis=1)
#赋予y_data的Y轴多一个维度,方便接下来的np.mat命令:
y_data = data[:,-1, np.newaxis]


#定义sigmod函数
def sigmod(x):
    return 1.0/(1+np.exp(-x))
#定义代价函数
#这里Mat的意思是都已经是np中的矩阵模式
def cost(xMat, yMat, theta):
    #np.multiply(a,b)会对这两个数组的对应元素进行计算,因此它要求这两个数组有相同的大小(shape相同),并返回一个新的numpy数组
    #如果shape不同的话,会将小规格的矩阵延展成与另一矩阵一样大小,再求两者内积(不建议这样用)
    #此处要求theta是一个列向量,保证xMat*theta是一个单值
    left = np.multiply(yMat, np.log(sigmod(xMat*theta)))
    right = np.multiply(1-yMat, np.log(1-sigmod(xMat*theta)))
    #sum()中axis默认为0,即沿Y轴方向求和;
    #len()中axis默认也为0,即沿Y轴方向求长度;
    return np.sum(left + right) / -(len(xMat))
#梯度下降法
def gradAscent(xArr, yArr):
    #根据scale的值决定是否进行正则化处理
    if scale == True:
        #sklearn.preprocessing.scale的作用是数据标准化;
        #公式:(X-X_mean)/X_std 最后,对每个属性/每列来说所有数据都聚集在0附近,方差值为1
        #参数说明:
        #axis=0,表示沿Y轴处理;axis=1,表示沿X轴处理;
        #with_mean=True,表示使均值为0;
        #with_std=True,表示使方差为1;
        xArr = preprocessing.scale(xArr, axis=0)
    #np.mat(a)的作用是将a转换为矩阵
    xMat = np.mat(xArr)
    yMat = np.mat(yArr)

    lr = 0.001 #学习度
    epochs = 10000 #学习次数
    #用来存储每迭代50次后的代价函数的值
    costList = []
    #行m代表数据个数;列n代表权值个数
    #np.shape(a)会返回矩阵a的行数和列数
    m,n = np.shape(xMat)
    #初始化theta,显然theta需要是一个列向量
    theta = np.mat(np.ones((n, 1)))

    for i in range(epochs+1):
        #初始化ℎ𝜃(𝑥)
        h = sigmod(xMat*theta)
        #计算误差,注:此处直接对所有的𝜃j进行了更新,比伪代码中的描述更优越
        #xMat.T的意思是对xMat进行转置
        temp = xMat.T * (h-yMat) / m
        theta = theta - lr * temp

        if i%50 == 0:
            costList.append(cost(xMat, yMat, theta))
    return theta, costList

#训练模型
#补充,其实这里x_data和y_data已经是矩阵的形式了,所以gradAscent不适用np.mat也可以
theta, costList = gradAscent(x_data, y_data)
print(theta)

#绘图:
if scale == False:
    x_data = data[:,:-1]
    y_data = data[:,-1]
    x0 = []
    x1 = []
    y0 = []
    y1 = []
    #切分不同类型的数据:
    for i in range(len(x_data)):
        if y_data[i]==0:
            x0.append(x_data[i,0])
            y0.append(x_data[i,1])
        else:
            x1.append(x_data[i,0])
            y1.append(x_data[i,1])
    #画散点图:
    scatter0 = plt.scatter(x0, y0, c="b", marker="o")
    scatter1 = plt.scatter(x1, y1, c="r", marker="x")
    plt.legend(handles=[scatter0, scatter1], labels=["label0", "label1"], loc="best")
    #画斜线:
    #theta[0] + theta[1]*x1 + theta[2]*x2 = 0
    x1 = np.mat([[-4], [3]])
    x2 = (-theta[0] - x1*theta[1]) / theta[2]
    plt.plot(x1, x2, "k")
    plt.show()
else:
    x_data = data[:,:-1]
    y_data = data[:,-1]
    x_data = preprocessing.scale(x_data, axis=0)
    x0 = []
    x1 = []
    y0 = []
    y1 = []
    #切分不同类型的数据:
    for i in range(len(x_data)):
        if y_data[i]==0:
            x0.append(x_data[i,0])
            y0.append(x_data[i,1])
        else:
            x1.append(x_data[i,0])
            y1.append(x_data[i,1])
    #画散点图:
    scatter0 = plt.scatter(x0, y0, c="b", marker="o")
    scatter1 = plt.scatter(x1, y1, c="r", marker="x")
    plt.legend(handles=[scatter0, scatter1], labels=["label0", "label1"], loc="best")
    #画斜线:
    x1 = np.mat([[-4], [3]])
    x2 = (-theta[0] - x1*theta[1]) / theta[2]
    plt.plot(x1, x2, "k")
    plt.show()

#画代价函数的迭代情况:
#201表示一共有201个点:0、50、...、10000
x = np.linspace(0, 10001, 201)
plt.plot(x, costList, c="r")
plt.title("Train")
plt.xlabel("Epochs")
plt.ylabel("Cost")
plt.show()

#预测:
x_data = data[:,:-1]
x_data = np.concatenate((np.ones((100,1)), x_data), axis=1)
def predict(x_data, theta):
    if scale == True:
        x_data = preprocessing.scale(x_data, axis=0)
    xMat = np.mat(x_data)
    theta = np.mat(theta)
    #sigmod(xMat*theta)是一个列向量;若其元素>0.5,返回1;否则返回0
    return [1 if x>=0.5 else 0 for x in sigmod(xMat*theta)]

predictions = predict(x_data, theta)
print(classification_report(y_data, predictions))

用户流失预测.py:

import numpy as np
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import classification_report
from sklearn.linear_model import LogisticRegression

#导入测试集和训练集
#分隔符是“,”;结果数组类型是str
train_data = np.genfromtxt("Churn-Modelling.csv",delimiter=",",dtype=str)
test_data = np.genfromtxt("Churn-Modelling-Test-Data.csv",delimiter=",",dtype=str)

x_train = train_data[1:,:-1]
y_train = train_data[1:,-1]
x_test = train_data[1:,:-1]
y_test = train_data[1:,-1]

#前三列的数据无意义,因此删除
#np.delete(arr,obj,axis=None)
#arr:输入矩阵
#obj:需要处理的位置
#axis=0,在Y轴上选择删除;axis=1,在X轴上选择删除
x_train = np.delete(x_train, [0, 1, 2], axis=1)
x_test = np.delete(x_test, [0, 1, 2], axis=1)
#由于性别、国籍非数字类型,因此需要转化成数字类型
#LabelEncoder()的作用是把n个类别编码为0~n-1之间的整数,建立起1-1映射
#使用fit函数可以进行编码
#使用transform和invers_transform进行类别和整数之间的转换
#Ex:
#labelencoder1.inverse_transform([0,1,2]) 
#labelencoder1.transform(["France", "Germany", "Spain"])
labelencoder1 = LabelEncoder()
x_train[:,1] = labelencoder1.fit_transform(x_train[:,1])
x_test[:,1] = labelencoder1.fit_transform(x_test[:,1])
labelencoder2 = LabelEncoder()
x_train[:,2] = labelencoder1.fit_transform(x_train[:,2])
x_test[:,2] = labelencoder1.fit_transform(x_test[:,2])
#将引入的字符串类型数据转换为数字类型
#将str数组转换为float32数组
x_train = x_train.astype(np.float32)
x_test = x_test.astype(np.float32)
y_train = y_train.astype(np.float32)
y_test = y_test.astype(np.float32)
#归一化处理
#StandardScaler()的作用是数据标准化,公式:(X-X_mean)/X_std
#sklearn.preprocessing.scale(axis=0,with_mean=True,with_std=True)也有完全相同的作用
sc = StandardScaler()
x_train = sc.fit_transform(x_train)
x_test = sc.fit_transform(x_test)
#生成训练模型
LR = LogisticRegression()
LR.fit(x_train,y_train)
#对测试集进行预测
predictions = LR.predict(x_test)
print(classification_report(y_test, predictions))
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值