تنظيف وإعداد البيانات باستخدام بيثون لعلوم البيانات - أفضل الممارسات والباقات المفيدة

مقدمة

تنظيف البيانات هو مجرد شيء يجب عليك التعامل معه في التحليلات. إنه ليس عملاً رائعًا ، لكن يجب القيام به حتى تتمكن من إنتاج عمل رائع.

لقد قضيت الكثير من الوقت في كتابة وظائف إعادة الكتابة لمساعدتي في تنظيف البيانات ، حتى أنني أردت مشاركة بعض ما تعلمته على طول الطريق. إذا لم تكن قد تجاوزت هذا المنشور ، فتراجع عن كيفية تنظيم مشاريع علوم البيانات بشكل أفضل ، حيث إنها ستساعد في تشكيل بعض المفاهيم التي أذهب إليها أدناه.

بعد البدء في تنظيم الكود الخاص بي بشكل أفضل ، بدأت في الاحتفاظ بحزمة مخصصة حيث أحتفظ برمز "التنظيف". إذا كان أي شيء آخر ، فهو يوفر لي خطًا أساسيًا لكتابة الأساليب المخصصة على البيانات التي لا تتناسب تمامًا مع البرامج النصية السابقة للتنظيف. ولست بحاجة إلى كتابة مستخرج البريد الإلكتروني هذا الخاص بـ regex للمرة المائة لأنني قمت بحفظه في موقع يمكن الوصول إليه.

بعض الشركات لديها فرق كاملة مخصصة لتنظيف الكود ، ولكن معظمها لا يفعل ذلك. لذلك من الأفضل فهم بعض أفضل الممارسات. إذا كان هناك أي شيء ، فسوف تتحسن فهم بنية بياناتك ، وذلك لتوضيح سبب أو سبب عدم حدوث شيء ما بشكل أفضل.

أيضًا ، أثناء التحضير لهذا المنشور ، ركضت عبر هذا الريبو بواسطة kjam ، والذي كان سيكون مفيدًا بشكل لا يصدق عندما كنت أتعلم أولاً كيفية تنظيف البيانات. إذا كنت ترغب في التعمق في تنظيف الكود ، أقترح أن تبدأ هناك.

هدفك هو تنظيف الأشياء ... أو على الأقل محاولة القيام بذلك

تحقق من بياناتك ... بسرعة

أول شيء تريد القيام به عندما تحصل على مجموعة بيانات جديدة ، هو التحقق بسرعة من المحتويات باستخدام طريقة .head ().

استيراد الباندا كما PD
df = pd.read_csv ('path_to_data')
df.head (10)
>>
... بعض الإخراج هنا ...

الآن دعونا نرى بسرعة أسماء وأنواع الأعمدة. في معظم الأحيان ، ستحصل على بيانات ليست كما توقعت تمامًا ، مثل التواريخ التي هي في الواقع سلاسل وأشياء شاذة أخرى. ولكن للتحقق مقدما.

# الحصول على أسماء الأعمدة
column_names = df.columns
طباعة (COLUMN_NAMES)
# الحصول على أنواع البيانات العمود
df.dtypes
# تحقق أيضًا مما إذا كان العمود فريدًا أم لا
لأني في اسم العمود:
  الطباعة ('{} فريدة: {}'. التنسيق (i ، df [i] .is_unique))

الآن ، لنرى ما إذا كان لدى dataframe فهرس مرتبط به ، عن طريق الاتصال بـ .index على df. إذا لم يكن هناك فهرس ، فستحصل على AttributeError: لا يعرض كائن "دالة" خطأ "فهرس".

# تحقق من قيم الفهرس
df.index.values
# تحقق مما إذا كان هناك فهرس معين
"فو" في df.index.values
# إذا كان الفهرس غير موجود
df.set_index ('column_name_to_use'، inplace = True)

حسن. تم فحص بياناتنا بسرعة ، ونحن نعرف أنواع البيانات ، وإذا كانت الأعمدة فريدة من نوعها ، ونعرف أن لديها فهرسًا حتى نتمكن من القيام بعمليات الربط والاندماج لاحقًا. دعنا نتعرف على الأعمدة التي تريد الاحتفاظ بها أو إزالتها. في هذا المثال ، نرغب في التخلص من الأعمدة الموجودة في الفهارس 1 و 3 و 5 ، لذلك قمت فقط بإضافة قيم السلسلة إلى قائمة ، والتي سيتم استخدامها لإسقاط الأعمدة.

# إنشاء قائمة فهم الأعمدة التي تريد أن تفقد
columns_to_drop = [column_names [i] لـ i in [1، 3، 5]]
# إسقاط الأعمدة غير المرغوب فيها
df.drop (columns_to_drop ، inplace = صواب ، محور = 1)

تمت إضافة inplace = True ، لذا فلن تحتاج إلى الحفظ عبر df الأصلي عن طريق تعيين نتيجة .drop () إلى df. تدعم العديد من الطرق في الباندا inplace = True ، لذلك حاول استخدامها قدر الإمكان لتجنب إعادة التعيين غير الضرورية.

ماذا تفعل مع NaN

إذا كنت بحاجة إلى ملء الأخطاء أو الفراغات ، فاستخدم طريقتي fillna () و dropna (). يبدو ذلك سريعًا ، لكن يجب توثيق جميع عمليات معالجة البيانات حتى تتمكن من شرحها لشخص ما في وقت لاحق.

يمكنك ملء NaNs بالسلاسل ، أو إذا كانت أرقامًا ، فيمكنك استخدام القيمة المتوسطة أو الوسيطة. هناك الكثير من النقاش حول ما يتعلق بالبيانات المفقودة أو التالفة ، والإجابة الصحيحة هي ... ذلك يعتمد.

يجب عليك استخدام أفضل تقدير وإدخالات من الأشخاص الذين تعمل معهم حول السبب في أن إزالة أو ملء البيانات هي الطريقة الأفضل.

# ملء NaN مع ''
df ['col'] = df ['col']. fillna ('')
# ملء NaN مع 99
df ['col'] = df ['col']. fillna (99)
# ملء NaN مع الوسط من العمود
df ['col'] = df ['col']. fillna (df ['col']. mean ())

يمكنك أيضًا نشر القيم غير الخالية للأمام أو للخلف عن طريق وضع method = 'pad' كوسيطة الطريقة. سوف تملأ القيمة التالية في dataframe بالقيمة السابقة لغير NaN. ربما تريد فقط ملء قيمة واحدة (الحد = 1) أو تريد ملء جميع القيم. مهما كان ، تأكد من أنه يتوافق مع بقية تنظيف البيانات الخاصة بك.

df = pd.DataFrame (data = {'col1': [np.nan، np.nan، 2،3،4، np.nan، np.nan]})
    COL1
0 NaN
1 NaN
2 2.0
3 3.0
4 4.0 # هذه هي القيمة لملء الأمام
5 NaN
6 NaN
df.fillna (الطريقة = 'الوسادة' ، الحد = 1)
    COL1
0 NaN
1 NaN
2 2.0
3 3.0
4 4.0
5 4.0 # شغلها إلى الأمام
6 NaN

لاحظ كيف كان مؤشر 5 فقط شغل؟ إذا لم أقم بملء اللوحة ، فستملأ إطار البيانات بأكمله. نحن لا نقتصر على التعبئة الأمامية ، ولكن أيضًا الردم باستخدام bfill.

# املأ أول القيمتين NaN بالقيمة الأولى المتاحة
df.fillna (أسلوب = 'bfill')
    COL1
0 2.0 # معبأ
1 2.0 # معبأ
2 2.0
3 3.0
4 4.0
5 NaN
6 NaN

يمكنك فقط إسقاطها من إطار البيانات بالكامل ، إما عن طريق الصف أو العمود.

# إسقاط أي الصفوف التي لديها أي رانس
df.dropna ()
# إسقاط الأعمدة التي لديها أي رانس
df.dropna (المحور = 1)
# فقط إسقاط الأعمدة التي لا تقل عن 90 ٪ غير NaNs
df.dropna (thresh = int (df.shape [0] * .9) ، المحور = 1)

تتطلب المعلمة thresh = N أن يحتوي العمود على NN على الأقل غير للبقاء على قيد الحياة. فكر في هذا باعتباره الحد الأدنى للبيانات المفقودة التي ستجدها مقبولة في أعمدةك. النظر في بعض بيانات التسجيل التي قد تفوت بعض مجموعة من الميزات. تريد فقط السجلات التي تحتوي على 90٪ من الميزات المتاحة قبل أن تعتبرها مرشحة لنموذجك.

np.where (if_this_is_true ، do_this ، else_do_that)

أنا مذنب في عدم استخدام هذا في وقت سابق في عملي التحليلي لأنه يفوق الفائدة. أنه يوفر الكثير من الوقت والإحباط عندما تتدلى من خلال dataframe. إذا كنت ترغب في القيام ببعض أعمال التنظيف الأساسية أو هندسة الميزات بسرعة ، فيمكنك هنا إجراء ذلك.

ضع في اعتبارك ما إذا كنت تقيم عمودًا ، وتريد أن تعرف ما إذا كانت القيم أكبر من 10 نقاط. إذا كانت تريد أن تكون النتيجة "فو" ، وإذا كنت لا تريد أن تكون النتيجة "شريط".

# اتبع بناء الجملة
np.where (if_this_condition_is_true ، do_this ، else_this)
# مثال
df ['new_column'] = np.where (df [i]> 10 ، 'foo' ، 'bar)

يمكنك القيام بعمليات أكثر تعقيدًا مثل تلك الموضحة أدناه. نحن هنا نتحقق مما إذا كان سجل العمود يبدأ بـ foo ولا ينتهي بشريط. إذا تحقق هذا ، فسنقوم بإرجاع "صحيح" ، وسنعيد القيمة الحالية في العمود.

df ['new_column'] = np.where (df ['col']. str.startswith ('foo') و
                            لا df ['col']. str.endswith ('bar') ،
                            صحيح،
                            مدافع [ 'العقيد'])

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

# ثلاثة مستويات التعشيش مع np.where
np.where (if_this_condition_is_true_one ، do_this ،
  np.where (if_this_condition_is_true_two ، do_that ،
    np.where (if_this_condition_is_true_three ، do_foo ، do_bar)))
# مثال تافهة
df ['foo'] = np.where (df ['bar'] == 0 ، 'Zero' ،
              np.where (df ['bar'] == 1 ، 'One' ،
                np.where (df ['bar'] == 2 ، 'Two' ، 'Three')))

تأكيد واختبار ما لديك

الائتمان ل https://www.programiz.com

فقط لأن لديك بياناتك في إطار بيانات لطيف ، ولا توجد نسخ مكررة ، ولا توجد قيم مفقودة ، فقد تظل تواجه بعض المشكلات المتعلقة بالبيانات الأساسية. ومع وجود إطار بيانات مكون من 10 أمتار + صفوف أو واجهة برمجة تطبيقات جديدة ، كيف يمكنك التأكد من أن القيم هي بالضبط ما تتوقعه منهم؟

الحقيقة هي أنك لا تعرف حقًا ما إذا كانت بياناتك صحيحة حتى تقوم باختبارها. تعتمد أفضل الممارسات في هندسة البرمجيات اعتمادًا كبيرًا على اختبار عملها ، ولكن بالنسبة لعلم البيانات ، لا يزال العمل جارياً. من الأفضل أن تبدأ الآن وتعلم نفسك مبادئ العمل الجيد ، بدلاً من الاضطرار إلى إعادة تدريب نفسك في وقت لاحق.

دعنا نصنع إطار بيانات بسيط للاختبار.

df = pd.DataFrame (data = {'col1': np.random.randint (0 ، 10 ، 10) ، 'col2': np.random.randint (-10 ، 10 ، 10)})
>>
   col1 col2
0 0 6
1 6 -1
2 8 4
3 0 5
4 3 -7
5 4 -5
6 3 -10
7 9 -8
8 0 4
9 7 -4

دعنا نختبر ما إذا كانت جميع القيم في col1 هي> = 0 باستخدام تأكيد الأسلوب المدمج الذي يأتي مع المكتبة القياسية في بيثون. ما تطلبه من الثعبان إذا كان صحيحًا ، فكل العناصر الموجودة في df [‘col1 '] أكبر من الصفر. إذا كان هذا صحيحًا ، فاستمر في طريقك ، إن لم يكن يرمي خطأً.

التأكيد (df ['col1']> = 0) .all () # يجب أن يعيد أي شيء

عظيم يبدو أن عملت. ولكن ماذا لو لم يتم تضمين .all () في التأكيد؟

أكد (df ['col1']> = 0)
>>
ValueError: قيمة الحقيقة من سلسلة غامضة. استخدم a.empty أو a.bool () أو a.item () أو a.any () أو a.all ().

يبدو Humm أنه لدينا بعض الخيارات عندما نختبر بياناتنا. دعنا الاختبار هو أي من القيم سلاسل.

تأكيد (مدافع ['col1']! = شارع) .any () # يجب أن يعود شيئا

ماذا عن اختبار العمودين لمعرفة ما إذا كانا متساويين؟

أكد (df ['col1'] == df ['col2']). all ()
>>
تتبع (آخر مكالمة أخيرة):
  ملف "" ، السطر 1 ، في 
AssertionError

آه ، فشل تأكيدنا هنا!

أفضل ممارسة مع التأكيدات هي أن تستخدم لاختبار الظروف داخل البيانات الخاصة بك والتي لا ينبغي أن يحدث أبدا. هذا هو الحال عند تشغيل التعليمات البرمجية الخاصة بك ، كل شيء يتوقف إذا فشل أحد هذه التأكيدات.

سوف تتحقق طريقة .all () مما إذا كانت جميع العناصر الموجودة في الكائنات تمر على التأكيد ، بينما .any () ستتحقق مما إذا كان أي من العناصر في الكائنات يجتاز اختبار التوكيد.

يمكن أن يكون هذا مفيدًا عندما تريد:

  • تحقق مما إذا تم إدخال أي قيم سلبية في البيانات ؛
  • تأكد من وجود عمودين متماثلين تمامًا ؛
  • تحديد نتائج التحول ، أو ؛
  • تحقق مما إذا كان عدد المعرفات الفريد دقيقًا.

هناك المزيد من أساليب التأكيد التي لم أذهب إليها ، ولكن تعرف على ما يمكنك استخدامه هنا. لن تعرف أبدًا متى تحتاج إلى اختبار حالة معينة ، وفي الوقت نفسه ، يجب أن تبدأ اختبارًا للشروط التي لا تريدها في الشفرة.

لا تختبر كل شيء ، ولكن اختبر الأشياء التي من شأنها كسر نماذجك.

مثلا هي ميزة يجب أن تكون جميعها 0s و 1s ، يتم ملؤها فعليًا بتلك القيم.

بالإضافة إلى ذلك ، تتضمن حزمة الباندا العجائب أيضًا حزمة اختبار.

استيراد pandas.util.testing كما TM
tm.assert_series_equal (df ['col1'] ، df ['col2'])
>>
AssertionError: سلسلة مختلفة
قيم السلسلة مختلفة (100.0٪)
[يسار]: [0 ، 6 ، 8 ، 0 ، 3 ، 4 ، 3 ، 9 ، 0 ، 7]
[يمين]: [6 ، -1 ، 4 ، 5 ، -7 ، -5 ، -10 ، -8 ، 4 ، -4]

ليس فقط لقد حصلنا على خطأ ، لكن الباندا أخبرنا بالخطأ.

لطيف.

بالإضافة إلى ذلك ، إذا كنت ترغب في البدء في إنشاء مجموعة اختبار بنفسك - وقد ترغب في التفكير في القيام بذلك - تعرف على الحزمة غير المضمن في مكتبة Python. يمكنك معرفة المزيد عن ذلك هنا.

المجمل

بدلاً من الاضطرار إلى كتابة التعبير الخاص بك - وهو ألم في أفضل الأوقات - يتم ذلك أحيانًا من أجلك. تستطيع مجموعة أدوات التجميل مساعدتك في تنظيف بعض الأنماط الشائعة الاستخدام لرسائل البريد الإلكتروني أو عناوين URL. لا شيء يتوهم ولكن يمكن أن يساعد بسرعة في التنظيف.

pip3 دولار تثبيت تجميل
من استيراد البريد الإلكتروني ، عنوان url
email_string = 'foo@bar.com'
البريد الإلكتروني = البريد الإلكتروني (البريد الإلكتروني)
طباعة (email.domain)
طباعة (email.username)
طباعة (email.is_free_email)
>>
bar.com
فو
خاطئة
url_string = 'https://github.com/labtocat/beautifier/blob/master/beautifier/__init__.py'
url = Url (url_string)
طباعة (url.param)
طباعة (url.username)
طباعة (url.domain)
>>
لا شيء
{'msg': 'الميزة متاحة حاليًا فقط مع عناوين url المرتبطة'}
github.com

أستخدم هذه الحزمة عندما يكون لديّ عدد كبير من عناوين URL التي أحتاج إلى التعامل معها ولا أريد أن أكتب ركس ريكس للمرة المائة لاستخراج أجزاء معينة من العنوان.

التعامل مع يونيكود

عند القيام ببعض البرمجة اللغوية العصبية ، قد يكون التعامل مع Unicode محبطًا في أفضل الأوقات. سوف أمارس شيئًا ما في منتجع صحي ، وفجأة سينتهي كل شيء بسبب ظهور بعض أحرف يونيكود في مكان ما في نص الوثيقة.

انها حقا الأسوأ.

باستخدام ftfy (إصلاح ذلك من أجلك) ، يمكنك إصلاح Unicode المعطلة حقًا. فكر في قيام شخص ما بتشفير Unicode باستخدام معيار واحد وفك تشفيره باستخدام معيار مختلف. الآن عليك التعامل مع هذا بين سلسلة ، كما تسلسل هراء يسمى "mojibake".

# مثال على mojibake
والسن الدنيا، \\ _ (A \ x83 \ x84) _ / والسن الدنيا.
\ ufeffParty
\ 001 \ 033 [36؛ 44mI & # x92؛ م

لحسن الحظ ، يستخدم ftfy الأساليب البحثية لاكتشاف والتراجع عن mojibake ، مع معدل منخفض للغاية من الإيجابيات الخاطئة. دعونا نرى ما يمكن تحويل سلاسلنا أعلاه إلى ، حتى نتمكن من قراءتها. الطريقة الرئيسية هي fix_text () ، وستستخدم ذلك لتنفيذ فك التشفير.

استيراد ftfy
foo = '& macr؛ \\ _ (m \ x83 \ x84) _ / & macr؛'
bar = '\ ufeffParty'
baz = '\ 001 \ 033 [36؛ 44mI & # x92؛ m'
طباعة (ftfy.fix_text (فو))
طباعة (ftfy.fix_text (بار))
طباعة (ftfy.fix_text (الباز))

إذا كنت تريد أن ترى كيف يتم فك التشفير ، حاول ftfy.explain_unicode (). لا أعتقد أن هذا سيكون مفيدًا بشكل مفرط ، ولكن من المثير للاهتمام رؤية العملية.

ftfy.explain_unicode (فو)
U + 0026 & [Po] AMPERSAND
U + 006D m [Ll] LATIN SMALL LETTER M
U + 0061 a [Ll] LATIN SMAL LETTER A
U + 0063 c [Ll] LATIN SMALL LETTER C
U + 0072 r [Ll] LATIN SMALL LETTER R
U + 003B ؛ [بو] SEMICOLON
U + 005C \ [Po] عكس سوليدوس
U + 005F _ [Pc] LOW LINE
U + 0028 ([فرع فلسطين] اليسار الأبوة
U + 00E3 [[Ll] LATIN SMAL LETTER A with Tiled
U + 0083 \ x83 [نسخة] <غير معروف>
U + 0084 \ x84 [نسخة] <غير معروف>
U + 0029) [بي] الوصاية الصحيحة
U + 005F _ [Pc] LOW LINE
U + 002F / [Po] SOLIDUS
U + 0026 & [Po] AMPERSAND
U + 006D m [Ll] LATIN SMALL LETTER M
U + 0061 a [Ll] LATIN SMAL LETTER A
U + 0063 c [Ll] LATIN SMALL LETTER C
U + 0072 r [Ll] LATIN SMALL LETTER R
U + 003B ؛ [بو] SEMICOLON
لا شيء

ديدوبي

هذه مكتبة تستخدم التعلم الآلي لأداء التكرار ودقة الكيان بسرعة على البيانات المنظمة. يوجد منشور رائع هنا يحتوي على تفاصيل أكثر بكثير مما سأفعل والذي استفدت منه بشدة.

سنقوم بتنزيل بيانات موقع شيكاغو للطفولة المبكرة ، والتي يمكن العثور عليها هنا. يحتوي على مجموعة من القيم المفقودة والقيم المكررة من مصادر مختلفة للبيانات ، لذلك من الجيد أن نتعلمها.

إذا سبق لك أن مرت ببيانات مكررة من قبل ، فسيبدو ذلك مألوفًا للغاية.

# الأعمدة وعدد القيم المفقودة في كل منها
معرف لديه 0 القيم na
المصدر له قيم 0 na
اسم الموقع له قيم 0 na
يحتوي العنوان على قيم 0 na
يحتوي Zip على 1333 قيمة نا
يحتوي الهاتف على 146 قيمة نا
يحتوي الفاكس على 3299 قيمة نا
اسم البرنامج يحتوي على قيم عام 2009 غ
طول اليوم له قيم عام 2009
يحتوي معرف موفر IDHS على 3298 قيمة na
وكالة لديها 3325 القيم نا
الجوار لديه 2754 قيم نا
التمويل الممول يحتوي على 2424 قيمة نا
يحتوي خيار البرنامج على 2800 قيمة نا
الرقم لكل موقع يحتوي EHS على 3319 قيمة
عدد لكل موقع HS 3319 القيم
يحتوي المخرج على 3337 قيمة
يحتوي صندوق Start Start على 3337 قيمة
يحتوي Eearly Head Start Fund على 2881 قيمة نا
يحتوي صندوق CC على 2818 قيمة نا
يحتوي Progmod على 2818 قيمة نا
يحتوي الموقع على 2815 قيمة نا
المدير التنفيذي لديه 3114 القيم
مدير المركز لديه 2874 قيم نا
تحتوي برامج ECE المتوفرة على 2379 قيمة
NAEYC صالح حتى يحتوي على قيم 2968 غ
يحتوي معرف برنامج NAEYC على 3337 قيمة
يحتوي عنوان البريد الإلكتروني على 3203 قيمة نا
Ounce of Prevention Description يحتوي على 3185 قيمة نا
يحتوي نوع خدمة الموثق الأرجواني على قيم 3215 غ
يحتوي العمود على 3337 قيمة نا
يحتوي العمود 2 على 3018 قيمة na

تعد طريقة preProcess التي توفرها dedupe ضرورية للتأكد من عدم حدوث أخطاء أثناء مراحل أخذ العينات والتدريب في النموذج. ثق بي ، باستخدام هذا سيجعل استخدام dedupe أسهل بكثير. احفظ هذه الطريقة في "حزمة التنظيف" المحلية حتى تتمكن من استخدامها في المستقبل عند التعامل مع البيانات المكررة.

استيراد الباندا كما PD
استيراد شاذ
استيراد dedupe
استيراد نظام التشغيل
استيراد CSV
استيراد إعادة
من unidecode استيراد unidecode
قبل المعالجة (العمود):
    '' '
    يستخدم لمنع الأخطاء أثناء عملية إلغاء البيانات المكررة.
    '' '
    محاولة :
        عمود = عمود. الرمز ('utf8')
    باستثناء AttributeError:
        البشري
    عمود = unidecode (عمود)
    عمود = re.sub ('+' ، '' ، عمود)
    عمود = re.sub ('\ n'، ''، عمود)
    عمود = column.strip (). قطاع ('"'). شريط (" '"). أقل (). شريط ()
    
    إن لم يكن العمود:
        العمود = لا شيء
    عمود العودة

ابدأ الآن في استيراد العمود .csv حسب العمود ، أثناء معالجة البيانات.

def readData (اسم الملف):
    
    data_d = {}
    مع فتح (اسم الملف) كـ f:
        القارئ = csv.DictReader (f)
        للصف في القارئ:
            clean_row = [(k ، preProcess (v)) لـ (k ، v) في row.items ()]
            row_id = int (row ['Id'])
            data_d [row_id] = dict (clean_row)
العودة مد
name_of_file = 'data.csv'
طباعة ("تنظيف واستيراد البيانات ...")
df = readData (name_of_file)

نحتاج الآن إلى إخبار dedupe بالميزات التي يجب أن نبحث عنها لتحديد القيم المكررة. أدناه ، يتم تمييز كل ميزة حسب الحقل ، وتعيين نوع البيانات وإذا كان لديها أي قيم مفقودة. هناك قائمة كاملة بأنواع المتغيرات المختلفة التي يمكنك استخدامها هنا ، ولكن لإبقاء الأمر سهلاً ، سنلتزم بالسلاسل في الوقت الحالي.

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

# تعيين الحقول
الحقول = [
        {'الحقل': 'المصدر' ، 'النوع': 'Set'} ،
        {'الحقل': 'اسم الموقع' ، 'النوع': 'السلسلة'} ،
        {'الحقل': 'العنوان' ، 'النوع': 'السلسلة'} ،
        {'الحقل': 'Zip' ، 'type': 'Exact' ، 'مفقود': True} ،
        {'حقل': 'هاتف' ، 'نوع': 'سلسلة' ، 'مفقود': صواب '،
        {'field': 'عنوان البريد الإلكتروني' ، 'type': 'String' ، 'has مفقود': True} ،
        ]

الآن لنبدأ في تغذية dedupe بعض البيانات.

# تمر في نموذجنا
deduper = dedupe.Dedupe (الحقول)
# تحقق مما إذا كان يعمل
deduper
>>
# تغذية بعض بيانات العينة في ... 15000 السجلات
deduper.sample (df، 15000)

نحن الآن في جزء وضع العلامات. عند تشغيل هذه الطريقة أدناه ، سيُطلب منك بواسطة dedupe القيام ببعض العلامات البسيطة.

dedupe.consoleLabel (deduper)
ما يجب أن تراه ؛ تدريب يدويا على deduper

اللحظة الحقيقية "ها ها" هي عندما تحصل على هذه المطالبة. يطلب منك هذا التدريب تدريبه ، لذلك يعرف ما الذي تبحث عنه. أنت تعرف الشكل الذي يجب أن تبدو عليه القيمة المكررة ، لذلك عليك فقط نقل هذه المعرفة.

هل تشير هذه السجلات إلى نفس الشيء؟
(y) es / (n) o / (u) nsure / (f) inished

الآن لم تعد بحاجة إلى البحث من خلال أطنان وأطنان من السجلات لمعرفة ما إذا كان قد حدث تكرار. بدلاً من ذلك ، يتم تدريب شبكة عصبية بواسطتك للعثور على التكرارات في dataframe.

بمجرد تزويدك ببعض العلامات ، أكمل عملية التدريب واحفظ تقدمك. يمكنك العودة إلى شبكتك العصبية لاحقًا إذا وجدت أن لديك كائنات متكررة من dataframe تحتاج إلى إلغاء التنقيح.

deduper.train ()
# حفظ التدريب
مع فتح (training_file ، 'w') كـ tf:
        deduper.writeTraining (فريق العمل)
# احفظ التغييرات
مع open (settings_file ، 'wb') كـ sf:
        deduper.writeSettings (سادس)

لقد انتهينا تقريبًا ، حيث نحتاج بعد ذلك إلى تعيين حد لبياناتنا. عندما تكون قيمة تذكر - يساوي 1 ، فإننا نطلب من deduper تقييم قيمة الاسترداد بقدر الدقة. ومع ذلك ، إذا كان التذكير = 3 ، فإننا نقدر استدعاء ثلاثة أضعاف ذلك. يمكنك اللعب باستخدام هذه الإعدادات لمعرفة ما يناسبك بشكل أفضل.

العتبة = deduper.threshold (df، التذكير = 1 =)

أخيرًا ، يمكننا الآن البحث من خلال مدونتنا ونرى أين توجد التكرارات. لقد مضى وقت طويل على الوصول إلى هذا الموقف ، لكن هذا أفضل بكثير من القيام بذلك يدويًا.

# الكتلة التكرارات معا
clustered_dupes = deduper.match (data_d ، العتبة)
print ('{{هناك مجموعات مكررة. تنسيق (len (clustered_dupes)))

لذلك دعونا نلقي نظرة على التكرارات لدينا.

clustered_dupes
>>
[((0 ، 1 ، 215 ، 509 ، 510 ، 1225 ، 1226 ، 1879 ، 2758 ، 3255) ،
  مجموعة ([0.88552043 ، 0.88552043 ، 0.77351897 ، 0.88552043 ، 0.88552043 ،
         0.88552043 ، 0.88552043 ، 0.89765924 ، 0.75684386 ، 0.83023088])) ،
 ((2 ، 3 ، 216 ، 511 ، 512 ، 1227 ، 1228 ، 2687) ، ...

همهمة ، هذا لا يخبرنا كثيرا. في الواقع ، ما الذي يظهر لنا؟ ماذا حدث لجميع قيمنا؟

إذا نظرت عن كثب ، فإن القيم (0 ، 1 ، 215 ، 509 ، 510 ، 1225 ، 1226 ، 1879 ، 2758 ، 3255) هي جميع مواقع معرف التكرارات التي يستنتجها deduper وتعتقد أنها في الواقع نفس القيمة. ويمكننا أن ننظر إلى البيانات الأصلية للتحقق من ذلك.

{'Id': '215' ،
 "المصدر": 'cps_early_childhood_portal_scrape.csv' ،
 "اسم الموقع": "معبد جيش الخلاص" ،
 "العنوان": "1 ن. أغدن،
...
{'Id': '509' ،
 "المصدر": 'cps_early_childhood_portal_scrape.csv' ،
 "اسم الموقع": "جيش الخلاص - جيش المعبد / الخلاص" ،
 'العنوان': '1 ن أودين أفي' ،
 الرمز البريدي: لا شيء ،
..

هذا يبدو وكأنه التكرارات بالنسبة لي. لطيف.

هناك العديد من الاستخدامات المتقدمة لـ deduper ، مثل matchBlocks لتسلسل المجموعات ، أو حقول التفاعل حيث التفاعل بين الحقلين ليس مجرد مادة مضافة بل متعدد. لقد كان هناك الكثير مما يجب فعله ، لذلك سأترك هذا التفسير للمقالة أعلاه.

سلسلة مطابقة مع fuzzywuzzy

جرب هذه المكتبة. إنه أمر مثير للاهتمام حقًا لأنه يمنحك درجة لمعرفة مدى قرب الجمل عند مقارنتها.

لقد كانت هذه أداة رائعة للغاية ، حيث قمت بتنفيذ مشاريع في الماضي حيث كنت بحاجة إلى الاعتماد على الملحق fuzzymatch الخاص بـ Google Sheet لتشخيص مشكلات التحقق من صحة البيانات - أعتقد أن قواعد CRM لا يتم تطبيقها أو التصرف عليها بشكل صحيح - وهناك حاجة إلى التنظيف سجلات للقيام بأي نوع من التحليل.

ولكن بالنسبة لمجموعات البيانات الكبيرة ، فإن هذا النهج يقع في مكان ما.

ومع ذلك ، مع fuzzywuzzy ، يمكنك البدء في التوفيق بين سلسلة في مسألة أكثر علمية. ليس للحصول على تقنية أكثر من اللازم ، لكنه يستخدم شيئًا يُسمى مسافة ليفينشتاين عند المقارنة. هذا عبارة عن مقياس تشابه السلسلة لتسلسلين ، بحيث تكون المسافة بين عدد تعديلات الأحرف الفردية المطلوبة لتغيير كلمة واحدة إلى الكلمة الأخرى.

مثلا إذا كنت تريد تغيير السلسلة foo إلى شريط ، فإن الحد الأدنى لعدد الأحرف المراد تغييرها هو 3 ، ويستخدم هذا لتحديد "المسافة".

دعونا نرى كيف يعمل هذا في الممارسة العملية.

pip3 $ تثبيت fuzzywuzzy
# test.py
من fuzzywuzzy استيراد زغب
من عملية الاستيراد fuzzywuzzy
فو = 'هذه السلسلة'
شريط = 'مثل هذه السلسلة؟
fuzz.ratio (فو ، بار)
>>
71
fuzz.WRatio (foo ، شريط) # النسبة المرجحة
>>
73
fuzz.UQRatio (فو ، بار) # نسبة سريعة Unicode
>> 73

تحتوي حزمة fuzzywuzzy على طرق مختلفة لتقييم السلاسل (WRatio ، UQRatio ، وما إلى ذلك) ، وسألتزم فقط بالتطبيق القياسي لهذه المقالة.

بعد ذلك ، يمكننا إلقاء نظرة على سلسلة رمزية ، والتي تُرجع مقياسًا لتشابه التسلسلات بين 0 و 100 ولكن مع فرز الرمز المميز قبل المقارنة. هذا هو المفتاح لأنه قد ترغب فقط في رؤية محتويات السلاسل ، بدلاً من مواضعها.

تحتوي الأوتار والحانات على نفس الرموز ولكنهما مختلفان من الناحية الهيكلية. هل تريد أن تعاملهم نفس الشيء؟ يمكنك الآن البحث بسهولة عن هذا النوع من الاختلاف في بياناتك وحسابه.

فو = "هذا فو"
bar = 'foo a is this'
fuzz.ratio (فو ، بار)
>>
31
fuzz.token_sort_ratio ('هذا foo' ، 'foo a is this')
>>
100

أو بعد ذلك ، تحتاج إلى العثور على أقرب تطابق لسلسلة من قائمة القيم. في هذه الحالة ، سننظر في ألقاب هاري بوتر.

ماذا عن كتاب هاري بوتر مع ... عنوان شيء ... له ... أنا لا أعلم. أنا فقط بحاجة إلى تخمين ومعرفة أي واحد من هذه الكتب الأقرب إلى تخميني.

تخميني هو "إطلاق نار" ودعونا نرى كيف تسجل النقاط مقابل قائمة العناوين المحتملة.

lst_to_eval = ['هاري بوتر وحجر الفيلسوف' ،
"هاري بوتر وغرفة الأسرار" ،
"هاري بوتر وسجين أزكابان" ،
"هاري بوتر وكأس النار" ،
"هاري بوتر وجماعة العنقاء" ،
"هاري بوتر والأمير نصف الدم" ،
'هاري بوتر و الأقداس المهلكة']
# أعلى اثنين من الردود على أساس تخميني
process.extract ("fire"، lst_to_eval، limit = 2)
>>
[('هاري بوتر وكأس النار' ، 60) ، ("هاري بوتر وحجر الساحر" ، 30)
النتائج = process.extract ("fire" ، lst_to_eval ، limit = 2)
للنتيجة في النتائج:
  print ('{}: له درجة {}'. التنسيق (النتيجة [0] ، النتيجة [1]))
>>
هاري بوتر وكأس النار: حصل على 60 نقطة
هاري بوتر وحجر الساحر: لديه درجة 30

أو إذا كنت ترغب فقط في إرجاع واحدة ، يمكنك ذلك.

>>> process.extractOne ("stone"، lst_to_eval)
("هاري بوتر وحجر الساحر" ، 90)

أعلم أننا تحدثنا عن إلغاء التسجيل في وقت سابق ، ولكن هنا تطبيق آخر لنفس العملية مع fuzzywuzzy. يمكننا أن نأخذ قائمة من السلاسل التي تحتوي على التكرارات ونستخدم مطابقة غامض لتحديد التكرارات وإزالتها.

لا يتوهم مثل صافي العصبية ، لكنها ستقوم بهذه المهمة لعمليات صغيرة.

سنستمر في استخدام سمة Harry Potter ، ونبحث عن الأحرف المكررة من الكتب الموجودة في القائمة.

ستحتاج إلى تعيين عتبة تتراوح بين 0 و 100. مع انخفاض العتبة ، سيزداد عدد التكرارات التي تم العثور عليها ، وبالتالي سيتم تقليل القائمة التي تم إرجاعها. الافتراضي هو 70.

# قائمة أسماء الشخصيات المكررة
يحتوي على = =
'هاري بوتر'،
'هيدروجين. بوتر "،
"هاري جيمس بوتر" ،
"جيمس بوتر" ،
"رونالد بيليوس \" رون \ "ويزلي" ،
'رون ويزلي'،
"رونالد ويزلي"]
# طباعة القيم المكررة
process.dedupe (contains_dupes)
>>
dict_keys (['هاري جيمس بوتر' ، "رونالد بيليوس 'رون' ويزلي"])
# طباعة القيم المكررة مع عتبة أعلى
process.dedupe (contain_dupes ، العتبة = 90)
>>
dict_keys (['هاري جيمس بوتر' ، 'هـ. بوتر' ، 'رونالد بيليوس' رون 'ويزلي "])

وكمكافأة سريعة ، يمكنك أيضًا القيام ببعض المطابقة الضبابية مع حزمة التاريخ والوقت لاستخراج التواريخ من سلسلة نصية. هذا شيء رائع عندما لا ترغب في (مرة أخرى) كتابة تعبير regex.

من dateutil.parser تحليل الاستيراد
dt = parse ("اليوم هو 1 يناير 2047 الساعة 8:21:00 صباحًا" ، غامض = صحيح)
طباعة (دينارا)
>>
2047-01-01 08:21:00
dt = parse ("18 مايو 2049 شيء ما" ، غامض = صحيح)
طباعة (دينارا)
>>
2049-05-18 00:00:00

حاول بعض sklearn

إلى جانب تنظيف البيانات ، ستحتاج أيضًا إلى إعداد البيانات بحيث تكون في نموذج يمكنك إدخاله في النموذج الخاص بك. يتم سحب معظم الأمثلة هنا مباشرة من الوثائق ، والتي يجب أن يتم سحبها لأنها تقوم بعمل جيد في شرح المزيد من أحدث كل حزمة.

سنقوم باستيراد حزمة المعالجة المسبقة أولاً ، ثم الحصول على طرق إضافية من هناك ونحن نمضي قدمًا. أيضًا ، أنا أستخدم إصدار sklearn 0.20.0 ، لذا إذا كنت تواجه مشكلات في استيراد بعض الحزم ، فافحص الإصدار الخاص بك.

سنعمل مع نوعين مختلفين من البيانات ، str و int لتسليط الضوء على كيفية عمل أساليب المعالجة المسبقة المختلفة.

# في بداية المشروع
من sklearn استيراد المعالجة المسبقة
# ودعونا نخلق مجموعة عشوائية من ints للمعالجة
ary_int = np.random.randint (-100 ، 100 ، 10)
ary_int
>> [5 ، -41 ، -67 ، 23 ، -53 ، -57 ، -36 ، -25 ، 10 ، 17]
# وبعض شارع للعمل مع
ary_str = ['foo' ، 'bar' ، 'baz' ، 'x' ، 'y' ، 'z']

دعونا نجرب بعض العلامات السريعة مع LabelEncoder على ary_str. يعد هذا الأمر مهمًا لأنه لا يمكنك فقط تغذية الجمل الأولية - يمكنك ذلك ولكن هذا خارج عن نطاق هذه المقالة - في النماذج الخاصة بك. لذلك ، سنقوم بتشفير العلامات إلى كل من السلاسل ، بقيمة بين 0 و n. في ary_str لدينا ، لدينا 6 قيم فريدة لذلك لدينا مجموعة سيكون 0 - 5.

من sklearn.preprocessing استيراد LabelEncoder
l_encoder = preprocessing.LabelEncoder ()
l_encoder.fit (ary_str)
>> LabelEncoder ()
# ما هي قيمنا؟
l_encoder.transform ([ 'فو'])
>> مجموعة ([2])
l_encoder.transform ([ 'الباز'])
>> مجموعة ([1])
l_encoder.transform ([ 'بار'])
>> مجموعة ([0])

ستلاحظ أنه لم يتم طلب ذلك ، حتى من خلال foo جاء قبل الشريط في الصفيف ، تم تشفيره برقم 2 بينما تم ترميز الشريط بالرقم 1. سنستخدم طريقة ترميز مختلفة عندما نحتاج إلى التأكد من ترميز قيمنا في الترتيب الصحيح.

إذا كان لديك الكثير من الفئات التي يمكنك متابعتها ، فقد تنسى خرائط str التي يجب عليك تحديدها. لذلك ، يمكننا إنشاء الإملاء.

# تحقق التعيينات
قائمة (l_encoder.classes_)
>> ['bar' ، 'baz' ، 'foo' ، 'x' ، 'y' ، 'z']
# إنشاء قاموس التعيينات
dict (zip (l_encoder.classes_، l_encoder.transform (l_encoder.classes_))))
>> {'bar': 0 ، 'baz': 1 ، 'foo': 2 ، 'x': 3 ، 'y': 4 ، 'z': 5}

تختلف العملية قليلاً إذا كان لديك إطار بيانات ، ولكن في الواقع أسهل قليلاً. تحتاج فقط إلى .apply () الكائن LabelEncoder إلى DataFrame. لكل عمود ، ستحصل على تصنيف فريد للقيم داخل هذا العمود. لاحظ كيف يتم ترميز foo إلى 1 ، ولكن كذلك y.

# حاول LabelEncoder على مخطط البيانات
استيراد الباندا كما PD
l_encoder = preprocessing.LabelEncoder () # كائن جديد
df = pd.DataFrame (data = {'col1': ['foo' ، 'bar' ، 'foo' ، 'bar'] ،
                          'col2': ['x' ، 'y' ، 'x' ، 'z'] ،
                          "col3": [1 ، 2 ، 3 ، 4]})
# الآن للجزء السهل
df.apply (l_encoder.fit_transform)
>>
   col1 col2 col3
0 1 0 0
1 0 1 1
2 1 0 2
3 0 2 3

الآن ، نحن ننتقل إلى الترميز الترتيبي حيث لا تزال يتم التعبير عن الميزات كقيم عدد صحيح ، ولكن لديهم شعور المكان والبنية. بحيث يأتي x قبل y ، ويأتي قبل z.

ومع ذلك ، سوف نلقي مفتاحًا هنا. ليس فقط القيم المطلوبة ، ولكن سيتم إقرانها مع بعضها البعض.

سنأخذ مجموعة من القيم [‘foo 'و‘ bar' و ‘baz’ و [‘x’ و ‘y’ و ‘z’]. بعد ذلك سنقوم بتشفير 0 و 1 و 2 لكل مجموعة من القيم في كل صفيف ، وننشئ زوجًا مشفرًا لكل من القيم.

مثلا سيتم تعيين [foo '، ‘z'] على [0، 2] ، وسيتم تعيين [‘ baz '، ‘x'] على [2، 0].

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

من sklearn.preprocessing استيراد OrdinalEncoder
o_encoder = OrdinalEncoder ()
ary_2d = [['foo' ، 'bar' ، 'baz'] ، ['x' ، 'y' ، 'z']]
o_encoder.fit (2d_ary) # احتواء القيم
o_encoder.transform ([['' foo '،' y ']])
>> مجموعة ([[0. ، 1.]])

الترميز الكلاسيكي "hot" أو "dummy" ، حيث يتم التعبير عن الميزات الفردية للفئات كأعمدة إضافية من 0s أو 1s ، وفقًا لذلك تظهر القيمة أو لا. تقوم هذه العملية بإنشاء عمود ثنائي لكل فئة وإرجاع مصفوفة متفرقة أو صفيف كثيفة.

الائتمان إلى https://blog.myyellowroad.com/

لماذا حتى استخدام هذا؟ لأن هذا النوع من الترميز ضروري لتغذية البيانات الفئوية للعديد من نماذج scikit مثل نماذج الانحدار الخطي و SVMs. حتى تشعر بالراحة مع هذا.

من sklearn.preprocessing استيراد OneHotEncoder
hot_encoder = OneHotEncoder (handle_unknown = 'ignore')
hot_encoder.fit (ary_2d)
hot_encoder.categories_
>>
[صفيف (['foo' ، 'x'] ، dtype = كائن) ، صفيف (['bar' ، 'y'] ، dtype = object) ، صفيف (['baz' ، 'z'] ، dtype = كائن )]
hot_encoder.transform ([['' foo '،' foo '،' baz '] ، [' y '،' y '،' x ']]). toarray ()
>>
مجموعة ([[1. ، 0. ، 0. ، 0. ، 1. ، 0.] ،
       [0.، 0.، 0.، 1.، 0.، 0.]])

ماذا لو كان لدينا قاعدة بيانات للعمل معها؟

هل لا يزال بإمكاننا استخدام ترميز واحد ساخن؟ إنه في الواقع أسهل بكثير مما تعتقد حيث تحتاج فقط إلى استخدام .get_dummies () المضمنة في الباندا.

pd.get_dummies (مدافع)
      col3 col1_bar col1_foo col2_x col2_y col2_z
0 1 - 1 1 - 0
1 2 1 - - 1 0
2 3 - 1 1 - 0
3 4 1 - - - 1

تم تقسيم عمودين من الأعمدة الثلاثة في df وترميز ثنائي إلى إطار بيانات.

مثلا العمود col1_bar هو col1 من df ، لكن يحتوي على 1 كقيمة قياسية عندما يكون الشريط هو القيمة في ملف البيانات الأصلي.

ماذا عن متى يجب تحويل ميزاتنا ضمن نطاق معين. باستخدام MinMaxScaler ، يمكن تغيير حجم كل ميزة على حدة بحيث تكون في النطاق المحدد. بشكل افتراضي ، تتراوح القيم بين 0 و 1 ، ولكن يمكنك تغيير النطاق.

من sklearn.preprocessing استيراد MinMaxScaler
mm_scaler = MinMaxScaler (feature_range = (0 ، 1)) # بين 0 و 1
mm_scaler.fit ([ary_int])
>> MinMaxScaler (copy = True، feature_range = (0، 1))
طباعة (scaler.data_max_)
>> [5. -41. -67. 23. -53. -57. -36. -25. 10. 17.]
طباعة (mm_scaler.fit_transform ([ary_int]))
>> [[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] # Humm شيء خاطئ

إذا لاحظت أن القدرة هي كل الأصفار ... وهذا ليس ما أردناه. يوجد تفسير جيد هنا وهنا ، حول سبب حدوث ذلك ، لكن القصة القصيرة هي أن الصفيف تم تنسيقه بشكل غير صحيح.

إنها مصفوفة (1 ، ن) ويجب تحويلها إلى مصفوفة (ن ، 1). أسهل طريقة للقيام بذلك هي التأكد من أن الصفيف الخاص بك عبارة عن صفيف numpy ، لذلك يمكنك التعامل مع الشكل.

# إنشاء مجموعة numpy
ary_int = np.array ([5 ، -41 ، -67 ، 23 ، -53 ، -57 ، -36 ، -25 ، 10 ، 17])
# تحول
mm_scaler.fit_transform (ary_int [:، np.newaxis])
>>
مجموعة ([[0.8] ،
       [0.28888889]،
       [0. ]،
       [1. ]،
       [0.15555556]،
       [0.11111111]،
       [0.34444444]،
       [0.46666667]،
       [0.85555556]،
       [0.93333333]])
# تستطيع ايضا استخذام
mm_scaler.fit_transform (ary_int.reshape (-1، 1))
# أيضا محاولة على نطاق مختلف
mm_scaler = MinMaxScaler (feature_range = (0 ، 10))
mm_scaler.fit_transform (ary_int.reshape (-1، 1))
>>
مجموعة ([[8.] ،
       [2.88888889] ،
       [0.] ،
       [10. ]،
       [1.55555556] ،
       [1.11111111] ،
       [3.44444444] ،
       [4.66666667] ،
       [8.55555556] ،
       [9.33333333]])

والآن بعد أن أصبح بمقدورنا توسيع نطاق بياناتنا بسرعة ، ماذا عن تطبيق نوع من الشكل على بياناتنا المحولة؟ نحن نبحث في توحيد البيانات ، والتي ستمنحك القيم التي تنشئ غاوسيًا بمتوسط ​​0 و 1 من sd. قد تفكر في هذا النهج عند تطبيق النسب التدرجي ، أو إذا كنت بحاجة إلى مدخلات مرجحة مثل الانحدار و الشبكات العصبية. أيضًا ، إذا كنت ستقوم بتطبيق KNN ، فقم بتوسيع نطاق بياناتك أولاً. لاحظ أن هذا النهج مختلف عن التطبيع ، لذلك لا تشعر بالارتباك.

ببساطة استخدام مقياس من قبل المعالجة.

preprocessing.scale (فو)
>> array ([0.86325871، -0.58600774، -1.40515833، 1.43036297، -0.96407724، -1.09010041، -0.42847877، -0.08191506، 1.02078767، 1.24132821])
preprocessing.scale (فو) .mean ()
>> -4.4408920985006264e-17 # أساسًا صفر
 preprocessing.scale (فو) .std ()
>> 1.0 # بالضبط ما أردنا

آخر حزمة sklearn التي يجب النظر إليها هي Binarizer ، لا تزال تحصل على 0 و 1 من خلال هذا ولكن الآن يتم تحديدها وفقًا لشروطك الخاصة. هذه هي عملية "العتبة" للميزات العددية للحصول على قيم منطقية. سيتم تعيين قيم العتبة أكبر من العتبة على 1 ، بينما سيتم تعيين القيم المراد تعيينها على 0. كذلك ، هذه عملية شائعة عند معالجة النصوص مسبقًا للحصول على ترددات المصطلح ضمن مستند أو مجموعة.

ضع في اعتبارك أن كلا من fit () و convert () يتطلبان صفيفًا ثنائي الأبعاد ، وهذا هو السبب في أنني قد تداخلت ary_int في صفيف آخر. في هذا المثال ، وضعت العتبة على أنها -25 ، لذلك سيتم تعيين أي أرقام أعلى تمامًا من الرقم 1.

من sklearn.preprocessing استيراد Binarizer
# تعيين -25 كما عتبة لدينا
tz = Binarizer (العتبة = -25.0). صالح ([ary_int])
tz.transform ([ary_int])
>> مجموعة ([[1 ، 0 ، 0 ، 1 ، 0 ، 0 ، 0 ، 0 ، 1 ، 1]])

الآن بعد أن أصبح لدينا بعض هذه التقنيات المختلفة ، ما هي الطريقة الأفضل للخوارزمية؟ قد يكون من الأفضل حفظ بضع إطارات بيانات وسيطة مختلفة مع بيانات محجوبة ، بيانات محذوفة ، وما إلى ذلك حتى تتمكن من رؤية التأثير على مخرجات الطراز (النماذج) الخاص بك.

افكار اخيرة

تنظيف وإعداد البيانات أمر لا مفر منه وعموما مهمة ناكر للجميل عندما يتعلق الأمر بعلم البيانات. إذا كنت محظوظًا بما فيه الكفاية لوجود فريق هندسة البيانات معك والذي يمكنه المساعدة في إنشاء خطوط أنابيب ETL لتسهيل عملك ، فقد تكون في أقلية من علماء البيانات.

ليست الحياة مجرد مجموعة من مجموعات بيانات Kaggle ، حيث سيتعين عليك في الواقع اتخاذ قرارات بشأن كيفية الوصول إلى البيانات التي تحتاج إليها وتنظيفها يوميًا. في بعض الأحيان ، سيكون لديك متسع من الوقت للتأكد من أن كل شيء في المكان المناسب ، ولكن في معظم الأوقات ستتم الضغط عليك للحصول على إجابات. إذا كانت لديك الأدوات المناسبة في المكان وفهم ما هو ممكن ، فستتمكن من الوصول إلى هذه الإجابات بسهولة.

كالمعتاد ، أتمنى أن تكون قد تعلمت شيئًا جديدًا.

في صحتك،

قراءة إضافية