В этом сообщении блога я покажу вам пошаговое руководство по проекту с использованием набора данных об оттоке клиентов в сфере телекоммуникаций. Мы получим представление о подготовке данных, выборе и оценке модели, а также о том, как эффективно представить и передать решение.

Для начала мы начнем с формулировки проблемы.

Помимо достижения наилучших показателей оценки, мы должны определить KPI (ключевые показатели эффективности), которые окажут положительное влияние на работу или бизнес-среду. В этом проекте по прогнозированию оттока основная цель — добиться более высокого уровня удержания клиентов.

Определение бизнес-проблемы

Необходимо знать, кто из ваших клиентов собирается отказаться от услуг. А для этого мы должны исследовать предварительные признаки их ухода, чтобы попытаться их сохранить. Таким образом, бизнес-задача состоит в том, чтобы уменьшить отток клиентов и увеличить их удержание.

КПЭ (ключевые показатели эффективности)

  • Получение раннего предупреждения о клиентах, которые собираются отказаться от услуг компании, приведет к более высокому уровню удержания клиентов.
  1. Получение данных

Набор данных, используемый для этого проекта, представляет собой прогноз оттока клиентов в сфере телекоммуникаций. Таблица Customer Churn содержит информацию обо всех 7043 клиентах телекоммуникационной компании в Калифорнии во втором квартале 2022 года.

Каждая запись представляет одного клиента и содержит сведения об их демографических данных, местоположении, сроке пребывания, услугах подписки, статусе за квартал (присоединился, остался или ушел) и многое другое!

2. Изучение данных, чтобы получить представление.

Этот шаг является очень важным и, вероятно, занимает больше всего времени. нам необходимо изучить каждый атрибут и его характеристики, а также выявить проблемы с качеством данных, которые необходимо решить. После очистки данных мы визуализируем результаты, можем получить представление о корреляциях между атрибутами и ответить на вопросы.

После расследования (проблемы качества данных, задавание необходимых вопросов и ответы на них) и очистки данных. Следующим шагом будет разделение ваших данных на наборы для обучения и тестирования.

После изучения проблем с качеством данных следующим шагом будет очистка данных. На этом этапе мы просто изменили тип там, где это необходимо, удалили пустые столбцы и заполнили некоторые с помощью функций и, наконец, удалили столбцы, которые не нужны.

#Replacing the null values of the Avg Monthly GB Downloadm  
mean_value1=df['Avg Monthly GB Download'].mean()
df['Avg Monthly GB Download'].fillna(value=mean_value1, inplace=True)
mean_value2 = df['Avg Monthly Long Distance Charges'].mean()
df['Avg Monthly Long Distance Charges'].fillna(value=mean_value2, inplace=True)
df = df.drop(['Churn Category','Churn Reason'], axis=1)

#Changing Married,, , Phone Service,
#Multiple Lines, Internet Service, Online Service, Online Backup, Device Protection Plan
#Premium Tech Support, Streaming TV, Streaming Movies, Streaming Music
#Unlimited Data, Paperless Billing to Bool
object_to_bool_columns = ['Married', 'Phone Service','Multiple Lines', 'Internet Service', 'Online Security', 'Online Backup', 'Device Protection Plan',
'Premium Tech Support', 'Streaming TV', 'Streaming Movies', 'Streaming Music' ,'Unlimited Data', 'Paperless Billing']
for column in object_to_bool_columns:
    df[column] = df[column].replace({'Yes':'True','No':'False'})
    #This step is to convert the 'True' string into real boolean
    df[column] = df[column].apply(lambda x : x =='True')
    
#Channging the results of Customer Status from object to bool where Joined and Stayed is False, Churned is True
object_to_bool_columns1 = ['Customer Status']
for column in object_to_bool_columns1:
    df[column] = df[column].replace({'Stayed':'False','Joined':'False','Churned':'True'})
    #This step is to convert the 'True' string into real boolean
    df[column] = df[column].apply(lambda x : x =='True')
#Renaming Customer status column
df = df.rename(columns = {'Customer Status':'Customer_Status'})

#Changing Number of Dependents and Number of Referrals from int to bool, because the amount of dependet
colName = 'Number of Dependents'    
df[colName][df[colName]>1] = 1

colname = 'Number of Referrals'
df[colname][df[colname]>1] = 1

#Changing from int to bool
df['Number of Dependents'] = df['Number of Dependents'].astype('bool')
df['Number of Referrals'] = df['Number of Referrals'].astype('bool')

#This is to create a new age group column based on different age ranges
df.loc[df['Age']<11, 'Age group'] = 'Youngins'
df.loc[df['Age'].between(11,26), 'Age group'] = 'Gen Z'
df.loc[df['Age'].between(27,42), 'Age group'] = 'Millenials'
df.loc[df['Age'].between(43,58), 'Age group'] = 'Gen X'
df.loc[df['Age']>59, 'Age group'] = 'Boomers ii'

#Finally, dropping columns that are not needed
df.drop(['Customer ID','Total Refunds','Zip Code','Latitude', 'Longitude'],axis='columns',inplace=True)

После очистки данных мы сформулировали несколько вопросов по аналитике.

Имея в виду вопросы аналитики, мы можем исследовать и визуализировать имеющуюся информацию.

Прежде чем приступить к созданию модели, необходимо убедиться, что все данные представлены на языке, который модель будет полностью понимать, поэтому вам, возможно, придется выполнить небольшое сопоставление, кодирование меток или и то, и другое, как в данном случае.

#Replacing the Gender column in the dataset with Label Encoding, 0 for Female, 1 for Male
df.replace({'Gender':{'Female':0, 'Male' : 1}}, inplace = True)

#Replacing the columns with 'yes' and 'no' output by label encoding
#0 for No, 1 for yes

yes_and_no = ['Paperless Billing', 'Unlimited Data', 'Streaming Movies', 'Streaming Music', 'Streaming TV', 'Premium Tech Support','Online Security', 'Multiple Lines','Online Security','Multiple Lines','Married']
for i in yes_and_no:
    df.replace({'No': 0, 'Yes': 1}, inplace=True)
    
df.replace({'Phone Service':{'Yes':1}}, inplace=True)

from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
df.Customer_Status = le.fit_transform(df.Customer_Status)

#Convert categorical variable into dummy variables
df = pd.get_dummies(data = df, columns = ['Payment Method', 'Contract', 'Internet Type','Offer','City','Age group'])

3. Подготовка данных для лучшего раскрытия шаблонов алгоритму машинного обучения.

Итак, мы говорили только о том, что у нас есть на местах, то есть об описательном анализе, и это то, что происходило в прошлом. Но для того, чтобы предсказать отток клиентов, мы должны иметь возможность прогнозировать будущие возможности, и именно здесь вступают в действие наши модели машинного обучения (конечно). Этот этап требует для начала шагов предварительной обработки, которые представляют собой просто преобразования наших данных с использованием различных функций, чтобы наши данные были хорошо подготовлены для нашей модели.

Чтобы начать этот процесс, вы должны разделить наши данные, используя функцию разделения тестов поезда.

#MODEL SELECTION
#Splitting into features and label
x = df.drop("Customer_Status",axis = 1)
y = df["Customer_Status"]
#Splitting our data into training and validation sets so we can validate our model on a data it hasnt seen before.
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
x_train, x_test, y_train, y_test = train_test_split(x, y,test_size=0.2,random_state=101)
scaler = StandardScaler()

scaled_x_train = scaler.fit_transform(x_train)
scaled_x_test = scaler.transform(x_test)

4. Изучите различные модели и выберите лучшую с максимальной точностью.

#Importing Models

from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier

model_parameters ={
    'random_forest':{
        'model': RandomForestClassifier(), 
        'params' : {'n_estimators': [1,5,10]}
    },
    'Logistic_regression':{
    'model': LogisticRegression(solver='liblinear',multi_class='auto'),
        'params':{'C' : [1,5,10]
                 
                 }
    },
        'KNeighbors':{
            'model' : KNeighborsClassifier(),
         'params' : {}
    },       
    'decision_tree': {
            'model' : DecisionTreeClassifier(),
            'params' : {'criterion' : ['gini','entropy']}
        
            
        },
}model_selection import ShuffleSplit
from sklearn.model_selection import GridSearchCV
scores = []
cv = ShuffleSplit(n_splits = 5, test_size=0.2, random_state=101)
for model_name, mp in model_parameters.items():
    clf = GridSearchCV (mp['model'], mp['params'], cv=cv, return_train_score=False)
    clf.fit(x,y)
    scores.append({
        'model' : model_name,
         'accuracy_score' : clf.best_score_,
        'best_params' : clf.best_params_
    })
df = pd.DataFrame(scores, columns = ['model', 'accuracy_score','best_params'])
df

5. Получив модель с наилучшей точностью, мы затем проверяем ее производительность.

rfc = RandomForestClassifier()
rfc.fit(scaled_x_train, y_train)

rfc.score(scaled_x_test, y_test)
#Predicting values from the model build to check the accuracy
y_predicted = rfc.predict(scaled_x_test)
y_predicted[:5]

#Importing Classification report

from sklearn.metrics import classification_report
print(classification_report(y_test, y_predicted))

Сводка

Этот пост представляет собой просто пошаговое руководство по типичному проекту машинного обучения для прогнозирования оттока с использованием набора данных об оттоке Telecom. Начали с понимания данных, затем приступили к изучению, подготовке, обучению данных и, наконец, к оценке производительности модели.