CoolFace
Apppublic

aliakyurek/LinearRegression1_OLS

sourceHugging Faceupdated 4y agoView on Hugging Face
0likes
app.py150 linesDownload Raw Back to root
1import pandas as pd
2import numpy as np
3import matplotlib
4matplotlib.use("Agg")
5import matplotlib.pyplot as plt
6import gradio as gr
7
8def load_dataset(n=100, w = 0.4, b=5., x_range = [0, 50]):
9    np.random.seed(42)
10    def s(x):
11        g = (x - x_range[0]) / (x_range[1] - x_range[0])
12        return 5 * (0.25 + g**2.)
13
14    x = (x_range[1] - x_range[0]) * np.random.rand(n) + x_range[0]
15    eps = np.random.randn(n) * s(x)
16    y = (w * x * (1. + np.sin(x)/5) + b) + eps
17    y = (y - y.mean()) / y.std()
18    idx = np.argsort(x)
19    return pd.DataFrame({"x": x[idx], "y": y[idx]})
20
21def check_sanitize_data(inp):
22    try:
23        inp=inp.astype(float)
24    except:
25        return None, [("Data points not numeric", "Error")]
26    x,y = inp["x"].to_numpy(), inp["y"].to_numpy()
27    if(len(x)<2):
28        return None, [("Data points not provided", "Error")]
29    return (x,y), [("", "OK")]
30
31def plot_data(inp, m=None, b=None):
32    xy, status = check_sanitize_data(inp)
33    if xy is None:
34        return None, status
35    x, y = xy
36    fig,ax = plt.subplots()
37    ax.set(aspect=np.std(x).item()/3, ylabel="Y-axis")
38    ax.plot(x, y, "o", label="Original data", markersize=2)
39    # center text
40    # fig.text(.5, .05, "OLS", ha="center")
41    if(m):
42        y_hat = m * x + b
43        rss = np.sum((y-y_hat)**2)
44        ax.set(xlabel = f"RSS:{rss:.4f}")
45        ax.xaxis.label.set(color="red")
46        ax.plot(x, m * x + b, "r", label="Fitted line")
47    ax.legend()
48    ax.grid()
49    fig.tight_layout()
50    return fig, [("Data check", "OK")]
51
52def linear_regression_from_scratch(X,y):
53    XT_X = np.matmul(X.T, X)
54    XT_y = np.matmul(X.T, y)
55    m,b = np.matmul(np.linalg.inv(XT_X), XT_y)
56    return m,b
57
58def linear_regression_linalg_lstsq(X,y):
59    (m,b),*_ = np.linalg.lstsq(X, y, rcond=None)
60    return m,b
61
62def linear_regression_plot(method, inp):
63    xy, status = check_sanitize_data(inp)
64    if xy is None:
65        return None, status
66    x,y = xy
67    X = np.column_stack((x, np.ones(len(x))))
68    if method == "numpy from scratch":
69        m, b = linear_regression_from_scratch(X, y)
70    elif method == "numpy.linalg.lstsq":
71        m, b = linear_regression_linalg_lstsq(X, y)
72    else:
73        return None, [("Method not selected", "Error")]
74    fig, _ = plot_data(inp, m, b)
75    return fig, [("Regression", "OK")]
76
77data = load_dataset()
78block_params = {
79    "title": "Ordinary Least Squares",
80    "css": """
81            #XY {max-height: 350px; overflow-y: scroll}
82            #images img {width:auto; height:auto}
83            #images .flex {display:none; height:auto}
84            #accord > div > span {font-weight: bold}
85            """
86}
87plot_data(data)
88
89with gr.Blocks(**block_params) as demo:
90    with gr.Row():
91        with gr.Column(scale=1):
92
93            data_frm = gr.Dataframe(headers=data.columns.tolist(),
94                                datatype=["number", "number"],
95                                col_count=(2, "fixed"), elem_id="XY"
96                                )
97            plot_btn = gr.Button("Check&Plot")
98            gr.Examples([[data.values.tolist()]], inputs=data_frm)
99            gr.Markdown("""
100                        #### How to use?
101                        1.Fill the x-y table below (or use the example data provided)  
102                        2.**Check&Plot**  
103                        3.Select an implementation   
104                        4.**Regression&Plot**
105                        """)
106        with gr.Column(scale=1):
107            status_hlt = gr.HighlightedText(
108                label="Status",
109                combine_adjacent=True,
110            ).style(color_map={"Error": "red", "OK": "green"})
111            data_plt = gr.Plot(label="Plot")
112            method_dd = gr.Dropdown(label="Select an implementation",choices=["numpy from scratch", "numpy.linalg.lstsq"],)
113            regression_btn = gr.Button("Regression&Plot")
114            # gr.Examples(label="Proofs", examples=[["img.png"]],inputs=img)
115
116    with gr.Accordion("Motivation", open=False, elem_id="accord"):
117        gr.Markdown("""
118                    In this space, I tried to get most out of Gradio an HF. So that this combination can be
119                    used not only for advanced ML models but also to demonstrate the topics regarding
120                    mathematical background of ML. The first topic is Linear Regression optimized with OLS 
121                    """)
122    with gr.Accordion("Model Card", open=False, elem_id="accord"):
123        gr.Markdown("""
124                    | Name | Objective | Metric | Solution |
125                    | -------- | ------- | -------- | -------- |
126                    | Linear regression | Ord. least squares (OLS) | Residual sum-of-squares (RSS) | Analytical |
127                    """)
128    with gr.Accordion("Math Background", open=False, elem_id="accord"):
129        with gr.Row():
130            with gr.Column(scale=1):
131                gr.Markdown("""
132                            We have a linear regression model in (1).  
133                            We want to minimize RSS (2).  
134                            We need the derivative of RSS(β) with respect to β to and set it zero.
135                            The resulting formula is given (3).  
136                            An example matrix represenation of the model y = Xβ is given (4).    
137                            """)
138            with gr.Column(scale=1):
139                img = gr.Image(label="Proof", value="img.png", elem_id="images")
140    with gr.Accordion("References", open=False, elem_id="accord"):
141        links = ("statproofbook.github.io/P/mlr-ols",
142                 "statproofbook.github.io/P/mlr-ols2",
143                 "towardsdatascience.com/building-linear-regression-least-squares-with-linear-algebra-2adf071dd5dd")
144        gr.Markdown("\n".join(f"{i}.[https://{l}](https://{l})  " for i, l in enumerate(links,1)))
145
146    plot_btn.click(fn=plot_data, inputs=data_frm, outputs=[data_plt,status_hlt])
147    regression_btn.click(fn=linear_regression_plot, inputs=[method_dd,data_frm], outputs=[data_plt,status_hlt])
148
149demo.launch()
150