اذهب إلى المحتوى

السؤال

نشر

السلام عليكم 

كيف تتعرف نماذج تعويض القيم المفقودة مثل KNNImputer أو IterativeImputer على القيم المفقودة؟
يعني لو في القيمة المفقودة مكتوبة على شكل -1، هل النموذج هيعرف إنها مفقودة؟

Recommended Posts

  • 0
نشر

هذا الأمر يعتمد على كون القيم المفقودة ممثلة بصيغة np.nan أي Not a Number حتى تتعرف عليها وتقوم بتعويضها، أما إذا كانت القيمة المفقودة مكتوبة بشكل يدوي مثل -1 أو أي قيمة رقمية أخرى، فإن هذه النماذج لن تتعرف عليها تلقائيا كمفقودة، بل ستعاملها كقيمة عادية موجودة في البيانات، لذا من الضروري قبل استخدام هذه النماذج أن تقوم بتحويل القيم التي ترمز للمفقود إلى np.nan بهذا الشكل:

df.replace(-1, np.nan, inplace=True)

وبذلك يمكن للموديل أن يتعرف عليها ويعالجها بالشكل الصحيح.

  • 0
نشر

في نماذج تعويض القيم المفقودة يتم التعرف على القيم المفقودة من خلال تمثيلها بصيغة معيارية وهي np.nan، و هذه النماذج لا تعتبر القيم مثل -1 أو أي قيمة عددية أخرى كمفقودة بشكل تلقائي، إذ تعاملها كبيانات صحيحة، وبالتالي يتعين على المستخدم قبل تطبيق أي من هذه النماذج أن يقوم بمعالجة البيانات أولا واستبدال أي رموز مخصصة لتمثيل القيم المفقودة مثل -1 بـ np.nan، و هذه الخطوة ضرورية لضمان أن النماذج تتعرف على القيم المفقودة وتعوضها بطريقة صحيحة بناء على الأنماط الموجودة في البيانات.

  • 0
نشر
بتاريخ 11 دقائق مضت قال Ali Ahmed55:

طيب انا هستخدم النموذج ده IterativeImputer و النموذج ده فيه خاصيه اسمه missing_values فا ممكن استخدم دي وخالها = -1.0

 

بدل من NaN

نعم يمكنك ذلك و هذه الخاصية تكون مضبوطة على np.nan، ولكن يمكنك تعديلها لتأخذ أي قيمة عددية أخرى، مثل -1.0، إذا كنت تستخدمها لتمثيل القيم المفقودة، لكن يجب أن تتأكد أيضا أنه لازال يحتسب np.nan كقيم مفقودة أيضا.

  • 0
نشر

 

 

بتاريخ 14 دقائق مضت قال Ali Ahmed55:

طيب انا هستخدم النموذج ده IterativeImputer و النموذج ده فيه خاصيه اسمه missing_values فا ممكن استخدم دي وخالها = -1.0

بدل من NaN

عليك ضبط الوسيط missing_values في IterativeImputer ليكون ‎-1.0 بحيث يعامل كل تكرار للرقم على أنه مفقود، كالتالي:

from sklearn.experimental import enable_iterative_imputer 
from sklearn.impute import IterativeImputer

imp = IterativeImputer(
        missing_values=-1.0,   
        max_iter=10,
        random_state=0)
X_imp = imp.fit_transform(X)

لكن لو يوجد قيم حقيقية تُساوي ‎-1 فعلاً في بعض الصفوف، فاستخدام ‎-1 كرمز للفقد سيخلط بين المفقود والقيمة الحقيقية، لذا الأفضل دائمًا استخدام np.nan أو pd.NA كرمز وحيد للفقد.

ولو العمود من نوع int فوجود ‎-1 لا يسبب مشكلة، ولكن لو استبدلت إلى np.nan فيما بعد، فستضطر لتحويل الأعمدة إلى float أو Int64.

عامًة كل المُحسنات أي الـ Imputers الموجودة في scikit-learn  سواء SimpleImputer أو KNNImputer أو IterativeImputer  لا تكتشف القيم المفقودة تلقائيًا، بل تبحث عن قيمة معينة تحددها أنت في الوسيط missing_values وافتراضيًا هي np.nan.

ولو القيم المفقودة مُمثلة في البيانات بالعدد ‎-1 فلن تعتبرها تلك الأدوات مفقودة إلا إن أخبرتها بذلك صراحة أو قمت بتحويلها إلى np.nan قبل تمرير البيانات إلى المُحْسن.

للتوضيح، عند استدعاء fit أو fit_transform، يُنشئ المُحسن mask أي قناع يساوي True حيث تكون الخانة مفقودة و False حيث لا تكون مفقودة.

ويتم بناء القناع كالتالي:

لو missing_values=np.nan وهي القيمة الافتراضية، فيتم تطبيق np.isnan(X).

وفي حال حددت عدد أو رمز آخر ولينك missing_values = -1، يتم استخدام المقارنة X == -1.

والقيم المفقودة المكتوبة - ستُعامل كقيمة عددية عادية إن أبقيت الوسيط على الحالة الافتراضية np.nan، بالتالي قبل التدريب استبدال ‎-1 بـ np.nan أو قم بتحديد ذلك للمُحسن مباشرًة كالتالي:

from sklearn.impute import KNNImputer

imputer = KNNImputer(missing_values=-1)
X_imp = imputer.fit_transform(df.values) 

 

  • 0
نشر

طيب ده الكود بتاعي

from sklearn.compose import ColumnTransformer
from sklearn.impute import IterativeImputer  # Import IterativeImputer for handling missing values
import pandas as pd

# Identify numeric and text (object) columns in the DataFrame
numeric_features = df.select_dtypes(include=['number']).columns.tolist()
text_features = df.select_dtypes(include=['object']).columns.tolist()

# Create a ColumnTransformer to apply IterativeImputer to numeric columns
# and pass through text columns without any transformation
preprocessor = ColumnTransformer(
    transformers=[
        ('num', IterativeImputer(missing_values=-1.0), numeric_features),  # Apply IterativeImputer to numeric features
        ('text', 'passthrough', text_features)          # Leave text features unchanged
    ]
)

# Fit the transformer to the data and transform it
df_transformed = preprocessor.fit_transform(df)

# Reconstruct the transformed data into a DataFrame with original column names
feature_names = numeric_features + text_features
df_final = pd.DataFrame(df_transformed, columns=feature_names)

بس بيطهر الخطاء ده

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/tmp/ipykernel_34/678675408.py in <cell line: 0>()
     15 
     16 # Fit the transformer to the data and transform it
---> 17 df_transformed = preprocessor.fit_transform(data_train)
     18 
     19 # Reconstruct the transformed data into a DataFrame with original column names

/usr/local/lib/python3.11/dist-packages/sklearn/utils/_set_output.py in wrapped(self, X, *args, **kwargs)
    138     @wraps(f)
    139     def wrapped(self, X, *args, **kwargs):
--> 140         data_to_wrap = f(self, X, *args, **kwargs)
    141         if isinstance(data_to_wrap, tuple):
    142             # only wrap the first output for cross decomposition

/usr/local/lib/python3.11/dist-packages/sklearn/compose/_column_transformer.py in fit_transform(self, X, y)
    725         self._validate_remainder(X)
    726 
--> 727         result = self._fit_transform(X, y, _fit_transform_one)
    728 
    729         if not result:

/usr/local/lib/python3.11/dist-packages/sklearn/compose/_column_transformer.py in _fit_transform(self, X, y, func, fitted, column_as_strings)
    656         )
    657         try:
--> 658             return Parallel(n_jobs=self.n_jobs)(
    659                 delayed(func)(
    660                     transformer=clone(trans) if not fitted else trans,

/usr/local/lib/python3.11/dist-packages/sklearn/utils/parallel.py in __call__(self, iterable)
     61             for delayed_func, args, kwargs in iterable
     62         )
---> 63         return super().__call__(iterable_with_config)
     64 
     65 

/usr/local/lib/python3.11/dist-packages/joblib/parallel.py in __call__(self, iterable)
   1983             output = self._get_sequential_output(iterable)
   1984             next(output)
-> 1985             return output if self.return_generator else list(output)
   1986 
   1987         # Let's create an ID that uniquely identifies the current call. If the

/usr/local/lib/python3.11/dist-packages/joblib/parallel.py in _get_sequential_output(self, iterable)
   1911                 self.n_dispatched_batches += 1
   1912                 self.n_dispatched_tasks += 1
-> 1913                 res = func(*args, **kwargs)
   1914                 self.n_completed_tasks += 1
   1915                 self.print_progress()

/usr/local/lib/python3.11/dist-packages/sklearn/utils/parallel.py in __call__(self, *args, **kwargs)
    121             config = {}
    122         with config_context(**config):
--> 123             return self.function(*args, **kwargs)

/usr/local/lib/python3.11/dist-packages/sklearn/pipeline.py in _fit_transform_one(transformer, X, y, weight, message_clsname, message, **fit_params)
    891     with _print_elapsed_time(message_clsname, message):
    892         if hasattr(transformer, "fit_transform"):
--> 893             res = transformer.fit_transform(X, y, **fit_params)
    894         else:
    895             res = transformer.fit(X, y, **fit_params).transform(X)

/usr/local/lib/python3.11/dist-packages/sklearn/utils/_set_output.py in wrapped(self, X, *args, **kwargs)
    138     @wraps(f)
    139     def wrapped(self, X, *args, **kwargs):
--> 140         data_to_wrap = f(self, X, *args, **kwargs)
    141         if isinstance(data_to_wrap, tuple):
    142             # only wrap the first output for cross decomposition

/usr/local/lib/python3.11/dist-packages/sklearn/impute/_iterative.py in fit_transform(self, X, y)
    702         self.initial_imputer_ = None
    703 
--> 704         X, Xt, mask_missing_values, complete_mask = self._initial_imputation(
    705             X, in_fit=True
    706         )

/usr/local/lib/python3.11/dist-packages/sklearn/impute/_iterative.py in _initial_imputation(self, X, in_fit)
    599             force_all_finite = True
    600 
--> 601         X = self._validate_data(
    602             X,
    603             dtype=FLOAT_DTYPES,

/usr/local/lib/python3.11/dist-packages/sklearn/base.py in _validate_data(self, X, y, reset, validate_separately, **check_params)
    563             raise ValueError("Validation should be done on X, y or both.")
    564         elif not no_val_X and no_val_y:
--> 565             X = check_array(X, input_name="X", **check_params)
    566             out = X
    567         elif no_val_X and not no_val_y:

/usr/local/lib/python3.11/dist-packages/sklearn/utils/validation.py in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, estimator, input_name)
    919 
    920         if force_all_finite:
--> 921             _assert_all_finite(
    922                 array,
    923                 input_name=input_name,

/usr/local/lib/python3.11/dist-packages/sklearn/utils/validation.py in _assert_all_finite(X, allow_nan, msg_dtype, estimator_name, input_name)
    159                 "#estimators-that-handle-nan-values"
    160             )
--> 161         raise ValueError(msg_err)
    162 
    163 

ValueError: Input X contains NaN.
IterativeImputer does not accept missing values encoded as NaN natively. For supervised learning, you might want to consider sklearn.ensemble.HistGradientBoostingClassifier and Regressor which accept missing values encoded as NaNs natively. Alternatively, it is possible to preprocess the data, for instance by using an imputer transformer in a pipeline or drop samples with missing values. See https://scikit-learn.org/stable/modules/impute.html You can find a list of all estimators that handle NaN values at the following page: https://scikit-learn.org/stable/modules/impute.html#estimators-that-handle-nan-values

ليه بيظهر الخطاء ده ؟

  • 0
نشر
بتاريخ 10 دقائق مضت قال Ali Ahmed55:

طيب ده الكود بتاعي

from sklearn.compose import ColumnTransformer
from sklearn.impute import IterativeImputer  # Import IterativeImputer for handling missing values
import pandas as pd

# Identify numeric and text (object) columns in the DataFrame
numeric_features = df.select_dtypes(include=['number']).columns.tolist()
text_features = df.select_dtypes(include=['object']).columns.tolist()

# Create a ColumnTransformer to apply IterativeImputer to numeric columns
# and pass through text columns without any transformation
preprocessor = ColumnTransformer(
    transformers=[
        ('num', IterativeImputer(missing_values=-1.0), numeric_features),  # Apply IterativeImputer to numeric features
        ('text', 'passthrough', text_features)          # Leave text features unchanged
    ]
)

# Fit the transformer to the data and transform it
df_transformed = preprocessor.fit_transform(df)

# Reconstruct the transformed data into a DataFrame with original column names
feature_names = numeric_features + text_features
df_final = pd.DataFrame(df_transformed, columns=feature_names)

بس بيطهر الخطاء ده

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/tmp/ipykernel_34/678675408.py in <cell line: 0>()
     15 
     16 # Fit the transformer to the data and transform it
---> 17 df_transformed = preprocessor.fit_transform(data_train)
     18 
     19 # Reconstruct the transformed data into a DataFrame with original column names

/usr/local/lib/python3.11/dist-packages/sklearn/utils/_set_output.py in wrapped(self, X, *args, **kwargs)
    138     @wraps(f)
    139     def wrapped(self, X, *args, **kwargs):
--> 140         data_to_wrap = f(self, X, *args, **kwargs)
    141         if isinstance(data_to_wrap, tuple):
    142             # only wrap the first output for cross decomposition

/usr/local/lib/python3.11/dist-packages/sklearn/compose/_column_transformer.py in fit_transform(self, X, y)
    725         self._validate_remainder(X)
    726 
--> 727         result = self._fit_transform(X, y, _fit_transform_one)
    728 
    729         if not result:

/usr/local/lib/python3.11/dist-packages/sklearn/compose/_column_transformer.py in _fit_transform(self, X, y, func, fitted, column_as_strings)
    656         )
    657         try:
--> 658             return Parallel(n_jobs=self.n_jobs)(
    659                 delayed(func)(
    660                     transformer=clone(trans) if not fitted else trans,

/usr/local/lib/python3.11/dist-packages/sklearn/utils/parallel.py in __call__(self, iterable)
     61             for delayed_func, args, kwargs in iterable
     62         )
---> 63         return super().__call__(iterable_with_config)
     64 
     65 

/usr/local/lib/python3.11/dist-packages/joblib/parallel.py in __call__(self, iterable)
   1983             output = self._get_sequential_output(iterable)
   1984             next(output)
-> 1985             return output if self.return_generator else list(output)
   1986 
   1987         # Let's create an ID that uniquely identifies the current call. If the

/usr/local/lib/python3.11/dist-packages/joblib/parallel.py in _get_sequential_output(self, iterable)
   1911                 self.n_dispatched_batches += 1
   1912                 self.n_dispatched_tasks += 1
-> 1913                 res = func(*args, **kwargs)
   1914                 self.n_completed_tasks += 1
   1915                 self.print_progress()

/usr/local/lib/python3.11/dist-packages/sklearn/utils/parallel.py in __call__(self, *args, **kwargs)
    121             config = {}
    122         with config_context(**config):
--> 123             return self.function(*args, **kwargs)

/usr/local/lib/python3.11/dist-packages/sklearn/pipeline.py in _fit_transform_one(transformer, X, y, weight, message_clsname, message, **fit_params)
    891     with _print_elapsed_time(message_clsname, message):
    892         if hasattr(transformer, "fit_transform"):
--> 893             res = transformer.fit_transform(X, y, **fit_params)
    894         else:
    895             res = transformer.fit(X, y, **fit_params).transform(X)

/usr/local/lib/python3.11/dist-packages/sklearn/utils/_set_output.py in wrapped(self, X, *args, **kwargs)
    138     @wraps(f)
    139     def wrapped(self, X, *args, **kwargs):
--> 140         data_to_wrap = f(self, X, *args, **kwargs)
    141         if isinstance(data_to_wrap, tuple):
    142             # only wrap the first output for cross decomposition

/usr/local/lib/python3.11/dist-packages/sklearn/impute/_iterative.py in fit_transform(self, X, y)
    702         self.initial_imputer_ = None
    703 
--> 704         X, Xt, mask_missing_values, complete_mask = self._initial_imputation(
    705             X, in_fit=True
    706         )

/usr/local/lib/python3.11/dist-packages/sklearn/impute/_iterative.py in _initial_imputation(self, X, in_fit)
    599             force_all_finite = True
    600 
--> 601         X = self._validate_data(
    602             X,
    603             dtype=FLOAT_DTYPES,

/usr/local/lib/python3.11/dist-packages/sklearn/base.py in _validate_data(self, X, y, reset, validate_separately, **check_params)
    563             raise ValueError("Validation should be done on X, y or both.")
    564         elif not no_val_X and no_val_y:
--> 565             X = check_array(X, input_name="X", **check_params)
    566             out = X
    567         elif no_val_X and not no_val_y:

/usr/local/lib/python3.11/dist-packages/sklearn/utils/validation.py in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, estimator, input_name)
    919 
    920         if force_all_finite:
--> 921             _assert_all_finite(
    922                 array,
    923                 input_name=input_name,

/usr/local/lib/python3.11/dist-packages/sklearn/utils/validation.py in _assert_all_finite(X, allow_nan, msg_dtype, estimator_name, input_name)
    159                 "#estimators-that-handle-nan-values"
    160             )
--> 161         raise ValueError(msg_err)
    162 
    163 

ValueError: Input X contains NaN.
IterativeImputer does not accept missing values encoded as NaN natively. For supervised learning, you might want to consider sklearn.ensemble.HistGradientBoostingClassifier and Regressor which accept missing values encoded as NaNs natively. Alternatively, it is possible to preprocess the data, for instance by using an imputer transformer in a pipeline or drop samples with missing values. See https://scikit-learn.org/stable/modules/impute.html You can find a list of all estimators that handle NaN values at the following page: https://scikit-learn.org/stable/modules/impute.html#estimators-that-handle-nan-values

ليه بيظهر الخطاء ده ؟

بسبب أنك عرفت IterativeImputer وهو يعتبر القيمة -1.0 هي القيمة المفقودة:

IterativeImputer(missing_values=-1.0)

لكن البيانات الفعلية التي يستقبلها IterativeImputer وهي الأعمدة الرقمية numeric_features من data_train تحتوي على قيم NaN، وهي الطريقة المتبعة في Pandas و NumPy لتمثيل القيم المفقودة.

بالتالي عند استقبال NaN يجد -1.0 كعلامة للقيم المفقودة، لذا يعتبر الـ NaN قيمة غير صالحة ولا يستطيع التعامل معها.

عليك تغيير missing_values=-1.0 إلى missing_values=np.nan. 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...