Feature Engineering و Pipelines
الفرق بين موديل عادي وموديل ممتاز غالباً بيبقى هنا.
النصوص لأرقام: One-Hot Encoding
الموديل مبيفهمش «Cairo». ممكن تقول Cairo=1 و Giza=2 و Alexandria=3؟ لأ، كده الموديل هيفهم إن إسكندرية «أكبر» من القاهرة، وده مالوش معنى. الحل: عمود لكل مدينة فيه ١ أو ٠.
import pandas as pd df = pd.DataFrame({"city": ["Cairo", "Giza", "Alexandria", "Cairo"]}) print(pd.get_dummies(df, columns=["city"], dtype=int))
اعمل features جديدة من خبرتك
انت فاهم المجال أكتر من الموديل. عمود زي «المساحة لكل أوضة» أو «قريب من المترو؟» ممكن يساعد الموديل أكتر من الأعمدة الخام. وفي التواريخ: اليوم في الأسبوع، والشهر، وهل هو إجازة، كلها features مفيدة جداً.
الـ Pipeline: كل الخطوات في حتة واحدة
الـ Pipeline بيربط التجهيز والموديل في object واحد. ليه ده مهم؟ لأن الـ scaling مثلاً لازم يتعلم المتوسط من الـ train بس، مش من الداتا كلها، وإلا يبقى leakage. الـ Pipeline بيعمل ده صح لوحده، وكمان بتحفظه وتستخدمه في الإنتاج كحتة واحدة.
import pandas as pd from sklearn.model_selection import train_test_split from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder, StandardScaler from sklearn.pipeline import Pipeline from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_absolute_error df = pd.read_csv("apartments.csv") numeric = ["area", "rooms", "floor", "age", "metro_km"] categorical = ["city"] X_train, X_test, y_train, y_test = train_test_split( df[numeric + categorical], df["price_k"], test_size=0.2, random_state=42) prep = ColumnTransformer([ ("num", StandardScaler(), numeric), # scale numbers ("cat", OneHotEncoder(handle_unknown="ignore"), categorical), # encode text ]) pipe = Pipeline([("prep", prep), ("model", LinearRegression())]) pipe.fit(X_train, y_train) mae = mean_absolute_error(y_test, pipe.predict(X_test)) print(f"MAE with city: {mae:.0f}K EGP")
الغلط نزل من حوالي ٢٨٥ ألف لـ ١٨٤ ألف، يعني أقل بأكتر من الربع، وده من مجرد إننا ضفنا المدينة بطريقة صح. ده معنى إن Feature Engineering غالباً بيفرق أكتر من تغيير الموديل.
احفظ الموديل واستخدمه بعدين
import joblib import pandas as pd from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder from sklearn.pipeline import Pipeline from sklearn.linear_model import LinearRegression df = pd.read_csv("apartments.csv") cols = ["area", "rooms", "floor", "age", "metro_km", "city"] pipe = Pipeline([ ("prep", ColumnTransformer([("cat", OneHotEncoder(), ["city"])], remainder="passthrough")), ("model", LinearRegression()), ]).fit(df[cols], df["price_k"]) joblib.dump(pipe, "price_model.joblib") # save to disk loaded = joblib.load("price_model.joblib") # later, in another program flat = pd.DataFrame([{"area": 130, "rooms": 3, "floor": 4, "age": 5, "metro_km": 1.2, "city": "Cairo"}]) print(f"Cairo flat: {loaded.predict(flat)[0]:,.0f}K EGP")
price_model.joblib ده في المرحلة ٨ هنحطه ورا API بـ FastAPI، فأي تطبيق أو موقع يبعتله بيانات شقة ويرجعله السعر. كده الموديل يطلع من الـ notebook للعالم.