16-逻辑回归
2019-10-01 本文已影响0人
jxvl假装
逻辑回归
应用场景:二分类问题。逻辑回归也能得出概率值
逻辑回归为什么叫逻辑回归:因为是二分类,结果非此即彼,与逻辑运算类似
线性回归的式子作为逻辑回归的输入

所以线性回归的问题,逻辑回归也会出现
如何将线性回归的输入转换为一个分类问题的
sigmoid函数
特点:最后的输出值在0-1之间,当x=0时,y=0.5。0-1与概率是可以相对应的
sigmoid公式

输出:[0,1]区间的概率值,默认0.5作为阀值,大于0.5的可以分为1,小于0.5的可以分为0
注:g(z)为sigmoid函数。z就是线性回归的输入,即θ的转置与x的乘积
逻辑回归的损失函数
与线性回归原理相同,但由于是分类问题,损失函数不一样,只能通过梯度下降来求解。逻辑回归的损失函数称对数似然损失
当y=1时,损失函数(判断属于1的概率):
在完整的损失函数中,其公式和信息熵比较像
用案例理解逻辑回归的损失函数:
"""
假设对4个样本进行分类:【样本1, 样本2, 样本3, 样本4】
实际的结果为:【1 0 0 1】
但是分类的概率为:【0.6, 0.1, 0.51, 0.7】,阀值为0.5
所以分类结果为:【1 0 1 1】
四个损失相加:1log(0.6) + 0log(0.1) + 0log(0.51) + 1log(0.7) #可以将其理解为信息熵的大小(信息熵的大小越小越好,越小,不确定性越小)
"""
**逻辑回归中要做的还是还是更新权重**
损失函数出现多个极小值
至今学习的损失函数中,主要有均方误差和对数似然损失函数两种。
在均方误差中,损失函数不会出现多个极小值(局部最低点)的情况
而在对数似然损失函数中:如图
可能会出现多个极小值(局部最小值),这个问题目前无法解决,即:无法保证找到最小点
如何改善(不能完全解决):
- 多次随机初始化,多次比较最小值结果
- 求解过程中,调整学习率
尽管没有全局最低点,但是效果机器学习的效果是不错的
应用
api
所谓正则化,即调整特征的权重,将某些特征的权重减小
一般的二分类问题,哪一个类别少,就把这个类别作为判定的概率值(即判断结果为这个类别的概率,正例)
逻辑回归预测癌症案例
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import classification_report
def logistic():
"""
逻辑回归做二分类的预测(根据细胞的属性特征)
:return None
"""
# 读取数据
column_names = ['Sample code number', 'Clump Thickness', 'Uniformity of Cell Size', 'Uniformity of Cell Shape',
'Marginal Adhesion', 'Single Epithelial Cell Size', 'Bare Nuclei', 'Bland Chromatin',
'Normal Nucleoli', 'Mitoses', 'Class']
data = pd.read_csv(
"https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data",
names=column_names) # names指定读取数据时的列名
# print(data.info())
# 对缺失值进行处理(以?标记的缺失值)
data = data.replace(to_replace="?", value=np.nan) # 用np.nan替换?
data = data.dropna()
print(data.shape)
print(data)
# 进行数据的分割
x_train, x_test, y_train, y_test = train_test_split(data[column_names[1:10]], data[column_names[10]], test_size=0.25)
# 进行标准化。目标值不需要进行标准化,会默认标记为0和1
std = StandardScaler()
x_train = std.fit_transform(x_train)
x_test = std.transform(x_test)
# 预测
lg = LogisticRegression(C=1.0)
lg.fit(x_train, y_train)
y_predict = lg.predict(x_test)
print("特征的权重:\n", lg.coef_)
print("准确率:\n", lg.score(x_test, y_test))
print("召回率:\n", classification_report(y_predict, y_test, labels=[2,4], target_names=['良性', '恶性'])) #2代表良性,4代表恶性,2、4是本来的标签
return None
if __name__ == "__main__":
logistic()