<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 如何利用Python從頭開始隨機梯度下降實現Logistic回歸 > 原文: [https://machinelearningmastery.com/implement-logistic-regression-stochastic-gradient-descent-scratch-python/](https://machinelearningmastery.com/implement-logistic-regression-stochastic-gradient-descent-scratch-python/) Logistic回歸是兩類問題的首選線性分類算法。 它易于實現,易于理解,并且可以在各種各樣的問題上獲得很好的結果,即使這些方法對您的數據的期望受到侵犯也是如此。 在本教程中,您將了解如何使用Python從頭開始隨機梯度下降實現邏輯回歸。 完成本教程后,您將了解: * 如何使用邏輯回歸模型進行預測。 * 如何使用隨機梯度下降估計系數。 * 如何將邏輯回歸應用于實際預測問題。 讓我們開始吧。 * **2017年1月更新**:將cross_validation_split()中的fold_size計算更改為始終為整數。修復了Python 3的問題。 * **更新Mar / 2018** :添加了備用鏈接以下載數據集,因為原始圖像已被刪除。 * **更新Aug / 2018** :經過測試和更新,可與Python 3.6配合使用。 ![How To Implement Logistic Regression With Stochastic Gradient Descent From Scratch With Python](img/5bf94c3190b2f31398104e303c49125d.jpg) 如何使用隨機梯度下降實現Logistic回歸從Python [照片](https://www.flickr.com/photos/31246066@N04/15171955576/) [Ian Sane](https://www.flickr.com/photos/31246066@N04/15171955576/) ,保留一些權利。 ## 描述 本節將簡要介紹邏輯回歸技術,隨機梯度下降和我們將在本教程中使用的Pima Indians糖尿病數據集。 ### Logistic回歸 邏輯回歸以在該方法的核心使用的函數命名,即邏輯函數。 Logistic回歸使用方程作為表示,非常類似于線性回歸。使用權重或系數值線性組合輸入值( **X** )以預測輸出值( **y** )。 與線性回歸的主要區別在于,建模的輸出值是二進制值(0或1)而不是數值。 ```py yhat = e^(b0 + b1 * x1) / (1 + e^(b0 + b1 * x1)) ``` 這可以簡化為: ```py yhat = 1.0 / (1.0 + e^(-(b0 + b1 * x1))) ``` 其中 **e** 是自然對數(歐拉數)的基礎, **yhat** 是預測輸出, **b0** 是偏差或截距項和 **b1** 是單輸入值的系數( **x1** )。 yhat預測是0到1之間的實數值,需要舍入為整數值并映射到預測的類值。 輸入數據中的每一列都有一個相關的b系數(一個恒定的實際值),必須從訓練數據中學習。您將存儲在存儲器或文件中的模型的實際表示是等式中的系數(β值或b)。 邏輯回歸算法的系數必須根據您的訓練數據進行估算。 ### 隨機梯度下降 梯度下降是通過遵循成本函數的梯度來最小化函數的過程。 這包括了解成本的形式以及衍生物,以便從給定的點知道梯度并且可以在該方向上移動,例如,向下走向最小值。 在機器學習中,我們可以使用一種技術來評估和更新稱為隨機梯度下降的每次迭代的系數,以最小化模型對我們的訓練數據的誤差。 此優化算法的工作方式是每個訓練實例一次顯示給模型一個。該模型對訓練實例進行預測,計算誤差并更新模型以減少下一次預測的誤差。 該過程可用于在模型中找到導致訓練數據上模型的最小誤差的系數集。每次迭代,機器學習語言中的系數(b)使用以下等式更新: ```py b = b + learning_rate * (y - yhat) * yhat * (1 - yhat) * x ``` **b** 是被優化的系數或權重, **learning_rate** 是你必須配置的學習率(例如0.01),**(y - yhat)**是預測對于歸因于權重的訓練數據的模型的誤差, **yhat** 是由系數做出的預測, **x** 是輸入值。 ### 皮馬印第安人糖尿病數據集 Pima Indians數據集涉及在皮馬印第安人中預測5年內糖尿病的發病情況,并提供基本醫療細節。 這是一個二元分類問題,其中預測是0(無糖尿病)或1(糖尿病)。 它包含768行和9列。文件中的所有值都是數字,特別是浮點值。下面是問題前幾行的一小部分樣本。 ```py 6,148,72,35,0,33.6,0.627,50,1 1,85,66,29,0,26.6,0.351,31,0 8,183,64,0,0,23.3,0.672,32,1 1,89,66,23,94,28.1,0.167,21,0 0,137,40,35,168,43.1,2.288,33,1 ... ``` 預測多數類(零規則算法),該問題的基線表現為65.098%分類精度。 您可以在 [UCI機器學習庫](https://archive.ics.uci.edu/ml/datasets/Pima+Indians+Diabetes)上了解有關此數據集的更多信息(更新:[從此處下載](https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv))。 下載數據集并使用文件名 **pima-indians-diabetes.csv** 將其保存到當前工作目錄。 ## 教程 本教程分為3個部分。 1. 做出預測。 2. 估計系數。 3. 糖尿病預測。 這將為您自己的預測建模問題提供實施和應用具有隨機梯度下降的邏輯回歸所需的基礎。 ### 1.做出預測 第一步是開發一個可以進行預測的功能。 在隨機梯度下降中的候選系數值的評估中以及在模型完成之后,我們希望開始對測試數據或新數據進行預測。 下面是一個名為 **predict()**的函數,它預測給定一組系數的行的輸出值。 第一個系數in總是截距,也稱為偏差或b0,因為它是獨立的,不負責特定的輸入值。 ```py # Make a prediction with coefficients def predict(row, coefficients): yhat = coefficients[0] for i in range(len(row)-1): yhat += coefficients[i + 1] * row[i] return 1.0 / (1.0 + exp(-yhat)) ``` 我們可以設計一個小數據集來測試我們的 **predict()**函數。 ```py X1 X2 Y 2.7810836 2.550537003 0 1.465489372 2.362125076 0 3.396561688 4.400293529 0 1.38807019 1.850220317 0 3.06407232 3.005305973 0 7.627531214 2.759262235 1 5.332441248 2.088626775 1 6.922596716 1.77106367 1 8.675418651 -0.242068655 1 7.673756466 3.508563011 1 ``` 下面是使用不同顏色的數據集的圖,以顯示每個點的不同類。 ![Small Contrived Classification Dataset](img/1185be78011e6ed0a7abd2f441ce26dc.jpg) 小型受控分類數據集 我們還可以使用先前準備的系數來對該數據集進行預測。 綜合這些,我們可以測試下面的 **predict()**函數。 ```py # Make a prediction from math import exp # Make a prediction with coefficients def predict(row, coefficients): yhat = coefficients[0] for i in range(len(row)-1): yhat += coefficients[i + 1] * row[i] return 1.0 / (1.0 + exp(-yhat)) # test predictions dataset = [[2.7810836,2.550537003,0], [1.465489372,2.362125076,0], [3.396561688,4.400293529,0], [1.38807019,1.850220317,0], [3.06407232,3.005305973,0], [7.627531214,2.759262235,1], [5.332441248,2.088626775,1], [6.922596716,1.77106367,1], [8.675418651,-0.242068655,1], [7.673756466,3.508563011,1]] coef = [-0.406605464, 0.852573316, -1.104746259] for row in dataset: yhat = predict(row, coef) print("Expected=%.3f, Predicted=%.3f [%d]" % (row[-1], yhat, round(yhat))) ``` 有兩個輸入值(X1和X2)和三個系數值(b0,b1和b2)。我們為這個問題建模的預測方程是: ```py y = 1.0 / (1.0 + e^(-(b0 + b1 * X1 + b2 * X2))) ``` 或者,我們手動選擇的具體系數值為: ```py y = 1.0 / (1.0 + e^(-(-0.406605464 + 0.852573316 * X1 + -1.104746259 * X2))) ``` 運行此函數,我們可以得到與預期輸出(y)值相當接近的預測,并在舍入時對類進行正確的預測。 ```py Expected=0.000, Predicted=0.299 [0] Expected=0.000, Predicted=0.146 [0] Expected=0.000, Predicted=0.085 [0] Expected=0.000, Predicted=0.220 [0] Expected=0.000, Predicted=0.247 [0] Expected=1.000, Predicted=0.955 [1] Expected=1.000, Predicted=0.862 [1] Expected=1.000, Predicted=0.972 [1] Expected=1.000, Predicted=0.999 [1] Expected=1.000, Predicted=0.905 [1] ``` 現在我們準備實施隨機梯度下降來優化我們的系數值。 ### 2.估計系數 我們可以使用隨機梯度下降來估計訓練數據的系數值。 隨機梯度下降需要兩個參數: * **學習率**:用于限制每次更新時每個系數的校正量。 * **時期**:更新系數時運行訓練數據的次數。 這些以及訓練數據將是該函數的參數。 我們需要在函數中執行3個循環: 1. 循環每個時代。 2. 循環遍歷訓練數據中的每一行以獲得一個迭代。 3. 循環遍歷每個系數并將其更新為一個迭代中的一行。 如您所見,我們更新訓練數據中每一行的每個系數,每個時期。 系數根據模型產生的誤差進行更新。該誤差被計算為預期輸出值與利用候選系數進行的預測之間的差異。 有一個系數可以對每個輸入屬性進行加權,并且這些系數以一致的方式更新,例如: ```py b1(t+1) = b1(t) + learning_rate * (y(t) - yhat(t)) * yhat(t) * (1 - yhat(t)) * x1(t) ``` 列表開頭的特殊系數(也稱為截距)以類似的方式更新,除非沒有輸入,因為它與特定輸入值無關: ```py b0(t+1) = b0(t) + learning_rate * (y(t) - yhat(t)) * yhat(t) * (1 - yhat(t)) ``` 現在我們可以將所有這些放在一起。下面是一個名為 **coefficients_sgd()**的函數,它使用隨機梯度下降計算訓練數據集的系數值。 ```py # Estimate logistic regression coefficients using stochastic gradient descent def coefficients_sgd(train, l_rate, n_epoch): coef = [0.0 for i in range(len(train[0]))] for epoch in range(n_epoch): sum_error = 0 for row in train: yhat = predict(row, coef) error = row[-1] - yhat sum_error += error**2 coef[0] = coef[0] + l_rate * error * yhat * (1.0 - yhat) for i in range(len(row)-1): coef[i + 1] = coef[i + 1] + l_rate * error * yhat * (1.0 - yhat) * row[i] print('>epoch=%d, lrate=%.3f, error=%.3f' % (epoch, l_rate, sum_error)) return coef ``` 你可以看到,此外,我們跟蹤每個時期的平方誤差(正值)的總和,這樣我們就可以在每個外環中打印出一條好消息。 我們可以在上面的同樣小的人為數據集上測試這個函數。 ```py from math import exp # Make a prediction with coefficients def predict(row, coefficients): yhat = coefficients[0] for i in range(len(row)-1): yhat += coefficients[i + 1] * row[i] return 1.0 / (1.0 + exp(-yhat)) # Estimate logistic regression coefficients using stochastic gradient descent def coefficients_sgd(train, l_rate, n_epoch): coef = [0.0 for i in range(len(train[0]))] for epoch in range(n_epoch): sum_error = 0 for row in train: yhat = predict(row, coef) error = row[-1] - yhat sum_error += error**2 coef[0] = coef[0] + l_rate * error * yhat * (1.0 - yhat) for i in range(len(row)-1): coef[i + 1] = coef[i + 1] + l_rate * error * yhat * (1.0 - yhat) * row[i] print('>epoch=%d, lrate=%.3f, error=%.3f' % (epoch, l_rate, sum_error)) return coef # Calculate coefficients dataset = [[2.7810836,2.550537003,0], [1.465489372,2.362125076,0], [3.396561688,4.400293529,0], [1.38807019,1.850220317,0], [3.06407232,3.005305973,0], [7.627531214,2.759262235,1], [5.332441248,2.088626775,1], [6.922596716,1.77106367,1], [8.675418651,-0.242068655,1], [7.673756466,3.508563011,1]] l_rate = 0.3 n_epoch = 100 coef = coefficients_sgd(dataset, l_rate, n_epoch) print(coef) ``` 我們使用更大的學習率0.3并且將模型訓練100個時期,或者將系數的100次曝光訓練到整個訓練數據集。 運行該示例在每個時期打印一條消息,該消息包含該時期的總和平方誤差和最后一組系數。 ```py >epoch=95, lrate=0.300, error=0.023 >epoch=96, lrate=0.300, error=0.023 >epoch=97, lrate=0.300, error=0.023 >epoch=98, lrate=0.300, error=0.023 >epoch=99, lrate=0.300, error=0.022 [-0.8596443546618897, 1.5223825112460005, -2.218700210565016] ``` 你可以看到即使在最后一個時代,錯誤仍會繼續下降。我們可以訓練更長時間(更多迭代)或增加每個時期更新系數的量(更高的學習率)。 試驗并看看你提出了什么。 現在,讓我們將這個算法應用于真實數據集。 ### 3.糖尿病預測 在本節中,我們將使用糖尿病數據集上的隨機梯度下降來訓練邏輯回歸模型。 該示例假定數據集的CSV副本位于當前工作目錄中,文件名為 **pima-indians-diabetes.csv** 。 首先加載數據集,將字符串值轉換為數字,并將每列標準化為0到1范圍內的值。這是通過輔助函數 **load_csv()**和 **str_column_to_float()實現的。** 加載并準備數據集和 **dataset_minmax()**和 **normalize_dataset()**來規范化它。 我們將使用k-fold交叉驗證來估計學習模型在看不見的數據上的表現。這意味著我們將構建和評估k模型并將表現估計為平均模型表現。分類精度將用于評估每個模型。這些行為在 **cross_validation_split()**, **accuracy_metric()**和 **evaluate_algorithm()**輔助函數中提供。 我們將使用上面創建的 **predict()**, **coefficient_sgd()**函數和新的 **logistic_regression()**函數來訓練模型。 以下是完整的示例。 ```py # Logistic Regression on Diabetes Dataset from random import seed from random import randrange from csv import reader from math import exp # Load a CSV file def load_csv(filename): dataset = list() with open(filename, 'r') as file: csv_reader = reader(file) for row in csv_reader: if not row: continue dataset.append(row) return dataset # Convert string column to float def str_column_to_float(dataset, column): for row in dataset: row[column] = float(row[column].strip()) # Find the min and max values for each column def dataset_minmax(dataset): minmax = list() for i in range(len(dataset[0])): col_values = [row[i] for row in dataset] value_min = min(col_values) value_max = max(col_values) minmax.append([value_min, value_max]) return minmax # Rescale dataset columns to the range 0-1 def normalize_dataset(dataset, minmax): for row in dataset: for i in range(len(row)): row[i] = (row[i] - minmax[i][0]) / (minmax[i][1] - minmax[i][0]) # Split a dataset into k folds def cross_validation_split(dataset, n_folds): dataset_split = list() dataset_copy = list(dataset) fold_size = int(len(dataset) / n_folds) for i in range(n_folds): fold = list() while len(fold) < fold_size: index = randrange(len(dataset_copy)) fold.append(dataset_copy.pop(index)) dataset_split.append(fold) return dataset_split # Calculate accuracy percentage def accuracy_metric(actual, predicted): correct = 0 for i in range(len(actual)): if actual[i] == predicted[i]: correct += 1 return correct / float(len(actual)) * 100.0 # Evaluate an algorithm using a cross validation split def evaluate_algorithm(dataset, algorithm, n_folds, *args): folds = cross_validation_split(dataset, n_folds) scores = list() for fold in folds: train_set = list(folds) train_set.remove(fold) train_set = sum(train_set, []) test_set = list() for row in fold: row_copy = list(row) test_set.append(row_copy) row_copy[-1] = None predicted = algorithm(train_set, test_set, *args) actual = [row[-1] for row in fold] accuracy = accuracy_metric(actual, predicted) scores.append(accuracy) return scores # Make a prediction with coefficients def predict(row, coefficients): yhat = coefficients[0] for i in range(len(row)-1): yhat += coefficients[i + 1] * row[i] return 1.0 / (1.0 + exp(-yhat)) # Estimate logistic regression coefficients using stochastic gradient descent def coefficients_sgd(train, l_rate, n_epoch): coef = [0.0 for i in range(len(train[0]))] for epoch in range(n_epoch): for row in train: yhat = predict(row, coef) error = row[-1] - yhat coef[0] = coef[0] + l_rate * error * yhat * (1.0 - yhat) for i in range(len(row)-1): coef[i + 1] = coef[i + 1] + l_rate * error * yhat * (1.0 - yhat) * row[i] return coef # Linear Regression Algorithm With Stochastic Gradient Descent def logistic_regression(train, test, l_rate, n_epoch): predictions = list() coef = coefficients_sgd(train, l_rate, n_epoch) for row in test: yhat = predict(row, coef) yhat = round(yhat) predictions.append(yhat) return(predictions) # Test the logistic regression algorithm on the diabetes dataset seed(1) # load and prepare data filename = 'pima-indians-diabetes.csv' dataset = load_csv(filename) for i in range(len(dataset[0])): str_column_to_float(dataset, i) # normalize minmax = dataset_minmax(dataset) normalize_dataset(dataset, minmax) # evaluate algorithm n_folds = 5 l_rate = 0.1 n_epoch = 100 scores = evaluate_algorithm(dataset, logistic_regression, n_folds, l_rate, n_epoch) print('Scores: %s' % scores) print('Mean Accuracy: %.3f%%' % (sum(scores)/float(len(scores)))) ``` k值為5用于交叉驗證,每次迭代時評估每個折疊768/5 = 153.6或僅超過150個記錄。通過一些實驗選擇了0.1和100個訓練時期的學習率。 您可以嘗試自己的配置,看看是否可以打敗我的分數。 運行此示例將打印5個交叉驗證折疊中每個折疊的分數,然后打印平均分類精度。 我們可以看到,如果我們使用零規則算法預測大多數類,精度約為77%,高于基線值65%。 ```py Scores: [73.8562091503268, 78.43137254901961, 81.69934640522875, 75.81699346405229, 75.81699346405229] Mean Accuracy: 77.124% ``` ## 擴展 本節列出了本教程的一些擴展,您可能希望考慮這些擴展。 * **調整示例**。調整學習率,時期數甚至數據準備方法以獲得數據集上的改進分數。 * **批隨機梯度下降**。改變隨機梯度下降算法以在每個時期累積更新,并且僅在時期結束時批量更新系數。 * **其他分類問題**。將該技術應用于UCI機器學習庫中的其他二進制(2類)分類問題。 **你有沒有探索過這些擴展?** 請在下面的評論中告訴我。 ## 評論 在本教程中,您了解了如何使用Python從頭開始使用隨機梯度下降來實現邏輯回歸。 你學到了 * 如何預測多變量分類問題。 * 如何使用隨機梯度下降來優化一組系數。 * 如何將該技術應用于真實的分類預測建模問題。 **你有什么問題嗎?** 在下面的評論中提出您的問題,我會盡力回答。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看