其他回归模型

目录

  • 模型的假设检验(F与T)

  • 岭回归与Lasso回归

  • Logistic回归模型

  • 决策树与随机森林

  • K近邻模型

 

模型的假设检验

F检验

提出原假设(正向验证)和备择假设(反向验证),之后计算统计量与理论值,最后比较大小,如果统计量的值大于理论值,则模型是合理的

代码:

# 导⼊第三⽅模块
import numpy as np
# 计算建模数据中因变量的均值
ybar=train.Profit.mean()
# 统计变量个数和观测个数
p=model2.df_model
n=train.shape[0]
# 计算回归离差平⽅和
RSS=np.sum((model2.fittedvalues-ybar)**2)
# 计算误差平⽅和
ESS=np.sum(model2.resid**2)
# 计算F统计量的值
F=(RSS/p)/(ESS/(n-p-1))
print('F统计量的值:',F)
F统计量的值:174.6372
    
# 导⼊模块
from scipy.stats import f
# 计算F分布的理论值
F_Theroy = f.ppf(q=0.95, dfn = p,dfd = n-p-1)
print('F分布的理论值为:',F_Theroy)
out:
F分布的理论值为: 2.5026
'''
计算出来的F统计量值174.64远远⼤于F分布的理论值2.50
所以应当拒绝原假设(先假设模型不合理)
'''
View Code

 T检验

model.summary()  # 绝对值越小影响越大

# F检验与T检验的区别
F检验主要检验的是模型是否合理
T检验更加侧重于检验模型的各个参数是否合理

 补充:线性回归模型的短板

1.自变量的个数大于样本量
2.自变量之间存在多重共线性

 

解决线性回归模型的短板

1.岭回归模型

在线性回归模型的基础之上添加一个l2惩罚项(平方项、正则项)

 通过凸优化等价推导

 该模型最终转变成求解圆柱体与椭圆抛物线的焦点问题

 

交叉验证

将所有数据都参与到模型的构建和测试中,最后生成多个模型
再从多个模型中筛选出得分最高(准确度)的模型

 岭回归的交叉验证法如何验证:

RidgeCV(alphas=(0.1, 1.0, 10.0), fit_intercept=True, normalize=False,
scoring=None, cv=None)

alphas:⽤于指定多个lambda值的元组或数组对象,默认该参数包含0.1、1和10三种值。
fit_intercept:bool类型参数,是否需要拟合截距项,默认为True。
normalize:bool类型参数,建模时是否需要对数据集做标准化处理,默认为False。
scoring:指定⽤于评估模型的度量⽅法。
cv:指定交叉验证的重数。

岭回归模型的应用

糖尿病数据的预测

# 导入第三方模块
import pandas as pd
import numpy as np
from sklearn import model_selection
from sklearn.linear_model import Ridge,RidgeCV
import matplotlib.pyplot as plt

# 读取糖尿病数据集
diabetes = pd.read_excel(r'diabetes.xlsx')
# diabetes.head()
# 构造自变量(剔除患者性别、年龄和因变量)
predictors = diabetes.columns[2:-1]
# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = model_selection.train_test_split(diabetes[predictors], diabetes['Y'], 
                                                                    test_size = 0.2, random_state = 1234 )

# 构造不同的Lambda值
Lambdas = np.logspace(-5, 2, 200)
# 岭回归模型的交叉验证
# 设置交叉验证的参数,对于每一个Lambda值,都执行10重交叉验证
ridge_cv = RidgeCV(alphas = Lambdas, normalize=True, scoring='neg_mean_squared_error', cv = 10)
# 模型拟合
ridge_cv.fit(X_train, y_train)
# 返回最佳的lambda值
ridge_best_Lambda = ridge_cv.alpha_
ridge_best_Lambda

# 导入第三方包中的函数
from sklearn.metrics import mean_squared_error
# 基于最佳的Lambda值建模
ridge = Ridge(alpha = ridge_best_Lambda, normalize=True)
ridge.fit(X_train, y_train)
# 返回岭回归系数
pd.Series(index = ['Intercept'] + X_train.columns.tolist(),data = [ridge.intercept_] + ridge.coef_.tolist())
# 预测
ridge_predict = ridge.predict(X_test)
# 预测效果验证
RMSE = np.sqrt(mean_squared_error(y_test,ridge_predict))
RMSE
View Code

 

2.Lasso回归模型

在线性回归模型的基础之上添加一个l1惩罚项(绝对值项、正则项)

通过凸优化等价推导

  该模型最终转变成求解正方体与椭圆抛物线的焦点问题

 Lasso回归的交叉验证法如何验证:

LassoCV(alphas=None, fit_intercept=True, 
normalize=False,max_iter=1000, tol=0.0001)
alphas:指定具体的Lambda值列表⽤于模型的运算
fit_intercept:bool类型参数,是否需要拟合截距项,默认为True
normalize:bool类型参数,建模时是否需要对数据集做标准化处理,默认为False
max_iter:指定模型最⼤的迭代次数,默认为1000次

 

Lasso回归模型的应用

# 导入第三方模块中的函数
from sklearn.linear_model import Lasso,LassoCV
# LASSO回归模型的交叉验证
lasso_cv = LassoCV(alphas = Lambdas, normalize=True, cv = 10, max_iter=10000)
lasso_cv.fit(X_train, y_train)
# 输出最佳的lambda值
lasso_best_alpha = lasso_cv.alpha_
lasso_best_alpha

# 基于最佳的lambda值建模
lasso = Lasso(alpha = lasso_best_alpha, normalize=True, max_iter=10000)
lasso.fit(X_train, y_train)
# 返回LASSO回归的系数
pd.Series(index = ['Intercept'] + X_train.columns.tolist(),data = [lasso.intercept_] + lasso.coef_.tolist())

# 预测
lasso_predict = lasso.predict(X_test)
# 预测效果验证
RMSE = np.sqrt(mean_squared_error(y_test,lasso_predict))
RMSE
View Code

ps:还可以用多元线性回归模型

# 导入第三方模块
from statsmodels import api as sms
# 为自变量X添加常数列1,用于拟合截距项
X_train2 = sms.add_constant(X_train)
X_test2 = sms.add_constant(X_test)

# 构建多元线性回归模型
linear = sms.OLS(y_train, X_train2).fit()
# 返回线性回归模型的系数
linear.params

# 模型的预测
linear_predict = linear.predict(X_test2)
# 预测效果验证
RMSE = np.sqrt(mean_squared_error(y_test,linear_predict))
RMSE
View Code

 

岭回归与Lasso回归的区别

1.惩罚项不一样,一个是平方项一个是绝对值项
2.相较于岭回归降低了模型的复杂度

 

Logistic回归模型

将线性回归模型的公式做Logit变换

# 特点
将预测问题变成了0到1之间的概率问题

 通过坐标系也可发现:

 

 事件发生比(示例)

 

 

 

混淆矩阵

准确率:表示正确预测的正负例样本数与所有样本数量的⽐值,即(A+D)/(A+B+C+D)
正例覆盖率:表示正确预测的正例数在实际正例数中的⽐例,即D/(B+D)
负例覆盖率:表示正确预测的负例数在实际负例数中的⽐例,即A/(A+C)
正例命中率:表示正确预测的正例数在预测正例数中的⽐例,即D/(C+D)

 

模型的评估方法

1.F检验

2.T检验

3.ROC曲线

通过计算AUC阴影部分的面积来判断模型是否合理(通常大于0.8表示OK)

 4.KS曲线

通过计算两条折现之间最大距离来衡量模型是否合理(通常大于0.4表示OK)

 

Logistic回归模型函数说明

LogisticRegression(tol=0.0001, fit_intercept=True,class_weight=None, max_iter=100)
tol:⽤于指定模型跌倒收敛的阈值
fit_intercept:bool类型参数,是否拟合模型的截距项,默认为True
class_weight:⽤于指定因变量类别的权重,如果为字典,则通过字典的形式{class_label:weight}传
递每个类别的权重;如果为字符串'balanced',则每个分类的权重与实际样本中的⽐例成反⽐,当各分
类存在严重不平衡时,设置为'balanced'会⽐较好;如果为None,则表示每个分类的权重相等
max_iter:指定模型求解过程中的最⼤迭代次数, 默认为100

 

Logistic回归模型应用

自定义绘制ks曲线的函数代码

# 导入第三方模块
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 自定义绘制ks曲线的函数
def plot_ks(y_test, y_score, positive_flag):
    # 对y_test重新设置索引
    y_test.index = np.arange(len(y_test))
    # 构建目标数据集
    target_data = pd.DataFrame({'y_test':y_test, 'y_score':y_score})
    # 按y_score降序排列
    target_data.sort_values(by = 'y_score', ascending = False, inplace = True)
    # 自定义分位点
    cuts = np.arange(0.1,1,0.1)
    # 计算各分位点对应的Score值
    index = len(target_data.y_score)*cuts
    scores = np.array(target_data.y_score)[index.astype('int')]
    # 根据不同的Score值,计算Sensitivity和Specificity
    Sensitivity = []
    Specificity = []
    for score in scores:
        # 正例覆盖样本数量与实际正例样本量
        positive_recall = target_data.loc[(target_data.y_test == positive_flag) & (target_data.y_score>score),:].shape[0]
        positive = sum(target_data.y_test == positive_flag)
        # 负例覆盖样本数量与实际负例样本量
        negative_recall = target_data.loc[(target_data.y_test != positive_flag) & (target_data.y_score<=score),:].shape[0]
        negative = sum(target_data.y_test != positive_flag)
        Sensitivity.append(positive_recall/positive)
        Specificity.append(negative_recall/negative)
    # 构建绘图数据
    plot_data = pd.DataFrame({'cuts':cuts,'y1':1-np.array(Specificity),'y2':np.array(Sensitivity), 
                              'ks':np.array(Sensitivity)-(1-np.array(Specificity))})
    # 寻找Sensitivity和1-Specificity之差的最大值索引
    max_ks_index = np.argmax(plot_data.ks)
    plt.plot([0]+cuts.tolist()+[1], [0]+plot_data.y1.tolist()+[1], label = '1-Specificity')
    plt.plot([0]+cuts.tolist()+[1], [0]+plot_data.y2.tolist()+[1], label = 'Sensitivity')
    # 添加参考线
    plt.vlines(plot_data.cuts[max_ks_index], ymin = plot_data.y1[max_ks_index], 
               ymax = plot_data.y2[max_ks_index], linestyles = '--')
    # 添加文本信息
    plt.text(x = plot_data.cuts[max_ks_index]+0.01,
             y = plot_data.y1[max_ks_index]+plot_data.ks[max_ks_index]/2,
             s = 'KS= %.2f' %plot_data.ks[max_ks_index])
    # 显示图例
    plt.legend()
    # 显示图形
    plt.show()

# 导入虚拟数据
virtual_data = pd.read_excel(r'virtual_data.xlsx')
# 应用自定义函数绘制k-s曲线
plot_ks(y_test = virtual_data.Class, y_score = virtual_data.Score,positive_flag = 'P')
View Code

 实操步骤

# -----------------------第一步 建模 ----------------------- #
# 导入第三方模块
import statsmodels.api as sm
# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size = 0.25, random_state = 1234)
# 为训练集和测试集的X矩阵添加常数列1
X_train2 = sm.add_constant(X_train)
X_test2 = sm.add_constant(X_test)
# 拟合Logistic模型
sm_logistic = sm.Logit(y_train, X_train2).fit()
# 返回模型的参数
sm_logistic.params


# -----------------------第二步 预测构建混淆矩阵 ----------------------- #
# 模型在测试集上的预测
sm_y_probability = sm_logistic.predict(X_test2)
# 根据概率值,将观测进行分类,以0.5作为阈值
sm_pred_y = np.where(sm_y_probability >= 0.5, 1, 0)
# 混淆矩阵
cm = metrics.confusion_matrix(y_test, sm_pred_y, labels = [0,1])
cm



# -----------------------第三步 绘制ROC曲线 ----------------------- #
# 计算真正率和假正率 
fpr,tpr,threshold = metrics.roc_curve(y_test, sm_y_probability)
# 计算auc的值  
roc_auc = metrics.auc(fpr,tpr)
# 绘制面积图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
# 添加边际线
plt.plot(fpr, tpr, color='black', lw = 1)
# 添加对角线
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
# 添加文本信息
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
# 添加x轴与y轴标签
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
# 显示图形
plt.show()

# -----------------------第四步 绘制K-S曲线 ----------------------- #
# 调用自定义函数,绘制K-S曲线
sm_y_probability.index = np.arange(len(sm_y_probability))
plot_ks(y_test = y_test, y_score = sm_y_probability, positive_flag = 1)
View Code

 

决策树与随机森林

树的概念

树其实是一种计算机底层的数据结构,与现实不同
计算机里面的树都是自上而下的生长

决策树

是算法模型中的一种概念

有三个主要部分
1.根节点
2.枝节点
3.叶子节点

# 根节点与枝节点用于存放条件 叶子节点存放真正的数据结果

决策树节点字段的选择

1.信息熵

⽤来表示信息量的⼤⼩,信息量越⼤,对应的熵值就越⼤,反之亦然

eg:

信息熵小相当于红绿灯情况

信息熵大相当于买彩票中奖情况

公式

 2.条件熵

条件熵其实就是由信息熵再次细分而来
按一个新的变量的每个值对原变量进行分类

eg:

有九个用户购买了商品五个没有购买 那么条件熵就是继续从购买不购买的用户中再选择一个条件(比如按照性别计算男和女的熵)

3.信息增益

信息增益可以反映出某个条件是否对最终的分类有决定性的影响

ps:在构建决策树时根节点与枝节点所放的条件按照信息增益由大到小排

4.信息增益率

决策树中的ID3算法使⽤信息增益指标实现根节点或中间节点的字段选择,但是该指标存在⼀个⾮常明显的缺点,即信息增益会偏向于取值较多的字段
为了克服信息增益指标的缺点,提出了信息增益率的概念,它的思想很简单,就是在信息增益的基础上进⾏相应的惩罚

公式:

 

 基尼指数

可以让模型解决预测问题

基尼指数增益

与信息增益类似,还需要考虑⾃变量对因变量的影响程度,即因变量的基尼指数下降速度的快慢,下降得越快,⾃变量对因变量的影响就越强

公式

 

 小结论

默认情况下解决分类问题(买与不买、带与不带、走与不走)
也可以切换算法解决预测问题(具体数值多少)

 

决策树模型函数说明

DecisionTreeClassifier(criterion='gini', splitter='best',
max_depth=None,min_samples_split=2,
min_samples_leaf=1,max_leaf_nodes=None,
class_weight=None)
criterion:⽤于指定选择节点字段的评价指标,对于分类决策树,默认为'gini',表示采⽤基尼指数选
择节点的最佳分割字段;对于回归决策树,默认为'mse',表示使⽤均⽅误差选择节点的最佳分割字段
splitter:⽤于指定节点中的分割点选择⽅法,默认为'best',表示从所有的分割点中选择最佳分割点;
如果指定为'random',则表示随机选择分割点
max_depth:⽤于指定决策树的最⼤深度,默认为None,表示树的⽣⻓过程中对深度不做任何限制
min_samples_split:⽤于指定根节点或中间节点能够继续分割的最⼩样本量, 默认为2
min_samples_leaf:⽤于指定叶节点的最⼩样本量,默认为1
max_leaf_nodes:⽤于指定最⼤的叶节点个数,默认为None,表示对叶节点个数不做任何限制
class_weight:⽤于指定因变量中类别之间的权重,默认为None,表示每个类别的权重都相等;如果
为balanced,则表示类别权重与原始样本中类别的⽐例成反⽐;还可以通过字典传递类别之间的权重
差异,其形式为{class_label:weight}
 

 

随机森林

随机森林中每颗决策树都不限制节点字段选择
由多棵树组成的随机森林在解决分类问题的时候采用投票法,
解决预测问题的时候采用均值法

 

随机森林模型函数说明

RandomForestClassifier(n_estimators=10, criterion='gini', max_depth=None,
min_samples_split=2, min_samples_leaf=1,
max_leaf_nodes=None, bootstrap=True, class_weight=None)
n_estimators:⽤于指定随机森林所包含的决策树个数
criterion:⽤于指定每棵决策树节点的分割字段所使⽤的度量标准,⽤于分类的随机森林,默认的
criterion值为'gini';⽤于回归的随机森林,默认的criterion值为'mse'
max_depth:⽤于指定每棵决策树的最⼤深度,默认不限制树的⽣⻓深度
min_samples_split:⽤于指定每棵决策树根节点或中间节点能够继续分割的最⼩样本量, 默认为2
min_samples_leaf:⽤于指定每棵决策树叶节点的最⼩样本量,默认为1
max_leaf_nodes:⽤于指定每棵决策树最⼤的叶节点个数,默认为None,表示对叶节点个数不做任
何限制
bootstrap:bool类型参数,是否对原始数据集进⾏bootstrap抽样,⽤于⼦树的构建,默认为True
class_weight:⽤于指定因变量中类别之间的权重,默认为None,表示每个类别的权重都相等

 

决策树与随机森林应用

# 导入第三方模块
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn import model_selection
from sklearn import linear_model
# 读⼊数据
Titanic = pd.read_csv(r'Titanic.csv')
Titanic
# 删除⽆意义的变量,并检查剩余变量是否含有缺失值
Titanic.drop(['PassengerId','Name','Ticket','Cabin'], axis = 1, inplace = True)
Titanic.isnull().sum(axis = 0)
# 对Sex分组,⽤各组乘客的平均年龄填充各组中的缺失年龄
fillna_Titanic = []
for i in Titanic.Sex.unique():
    update = Titanic.loc[Titanic.Sex == i,].fillna(value = {'Age': Titanic.Age[Titanic.Sex == i].mean()}, inplace
    = False)
fillna_Titanic.append(update)
Titanic = pd.concat(fillna_Titanic)
# 使⽤Embarked变量的众数填充缺失值
Titanic.fillna(value = {'Embarked':Titanic.Embarked.mode()[0]}, inplace=True)

# 将数值型的Pclass转换为类别型,否则⽆法对其哑变量处理
Titanic.Pclass = Titanic.Pclass.astype('category')
# 哑变量处理
dummy = pd.get_dummies(Titanic[['Sex','Embarked','Pclass']])
# ⽔平合并Titanic数据集和哑变量的数据集
Titanic = pd.concat([Titanic,dummy], axis = 1)
# 删除原始的Sex、Embarked和Pclass变量
Titanic.drop(['Sex','Embarked','Pclass'], inplace=True, axis = 1)
# 取出所有⾃变量名称
predictors = Titanic.columns[1:]
# 将数据集拆分为训练集和测试集,且测试集的⽐例为25%
X_train, X_test, y_train, y_test = model_selection.train_test_split(Titanic[predictors], Titanic.Survived,
test_size = 0.25, random_state = 1234)

from sklearn.model_selection import GridSearchCV
from sklearn import tree.metrics
# 预设各参数的不同选项值
max_depth = [2,3,4,5,6]
min_samples_split = [2,4,6,8]
min_samples_leaf = [2,4,8,10,12]
# 将各参数值以字典形式组织起来
parameters = {'max_depth':max_depth, 'min_samples_split':min_samples_split,
'min_samples_leaf':min_samples_leaf}
# ⽹格搜索法,测试不同的参数值
grid_dtcateg = GridSearchCV(estimator = tree.DecisionTreeClassifier(), param_grid = parameters, cv=10)
# 模型拟合
grid_dtcateg.fit(X_train, y_train)
# 返回最佳组合的参数值
grid_dtcateg.param_grid

# 构建分类决策树
CART_Class = tree.DecisionTreeClassifier(max_depth=3,min_samples_leaf=4,min_samples_split=2)
# 模型拟合
decision_tree = CART_Class.fit(X_train,y_train)
# 模型在测试集上的预测
pred = CART_Class.predict(X_test)
# 模型的准确率
print('模型在测试集的预测准确率:\n',metrics.accuracy_score(y_test,pred))
print('模型在训练集的预测准确率:\n',
metrics.accuracy_score(y_train,CART_Class.predict(X_train)))
View Code

 

K近邻模型

思想:根据位置样本点周边K个邻居样本完成预测或者分类

 

 K值的选择

1.先猜测待测试的不同K值

2.交叉验证

3.作图选择最合理的k值
准确率(越大越好) MSE(越小越好)

 

过拟合

在统计模型中,由于使用的参数过多而导致模型对观测数据过度拟合,以至于用该模型来预测其他测试样本输出的时候与实际输出或者期望值相差很大的现象

欠拟合

由于统计模型使用的参数过少,以至于得到的模型难以拟合观测数据的现象

 距离

1.欧式距离

两点之间的直线距离

 2.曼哈顿距离

默认两点直接有障碍物

 3.余弦相似度

通过计算两个向量的夹角余弦值来评估他们的相似度(论文查重)

 

 K近邻模型函数说明

neighbors.KNeighborsClassifier(n_neighbors=5, weights='uniform',
p=2, metric='minkowski',)
n_neighbors:⽤于指定近邻样本个数K,默认为5
weights:⽤于指定近邻样本的投票权重,默认为'uniform',表示所有近邻样本的投票权重⼀样;如果
为'distance',则表示投票权重与距离成反⽐,即近邻样本与未知类别的样本点距离越远,权重越⼩,
反之,权重越⼤
metric:⽤于指定距离的度量指标,默认为闵可夫斯基距离
p:当参数metric为闵可夫斯基距离时,p=1,表示计算点之间的曼哈顿距离;p=2,表示计算点之间
的欧⽒距离;该参数的默认值为2

 

K近邻模型应用

# 导入第三方包
import pandas as pd
# 导入数据
Knowledge = pd.read_excel(r'Knowledge.xlsx')
# 返回前5行数据
Knowledge.head()
# 构造训练集和测试集
# 导入第三方模块
from sklearn import model_selection
# 将数据集拆分为训练集和测试集
predictors = Knowledge.columns[:-1]
predictors
X_train, X_test, y_train, y_test = model_selection.train_test_split(Knowledge[predictors], Knowledge.UNS, 
                                                                    test_size = 0.25, random_state = 1234)

# 导入第三方模块
import numpy as np
from sklearn import neighbors
import matplotlib.pyplot as plt

# 设置待测试的不同k值
K = np.arange(1,np.ceil(np.log2(Knowledge.shape[0]))).astype(int)
# 构建空的列表,用于存储平均准确率
accuracy = []
for k in K:
    # 使用10重交叉验证的方法,比对每一个k值下KNN模型的预测准确率
    cv_result = model_selection.cross_val_score(neighbors.KNeighborsClassifier(n_neighbors = k, weights = 'distance'), 
                                                X_train, y_train, cv = 10, scoring='accuracy')
    accuracy.append(cv_result.mean())

# 从k个平均准确率中挑选出最大值所对应的下标    
arg_max = np.array(accuracy).argmax()
# 中文和负号的正常显示
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
# 绘制不同K值与平均预测准确率之间的折线图
plt.plot(K, accuracy)
# 添加点图
plt.scatter(K, accuracy)
# 添加文字说明
plt.text(K[arg_max], accuracy[arg_max], '最佳k值为%s' %int(K[arg_max]))
# 显示图形
plt.show()

# 导入第三方模块
from sklearn import metrics

# 重新构建模型,并将最佳的近邻个数设置为6
knn_class = neighbors.KNeighborsClassifier(n_neighbors = 6, weights = 'distance')
# 模型拟合
knn_class.fit(X_train, y_train)
# 模型在测试数据集上的预测
predict = knn_class.predict(X_test)
# 构建混淆矩阵
cm = pd.crosstab(predict,y_test)
cm

# 导入第三方模块
import seaborn as sns

# 将混淆矩阵构造成数据框,并加上字段名和行名称,用于行或列的含义说明
cm = pd.DataFrame(cm)
# 绘制热力图
sns.heatmap(cm, annot = True,cmap = 'GnBu')
# 添加x轴和y轴的标签
plt.xlabel(' Real Lable')
plt.ylabel(' Predict Lable')
# 图形显示
plt.show()



# 模型整体的预测准确率
metrics.scorer.accuracy_score(y_test, predict)
# 分类模型的评估报告
print(metrics.classification_report(y_test, predict))
View Code
# 读入数据
ccpp = pd.read_excel(r'CCPP.xlsx')
ccpp.head()
# 返回数据集的行数与列数
ccpp.shape
#################################################################
# 导入第三方包
from sklearn.preprocessing import minmax_scale
# 对所有自变量数据作标准化处理(统一量纲)
predictors = ccpp.columns[:-1]
X = minmax_scale(ccpp[predictors])
#################################################################


# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, ccpp.PE, 
                                                                    test_size = 0.25, random_state = 1234)

# 设置待测试的不同k值
K = np.arange(1,np.ceil(np.log2(ccpp.shape[0]))).astype(int)
# 构建空的列表,用于存储平均MSE
mse = []
for k in K:
    # 使用10重交叉验证的方法,比对每一个k值下KNN模型的计算MSE
    cv_result = model_selection.cross_val_score(neighbors.KNeighborsRegressor(n_neighbors = k, weights = 'distance'), 
                                                X_train, y_train, cv = 10, scoring='neg_mean_squared_error')
    mse.append((-1*cv_result).mean())

# 从k个平均MSE中挑选出最小值所对应的下标  
arg_min = np.array(mse).argmin()
# 绘制不同K值与平均MSE之间的折线图
plt.plot(K, mse)
# 添加点图
plt.scatter(K, mse)
# 添加文字说明
plt.text(K[arg_min], mse[arg_min] + 0.5, '最佳k值为%s' %int(K[arg_min]))
# 显示图形
plt.show()

# 重新构建模型,并将最佳的近邻个数设置为7
knn_reg = neighbors.KNeighborsRegressor(n_neighbors = 7, weights = 'distance')
# 模型拟合
knn_reg.fit(X_train, y_train)
# 模型在测试集上的预测
predict = knn_reg.predict(X_test)
# 计算MSE值
metrics.mean_squared_error(y_test, predict)

# 对比真实值和实际值
pd.DataFrame({'Real':y_test,'Predict':predict}, columns=['Real','Predict']).head(10)
View Code

 

posted @ 2021-10-23 18:28  陌若安然  阅读(269)  评论(0)    收藏  举报