日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

【Python數(shù)據(jù)挖掘】回歸模型與應(yīng)用

 highoo 2019-03-20
線性回歸 ( Linear Regression )

  線性回歸中,只包括一個(gè)自變量和一個(gè)因變量,且二者的關(guān)系可用一條直線近似表示,這種回歸稱為一元線性回歸。

  如果回歸分析中包括兩個(gè)或兩個(gè)以上的自變量,且因變量和自變量之間是線性關(guān)系,則稱為多元線性回歸。

  在監(jiān)督學(xué)習(xí)中,學(xué)習(xí)樣本為 D = { (x(i), y(i));i =1, . . . , m } ,預(yù)測的結(jié)果y(i)為連續(xù)值變量,需要學(xué)習(xí)映射 f:X → Y ,并且假定輸入X和輸出Y之間有線性相關(guān)關(guān)系。

給出一組數(shù)據(jù):

  

其中x是實(shí)數(shù)域中的二維向量。比如,xi1是第i個(gè)房子的居住面積,xi2是這個(gè)房子的房間數(shù)。 

為了執(zhí)行監(jiān)督學(xué)習(xí),我們需要決定怎樣在計(jì)算機(jī)中表示我們的函數(shù)/假設(shè)。我們可以近似地使用線性函數(shù)來表示。 

(矩陣形式)

現(xiàn)在,有了訓(xùn)練數(shù)據(jù),我們怎么挑選,或者說得知θ的值呢?一個(gè)可信的方法是使得h(x)與y更加接近,至少對于我們訓(xùn)練的例子來說是這樣的。

于是,我們定義一個(gè)損失函數(shù) / 成本函數(shù)( loss function / cost function ): 

我們把 x 到 y 的映射函數(shù) f 記作 θ 的函數(shù) hθ(x)

損失函數(shù)有很多種類型,根據(jù)需求進(jìn)行選擇。

然后進(jìn)行最小化損失函數(shù),將函數(shù)優(yōu)化成凸函數(shù) (往往只會(huì)有一個(gè)全局最優(yōu)解,不用過多擔(dān)心算法收斂到局部最優(yōu)解) 。

梯度下降 ( Gradient Descent algorithm )

  最快的速度最小化損失函數(shù),比作如何最快地下山,也就是每一步都應(yīng)該往坡度最陡的方向往下走,而坡度最陡的方向就是損失函數(shù)相應(yīng)的偏導(dǎo)數(shù)

因此算法迭代的規(guī)則是:

假設(shè)現(xiàn)在有n個(gè)特征、或者變量x(j=1…n)

其中α是算法的參數(shù)learning rate,α越大每一步下降的幅度越大,速度也會(huì)越快,但過大有可能反復(fù)震蕩,導(dǎo)致算法不準(zhǔn)確。

欠擬合與過擬合(Underfitting and Overfitting)

  欠擬合問題:特征值少,模型過于簡單不足與支撐。

  過擬合問題:有非常多特征,模型很復(fù)雜, 我們的假設(shè)函數(shù)曲線可以對原始數(shù)據(jù)擬合得非常好, 但喪失了一般性, 從而導(dǎo)致對新給的待預(yù)測樣本,預(yù)測效果差。

正則項(xiàng)、正則化

  通過正則項(xiàng)控制參數(shù)幅度。

正則項(xiàng)有多種方式選擇,常采用的有:

  L1正則:|θj|

  L2正則:θj2

 

Logistic 回歸(Logistic Regression)

采用線性回歸解決分類問題時(shí),往往會(huì)遇到模型健壯性低,遇到噪聲時(shí),受干擾嚴(yán)重。

我們可以對舊的線性回歸算法來進(jìn)行適當(dāng)?shù)男薷膩淼玫轿覀兿胍暮瘮?shù)。

引入sigmoid 函數(shù):

對原函數(shù)hθ(x)進(jìn)行改寫得到:

觀察函數(shù)圖像發(fā)現(xiàn):當(dāng)x大于0時(shí),y的值大于0.5,根據(jù)這特性可以將線性回歸得到的預(yù)測值壓縮在0~1范圍內(nèi)。

1.線性判定邊界:

假設(shè)線性函數(shù)為:,

當(dāng) hθ(x) > 0 時(shí),g(hθ(x)) 的值為大于 0.5;

當(dāng) hθ(x) < 0 時(shí),g(hθ(x)) 的值為小于 0.5;

2.非線性判定邊界:

假設(shè)函數(shù)為:

當(dāng)θ0=0,θ1=0,θ2=0,θ3=1,θ4=1,得到函數(shù)g(x12+x22-1),邊界為一個(gè)圓,圓內(nèi)點(diǎn)的值小于0

定義損失函數(shù):

該函數(shù)為非凸函數(shù),有局部最小值,應(yīng)選擇其他函數(shù)。

定義損失函數(shù)為:

該函數(shù)的圖像如下:

 

我們可以發(fā)現(xiàn)該函數(shù)在:

y=1的正樣本中,hθ(x)趨向于0.99~9 ,此時(shí)我們希望得到的代價(jià)越小,而當(dāng)?shù)玫降念A(yù)測值是0.00~1時(shí),我們希望它的代價(jià)越大;

y=0的負(fù)樣本中,hθ(x)趨向于0.00~1 ,此時(shí)我們希望得到的代價(jià)越小,而當(dāng)?shù)玫降念A(yù)測值是0.99~9時(shí),我們希望它的代價(jià)越大;

損失函數(shù)可以改寫成

加入正則項(xiàng):

二分類與多分類

one vs one

one vs rest

方法一:

1.先對三角形與叉叉進(jìn)行分類,得到分類器C1,以及概率值Pc1(x) 和 1-Pc1(x)

2.然后對三角形與正方形進(jìn)行分類,得到分類器C2,以及概率值Pc2(x) 和 1-Pc2(x)

3.最后對正方形與叉叉進(jìn)行分類,得到分類器C3,以及概率值Pc3(x) 和 1-Pc3(x)

得到通過3個(gè)分類器,6個(gè)概率值,概率值最大的判斷為相應(yīng)的類型!

方法二:

1.先對三角形進(jìn)行分類,判斷是否為三角形,得到分類器C1,以及概率值Pc1(x)

2.然后對正方形進(jìn)行分類,判斷是否為正方形,得到分類器C2,以及概率值Pc2(x)

3.最后對叉叉叉進(jìn)行分類,判斷是否為叉叉叉,得到分類器C3,以及概率值Pc3(x)

得到3個(gè)分類器,3個(gè)概率值,概率值最大的判斷為相應(yīng)的類型!

 

應(yīng)用一:( Linear Regression )

1、導(dǎo)入相應(yīng)的包,設(shè)置畫圖格式:

1
2
3
4
5
6
7
8
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_context('notebook')
sns.set_style('white')
plt.figure(figsize=(8,6))

2、數(shù)據(jù)準(zhǔn)備:                                                                           ??下載地址

1
2
3
4
df = pd.read_csv(r'..\..\input\data1.txt',header=None,names=['x','y'])
xdata = np.c_[np.ones(df.shape[0]),df['x']]           # 轉(zhuǎn)換成numpy 形式
ydata = np.c_[df['y']]

3、畫出數(shù)據(jù)的散點(diǎn)圖:

1
2
3
4
5
plt.scatter(xdata[:,1],ydata,s=50,marker='x',color='r')
plt.xlim(4,24)
plt.xlabel('Population of City in 10,000s')
plt.ylabel('Profit in $10,000s');
plt.show()

4、定義Loss function:

1
2
3
4
5
6
def computeCost(x,y,theta=[[0],[0]]):
    m = y.size
    h = x.dot(theta)
    j = 0
    j = 1.0/(2*m)*(np.sum(np.square(h-y)))
    return j

5、定義梯度下降算法:

1
2
3
4
5
6
7
8
9
def gradientDescent(x,y,theta=[[0],[0]],alpha=0.01, num_iters=1500):
    m = y.size
    J_history = np.zeros(num_iters)
     
    for i in range(num_iters):
        h = x.dot(theta)
        theta = theta - alpha * (1.0/m) * (x.T.dot(h-y))
        J_history[i]  = computeCost(x,y,theta)
    return (theta,J_history)

6、計(jì)算&畫圖:

1
2
3
4
5
6
7
8
theta,Cost_J = gradientDescent(xdata,ydata)
print('theta: ',theta.ravel())                       # theta:  [-3.63029144  1.16636235]
plt.figure(figsize=(8,6))
plt.plot(Cost_J)
plt.ylabel('Cost J')
plt.xlabel('Iterations');
plt.show()

得到θ的變化曲線:

通過計(jì)算我們能夠得到 θ 的兩個(gè)值,由此我們能畫出一條與預(yù)測直線。

1
2
xx = np.arange(5,23)              # 生成直線上的點(diǎn)
yy = theta[0]+theta[1]*xx         # 計(jì)算出直線的方程表達(dá)式

7、散點(diǎn)圖中畫出直線 與 sklearn得到的結(jié)果進(jìn)行對比:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 畫出我們自己寫的線性回歸梯度下降收斂的情況
plt.figure(figsize=(8,6))
plt.scatter(xdata[:,1],ydata,s=50,marker='x',color='r')
plt.plot(xx,yy, label='Linear regression (Gradient descent)',c='b')
# 和Scikit-learn中的線性回歸對比一下
from sklearn.linear_model import LinearRegression
regr = LinearRegression()
regr.fit(xdata[:,1].reshape(-1,1), ydata.ravel())
plt.plot(xx, regr.intercept_+regr.coef_*xx, label='Linear regression (Scikit-learn GLM)',c='g')
plt.xlim(4,24)
plt.xlabel('Population of City in 10,000s')
plt.ylabel('Profit in $10,000s');
plt.legend(loc=4);
plt.show()

可以看出兩條直線是非常接近的!

8、進(jìn)行數(shù)據(jù)的預(yù)測:

1
2
3
4
5
6
# 預(yù)測一下人口為35000和70000的城市的結(jié)果
print(theta.T.dot([1, 3.5])*10000)
print(theta.T.dot([1, 7])*10000)
[ 4519.7678677]
[ 45342.45012945]

補(bǔ)充:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
numpy.c_              # 將切片對象轉(zhuǎn)換為沿第二軸的連接。
>>> np.c_[np.array([[1,2,3]]), 0, 0, np.array([[4,5,6]])]  
array([[1, 2, 3, 0, 0, 4, 5, 6]])        # 1行8列!
#######################################
numpy.ravel           # 返回一個(gè)連續(xù)的扁平數(shù)組。
>>> x = np.array([[1, 2, 3], [4, 5, 6]])
>>> print(np.ravel(x))
[1 2 3 4 5 6]
#######################################
numpy.reshape(-1,1)   # 為數(shù)組提供新形狀,而不更改其數(shù)據(jù)。
此為: n行1

  

應(yīng)用二:( Logistic Regression )

1、導(dǎo)入相應(yīng)的包,設(shè)置畫圖格式:

1
2
3
4
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

2、數(shù)據(jù)準(zhǔn)備

1
2
3
4
data = np.loadtxt(file, delimiter=delimeter)
X = np.c_[np.ones((data.shape[0],1)), data[:,0:2]]
y = np.c_[data[:,2]]

3、畫出樣本的散點(diǎn)圖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def plotData(data, label_x, label_y, label_pos, label_neg, axes=None):
    # 獲得正負(fù)樣本的下標(biāo)(即哪些是正樣本,哪些是負(fù)樣本)
    neg = data[:,2] == 0
    pos = data[:,2] == 1
     
    if axes == None:
        axes = plt.gca()
    axes.scatter(data[pos][:,0], data[pos][:,1], marker='+', c='k', s=60, linewidth=2, label=label_pos)
    axes.scatter(data[neg][:,0], data[neg][:,1], c='y', s=60, label=label_neg)
    axes.set_xlabel(label_x)
    axes.set_ylabel(label_y)
    axes.legend(frameon= True, fancybox = True);
plt.figure(figsize=(8,6))
plotData(data, 'Exam 1 score', 'Exam 2 score', 'Pass', 'Fail')

4、定義sigmoid函數(shù)

1
2
def sigmoid(z):
    return 1 / ( 1 + np.exp(-z) )

5、定義損失函數(shù)

1
2
3
4
5
6
7
8
9
def costFunction(theta, X, y):
    m = y.size
    h = sigmoid(X.dot(theta))
     
    J = -1.0*(1.0/m)*(np.log(h).T.dot(y)+np.log(1-h).T.dot(1-y))
     
    if np.isnan(J[0]):
        return(np.inf)
    return J[0]

6、求解剃度函數(shù):

1
2
3
4
5
def gradient(theta, X, y):
    m = y.size
    h = sigmoid(X.dot(theta.reshape(-1,1)))<br>
    grad =(1.0/m)*X.T.dot(h-y)<br>
    return(grad.flatten())

7、最小化損失函數(shù):

1
2
initial_theta = np.zeros(X.shape[1])
res = minimize(costFunction, initial_theta, args=(X,y), jac=gradient, options={'maxiter':400})

8、預(yù)測:

1
sigmoid(np.array([1, 45, 85]).dot(res.x.T))

9、畫出決策邊界

1
2
3
4
5
6
7
8
plt.scatter(45, 85, s=60, c='r', marker='v', label='(45, 85)')
plotData(data, 'Exam 1 score', 'Exam 2 score', 'Admitted', 'Not admitted')
x1_min, x1_max = X[:,1].min(), X[:,1].max(),
x2_min, x2_max = X[:,2].min(), X[:,2].max(),
xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max))
h = sigmoid(np.c_[np.ones((xx1.ravel().shape[0],1)), xx1.ravel(), xx2.ravel()].dot(res.x))
h = h.reshape(xx1.shape)
plt.contour(xx1, xx2, h, [0.5], linewidths=1, colors='b');

10、添加正則項(xiàng):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def costFunctionReg(theta, reg, *args):
    m = y.size
    h = sigmoid(XX.dot(theta))
     
    J = -1.0*(1.0/m)*(np.log(h).T.dot(y)+np.log(1-h).T.dot(1-y)) + (reg/(2.0*m))*np.sum(np.square(theta[1:]))
     
    if np.isnan(J[0]):
        return(np.inf)
    return(J[0])
def gradientReg(theta, reg, *args):
    m = y.size
    h = sigmoid(XX.dot(theta.reshape(-1,1)))
       
    grad = (1.0/m)*XX.T.dot(h-y) + (reg/m)*np.r_[[[0]],theta[1:].reshape(-1,1)]
         
    return(grad.flatten())

11、最優(yōu)化:

1
2
# C = [0.0, 1.0, 100.0]
res2 = minimize(costFunctionReg, initial_theta, args=(C, XX, y), jac=gradientReg, options={'maxiter':3000})

  

Kaggle比賽應(yīng)用:

San Francisco Crime Classification

Predict the category of crimes that occurred in the city by the bay

復(fù)制代碼
import pandas as pd
import numpy as np

train = pd.read_csv('\\train.csv')
test = pd.read_csv('\\test.csv')

all_address = list(np.array(train['Address'].tolist() + test['Address'].tolist()))

from sklearn.feature_extraction.text import CountVectorizer
stop_words = ['dr', 'wy', 'bl', 'av', 'st', 'ct', 'ln', 'block', 'of']
vectorizer = CountVectorizer(max_features=300, stop_words=stop_words)
features = vectorizer.fit_transform(all_address).toarray()

X = features[:train.shape[0]]
y = train.Category

#分成80%的訓(xùn)練集和20%的驗(yàn)證集
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=44)

from sklearn.linear_model import LogisticRegression
log_model = LogisticRegression()
log_model.fit(X_train,y_train)
results = log_model.predict_proba(X_test)

from sklearn.metrics import log_loss
log_loss_score = log_loss(y_test, results)
print('log loss score: {0}'.format(round(log_loss_score, 3)))
# log loss score: 2.511

# 使用整個(gè)train
log_model = LogisticRegression().fit(X=features[:train.shape[0]], y=train.Category)
results = log_model.predict_proba(features[train.shape[0]:])

submission = pd.DataFrame(results)
submission.columns = sorted(train.Category.unique())
submission.set_index(test.Id)
submission.index.name="Id"
submission.to_csv('py_submission_logreg_addr_300.csv')
復(fù)制代碼

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多