Logistic回归梯度下降

时间:2017-12-13 14:50:50

标签: python logistic-regression gradient-descent

我正在努力做标题,但我无法真正理解如何做到这一点。

如果你能帮助我理解什么是错的将是非常有帮助的。我必须使用批量梯度下降进行Logistic回归。

private async void btnSetDbConnection_OnClick(object sender, RoutedEventArgs e)
{
    string connectionString = null;

    try
    {
        await Task.Run(() =>
        {
            DataConnectionDialog dataConnectionDialog = new DataConnectionDialog();
            Microsoft.Data.ConnectionUI.DataSource.AddStandardDataSources(dataConnectionDialog);
            dataConnectionDialog.SelectedDataSource = Microsoft.Data.ConnectionUI.DataSource.SqlDataSource;
            dataConnectionDialog.SelectedDataProvider = Microsoft.Data.ConnectionUI.DataProvider.SqlDataProvider;

            if (DataConnectionDialog.Show(dataConnectionDialog) == System.Windows.Forms.DialogResult.OK)
            {
                _dataHandler.InitializeConnection(dataConnectionDialog.ConnectionString);
            }
        }).ConfigureAwait(false);
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

我必须这样做的方式就是这样,但我似乎无法理解如何让它发挥作用。

Method

1 个答案:

答案 0 :(得分:5)

看起来你在这里混淆了一些东西。这样做至关重要的是,你要跟踪你的矢量的形状,并确保你得到明智的结果。例如,您使用以下方法计算成本:

cost = ((-y) * np.log(sigmoid(X[i]))) - ((1 - y) * np.log(1 - sigmoid(X[i])))

在您的情况下,y是包含20个项目的向量,X [i]是单个值。这使您的成本计算成为20项向量,这是没有意义的。您的费用应该是单一价值。 (你也在梯度下降函数中无缘无故地计算这个成本)。

此外,如果您希望这能够适合您的数据,则需要向X添加偏见字词。那么让我们从那里开始吧。

X = np.asarray([
    [0.50],[0.75],[1.00],[1.25],[1.50],[1.75],[1.75],
    [2.00],[2.25],[2.50],[2.75],[3.00],[3.25],[3.50],
    [4.00],[4.25],[4.50],[4.75],[5.00],[5.50]])

ones = np.ones(X.shape)
X = np.hstack([ones, X])
# X.shape is now (20, 2)

Theta现在每个X需要2个值。所以初始化它和Y:

Y = np.array([0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1]).reshape([-1, 1])
# reshape Y so it's column vector so matrix multiplication is easier
Theta = np.array([[0], [0]])

你的sigmoid功能很好。我们还制作一个矢量化成本函数:

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

def cost(x, y, theta):
    m = x.shape[0]
    h = sigmoid(np.matmul(x, theta))
    cost = (np.matmul(-y.T, np.log(h)) - np.matmul((1 -y.T), np.log(1 - h)))/m
    return cost

费用函数有效,因为Theta的形状为(2,1),而X的形状为(20,2),因此matmul(X, Theta)将被塑造(20,1 )。 then矩阵乘以Y的转置(y.T形状为(1,20)),这导致单个值,我们的成本给出了Theta的特定值。

然后我们可以编写一个执行批量梯度下降的单一步骤的函数:

def gradient_Descent(theta, alpha, x , y):
    m = x.shape[0]
    h = sigmoid(np.matmul(x, theta))
    grad = np.matmul(X.T, (h - y)) / m;
    theta = theta - alpha * grad
    return theta

注意np.matmul(X.T, (h - y))将形状(2,20)和(20,1)相乘,形状为(2,1) - 形状与Theta相同,这就是你想要的从你的渐变。这允许你乘以你的学习率并从初始的Theta中减去它,这是梯度下降应该做的。

所以现在你只需要编写一个循环进行多次迭代并更新Theta,直到它看起来像收敛:

n_iterations = 500
learning_rate = 0.5

for i in range(n_iterations):
    Theta = gradient_Descent(Theta, learning_rate, X, Y)
    if i % 50 == 0:
        print(cost(X, Y, Theta))

这将每50次迭代打印成本,从而导致成本稳步下降,这是您所希望的:

  

[[0.6410409]]   [[0.44766253]]   [[0.41593581]]   [[0.40697167]]   [[0.40377785]]   [[0.4024982]]   [[0.40195]]   [[0.40170533]]   [[0.40159325]]   [[0.40154101]]

你可以尝试Theta的不同初始值,你会发现它总是收敛到同一个东西。

现在,您可以使用新发现的Theta值进行预测:

h = sigmoid(np.matmul(X, Theta))
print((h > .5).astype(int) )

这将打印您对数据的线性拟合所期望的内容:

  

[[0]    [0]    [0]    [0]    [0]    [0]    [0]    [0]    [0]    [0]    [1]    [1]    [1]    [1]    [1]    [1]    [1]    [1]    [1]    [1]]

相关问题