وقتی یک مشتری، کاربر، بازیکن، دنبالکننده یا هر نوعی از کاربر بازگشتکننده (returning client)، ارتباط خود را با یک مرکز قطع میکند، یک ریزش یا churn رخ داده است. مثلا اگر یک مشتری فروشگاه اینترنتی برای مدتی از آن فروشگاه خرید نکند، اصطلاحا میگوییم آن مشتری churn شده یا ریزش کرده است. ریزش یا چرن، انواع مختلفی دارد:
- ریزش قراردادی (contractual churn): در این نوع ریزش، مشتری یک قرارداد با ما دارد و به یک باره تصمیم میگیرد قرارداد را کنسل کند. (مثلا در قراردادهای شرکتهای SaaS یا شبکههای تلویزیونی)
- ریزش غیرقراردادی (non-contractual churn): این نوع ریزش در کسبوکارهای ایکامرسی مانند آمازون رخ میدهد؛ در این کسبوکار، هر خرید میتواند خرید آخر و در نتیجه چرن باشد؛ لذا ریزش غیرقرادادی پیچیدگی بیشتری از ریزش قراردادی دارد.
- ریزش داوطلبانه (voluntary churn): در این نوع ریزش، مشتری به انتخاب و آگاهی خود، به خرید سرویس یا محصول یک شرکت خاتمه میدهد و ارتباط خود را قطع میکند.
- ریزش غیرداوطلبانه (involuntary churn): این ریزش به عللی ایجاد میشود که در اختیار مشتری نیست و به صورت ناآگاهانه رخ میدهد؛ به عنوان مثال اگر درگاه پرداخت سایت مشکل داشته باشد، ممکن است ریزش غیرداوطلبانه رخ دهد.
علت ریزش یا چرن شدن مشتری چیست؟
کنسل کردن یک سرویس توسط کاربر معمولا به علل مختلفی رخ میدهد. برخی از این علل عبارتند از:
- ناکارآمدی سرویس یا محصول برای شما
- ضعیف بودن سرویس
- پیدا کردن سرویس مشابه با قیمت پایینتر
آشنایی با دیتاست مورد استفاده
در این مقاله، شما میآموزید که چگونه یک مدلسازی churn را به طور کامل انجام دهید. دیتاستی که در این دوره استفاده میشود، یک دیتاست واقعی از تماسهای تلفنی با نام Telco است. از فرم زیر میتوانید این دیتاست را دانلود کنید:
فیچرهای موجود در این دیتاست در جدول زیر توضیح داده شدهاند:
کد مخصوص مشتری | customerID |
جنسیت | gender |
آیا فرد بازنشسته هست یا نه | SeniorCitizen |
آیا فرد پارتنر دارد یا نه | Partner |
وابستگی مالی فرد به دیگران | Dependents |
تعداد ماههایی که فرد مشتری شرکت بوده | tenure |
آیا از سرویس تلفن استفاده میکند یا نه | PhoneService |
آیا از خطهای مختلفی استفاده میکند یا نه | MultipleLines |
نوع سرویس اینترنتی | InternetService |
آیا از سرویس امنیتی استفاده میکند یا نه | OnlineSecurity |
آیا از بکاپ استفاده میکند یا نه | OnlineBackup |
آیا از سرویسهای محافظتی استفاده میکند یا نه | DeviceProtection |
پشتیبانی فنی استفاده میکند یا نه | TechSupport |
آیا از سرویس استریم تلویزیونی استفاده میکند یا نه | StreamingTV |
آیا از سرویس استریم فیلم استفاده میکند | StreamingMovies |
نوع قرارداد | Contract |
پرداخت آنلاین استفاده می کند یا نه | PaperlessBilling |
روش پرداخت | PaymentMethod |
میانگین شارژ ماهانه | MonthlyCharges |
کل میزان شارژ | TotalCharges |
چرن شده است یا نه | Churn |
در این جا چرن این گونه تعریف شده است: کنسل کردن پلن سرویس تلفنی (مقادیر: yes / no)
در ادامه، با این دیتاست کار میکنید تا شناخت خوبی از فیچرهای آن به دست آورید. علاوه بر این با استفاده از توابع موجود در کتابخانه pandas، با نحوه توزیع دادههای هر فیچر آشنا خواهید شد. برخی از توابع، تابع head، تابع describe و تابع mean است. پیشنهاد میکنیم برای کسب آمادگی بیشتر، دوره آموزش پایتون و ویدیو آشنایی با کتابخانههای یادگیری ماشین در پایتون را ببینید.
وارد کردن و کار با دیتاست telco
حال که با مقدمات چرن (churn) آشنا شدیم، بیایید کمی با دیتاست کار کنیم. با استفاده از پانداس، دیتاست مد نظر را وارد میکنیم. کار کردن با دیتا و آشنایی کلی با ساختار آن، از مراحل اولیه انجام هر پروژه یادگیری ماشین است. با استفاده از متد info در پانداس میتوان یک دید کلی در مورد ستونهای (فیچرهای) دیتاست به دست آورد. فیچری که برای ما به عنوان تارگت اهمیت دارد، Churn است. در این ستون دو مقدار yes یا no وجود دارد که نشاندهندهی چرن شدن یا چرن نشدن است. با استفاده از دستور telco[‘Churn’] میتوان به مقادیر این ستون، دسترسی پیدا کرد. برای آن که بفهمید چند نفر چرن شدهاند، میتوانید از متد value_counts برای ستون Churn استفاده کنید.
1 2 3 4 5 6 |
file_path = '/content/drive/My Drive/Colab Notebooks/ml/churn rate prediction/WA_Fn-UseC_-Telco-Customer-Churn.csv' telco = pd.read_csv(file_path) print(telco.info()) print(telco['Churn']) print(telco['Churn'].value_counts()) |
دادههای موجود در بعضی ستونها، categorical هستند؛ به عنوان مثال در ستون Churn، دادهها یا yes هستند یا no. گاهی ممکن است بخواهید بدانید کسانی که چرن شدهاند (yes)، چه ویژگیهای دیگری داشتهاند؛ در حقیقت نیاز دارید که بر اساس لیبلهای موجود در یک ستون، کل دادههای دیتاست را با هم مقایسه کنید. برای فهم بهتر این موضوع، به مثال زیر توجه کنید. در این مثال با استفاده از متد groupby، میانگین و انحراف معیار سایر ستونها را بر اساس لیبلهای ستون Churn به دست آوردهایم. استفاده از متد groupby برای بررسی بهتر یک ستون (سوال ۳ و ۴ و ۵)
1 2 |
print(telco.groupby(['Churn']).mean()) print(telco.groupby(['Churn']).std()) |
1 |
print(telco.groupby('InternetService')['Churn'].value_counts()) |
مصورسازی دادههای دیتاست churn
مصورسازی دادهها به شما کمک میکند تا شناخت بهتر و درستتری از دادهها پیدا کنید. در پایتون، با استفاده از کتابخانه seaborn میتوان نمودارهای جذابی رسم کرد. کتابخانه seaborn بر روی کتابخانه matplotlib ساخته شده است.
یکی از مهمترین مواردی که باید دربارهی دیتاست دانست، چگونگی توزیع دادههاست. رسم هیستوگرام، روش خوبی برای فهم چگونگی توزیع دادههاست. با استفاده از تابع distplot کتابخانه seaborn، میتوان هیستوگرام دادههای یک ستون را رسم کرد. distplot خلاصهشدهی عبارت distribution plot است. در تکه کدهای زیر، دو نمودار رسم کردهایم که در ادامه به توزیع بیشتر آنها میپردازیم.
1 2 |
sns.distplot(telco['MonthlyCharges']) plt.show() |
در این کد، هیستوگرامِ میانگین شارژ ماهیانه را رسم کردهایم. محور افقی، میزان شارژ ماهیانه را نشان میدهد و محور عمودی، فراوانی آن میزان را نشان میدهد (دادههای در محور عمودی نرمالایز شدهاند). توجه کنید که هیستوگرام نمودار سادهای است که دید کلی نسبت به چگونگی توزیع «یک» متغیر را به ما میدهد. خروجی کد بالا به صورت زیر خواهد بود:
1 2 |
sns.boxplot(x='Churn', y='MonthlyCharges', data=telco) plt.show() |
در کد بالا، نمودار جعبهای دادههای موجود در ستون MonthlyCharges را بر حسب Churn رسم کردهایم. نمودار جعبهای پنج شاخص مهم را نشان میدهد: مینیمم، چارک اول، چارک دوم (میانه)، چارک سوم و ماکزیمم. در تصویر زیر، چگونگی خوانش نمودار جعبهای و خروجی کد بالا را میبینید.
برای ارزیابی تسلط خود تا این جای کار، پیشنهاد میکنیم سعی کنید به سوالات زیر پاسخ دهید:
۱-کدام مورد، مثالهایی برای churn rate است؟
- کنسل کردن قرارداد یک سرویس
- منقضی شدن تاریخ استفاده از کارت اعتباری
- پایان خرید یک محصول که قراردادی برای خرید آن نبوده است
- خرید از مغازهای دیگر
- همه موارد
۲-در دیتاست telco، چند نفر چرن شدهاند و چند نفر ریزش پیدا نکردهاند؟
- ۵۱۷۴ چرن شده و ۱۸۶۹ چرن نشده
- ۳۲۱۵ چرن شده و ۳۸۲۸ چرن نشده
- ۱۸۶۹ چرن شده و ۵۱۷۴ چرن نشده
- ۳۸۲۸ چرن شده و ۳۲۱۵ چرن نشده
۳-انحراف معیار میزان شارژ ماهیانه، برای کسانی که چرن شدهاند چقدر بوده است؟
- ۲۴.۶۷
- ۳۱.۰۹
- ۲۷.۸۸
- ۳۳.۶۵
۴-کدام گزینه درست است؟
- میانگین شارژ ماهیانه کسانی که چرن شدهاند از کسانی که چرن نشدهاند بیشتر بوده است.
- کسانی که چرن شدهاند، تعداد ماههای کمتری اشتراک داشتهاند.
- کل میزان شارژ کسانی که چرن شدهاند از کسانی که چرن نشدهاند بیشتر بوده است.
- همه موارد
۵-از میان کسانی که از سرویس اینترنتی DSL استفاده میکنند، چند نفر چرن شدهاند؟
- ۱۹۶۲
- ۱۲۹۷
- ۱۱۳
- ۴۵۹
پیش پردازش دادههای مورد استفاده در پیشبینی چرن
Encoding دادهها
در قسمتهای قبلی با کاوشهایی که در دیتاست داشتیم، دید نسبتا خوبی به دست آوردیم. حال زمان آن رسیده که با انجام پیشپردازشهایی بر روی دادهها، آمادهی ساخت مدل پیشبینی چرن شویم. بسیاری از مدلهای یادگیری ماشین، پیشفرضهایی در مورد نحوهی توزیع دادهها دارند. اگر فیچرهای دیتاست ما مطابق این پیشفرضهای مدل مورد استفاده نباشد، نتایج به دست آمده، قابل اعتماد نخواهد بود. انجام پیش پردازش بر روی دادهها به همین علت (فراهم کردن فیچرها مطابق با پیشفرضهای مورد نیاز مدل) صورت میگیرد. برخی از پیشفرضهایی که مدلهای ماشین لرنینگ دارند، عبارتند از:
- فیچرها به صورت نرمال، توزیع شدهاند.
- فیچرها، scale یکسانی دارند؛ یعنی اندازه آنها تقریبا در یک رنج است.
بسیاری از مدلهای یادگیری ماشین، تنها دادههای عددی را به عنوان ورودی قبول میکنند؛ بنابراین اگر هر یک از فیچرهای شما، دادههای غیرعددی (categorical) داشته باشند، باید آنها را به دادههای عددی تبدیل کنید؛ به این تبدیل encoding میگویند. برای فهمیدن دیتاتایپ هر یک از ستونها در دیتاست، میتوان از کد زیر استفاده کرد.
1 |
print(telco.info()) |
برای فهم encoding به این مثال توجه کنید:
دادههای موجود در ستون gender، غیرعددی هستند و دو حالت دارند: Male یا Female. برای عددی کردن این دادهها، میتوان Male را ۰ و Female را ۱ در نظر گرفت. برای encode کردن میتوان از متد replace به شکل زیر استفاده کرد.
1 2 3 |
print(telco.gender) telco.gender = telco.gender.replace({'Male':, 'Female':1}) print(telco.gender) |
به همین ترتیب بایستی سایر ستونها را نیز در صورت نیاز، encode کنیم.
نرمالسازی دادههای دیتاست churn
یکی از پیشپردازشهای مهم دیگری که باید انجام دهیم، نرمالیزیشن (feature scaling / normalization) است. اکثر مدلها نیاز دارند که دادههای ورودی آنها، تقریبا رنج یکسانی داشته باشند؛ عملا در دنیای واقعی، چنین اتفاقی به ندرت پیش میآید؛ پس باید به شکل دستی، رنج دادهها را یکسان کنیم. نرمالیزیشن انواع مختلفی دارد که یکی از مهمترین آنها، استاندارسازی (standardization) است. این کار با کم کردن میانگین از همه دادهها و تقسیم آنها بر انحراف معیار، حاصل میشود. با استفاده از کتابخانه scikit learn میتوان به راحتی دادهها را استاندارد کرد که در ادامه نحوه انجام آن را میبینید. توجه کنید که دادههای نرمالایزشده در یک دیتافریم جدید با نام telco_scaled ذخیره شدهاند.
1 2 3 4 5 6 7 |
telco_scaled = telco[['gender', 'SeniorCitizen', 'Partner', 'Dependents', 'tenure', 'PhoneService', 'MultipleLines', 'InternetService', 'OnlineSecurity', 'OnlineBackup', 'DeviceProtection', 'TechSupport', 'StreamingTV', 'StreamingMovies', 'Contract', 'PaperlessBilling', 'PaymentMethod', 'MonthlyCharges', 'TotalCharges', 'Churn']] telco_scaled = pd.DataFrame(StandardScaler().fit_transform(telco_scaled), index=telco_scaled.index, columns=telco_scaled.columns) print(telco_scaled.describe()) |
انتخاب و مهندسی فیچر
دیتاستها معمولا حاوی فیچرهایی هستند که هیچ تاثیری در پیشبینیهای ما ندارند؛ لذا برای سادگی محاسبات بهتر است این فیچرها را حذف کنیم. بعضی از فیچرهایی که خاصیت پیشبینیکننده ندارند، عبارتند از:
- فیچرهای خاص هر فرد (مانند شماره موبایل، کد ملی و آیدی)
- فیچرهایی که کاملا وابسته به فیچرهای دیگر هستند
با استفاده از متد drop در پانداس میتوان یک فیچر (ستون) خاص را حذف کرد. همچنین با استفاده از متد corr که سرواژه correlation است میتوان همبستگی بین فیچرها در یک دیتاست را به دست آورد.
به فرآیند انتخاب فیچرها برای استفاده در مدل یادگیری ماشین، feature selection گفته میشود. در کنار انتخاب فیچرهای مناسب، معمولا نیاز داریم فیچرهای جدید نیز بسازیم تا عملکرد مدل را بهبود بخشیم. این فرایند مهندسی فیچر (feature engineering) نام دارد. به عنوان مثال اگر در یک دیتاست، فیچرهای مختلفی داشته باشیم که بیانگر یک کمیت یکسان باشند، میتوان با جمع آنها به یک فیچر جدید رسید.
برای ارزیابی تسلط خود تا این جای کار، پیشنهاد میکنیم سعی کنید به سوال زیر پاسخ دهید:
۱-در دیتاست مورد استفاده، دیتا تایپ کدام فیچرها، object نیست؟
- SeniorCitizen / tenue / MonthlyCharges
- MonthlyCharges / PhoneService / TechSupport
- SeniorCitizen / Churn / PhoneService
ساخت مدل ماشین لرنینگ برای پیشبینی چرن با استفاده از scikit learn
در قسمت اول، با دیتاست کار کردیم و یک دید کلی نسبت به دیتاهای در دسترس و هدف پیدا کردیم؛ در قسمت دوم هم مراحل پیشپردازش دادهها را طی نمودیم و دیتاست را آمادهی وارد شدن به مدل یادگیری ماشین کردیم. حال وقت آن رسیده که مدل خود را بسازیم و پیشبینیهایی با استفاده از آن انجام دهیم! هدف ما آن است که تشخیص دهیم یک مشتری، با توجه به ویژگیهایش، آیا چرن میشود یا نه؟
برای ساخت مدل ماشین لرنینگ مد نظر، از روشهای یادگیری با ناظر (Supervised Machine Learning) استفاده میکنیم. ما پیشبینیهای خود را بر اساس یک سری دادههای تاریخی انجام میدهیم؛ این دادهها، دادهی train نام دارند؛ زیرا با استفاده از آن به مدل خود یاد میدهیم و آن را آمادهی پیشبینی میکنیم.
برای پیادهسازی یادگیری با ناظر در پایتون، متدها و الگوریتمهای مختلفی وجود دارد؛ در این دوره، ما با استفاده از کتابخانه scikit learn، مدلهای خود را میسازیم. یکی از سختترین سوالاتی که باید پاسخ دهیم، این است که از چه مدل یادگیری ماشینی استفاده کنیم؟ جواب این است که بستگی دارد! در این مقاله، سعی میکنیم با مدلهای مختلف یادگیری ماشین، چرن را پیشبینی کنیم.
برای مسائل کلسیفیکیشن، یکی از مدلهایی که معمولا کارایی خوبی دارد و بهتر است با آن کار را شروع کنیم، مدل رگرسیون لجستیک (logistic regression) است. این مدل ساده است اما برای پیدا کردن الگوها و روابط پیچیده مناسب نیست. مدل دیگر برای انجام با ناظر کلسیفیکیشن، مدل رندوم فارست (random forests) است. روش دیگر هم، روش SVM است. در این مقاله، همه این روشها را تست میکنیم.
ساخت مدل SVM برای پیش بینی چرن (churn prediction)
SVM سرواژهی عبارت support vector machine و یکی از روشهای مناسب یادگیری ماشین با ناظر است. SVM هم برای مسائل رگرسیون و هم برای کلسیفیکیشن، کارایی دارد. در ادامه، پیادهسازی این مدل با استفاده از کتابخانه scikit learn را میبینید.
1 2 |
svm_classifier = SVC() svm_classifier.fit(x_train, y_train) |
حال شما یک مدل ترینشده در اختیار دارید که با استفاده از متد predict، میتوانید از آن استفاده کنید:
1 2 |
svm_prediction = svm_classifier.predict(x_test) print(accuracy_score(svm_prediction, y_test)) |
متد accuracy_score میزان دقت عملکرد مدل را به شما میدهد؛ این عدد در واقع تعداد پیشبینیهای درست تقسیم بر تعداد کل پیشبینیهاست.
ساخت مدل رگرسیون لجستیک برای پیش بینی چرن (churn prediction)
برای ساخت این مدل نیز فرایند قبلی را طی میکنیم:
1 2 3 4 5 |
logistic_classifier = LogisticRegression() logistic_classifier.fit(x_train, y_train) logistic_prediction = logistic_classifier.predict(x_test) print(accuracy_score(logistic_prediction, y_test)) |
ساخت مدل درختی برای برای پیش بینی churn
برای ساخت این مدل نیز فرایند قبلی را طی میکنیم:
1 2 3 4 5 |
tree_classifier = DecisionTreeClassifier() tree_classifier.fit(x_train, y_train) tree_prediction = tree_classifier.predict(x_test) print(accuracy_score(tree_prediction, y_test)) |
ساخت مدل رندوم فارست برای پیش بینی ریزش مشتریان
برای ساخت این مدل نیز فرایند قبلی را طی میکنیم:
1 2 3 4 5 |
forest_classifier = RandomForestClassifier() forest_classifier.fit(x_train, y_train) forest_predict = forest_classifier.predict(x_test) print(accuracy_score(forest_predict, y_test)) |
متریکهای ارزیابی مدل یادگیری ماشین
تا کنون آموختیم که چگونه یک مدل یادگیری ماشین بسازیم و آن را train کنیم؛ علاوه بر این یاد گرفتیم با استفاده از مدل ساختهشده، حدسهایی بزنیم و با متد accuracy_score، آن حدسها و در نتیجه عملکرد مدل را بسنجیم. حال سوال این است که اگر به یک دقت مناسبی رسیدیم، کار ما پایان یافته است؟ نه!
در عمل، بسیاری از دیتاستها، کلاسهای نامتعادل دارند؛ به این معنا که اکثر دادهها متعلق به یک کلاس هستند و تعداد کمتری داده در کلاس دیگر موجودند. این موضوع ممکن است عملکرد مدل ما را تحت تاثیر قرار دهد؛ یعنی مدل ما برای پیشبینی کلاس غالب درست عمل کند، اما در پیشبینی کلاس دیگر، ضعیف باشد. روشهایی وجود دارند که میتوان این عدم تعادل را رفع کرد تا مسئله حل شود که در این دوره به آنها نمیپردازیم.
برای آن که بفهمیم مدل ما از عدم تعادل کلاسها تاثیر گرفته یا نه، accuracy متریک مناسبی نیست؛ ما اگر مدلی بسازیم که پیشبینی کند مشتری هیچ گاه چرن نمیشود، شاید accuracy مناسبی داشته باشد (چون اکثر مشتریان چرن نمیشوند و این کلاس، کلاس غالب است). برای ارزیابی درست عملکرد مدل، میتوان از ماتریس confusion استفاده کرد که در ادامه چیستی آن را توضیح میدهیم.
اگر ما دو کلاس داشته باشیم، ماتریس کانفیوژن به شکل زیر در میآید:
این که recall را بهبود بدهیم یا precision را، کاملا بستگی به اهداف و نوع کسبوکار شما دارد؛ اگر نگهداری مشتریانی که در حال چرن شدن هستند نسبت به از دست دادن مشتری، هزینه بیشتری برای شما دارد، احتمالا ترجیح میدهید مدلتان precision بالایی داشته باشد (FP را مینیمم میکنید)؛ در مقابل اگر از دست دادن مشتریانی که فکر میکردید چرن نمیشوند، هزینه بیشتری از نگه داشتن مشتری دارد، احتمالا ترجیح میدهید recall را افزایش دهید (FN را کاهش دهید).
با استفاده از کد زیر میتوانید یک ماتریس کانفیوژن در پایتون بسازید:
1 2 3 |
from sklearn.metrics import confusion_matrix print(confusion_matrix(y_test, svm_prediction)) |
بهینه سازی مدل پیشبینی churn
ما برای آن که مدلهای قابل اطمینانی داشته باشیم و بتوانیم در عمل از آنها استفاده کنیم، باید دقت را تا حد امکان بالا ببریم. روشهای مختلفی برای بالا بردن دقت مدل وجود دارند؛ در این جا با hyperparameter tuning آشنا میشویم.
هایپر پارامتر چیست؟
در قسمتهای قبل با مدلهای متعددی برای کلسیفیکیشن آشنا شدیم؛ در هنگام ساخت یک مدل با استفاده از scikit learn میتوان به دلخواه، پارامترهای مختلفی را به عنوان ورودی به مدل داد؛ به این پارامترها، هایپر پارامتر (hyperparameter) گفته میشود. هر یک از مدلهای یادگیری ماشین، هایپر پارامترهای مخصوص خود را دارد. همه مدلهایی که تا کنون استفاده کردهایم، از هایپر پارامترهای پیشفرض استفاده میکردند؛ حال میخواهیم با تغییر این پارامترها، به عملکرد بهتری دست یابیم؛ به این کار tuning گفته میشود. ما در این پروژه از یک تکنیک به نام Grid Search استفاده میکنیم. در این تکنیک، با بررسی عملکرد مدل با استفاده از پارامترهای مختلف، بهترین مقدار را برای هایپر پارامترهای مد نظر پیدا میکنیم. در قطعه کد زیر، مثالی از tuning یکی از هایپر پارامترهای مدل رندوم فارست را میبینید:
1 2 3 4 5 6 7 |
#hyperparameter tuning using GridSearchCV param_grid = {'n_estimators': np.arange(100, 200)} grid_search_random_forest = GridSearchCV(RandomForestClassifier(), param_grid) grid_search_random_forest.fit(x, y) print(grid_search_random_forest.best_params_) print(grid_search_random_forest.best_score_) |
البته میتوان بیش از یک هایپر پارامتر نیز در دیکشنری param_grid قرار داد؛ در این صورت، کلیهی ترکیبهای ممکن بین هایپر پارامترها تست میشود و بهترین آنها نمایش داده میشود؛ انجام چنین کاری، ممکن است به دلیل محاسبات زیاد، زمان زیادی از ما بگیرد؛ چون تمامی ترکیبها و حالتهای ممکن تست میشود. برای رفع این مشکل میتوان به جای GridSearchCV از RandomizedSearchCV استفاده کرد؛ در این حالت، به جای بررسی همهی حالتها، حالتهای محدودی به صورت رندوم انتخاب و تست میشوند؛ با این کار ممکن است واقعا به بهترین حالت ممکن دستیابی نداشته باشیم، اما از نظر زمانی بسیار بهینهتر است. در قطعه کد زیر، نحوه انجام این کار را میبینید:
1 2 3 4 5 6 |
#hyperparameter tuning using RandomizedSearchCV param_dist = {'n_estimators': np.arange(100, 200)} randomized_search_random_forest = RandomizedSearchCV(RandomForestClassifier(), param_dist) randomized_search_random_forest.fit(x, y) print(randomized_search_random_forest.best_params_) |
میزان تاثیر فیچرها در ریزش مشتریان
روشهای درختی در یادگیری ماشین مانند Random Forests، به ما این امکان را میدهند که اهمیت هر یک از فیچرها در پیشبینی نهایی را متوجه شویم. میزان اهمیت فیچر را با متریکی به نام Score مشخص میکنیم. مصورسازی اهمیت فیچرها و نشان دادن آن به افراد دیگر، روش خوبی برای تحلیل دادهها و به کار گرفتن آن تحلیلها در کسبوکار است. به عنوان مثال میتوانیم متوجه شویم کدام فیچرها، بیشترین اهمیت در Churn شدن مشتری را دارند. در تکه کد زیر، نحوه محاسبه اهمیت فیچرها در یک مدل رندوم فارست را میبینید:
1 2 3 4 |
#calculating frature importances feature_importances = forest_classifier.feature_importances_ print(feature_importances) |
با استفاده از کد زیر نیز میتوانید نمودار میلهای اهمیت فیچرها را رسم کنید:
1 2 |
plt.barh(range(, x.shape[1]), feature_importances) plt.show() |
برای آن که خوانایی نمودار بیشتر شود، مقادیر موجود در آن را sort کرده و سپس لیبل میزنیم:
1 2 3 4 5 6 7 8 |
#sorting indexes of feature_importances sorted_index = np.argsort(feature_importances) #creating labels labels = x.columns[sorted_index] plt.barh(range(, x.shape[1]), feature_importances[sorted_index], tick_label=labels) plt.show() |
در نهایت به نمودار زیر خواهیم رسید:
اضافه کردن فیچرهای جدید
یکی از راههای آسان برای بهبود عملکرد مدل، اضافه کردن فیچرهای جدید به دیتاست است. حتی بهبودهای چند درصدی در پیشبینی چرن هم میتواند درآمدهای زیادی برای شرکت ایجاد کند. نقاط اتصال مشتری با برند یک شرکت (touch point)، نقاط مهمی هستند که میتوان از آنها دادههای جمعآوری کرد که در پیشبینی churn موثر هستند. برخی از تاچ پوینتهای مشتریان با برند عبارتند از:
- پشتیبانی از مشتریان
- کمپینهای ایمیلی
- لاگهای مشتری در وبسایت
- دوستان و آشنایان مشتری
- تراکنشها
- و …
اضافه کردن هر یک از این دیتاها به مدل، میتواند عملکرد به شدت بهبود دهد. برخی از فواید کاهش دادن Churn Rate برای یک کسبوکار عبارتند از:
- بهبود ROI (درآمد به ازای سرمایهگذاری انجامشده)
- کاهش هزینهها
- بهبود عملکرد
با سلام ضمن تشکر از سایت خوب و علمی شما به نظرم در قسمت پیش پردازش داده ها خوب بود به صورت عملی feature selection پیاده سازی میکردید چون حتما شما بهتر از من میدونید قسمت عمده و شاید اصلی هر پروژه تمیزسازی داده ها و انتخاب فیچرهای تاثیرگذار می باشد.
با تشکر