В этом посте будет представлен высокоуровневый, удобный для новичков обзор проекта, над которым я работал, в котором использовались методы машинного обучения, чтобы предсказать, какие клиенты телекоммуникационной компании, скорее всего, откажутся от услуг (т. Е. Не будут продлевать подписку на услуги компании). Отток - серьезная проблема, с которой сталкиваются компании в самых разных отраслях, включая телекоммуникации. Прогнозируя отток клиентов, компании могут обратиться к этим клиентам, чтобы удержать их. Код этого проекта можно увидеть на Github здесь: https://github.com/ConorMoloney96/Churn_Prediction

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

Одним из методов, используемых для оценки модели, была k-кратная перекрестная проверка. Этот метод включает разбиение тренировочного набора на k складок / секций. Затем k-1 складки используются для обучения, а оставшаяся кратность используется для оценки модели. Это повторяется k раз, при этом каждая кратность используется в качестве средства оценки один раз. Затем можно рассчитать среднее значение баллов. Перекрестная проверка позволяет легко определить чрезмерную подгонку, не полагаясь на данные испытаний.

Логистическая регрессия - это вариант линейной регрессии, используемый для прогнозирования дискретных классов, в отличие от непрерывных числовых прогнозов, сделанных с помощью модели линейной регрессии.

lr = sklearn.linear_model.LogisticRegression(solver='lbfgs', max_iter = 1000)
#Reshape data into 2D array
X_train = X_train.to_numpy()
X_train = X_train.reshape(-1,25)
lr.fit(X_train, y_train)
print(lr.score(X_train, y_train))
    
scores = cross_val_score(lr, X_train, y_train, cv = 10)
print("Cross validation score: %0.4f" % scores.mean())

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

    lr = sklearn.tree.DecisionTreeClassifier()
    #Reshape data into 2D array
    X_train = X_train.to_numpy()
    X_train = X_train.reshape(-1,25)
    print(X_train.shape)
    lr.fit(X_train, y_train)
    visualize_tree(lr, df)
    #Accuracy = accurate predictions/total predictions
    print(lr.score(X_train, y_train))
    test_model(lr)
    scores = cross_val_score(lr, X_train, y_train, cv = 10)
    print("Cross validation score: %0.4f" % scores.mean())

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

rf = sklearn.ensemble.RandomForestClassifier(n_estimators=100,    n_jobs=-1, oob_score=True, bootstrap=True, random_state=24)
    X_train = X.to_numpy()
    #reshape input data into 26 columns for the 26 remaining features
    X_train = X_train.reshape(-1,25)
    rf.fit(X_train, y)
    importances = rf.feature_importances_
    for name, importance in zip(df.columns, importances):
        print(name, " = ", importance)
        
    #Create a dataframe to visualize importances
    feat_importances = pd.Series(importances, index = df.columns)
    feat_importances.nlargest(4).plot(kind='barh')
    
    print("Accuracy on training data: ")
    print(rf.score(X_train, y))
    print("Out of bag score: ")
    print(rf.oob_score_)
    scores = cross_val_score(rf, X_train, y, cv = 10)
    print("Cross validation score: %0.4f" % scores.mean())

Наконец, характеристики трех прогнозных моделей были сравнены друг с другом. Для этого сравнения использовалось несколько показателей, которые можно увидеть в таблице ниже. Как видно из приведенной ниже таблицы, все 3 модели успешно справились с прогнозированием оттока, а также с другими показателями. Поскольку все три модели были примерно одинаковы по своей предсказательной способности, я бы рекомендовал использовать дерево решений, поскольку оно наиболее интерпретируемое и легко объяснимое бизнес-пользователям (а также клиентам, регулирующим органам и другим заинтересованным сторонам).