逻辑回归
- 线性可分
from typing import final
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
#切片函数
def get_Xy(data):
data.insert(0, 'ones', 1) # 插入一行
X_ = data.iloc[:, 0:-1] ## 注意逗号相当于前两行切片
X = X_.values ##转换
y_ = data.iloc[:, -1]
y = y_.values.reshape(len(y_),1)
return X,y
# 实现sigmoid函数
def sigmoid(z):
return 1 / (1 + np.exp(-z))
# 实现逻辑回归的代价函数,两个部分,-y(log(hx)和-(1-y)log(1-hx)
def costFunction(theta, X, y):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(-y, np.log(sigmoid(X * theta)))
second = np.multiply((1 - y), np.log(1 - sigmoid(X * theta)))
return np.sum(first - second) / (len(X))
#梯度下降函数
def grandDescent(X,y,theta,alpha,iters):
costs = []
for i in range(iters):
theta = theta - (X.T @ (sigmoid(X@theta) - y)) * alpha/len(X)
cost = costFunction(theta,X,y)
costs.append(cost)
if i % 1000 == 0:
print(cost)
return theta,costs
#预测true flase
def predict(X,theta):
prob = sigmoid(X @ theta)
return [1 if x>=0.5 else 0 for x in prob]
##特征映射
def featureMapping(x1,x2,power):
for i in np.arange(power+1):
for j in np.arange(i+1):
data['F{}{}'.format(i-j,j)] = np.power(x1,i-j) * np.power(x2,j)
return pd.Dataframe(data)
#导入数据集
path = 'ex2data1.txt'
data = pd.read_csv(path, header=None, names=['Exam 1', 'Exam 2', 'Admitted'])
print(data.head())
#基本图
fig, ax = plt.subplots()
ax.scatter(data[data['Admitted'] == 0]['Exam 1'], data[data['Admitted'] == 0]['Exam 2'], c='r', marker='x', label='y=0')
ax.scatter(data[data['Admitted'] == 1]['Exam 1'], data[data['Admitted'] == 1]['Exam 2'], c='b', marker='o', label='y=1')
ax.legend()
ax.set(xlabel='exam1',
ylabel='exam2',
)
plt.show()
##迭代图
X,y = get_Xy(data)
print(X.shape)
theta=np.zeros((3,1))
cost_init =costFunction(theta,X,y)
print(cost_init)
alpha = 0.004
iters = 200000
theta_final,finalcosts = grandDescent(X,y,theta,alpha,iters)
fig,ax = plt.subplots()
#散点图 scatter plot 是图
ax.plot(np.arange(iters),finalcosts,'r') #最后是颜色 #costs是列表所以iters也得做成列表0,1,2到-1000
ax.set(xlabel='iters',
ylabel='cost',
title='cost vs iters')
#@ax.plot
plt.show()
#预测准确率
y_= np.array(predict(X,theta_final))
y_pre = y_.reshape(len(y_),1)
acc = np.mean(y_pre == y) # 算数平均值
print(acc)
#决策边界图
plotting_x1 = np.linspace(30, 100, 100) # 30 到 100 之间均匀100个值
plotting_h1 = -theta_final[0, 0] / theta_final[2, 0] - theta_final[1, 0] / theta_final[2, 0] * plotting_x1 ##决策边界函数
fig, ax = plt.subplots()
ax.scatter(data[data['Admitted'] == 0]['Exam 1'], data[data['Admitted'] == 0]['Exam 2'], c='r', marker='x', label='y=0')
ax.scatter(data[data['Admitted'] == 1]['Exam 1'], data[data['Admitted'] == 1]['Exam 2'], c='b', marker='o', label='y=1')
ax.legend()
ax.set(xlabel='exam1',
ylabel='exam2',
)
ax.plot(plotting_x1, plotting_h1, c='g')
plt.show()
##############特征映射 就是拟合高次函数 椭圆等 w出现了高次
- 线性不可分
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
#切片函数
def get_Xy(data):
data.insert(0, 'ones', 1) # 插入一行
X_ = data.iloc[:, 0:-1] ## 注意逗号相当于前两行切片
X = X_.values ##转换
y_ = data.iloc[:, -1]
y = y_.values.reshape(len(y_),1)
return X,y
# 实现sigmoid函数
def sigmoid(z):
return 1 / (1 + np.exp(-z))
# 实现逻辑回归的代价函数,两个部分,-y(log(hx)和-(1-y)log(1-hx)
def costFunction(X, y, theta, lamda):
A = sigmoid(X @ theta)
first = y * np.log(A)
second = (1 - y) * np.log(1 - A)
reg = np.sum(np.power(theta[1:], 2)) * (lamda / (2 * len(X)))
return -np.sum(first + second) / len(X) + reg
# 梯度下降函数
def grandDescent(X, y, theta, alpha, iters, lamda):
costs = []
for i in range(iters):
reg = theta[1:] * (lamda / len(X))
reg = np.insert(reg, 0, values=0, axis=0) ###加一行否则矩阵不匹配
# theta = theta - (X.T @ (sigmoid(X @ theta) - y)) * alpha / len(X) - alpha * reg
theta = theta - (X.T @ (sigmoid(X @ theta) - y)) * alpha / len(X) - reg * alpha
cost = costFunction(X, y, theta, lamda)
costs.append(cost)
if i % 1000 == 0:
print(cost)
return theta, costs
#预测true flase
def predict(X,theta):
prob = sigmoid(X @ theta)
return [1 if x>=0.5 else 0 for x in prob]
##特征映射 变成高次使拟合效果更好 一般用在线性不可分情况
def feature_mapping(x1, x2, power):
data = {}
for i in np.arange(power + 1):
for j in np.arange(i + 1):
data['F{}{}'.format(i - j, j)] = np.power(x1, i - j) * np.power(x2, j)
return pd.DataFrame(data)
plt.show()
#导入数据集
path = 'ex2data2.txt'
data = pd.read_csv(path, names=['Test 1', 'Test 2', 'Accepted'])
data.head()
x1 = data['Test 1']
x2 = data['Test 2']
#基本图
fig,ax = plt.subplots()
ax.scatter(data[data['Accepted']==0]['Test 1'],data[data['Accepted']==0]['Test 2'],c='r',marker='x',label='y=0')
ax.scatter(data[data['Accepted']==1]['Test 1'],data[data['Accepted']==1]['Test 2'],c='b',marker='o',label='y=1')
ax.legend()
ax.set(xlabel='Test1',
ylabel='Test2')
plt.show()
data2 = feature_mapping(x1,x2,6) # 设置为复杂曲线
print(data2.head())
# # print(data2.head())
lamda = 0.1 # 拉姆达参数
# X,y = get_Xy(data2) #这句出问题了不要用 !!因为data2已经不是低阶矩阵了 成了28层的
# print(X.shape)
X = data2.values
y = data.iloc[:,-1].values
y = y.reshape(len(y),1)
theta=np.zeros((28,1))
cost_init =costFunction(X,y,theta,lamda) #加入了正则化
print(cost_init)
alpha = 0.001
iters = 200000
theta_final,finalcosts = grandDescent(X,y,theta,alpha,iters,lamda)
fig,ax = plt.subplots()
#散点图 scatter plot 是图
ax.plot(np.arange(iters),finalcosts,'r') #最后是颜色 #costs是列表所以iters也得做成列表0,1,2到-1000
ax.set(xlabel='iters',
ylabel='cost',
title='cost vs iters')
#@ax.plot
plt.show()
#
# #预测准确率
y_= np.array(predict(X,theta_final))
y_pre = y_.reshape(len(y_),1)
acc = np.mean(y_pre == y) # 算数平均值
print(acc)
x = np.linspace(-1.2,1.2,200)
xx,yy = np.meshgrid(x,x)
z = feature_mapping(xx.ravel(),yy.ravel(),6).values
zz = z @ theta_final
zz = zz.reshape(xx.shape)
fig,ax = plt.subplots()
ax.scatter(data[data['Accepted']==0]['Test 1'],data[data['Accepted']==0]['Test 2'],c='r',marker='x',label='y=0')
ax.scatter(data[data['Accepted']==1]['Test 1'],data[data['Accepted']==1]['Test 2'],c='b',marker='o',label='y=1')
ax.legend()
ax.set(xlabel='Test1',
ylabel='Test2')
plt.contour(xx,yy,zz,0)
plt.show()
效果图: