CoolFace
Apppublic

Cash99/r2

sourceHugging Facemitupdated 1y agoView on Hugging Face
0likes
app.py129 linesDownload Raw Back to root
1import pandas as pd2import matplotlib.pyplot as plt3import streamlit as st4import matplotlib as mpl5from io import BytesIO6import numpy as np7 8# 字型設定(繁體中文)9font_path = "SourceHanSansTW-Regular.otf"10mpl.font_manager.fontManager.addfont(font_path)11plt.rcParams['font.family'] = "Source Han Sans TW"12 13# 標題14st.title("📐 R² 傾斜分析工具")15 16# 📘 簡要說明17with st.expander("📘 R² 計算說明", expanded=False):18    st.markdown(r"""19**R²(決定係數)** 是評估資料與趨勢線吻合程度的統計指標,數值範圍為 -∞ 到 1,越接近 1 表示線性趨勢越明顯。20 21其計算公式如下:22 23$$24R^2 = 1 - \frac{SS_{res}}{SS_{tot}}25$$26 27其中:  28- `SS_{res}`:預測殘差平方和(Residual Sum of Squares)  29- `SS_{tot}`:總變異平方和(Total Sum of Squares)30""")31 32# 資料來源選擇33mode = st.radio("請選擇資料來源:", ["手動輸入資料", "上傳 CSV 檔案"])34 35data = None36 37if mode == "手動輸入資料":38    manual_input = st.text_area("請輸入以逗號分隔的數值資料(例:1, 2, 3, 4)", height=100)39    threshold = st.number_input("請輸入判定用的 R² 門檻值", value=0.2, step=0.01)40 41    if st.button("開始分析"):42        try:43            y = [float(i.strip()) for i in manual_input.split(",") if i.strip()]44            if len(y) < 2:45                st.error("❌ 至少需要 2 筆資料")46            else:47                x = list(range(1, len(y) + 1))48                df = pd.DataFrame({"X": x, "Y": y})49                st.write("🔍 資料預覽")50                st.dataframe(df)51 52                # 線性回歸與 R²53                x_np = np.array(x)54                y_np = np.array(y)55                slope, intercept = np.polyfit(x_np, y_np, 1)56                y_pred = slope * x_np + intercept57                ss_total = np.sum((y_np - np.mean(y_np)) ** 2)58                ss_res = np.sum((y_np - y_pred) ** 2)59                r_squared = 1 - (ss_res / ss_total)60 61                # 顯示結果62                st.write(f"📊 R² = `{r_squared:.4f}`")63                st.write(f"📐 斜率 = `{slope:.4f}`")64 65                if r_squared > threshold:66                    st.error("🔺 判斷結果:傾斜")67                else:68                    st.success("✅ 判斷結果:正常")69 70                # 畫圖71                fig, ax = plt.subplots(figsize=(10, 4))72                ax.plot(x, y, 'o-', label='原始資料')73                ax.plot(x, y_pred, '--', color='red', label='趨勢線')74                ax.set_title("資料趨勢圖")75                ax.set_xlabel("X")76                ax.set_ylabel("Y")77                ax.grid(True)78                ax.legend()79                st.pyplot(fig)80        except:81            st.error("❌ 請輸入正確格式的數值(逗號分隔)")82 83else:84    uploaded_file = st.file_uploader("請上傳 CSV 檔案", type=["csv"])85    if uploaded_file:86        try:87            df = pd.read_csv(uploaded_file)88            st.success("✅ 成功讀取 CSV")89            st.write("🔍 資料預覽")90            st.dataframe(df.head())91 92            numeric_cols = df.select_dtypes(include="number").columns.tolist()93            if len(numeric_cols) < 2:94                st.warning("❗ 檔案中需至少包含兩個數值欄位")95            else:96                x_col = st.selectbox("請選擇 X 軸欄位", options=numeric_cols)97                y_col = st.selectbox("請選擇 Y 軸欄位", options=numeric_cols)98                threshold = st.number_input("請輸入判定用的 R² 門檻值", value=0.2, step=0.01)99 100                if st.button("開始分析"):101                    x = df[x_col].values102                    y = df[y_col].values103                    slope, intercept = np.polyfit(x, y, 1)104                    y_pred = slope * x + intercept105                    ss_total = np.sum((y - np.mean(y)) ** 2)106                    ss_res = np.sum((y - y_pred) ** 2)107                    r_squared = 1 - (ss_res / ss_total)108 109                    st.write(f"📊 R² = `{r_squared:.4f}`")110                    st.write(f"📐 斜率 = `{slope:.4f}`")111 112                    if r_squared > threshold:113                        st.error("🔺 判斷結果:傾斜")114                    else:115                        st.success("✅ 判斷結果:正常")116 117                    # 畫圖118                    fig, ax = plt.subplots(figsize=(10, 4))119                    ax.scatter(x, y, label="原始資料", color="#0072B2")120                    ax.plot(x, y_pred, '--', color='red', label='趨勢線')121                    ax.set_title("資料趨勢圖")122                    ax.set_xlabel(x_col)123                    ax.set_ylabel(y_col)124                    ax.grid(True)125                    ax.legend()126                    st.pyplot(fig)127        except Exception as e:128            st.error(f"❌ 讀取錯誤:{e}")129