線性迴歸和邏輯迴歸(比較清楚)

1.線性迴歸

在統計學中,線性迴歸(Linear Regression)是利用稱爲線性迴歸方程的最小平方函數對一個或多個自變量和因變量之間關係進行建模的一種迴歸分析。這種函數是一個或多個稱爲迴歸係數的模型參數的線性組合(自變量都是一次方)。只有一個自變量的情況稱爲簡單迴歸,大於一個自變量情況的叫做多元迴歸。

優點:結果易於理解,計算上不復雜。
缺點:對非線性數據擬合不好。
適用數據類型:數值型和標稱型數據。
算法類型:迴歸算法
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
其中線性迴歸模型中,L1正則化 —Lasso迴歸;L2正則化— Ridge迴歸(嶺迴歸)
正則化是用於約束損失函數的附加項

#Import Library
#Import other necessary libraries like pandas, numpy...
from sklearn import linear_model
#Load Train and Test datasets
#Identify feature and response variable(s) and values must be numeric and numpy arrays

x_train=input_variables_values_training_datasets
y_train=target_variables_values_training_datasets
x_test=input_variables_values_test_datasets

# Create linear regression object
linear = linear_model.LinearRegression()

# Train the model using the training sets and check score
linear.fit(x_train, y_train)
linear.score(x_train, y_train)

#Equation coefficient and Intercept
print('Coefficient: \n', linear.coef_)
print('Intercept: \n', linear.intercept_)

#Predict Output
predicted= linear.predict(x_test)

上述是使用sklearn包中的線性迴歸算法的代碼例子,下面是一個實現的具體例子。

# -*- coding: utf-8 -*-
"""
Created on Mon Oct 17 10:36:06 2016

@author: cai
"""

import os
import numpy as np
import pandas as pd
import matplotlib.pylab as plt
from sklearn import linear_model

# 計算損失函數
def computeCost(X, y, theta):
    inner = np.power(((X * theta.T) - y), 2)
    return np.sum(inner) / (2 * len(X))

# 梯度下降算法
def gradientDescent(X, y, theta, alpha, iters):
    temp = np.matrix(np.zeros(theta.shape))
    parameters = int(theta.ravel().shape[1])
    cost = np.zeros(iters)

    for i in range(iters):
        error = (X * theta.T) - y

        for j in range(parameters):
            # 計算誤差對權值的偏導數
            term = np.multiply(error, X[:, j])
            # 更新權值
            temp[0, j] = theta[0, j] - ((alpha / len(X)) * np.sum(term))

        theta = temp
        cost[i] = computeCost(X, y, theta)
    return theta, cost

dataPath = os.path.join('data', 'ex1data1.txt')
data = pd.read_csv(dataPath, header=None, names=['Population', 'Profit'])
# print(data.head())
# print(data.describe())
# data.plot(kind='scatter', x='Population', y='Profit', figsize=(12, 8))
# 在數據起始位置添加1列數值爲1的數據
data.insert(0, 'Ones', 1)
print(data.shape)

cols = data.shape[1]
X = data.iloc[:, 0:cols-1]
y = data.iloc[:, cols-1:cols]

# 從數據幀轉換成numpy的矩陣格式
X = np.matrix(X.values)
y = np.matrix(y.values)
# theta = np.matrix(np.array([0, 0]))
theta = np.matrix(np.zeros((1, cols-1)))
print(theta)
print(X.shape, theta.shape, y.shape)
cost = computeCost(X, y, theta)
print("cost = ", cost)

# 初始化學習率和迭代次數
alpha = 0.01
iters = 1000

# 執行梯度下降算法
g, cost = gradientDescent(X, y, theta, alpha, iters)
print(g)

# 可視化結果
x = np.linspace(data.Population.min(),data.Population.max(),100)
f = g[0, 0] + (g[0, 1] * x)

fig, ax = plt.subplots(figsize=(12, 8))
ax.plot(x, f, 'r', label='Prediction')
ax.scatter(data.Population, data.Profit, label='Training Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')

fig, ax = plt.subplots(figsize=(12, 8))
ax.plot(np.arange(iters), cost, 'r')
ax.set_xlabel('Iteration')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')


# 使用sklearn 包裏面實現的線性迴歸算法
model = linear_model.LinearRegression()
model.fit(X, y)

x = np.array(X[:, 1].A1)
# 預測結果
f = model.predict(X).flatten()
# 可視化
fig, ax = plt.subplots(figsize=(12, 8))
ax.plot(x, f, 'r', label='Prediction')
ax.scatter(data.Population, data.Profit, label='Training Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size(using sklearn)')
plt.show()

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
總結
優點:

1、實現簡單;

2、分類時計算量非常小,速度很快,存儲資源低;

缺點:

1、容易欠擬合,一般準確度不太高

2、只能處理兩分類問題(在此基礎上衍生出來的softmax可以用於多分類),且必須線性可分;

適用數據類型:數值型和標稱型數據。
類別:分類算法。
試用場景:解決二分類問題。

代碼實現
首先是採用sklearn包中的邏輯迴歸算法代碼:

#Import Library
from sklearn.linear_model import LogisticRegression
#Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset

# Create logistic regression object

model = LogisticRegression()

# Train the model using the training sets and check score
model.fit(X, y)
model.score(X, y)

#Equation coefficient and Intercept
print('Coefficient: \n', model.coef_)
print('Intercept: \n', model.intercept_)

#Predict Output
predicted= model.predict(x_test)

應用例子

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Time    : 2016/10/19 21:35
@Author  : cai

實現多類的邏輯迴歸算法
"""
import os
import numpy as np
import pandas as pd
import matplotlib.pylab as plt
from scipy.optimize import minimize
from scipy.io import loadmat

# 定義Sigmoid函數
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

# 定義 cost函數
def costReg(theta, X, y, lambdas):
    theta = np.matrix(theta)
    X = np.matrix(X)
    y = np.matrix(y)
    h = X * theta.T
    first = np.multiply(-y, np.log(sigmoid(h)))
    second = np.multiply((1-y), np.log(1 - sigmoid(h)))
    reg = (lambdas / 2 * len(X)) * np.sum(np.power(theta[:, 1:theta.shape[1]], 2))
    return np.sum(first - second) / (len(X)) + reg

# 梯度下降算法的實現, 輸出梯度對權值的偏導數
def gradient(theta, X, y, lambdas):
    theta = np.matrix(theta)
    X = np.matrix(X)
    y = np.matrix(y)

    parameters = int(theta.ravel().shape[1])
    grad = np.zeros(parameters)
    # 計算誤差
    error = sigmoid(X * theta.T) - y

    grad = ((X.T * error) / len(X)).T + ((lambdas / len(X)) * theta)

    grad[0, 0] = np.sum(np.multiply(error, X[:, 0])) / len(X)

    return np.array(grad).ravel()

# 實現一對多的分類方法
def one_vs_all(X, y, num_labels, lambdas):
    rows = X.shape[0]
    params = X.shape[1]

    # 每個分類器有一個 k * (n+1)大小的權值數組
    all_theta = np.zeros((num_labels, params + 1))

    # 增加一列,這是用於偏置值
    X = np.insert(X, 0, values=np.ones(rows), axis=1)

    # 標籤的索引從1開始
    for i in range(1, num_labels + 1):
        theta = np.zeros(params + 1)
        y_i = np.array([1 if label == i else 0 for label in y])
        y_i = np.reshape(y_i, (rows, 1))

        # 最小化損失函數
        fmin = minimize(fun=costReg, x0=theta, args=(X, y_i, lambdas), method='TNC', jac=gradient)
        all_theta[i-1, :] = fmin.x

    return all_theta

def predict_all(X, all_theta):
    rows = X.shape[0]
    params = X.shape[1]
    num_labels = all_theta.shape[0]

    # 增加一列,這是用於偏置值
    X = np.insert(X, 0, values=np.ones(rows), axis=1)

    X = np.matrix(X)
    all_theta = np.matrix(all_theta)

    # 對每個訓練樣本計算其類的概率值
    h = sigmoid(X * all_theta.T)

    # 獲取最大概率值的數組索引
    h_argmax = np.argmax(h, axis=1)
    # 數組是從0開始索引,而標籤值是從1開始,所以需要加1
    h_argmax = h_argmax + 1

    return h_argmax

dataPath = os.path.join('data', 'ex3data1.mat')
# 載入數據
data = loadmat(dataPath)
print(data)
print(data['X'].shape, data['y'].shape)

# print(np.unique(data['y']))
# 測試
# rows = data['X'].shape[0]
# params = data['X'].shape[1]
#
# all_theta = np.zeros((10, params + 1))
#
# X = np.insert(data['X'], 0, values=np.ones(rows), axis=1)
#
# theta = np.zeros(params + 1)
#
# y_0 = np.array([1 if label == 0 else 0 for label in data['y']])
# y_0 = np.reshape(y_0, (rows, 1))
# print(X.shape, y_0.shape, theta.shape, all_theta.shape)

all_theta = one_vs_all(data['X'], data['y'], 10, 1)
print(all_theta)

# 計算分類準確率
y_pred = predict_all(data['X'], all_theta)
correct = [1 if a == b else 0 for (a, b) in zip(y_pred, data['y'])]
accuracy = (sum(map(int, correct)) / float(len(correct)))
print('accuracy = {0}%'.format(accuracy * 100))

作者的github中有代碼:https://github.com/ccc013/CodingPractise/blob/master/Python/MachineLearning/mulLogisticRegressionPractise.py
參考python代碼資源:
https://www.johnwittenauer.net/machine-learning-exercises-in-python-part-1/
在這裏插入圖片描述
原文鏈接:https://blog.csdn.net/lc013/article/details/55002463

3.線性迴歸和邏輯迴歸的區別

1、 爲什麼是邏輯迴歸?
  都說線性迴歸用來做迴歸預測,邏輯迴歸用於做二分類,一個是解決迴歸問題,一個用於解決分類問題。但很多人問起邏輯迴歸和線性迴歸的區別,很多人會大喊一聲(也可能是三聲):邏輯迴歸就是對線性迴歸做了一個壓縮,將y 的閾值從y∈(+∞,−∞)y∈(+∞,−∞)壓縮到(0,1)(0,1)。那麼問題來了,問什麼僅僅做一個簡單的壓縮,就將回歸問題變成了分類問題?裏面蘊含着本質?
  首先要從數據說起,線性迴歸的樣本的輸出,都是連續值,y∈(+∞,−∞)y∈(+∞,−∞)而,邏輯迴歸中y∈{0,1}y∈{0,1},只能取0和1。對於擬合函數也有本質上的差別:
  線性迴歸:f(x)=θTX=θ1x1+θ2x2+⋯+θnxnf(x)=θTX=θ1x1+θ2x2+⋯+θnxn
  邏輯迴歸:f(x)=p(y=1∣x;θ)=g(θTX)f(x)=p(y=1∣x;θ)=g(θTX),其中,g(z)=11+e−zg(z)=11+e−z
可以看出,線性迴歸的擬合函數,的確是對f(x)的輸出變量y的擬合,而邏輯迴歸的擬合函數是對爲1類的樣本的概率的擬合。

2、那麼,爲什麼要以1類樣本的概率進行擬合呢,爲什麼可以這樣擬合呢?
  首先,logstic 函數的本質說起。若要直接通過迴歸的方法去預測二分類問題, y 到底是0類還是1類,最好的函數是單位階躍函數。然而單位階躍函數不連續(GLM 的必要條件),而 logsitic 函數恰好接近於單位階躍函數,且單調可微。於是希望通過該複合函數去擬合分類問題:
  
y=11+e−θTX
y=11+e−θTX

於是有:
  
lny1−y=θTX
lny1−y=θTX

發現如果我們假設 y=p(y爲1類∣x;θ)y=p(y爲1類∣x;θ) 作爲我們的擬合函數,等號左邊的表達式的數學意義就是1類和0類的對數機率(log odds)。這個表達式的意思就是:用線性模型的預測結果去逼近1類和0類的機率比。於是,θTX=0θTX=0就相當於是1類和0類的決策邊界:
  當θTX>0θTX>0,則有y>0.5y>0.5;若θTX→+∞θTX→+∞ ,則y→1y→1 ,即y 爲1類;
  當θTX<0θTX<0,則有y<0.5y<0.5 ; 若θTX→−∞θTX→−∞,則y→0y→0,即 y 爲0類。
  
  這個時候就能看出區別來了,在線性迴歸中θTXθTX爲預測值的擬合函數;而在邏輯迴歸中θTX=0θTX=0爲決策邊界。
————————————————
版權聲明:本文爲CSDN博主「會飛的蝸牛」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/u010692239/article/details/52345754

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章