赞
踩
customer_warning.py | |
# 读取数据 import pandas as pd df = pd.read_excel('股票客户流失.xlsx') | |
划分特征变量和目标变量 | # 划分特征变量和目标变量 # 利用drop()函数,删除‘是否流失’列 x = df.drop(columns='是否流失') # DataFrame类型 y = df['是否流失'] # Series类型 |
划分训练集和测试集 | 在进行模型搭建和使用前都会将数据分成: 训练集数据(简称训练集) 测试集数据(简称测试集) 划分训练集和测试集的目的一是为了对模型进行评估,二是可以通过测试集对模型进行调优。 |
# 划分训练集和测试集 # 引入train_test_split函数,用于划分训练集和测试集 from sklearn.model_selection import train_test_split as tts # x_train和x_test分别是x的训练集和测试集 # y_train和y_test分别是y的训练集和测试集 # test_size=0.2,表示在数据集合中,选择0.2,即20%作为测试集 # 每次的测试集,划分都是随机的。 # 如果要将划分数据固定,需要改为tts(x, y, test_size=0.2, random_state=1) # random_state等于非零整数,使得每次划分结果保持一致 # random_state=0,表示每次划分结果不同 x_train, x_test, y_train, y_test = tts(x, y, test_size=0.2, random_state=0) # 注意,这里只是划分数据集,并没有涉及任何建模 # x_train和x_test为DataFrame类型,因为x为DataFrame类型 # y_train和y_test为Series类型,因为y为Series类型 | |
模型搭建 | # 模型搭建 # 引入逻辑回归模型 from sklearn.linear_model import LogisticRegression # 构造初始的逻辑回归模型 model = LogisticRegression() # 进行模型训练,使用x_train和y_train做训练数据 model.fit(x_train, y_train) |
模型使用 | 预测数据结果 # 预测数据结果 # 原理是将x_test作为模型输入,得到y_pred集合 # 如果y_pred集合和y_test集合一致,或者有较高一致度,证明模型成功 y_pred = model.predict(x_test) # y_pred为数组类型 # 对比显示 a = pd.DataFrame() # 创建一个空DataFrame a['预测值'] = y_pred # y_pred为数组类型 a['实际值'] = y_test.values # y_test为Series类型,y_test.values转换成数组类型 # a['预测值']和a['实际值']为Series类型,a为DataFrame类型 print(a) 显示: 预测值 实际值 0 0 0 1 0 0 2 0 0 3 0 0 4 0 0 ... ... ... 1404 1 1 1405 1 1 1406 0 1 1407 0 0 1408 1 0 [1409 rows x 2 columns] |
查看所有数据精准度 | # 查看所有数据精准度 # 利用accuracy_score()函数对比两组数据的准确度 from sklearn.metrics import accuracy_score as accs score = accs(y_pred, y_test) print('预测准确度:' + str(score)) # 也可以直接使用LogisticRegression自带的score()函数计算预测准确度 # 注意,score()函数的输入,是x和y的测试集 # score = model.score(x_test, y_test) # print('预测准确度:' + str(score)) 显示: 预测准确度:0.772888573456352 由此可见,预测准确度达到77%,可以 |
查看预测概率 | # 预测概率 print(y_pred) # 打印0、1,代表是或者否流失 # 按照概率显示 y_pred_proba = model.predict_proba(x_test) # y_pred_proba为数组类型 b = pd.DataFrame(y_pred_proba, columns=['不流失概率', '流失概率']) print(b) 显示: [0 0 0 ... 0 0 1] 不流失概率 流失概率 0 0.794823 0.205177 1 0.774744 0.225256 2 0.622889 0.377111 3 0.675527 0.324473 4 0.891945 0.108055 ... ... ... 1404 0.217267 0.782733 1405 0.478332 0.521668 1406 0.773442 0.226558 1407 0.799966 0.200034 1408 0.438190 0.561810 [1409 rows x 2 columns] |
如果只想查看不流失概率 | # 如果只想查看不流失概率 print(y_pred_proba[:, 0]) # :,表示二维数组所有行 # 0,表示第0列 # 如果只想查看“流失率”,改为:print(y_pred_proba[:, 1]) 显示: [0.79482289 0.77474446 0.62288899 ... 0.77344169 0.79996554 0.43819005] |
获取逻辑回归系数 | # 获取逻辑回归系数 print(model.coef_) # 系数ki print(model.intercept_) # 截距项k0 显示: [[ 2.42241805e-05 8.30362317e-03 1.05091829e-02 -2.56629212e-03 -1.07272886e-04]] [-1.44369103e-06] |
反向观察 | # 将y_pred_proba的结果代入求概率的公式 import numpy as np # 设两个列表m、n # 每组x值代入公式,得出的概率,放到m列表,即“流失率” # y_pred_proba计算出来的“流失概率”,放到n列表 # r,用于统计m流失率和n流失率相同的个数 m = [] n = [] r = 0 # 由于x_test为DataFrame,x_test.iloc[i]取第i列数据 # model.coef_.T,对model.coef_转置 for i in range(len(x_test)): temp1 = 1 / (1 + np.exp(-(np.dot(x_test.iloc[i], model.coef_.T) + model.intercept_))) # temp1是一个数组(只有一个元素的数组),temp1[0]取第一个元素,相当于将一个只有一个元素的数组转化为一个数字 m.append(temp1[0]) # temp2是一个数组(只有一个元素的数组),temp2[0]取第一个元素,相当于将一个只有一个元素的数组转化为一个数字 temp2 = y_pred_proba[i:(i + 1), 1] n.append(temp2[0]) # 由于是浮点数比较,有精度问题。 # 所以,如果两者只差小于一个很小值,例如0.0000000000001,即认为两者相等 if abs(temp1[0] - temp2[0]) <= 0.0000000000001: r = r + 1 print(r/len(x_test)) 显示: 1.0 表示: 模型算出的“流失率”(预测概率)n(x) 用推导得出的公式,输入x,得出(预测概率)m(x) 两者一样 |
新数据代入 | # 使用模型 # 去掉警告信息 import warnings warnings.filterwarnings('ignore') # 代入新数据 # 用概率显示 print(model.predict_proba([[23000, 150, 301, 1500, 2],[23000, 150, 301, 1500, 2]])) # 直接显示0或者1的结论 print(model.predict([[23000, 160, 301, 1600, 3], [23000, 160, 301, 1600, 3], [23000, 160, 301, 1600, 3]])) print(model.predict([[22686.5, 297, 149.25, 2029.85, 0]])) # 材料数据 显示: [[0.24615641 0.75384359] [0.24600995 0.75399005]] [1 1 1] [0] 注意: 如果没有去掉警告信息,会显示以下警告: base.py:450: UserWarning: X does not have valid feature names, but LogisticRegression was fitted with feature names warnings.warn( |
出现警告的原因 | 当初df = pd.read_excel('股票客户流失.xlsx'),读取的文件,第一行是列表名 列表名成为feature names LogisticRegression使用了feature names model.predict([[23000, 160, 301, 1600, 3], [23000, 160, 301, 1600, 3], [23000, 160, 301, 1600, 3]]) 这样直接使用,没有列表名 所以出现警告信息 base.py:450: UserWarning: X does not have valid feature names, but LogisticRegression was fitted with feature names warnings.warn( 如果人工增加列表名,例如: t = pd.DataFrame([[23000, 160, 301, 1600, 3], [23000, 160, 301, 1600, 3], [23000, 160, 301, 1600, 3]], columns=['A', 'B', 'C', 'D', 'E']) print(model.predict(t)) 程序能运行,但也会出现警告信息,因为这里的列表名,与当初的列表名不一致。 警告信息如下: base.py:493: FutureWarning: The feature names should match those that were passed during fit. Starting version 1.2, an error will be raised. Feature names unseen at fit time: - A - B - C - D - E Feature names seen at fit time, yet now missing: - 上月交易佣金(元) - 最后一次交易距今时间(天) - 本券商使用时长(年) - 累计交易佣金(元) - 账户资金(元) warnings.warn(message, FutureWarning) 只要把列表名改成与之前的一致,就不会出现警告信息 t = pd.DataFrame([[23000, 160, 301, 1600, 3], [23000, 160, 301, 1600, 3], [23000, 160, 301, 1600, 3]], columns=['账户资金(元)', '最后一次交易距今时间(天)', '上月交易佣金(元)', '累计交易佣金(元)', '本券商使用时长(年)']) print(model.predict(t)) |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。