邏輯回歸解決分類問題

有監(jiān)督學習里面的兩個問題量瓜,一個是線性回歸打毛,一個是邏輯回歸柿赊。
線性回歸問題
指的是:能夠預測的值是連續(xù)的,比如房子的大小和價格的關系幻枉。

image.png

問題是預測750平方英尺的時候碰声,價格是多少?


image.png

邏輯回歸問題
指的是分類問題熬甫,也就是預測的結(jié)果是離散的胰挑。

預測一個乳腺癌是否是惡性的,假設乳腺癌是否惡性與年齡和腫瘤的尺寸的關系如下:


image.png

那么椿肩,問題是給出一個人瞻颂,告訴他的年齡和腫瘤的大小,判斷是否是惡性的郑象。這個問題是一個分類問題(邏輯回歸)贡这,因為它預測的結(jié)果是一個離散的值,只有惡性與非惡性的兩種情況厂榛。

1. 邏輯回歸

從網(wǎng)上找到一個數(shù)據(jù)集盖矫,做一個簡單的邏輯回歸的實驗丽惭。因為是初學者,所有就沒有調(diào)用第三方進行邏輯回歸的庫函數(shù)炼彪。自己寫函數(shù)實現(xiàn)一下吐根。

數(shù)據(jù)的格式:


2017-06-05 21-08-33屏幕截圖.png

將點顯示在圖上面:


2017-06-05 21-11-25屏幕截圖.png

問題:給綠色的點和紅色的點做一個分類。

2. 數(shù)學推理過程

這是源數(shù)據(jù)的格式:


image.png

手寫的推理過程:


image.png
image.png
import matplotlib.pyplot as plt
import numpy as np 
import math
alpha=0.01


def loadDataSet():
    dataMat = []; labelMat = []
    fr = open('testSet-LR.txt')
    for line in fr.readlines():
        lineArr = line.strip().split()
        dataMat.append([float(lineArr[0]), float(lineArr[1])])
        labelMat.append(int(lineArr[2]))
    return dataMat,labelMat
    
def plot_point(dataMat,labelMat):
    length=len(dataMat)

    xcord1=[]
    ycord1=[]

    xcord2=[]
    ycord2=[]

    for i in range(length):
        if labelMat[i]==1:
            xcord1.append(dataMat[i][0])
            ycord1.append(dataMat[i][1])
        else:
            xcord2.append(dataMat[i][0])
            ycord2.append(dataMat[i][1])
    plt.scatter(xcord1,ycord1,c='r')
    plt.scatter(xcord2,ycord2,c='g')
    

def sigmoid(inX):
    return 1.0/(1+np.exp(-inX))



def fun_z(th0,th1,th2,x1,x2):
    return th0+ th1*x1+th2*x2

def fun_h(z):
    return 1.0/(1+math.exp(-z))

def plot_line(theta0,theta1,theta2):
    x=np.arange(-5,5,0.1)
    #y=theta0+theta1*x
    y= (theta0+theta1*x)/(-theta2)
    plt.plot(x,y)
    plt.show()


def gradAscent(dataMat,labelMat):
    theta0=np.random.normal()
    theta1=np.random.normal()
    theta2=np.random.normal()
    
    m=len(dataMat)
    for times in range(3000):
        sum1=0.0
        sum2=0.0
        sum3=0.0
        for i in range(m):
            z=fun_z(theta0,theta1,theta2,dataMat[i][0],dataMat[i][1])

            sum1=sum1+(fun_h(z)-labelMat[i])
            sum2=sum2+(fun_h(z)-labelMat[i])*dataMat[i][0]
            sum3=sum3+(fun_h(z)-labelMat[i])*dataMat[i][1]
        theta0=theta0-(alpha*sum1)
        theta1=theta1-(alpha*sum2)
        theta2=theta2-(alpha*sum3)
    return theta0,theta1,theta2

d,l=loadDataSet()
th0,th1,th2=gradAscent(d,l)

print (th0,"  ,  ",th1,"  ,  ",th2)

plot_point(d,l)
plot_line(th0,th1,th2)

運行結(jié)果:

2017-06-05 22-03-10屏幕截圖.png

PS: 關于梯度下降的一種更好的寫法(直接用矩陣的乘法去寫辐马,這樣更簡介)

def gradAscent(dataMatIn, classLabels):
    dataMatrix = mat(dataMatIn)             #convert to NumPy matrix
    labelMat = mat(classLabels).transpose() #convert to NumPy matrix
    
    m,n = shape(dataMatrix)
    alpha = 0.001
    maxCycles = 500
   #wight就是表示的是theta0拷橘,theta1,theta2
    weights = ones((n,1))
    
    for k in range(maxCycles):              #heavy on matrix operations
        h = sigmoid(dataMatrix*weights)     #matrix mult
        error = (labelMat - h)              #vector subtraction
        weights = weights + alpha * dataMatrix.transpose()* error #matrix mult
    return weights

源代碼和數(shù)據(jù)集:
https://github.com/zhaozhengcoder/Machine-Learning/tree/master/LogisticRegression

2017年 9月12日 更新 (看了吳恩達 最近新出的deeplearning 的視頻)

這個問題喜爷,也可以從邏輯回歸的本身去理解冗疮。

微信圖片_20170913161445.jpg
微信圖片_20170913161457.jpg
"""
實現(xiàn)一個邏輯回歸

1. 數(shù)據(jù)集是testSet,機器學習實戰(zhàn)里面的一個數(shù)據(jù)集檩帐,格式如下:
   x1           x2      y
   -0.017612    14.053064   0
   ....


"""

import numpy as np
from numpy import random
import matplotlib.pyplot as plt

alpha=0.01


#加載數(shù)據(jù)集术幔,原來的數(shù)據(jù)在文件排列是按行排列
#為了計算需要,將原來的數(shù)據(jù)加載到了矩陣之后湃密,給矩陣裝置了诅挑,是數(shù)據(jù)變成按列排列
def loadDataset():
    data=[]
    label=[]
    f=open("textSet.txt")
    for line in f:
        lineArr=line.strip().split()
        data.append( [float(lineArr[0]),float(lineArr[1]) ] ) 
        label.append(float(lineArr[2]))
    mdata=np.array(data)
    mlabel=np.array(label)
    return mdata.T,mlabel.T


def sigmod(inX):
    return 1.0/(1+np.exp(-inX))

#計算error,也就是dz泛源,這個error 是為了計算梯度下降
def forward(mdata,mlabel,weight,b):
    z=np.dot(weight,mdata)+b        
    a=sigmod(z)
    error= a - mlabel
    return error

#梯度下降拔妥,計算出dw,db达箍,然后更新w和b
def gradDesc(mdata,error,weight,b):
    nx,m=mdata.shape
    dw=(1/m)*np.dot(mdata,error.T)
    db=(1/m)*np.sum(error)
    weight_transpose = weight.T - alpha*dw
    b=b-alpha*db
    return weight_transpose.T,b

#代價函數(shù)没龙,寫這個函數(shù)的目的是,在迭代的時候缎玫,輸出每一次迭代后的cost硬纤,判斷cost是否是在下降
def cost(mdata,mlabel,weight,b):    
    nx,m=mdata.shape
    z=np.dot(weight,mdata)+b        
    a=sigmod(z)
    cost=-mlabel*np.log(a)-(a-mlabel)*np.log(1-a)
    return np.sum(cost)/m

#show result
def show1(mdata,mlabel,weight,b):   
    nx,m=mdata.shape
    z=np.dot(weight,mdata)+b        
    a=sigmod(z)
    for i,j in zip(a[0],mlabel):
        print (i,' , ',j)

#將原始的數(shù)據(jù)和計算之后得到的數(shù)據(jù)對比,以折線圖的方式顯示
def show2(mdata,mlabel,weight,b):   
    nx,m=mdata.shape
    z=np.dot(weight,mdata)+b        
    a=sigmod(z)
    plt.plot(a[0])
    plt.plot(mlabel)
    plt.show()


#將計算得到的數(shù)據(jù)二值化赃磨,小于0.5的變成0筝家,大于0.5的變成1
#由于絕大多數(shù)的點都是相同的,所以很多點會被覆蓋
def show3(mdata,mlabel,weight,b):   
    nx,m=mdata.shape
    z=np.dot(weight,mdata)+b        
    a=sigmod(z)

    a2=[]   
    for i in a[0]:
        if i >0.5:
            a2.append(1)
        if i<=0.5:
            a2.append(0)
    plt.plot(a2,'.')
    plt.plot(mlabel,'.')
    plt.show()

def regress(maxcycle=100):
    mdata,mlabel=loadDataset()
    nx,m=mdata.shape

    #w和b 隨機初始化邻辉,代碼的目的就是求w和b
    weight=random.random(size=(1,nx))
    b=random.random(size=(1,m))
    
    #迭代
    for i in range(maxcycle):
        error=forward(mdata,mlabel,weight,b)
        weight,b=gradDesc(mdata,error,weight,b)
        print (cost(mdata,mlabel,weight,b))
    
    show1(mdata,mlabel,weight,b)
    show2(mdata,mlabel,weight,b)
    show3(mdata,mlabel,weight,b)

if __name__=='__main__':
    regress(3000)

源碼 : https://github.com/zhaozhengcoder/Machine-Learning/tree/master/LogisticRegression

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末溪王,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子恩沛,更是在濱河造成了極大的恐慌在扰,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雷客,死亡現(xiàn)場離奇詭異芒珠,居然都是意外死亡,警方通過查閱死者的電腦和手機搅裙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進店門皱卓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來裹芝,“玉大人,你說我怎么就攤上這事娜汁∩┮祝” “怎么了?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵掐禁,是天一觀的道長怜械。 經(jīng)常有香客問我,道長傅事,這世上最難降的妖魔是什么缕允? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮蹭越,結(jié)果婚禮上障本,老公的妹妹穿的比我還像新娘。我一直安慰自己响鹃,他們只是感情好驾霜,可當我...
    茶點故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著买置,像睡著了一般粪糙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上堕义,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天猜旬,我揣著相機與錄音脆栋,去河邊找鬼倦卖。 笑死,一個胖子當著我的面吹牛椿争,可吹牛的內(nèi)容都是我干的怕膛。 我是一名探鬼主播,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼秦踪,長吁一口氣:“原來是場噩夢啊……” “哼褐捻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起椅邓,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤柠逞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后景馁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體板壮,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年合住,在試婚紗的時候發(fā)現(xiàn)自己被綠了绰精。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撒璧。...
    茶點故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖笨使,靈堂內(nèi)的尸體忽然破棺而出卿樱,到底是詐尸還是另有隱情,我是刑警寧澤硫椰,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布繁调,位于F島的核電站,受9級特大地震影響靶草,放射性物質(zhì)發(fā)生泄漏涉馁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一爱致、第九天 我趴在偏房一處隱蔽的房頂上張望烤送。 院中可真熱鬧,春花似錦糠悯、人聲如沸帮坚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽试和。三九已至,卻和暖如春纫普,著一層夾襖步出監(jiān)牢的瞬間阅悍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工昨稼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留节视,地道東北人。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓假栓,卻偏偏與公主長得像寻行,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子匾荆,可洞房花燭夜當晚...
    茶點故事閱讀 45,747評論 2 361

推薦閱讀更多精彩內(nèi)容