【问题标题】:How to add a line to a seaborn scatterplot created by an arbitrary function如何在由任意函数创建的 seaborn 散点图中添加一条线
【发布时间】:2020-03-01 14:38:27
【问题描述】:

我希望能够在 python 中创建以下绘图(取自https://en.wikipedia.org/wiki/Logistic_regression#Logistic_model

数据为:

hours = [
    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,
]

passed = [0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1]
df = pd.DataFrame({"hours_study": hours, "passed": passed})

散点图很容易用以下方法创建:

sns.scatterplot(df.hours_study, df.passed)

给予

但我不确定如何在绘图中添加线条(在本例中为逻辑曲线)。

【问题讨论】:

    标签: python plot data-visualization seaborn visualization


    【解决方案1】:

    Matplotlib 的绘图可以在任何现有绘图上绘制曲线。要绘制逻辑函数,只需绘制1 / (1 + exp(-beta0 - beta1 * x)),其中 beta0 和 beta1 是对给定数据拟合逻辑函数的结果。 Scikit Learn的LogisticRegression是一个可以拟合这样一个函数并返回参数的函数:

    import matplotlib.pyplot as plt
    from sklearn.linear_model import LogisticRegression
    import seaborn as sns
    import pandas as pd
    import numpy as np
    
    def draw_logistic_regression_curve(beta0, beta1, x, **kwargs):
        y = 1 / (1 + np.exp(-beta0 - beta1 * x))
        plt.plot(x, y, '-', **kwargs)
    
    
    hours = np.array([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])
    passed = np.array([0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1])
    df = pd.DataFrame({"hours_study": hours, "passed": passed})
    sns.scatterplot(df.hours_study, df.passed)
    
    clf = LogisticRegression().fit(hours.reshape(-1, 1), passed)
    beta0 = clf.intercept_ # -3.13952411
    beta1 = clf.coef_[0] # 1.14860386
    x = np.linspace(min(hours) - 0.5, max(hours) + 0.5, 500)
    draw_logistic_regression_curve(beta0, beta1, x, color='crimson', label="Sklearn's default estimate")
    draw_logistic_regression_curve(-4.0777, 1.5046, x, color='limegreen', label="Wikipedia's estimate")
    plt.legend(loc='center right')
    plt.show()
    

    【讨论】:

    • sklearn 返回的系数似乎不正确(参考维基)。但问题的主要部分是关于绘图,所以谢谢(不太清楚为什么 sklearn 返回不同的值 - 这可能是一个拦截问题吗?)
    • 不,两者都不同,但都不正确。它们只是估计 beta0 和 beta1 的两种不同方法。维基百科页面有beta0 = -4.0777; beta1 = 1.5046,它给出了一个不太不同的曲线。 Sklearn 的LogisticRegression 有很多选项来估计系数,在上面的答案中只使用了默认参数。哪一个是“最好的”,取决于应用领域。
    猜你喜欢
    • 2018-03-17
    • 1970-01-01
    • 2019-08-17
    • 1970-01-01
    • 1970-01-01
    • 2016-09-11
    • 1970-01-01
    • 2021-05-16
    • 2020-11-03
    相关资源
    最近更新 更多