目录
线性回归(LinearRegression)的sklearn建模
得到多个回归系数coefficients、单个截距intercept
平均绝对误差 mean absolute error (MAE)
平均绝对百分比误差 mean absolute percentage error (MAPE)
逻辑回归(Logistic Regression)的sklearn建模
将分类属性转换成二元数值属性——pd.get_dummies()
机器算法分类
回归技术分类
逻辑回归是一种特殊的线性回归
回归技术流程
线性回归
一种预测建模技术
研究一个或多个自变量与一个因变量之间的显著关系
展示自变量对因变量的影响强度
通过已经建立的回归模型预测新的目标值
一元线性回归
可视化各个因素与房价之间的关系
for each in bostonDf.columns[:-1]:
_ = bostonDf.plot(x=each, y='MEDV', kind='scatter', figsize=(12, 6))
建立回归模型
A,B,C,D = stats.linregress(x,y)
返回回归系数(斜率)、p值、截距、R相关系数(R-squared,简称R²)
想象你有一套房子,房子的价格是由房间数量控制的
- p值是在说:“我们有多大的把握认为房间数量真的有控制房子的价格?”如果p值很小(比如小于0.05),我们就说我们有足够的证据相信房间数量确实在起作用,而不是仅仅是个偶然。
- R²就像是在说:“房间数量控制房子的价格有多好。”R²越接近1,说明房间数量控制得越出色,房子的价格越接近房间数量设定的价格。
from scipy import stats
rmb1, rmb0, rmr, rmpv, _ = stats.linregress(bostonDf['RM'], bostonDf['MEDV'])
print(f'房屋数量的回归系数是{rmb1:.3f},p值是{rmpv:.3f}, 回归方程的截距是{rmb0:.3f}
计算拟合值
预测yˆ = 回归系数(斜率) * x + 截距
bostonDf['rmMedv'] = rmb1*np.array(bostonDf['RM'])+rmb0
- 拟合值就是用房间数量设定的价格来预测房子实际价格会是多少。这些预测价格就是拟合值,它们可以帮助我们了解房间数量设定的价格和房子实际价格之间的关系。
- rmMedv即新建一列为预测的房价
绘制回归线
axrm = bostonDf.plot(x='RM', y='MEDV', kind='scatter',
figsize=(12, 6), label='原始数据')
_ = bostonDf.plot(x='RM', y='rmMedv', kind='line', label='拟合值', ax=axrm)
_ = axrm.legend()
ax=axrm指定了一个现有的轴对象axrm,这样新的线条图就会绘制在之前的散点图上,而不是创建一个新的图。
_ = axrm.legend()这行代码调用了轴对象axrm的legend()方法,显示了图例。图例会显示在图表的下方,标出了不同的数据集或组件。
多元线性回归
想象一下你正在尝试理解一个房子的价格(因变量,我们通常称之为Y)与几个可能影响房价的因素之间的关系,比如房子的面积(自变量,我们称之为X1)、距离市中心的距离(自变量,我们称之为X2)和房子的年龄(自变量,我们称之为X3)。多元线性回归允许我们同时考虑这些自变量对因变量的影响。
import statsmodels.formula.api as smf
导入statsmodels库的formula.api模块,并且给它指定了一个别名smf。
statsmodels是一个用于估计和测试统计模型的Python库,它支持线性回归、逻辑回归、时间序列分析等多种模型。formula.api模块是statsmodels中用于处理公式接口的部分,它提供了一种简便的方式来指定和估计回归模型。
# 构建模型
md = smf.ols(‘Y~X1+X2+...’,data=df,subset=df['列名'])
# 拟合数据
res = md.fit()
# 显示结果
print(res.summary())
subset(可选):这是一个字符串或布尔值,用于指定在模型估计时应该使用数据框中的哪些子集。
summary() 方法通常用于获取模型拟合的结果的统计摘要,包括参数估计、标准误差、t值、P值、拟合优度等统计量。
线性回归(LinearRegression)的sklearn建模
划分训练集与检验集
from sklearn.model_selection import train_test_split
bsTrainX, bsTestX, bsTrainY, bsTestY =
train_test_split(bostonDf.iloc[:,:bostonDf.shape[1]-1], test_size=0.3, random_state=42)
sklearn.model_selection是scikit-learn库中用于模型选择的模块,而train_test_split是这个模块中的一个函数,用于分割数据集。
bsTrainX和bsTestX分别用于存储训练集和测试集的特征,而bsTrainY和bsTestY分别用于存储训练集和测试集的目标。
在Python的pandas
库中,DataFrame.shape
属性返回一个元组,其中包含DataFrame的行数和列数。例如,如果一个DataFrame有3行4列,那么df.shape
将会返回(3, 4)
。
- 第一个元素(索引0)是行数。
- 第二个元素(索引1)是列数。
bostonDf.shape[1]
就是获取bostonDf
这个DataFrame的列数。这是因为shape
是一个元组,而shape[1]
是对应于元组中第二个元素的索引。
例如,如果bostonDf
的形状是(n, m)
,那么bostonDf.shape[1]
将会是m
。
bostonDf.shape[1]-1
是指数值减一,因为Python的索引是从0开始的,所以bostonDf.shape[1]
代表的是列的数量,减一之后就是除了最后一列之外的所有列。这意味着X将包含所有特征,而Y将只包含最后一列(剩下的未指定的就是Y),即房价目标。
参数test_size=0.3表示测试集的大小是整个数据集的30%。
参数random_state=42表示重复性,它确保每次分割数据时都是可复现的。
建立模型
from sklearn import linear_model
bstLearModel = linear_model.LinearRegression()
bstLearModel
linear_model是scikit-learn中用于线性模型估计的模块,它包含了LinearRegression类以及其他相关的线性模型类。
训练模型——.fit(TrainX,TrainY)
使用训练集的特征(bsTrainX)和目标(bsTrainY)来训练一个线性回归模型(bstLearModel)
bstLearModel.fit(bsTrainX,bsTrainY)
在训练过程中,线性回归模型会分析bsTrainX和bsTrainY之间的关系,并学习如何根据特征来预测目标值。一旦模型被训练完毕,它就可以使用predict方法来对新的数据样本进行预测了。
得到多个回归系数coefficients、单个截距intercept
print(f'回归系数为{[round(x,3) for x in bstLearModel.coef_]}')
print(f'截距为{bstLearModel.intercept_:.3f}')
- [round(x, 3) for x in bstLearModel.coef_]:这是一个列表推导式,它遍历
bstLearModel.coef_
中的每个元素x
,对每个元素应用round
函数,将其四舍五入到小数点后三位。 round(x, 3)
中的3
是表示保留小数点后三位的位数。
预测——.predict(TrainX)
predicted = bstLearModel.predict(bsTrainX)
resDf = pd.DataFrame({'原价格':bsTrainY,'预测价格':predicted})
resDf
拟合度——.score(TrainX,TrainY)
# 训练集的R2
bstR2 = bstLearModel.score(bsTrainX,bsTrainY)
print(f'训练集的R-square为{bstR2:.3f}')
平均绝对误差 mean absolute error (MAE)
MAE:预测值与实际值之间差的绝对值的平均数,
MAE越小,表示模型的预测值与实际值越接近,模型的准确性越高
from sklearn.metrics import mean_absolute_error
# 训练集的MAE
bstMAE = mean_absolute_error(bsTrainY,bstLearModel.predict(bsTrainX))
print(f'训练集的MAE为{bstMAE:.3f}')
# 检验集的MAE
bstMAETest = mean_absolute_error(bsTestY,bstLearModel.predict(bsTestX))
print(f'训练集的MAE为{bstMAETest:.3f}')
bstLearModel.predict(bsTrainX) 是模型 bstLearModel 对特征数据集 bsTrainX 进行预测得到的结果。
bstLearModel.predict(bsTestX) 是模型 bstLearModel 对特征数据集 bsTestX 进行预测得到的结果。
平均绝对百分比误差 mean absolute percentage error (MAPE)
MAPE:预测值与实际值之间差异的绝对值的平均百分比
MAPE越低,表示模型的预测值与实际值之间的差异越小,模型的性能越好。
MAPE的一个缺点是它对异常值非常敏感,因为即使只有一两个非常大的绝对误差,也会显著提高MAPE的值。
from sklearn.metrics import mean_absolute_percentage_error
# 训练集的MAE
bstMAPE = mean_absolute_percentage_error(bsTrainY,bstLearModel.predict(bsTrainX))
print(f'训练集的MAE为{bstMAPE:.3f}')
# 检验集的MAE
bstMAPETest = mean_absolute_percentage_error(bsTestY,bstLearModel.predict(bsTestX))
print(f'训练集的MAE为{bstMAPETest:.3f}')
均方误差 mean squared error (MSE)
MSE:预测值与实际值之间差的平方的平均值
MSE越小,表示模型的预测值与实际值之间的差异越小,模型的性能越好。
MSE的一个缺点是它对异常值非常敏感,因为即使只有一两个非常大的平方误差,也会显著提高MSE的值。
from sklearn.metrics import mean_squared_error
# 训练集的MAE
bstMSE = mean_squared_error(bsTrainY,bstLearModel.predict(bsTrainX))
print(f'训练集的MAE为{bstMSE:.3f}')
# 检验集的MAE
bstMSETest = mean_squared_error(bsTestY,bstLearModel.predict(bsTestX))
print(f'训练集的MAE为{bstMSETest:.3f}')
逻辑回归
逻辑回归(Logistic Regression)和线性回归(Linear Regression)是两种不同的统计模型,逻辑回归是线性回归在分类问题上的扩展,它将线性回归的连续输出转换为概率输出,适用于处理分类问题。
-
目的:
- 线性回归:用于预测一个连续的数值。它是一种用于估计两个或多个自变量与一个连续因变量之间线性关系的统计模型。
- 逻辑回归:用于预测一个分类的标签,通常是二分类(0和1)。它是一种用于估计两个或多个自变量与一个二元因变量之间关系的统计模型。
-
应用场景:
- 线性回归:适用于预测销售额、房价、体重等连续数据的情况。
- 逻辑回归:适用于预测疾病是否发生、客户是否流失、邮件是否为垃圾邮件等二元分类的情况。
- 输出类型:
- 逻辑回归:输出是概率值,通常用于计算分类的概率。
- 线性回归:输出是连续的数值。
import statsmodels.formula.api as smf
# 构建模型
md = smf.logit(’Y~X1,X2,...‘,data=df,subset=df['列名'])
# 拟合数据
res = md.fit()
# 显示结果
res.summary()
自变量为连续变量
# 读入泰坦尼克数据集
titanicDf = pd.read_csv('./data/analysis/train.csv',index_col=0)
titanicDf.head()
resTitanic = smf.logit('Survived~Fare+Age+SibSp+Parch', data=titanicDf).fit()
resTitanic.summary()
自变量含有分类变量
resTitanic2 =
smf.logit('Survived~Fare+Age+SibSp+Parch+C(Pclass)+C(Sex)+C(Embarked)')
resTitanic2.summary()
C(Pclass)、C(Sex)、C(Embarked) 表示的是类别变量,它们被编码为虚拟变量或称为指示变量(dummy variables)。
C()是statsmodels中用于将类别变量转换为虚拟变量的函数。
Pclass代表船票等级(如三等、二等、一等)
Sex代表性别,
Embarked代表登船港口,
通常情况下,如果数据集中某个类别有缺失值,那么会创建一个新的虚拟变量来表示这个缺失类别。
分类变量中指定参照组
resTitanic3 =
smf.logit('Survived~Fare+Age+SibSp+Parch+C(Pclass)+C(Sex,Treatment("male”))')
resTitanic3.summary()
- Treatment("male") 这行代码的意思是将性别中的男性作为参照组。
- 在逻辑回归中,参照组通常是用来定义模型的截距的,它代表当所有自变量等于其基值时的结果。
- 例如,在性别这个变量中,如果男性是参照组,那么当其他所有变量保持不变时,模型的预测结果(即生存的概率)就反映了女性相对于男性的生存概率的差异。
逻辑回归(Logistic Regression)的sklearn建模
将分类属性转换成二元数值属性——pd.get_dummies()
虚拟/指示变量(one-hot编码):将分类属性转换成二元数值属性
df_new = pd.get_dummies(df, columns=['列名']) #将分类属性转换成二元数值属性
eg:
titDf =
titanicDf.loc[:,~titanicDf.columns.isin(['Name','Ticket','Cabin'])].copy()
titDf = pd.get_dummies(titDf,columns=['Pclass','Sex','Embarked'])
titDf.head()
逻辑非操作符 ~:将后面的表达式取反。
.isin :检查一个元素是否存在于列表(或数组、集合等)中的方法。
.copy():创建一个复制对象,即原 DataFrame 的一个副本。避免直接修改原始 DataFrame,确保原始数据不会被意外改变。
返回值:由二元化的属性构成的 DataFrame
数据预处理——填充缺失值.fillna()
titDf.fillna({'Age':titDf['Age'].mean()},inplace=True)
{'Age':titDf['Age'].mean()}:这个字典指定了要填充缺失值的字段以及用于填充的值。
在这个例子中,'Age' 是需要填充缺失值的字段,而 titDf['Age'].mean() 是计算 'Age' 列的平均值,并用这个平均值来填充缺失值。
划分训练集与检验集
titTrainX, titTestX, titTrainY, titTestY =
train_test_split(titDf.loc[:,titDf.columns])
建立并训练模型
from sklearn.linear_model import LogisticRegression
lrTit =
LogisticRegression(C=1e9, max_iter=4000, solver='lbfgs', random_state=10)
lrTit.fit(titTrainX,titTrainY)
lrTit.coef_ # 系数
lrTit.intercept_ # 截距
想象一下你是一个侦探,你要通过一些线索(比如指纹、目击者描述等)来确定一个犯罪嫌疑人。这时候,你有一个工具箱,里面有不同的工具(算法)可以帮助你分析这些线索。
LogisticRegression 就是你工具箱中的一个工具,它可以帮助你根据线索来判断嫌疑人是不是罪犯。
C=1e9 这个参数就像是你设置的一个犯错成本。如果你设的犯错成本很高,那么你会在判断时非常谨慎,尽量不犯错,这可能会导致你倾向于做出比较保守的判断。数值越大,对错误分类的惩罚越大,模型越倾向于做出更安全的选择(即分类边界更简单)。
max_iter=4000 就像是你在使用工具时设定的最大尝试次数。你不会无限次尝试,你会设定一个次数,比如4000次,意思是说,如果4000次还找不到满意的答案,那你就放弃使用这个工具。即算法尝试多少次来找到最优解。
solver='lbfgs' 就像是你在使用工具时选择了一个特别的方法。lbfgs是一种特别复杂的查找方法,它可以帮助你在大量的线索中更快地找到正确的答案。
random_state=10 就像是你在使用工具时要求工具每次都按照同样的顺序来处理线索。这样可以确保每次你使用工具得到的结果都是一样的,这样可以避免因为工具的不同顺序处理线索而得到不同的结果。即确保每次运行算法时,产生随机数的顺序都一样,这样可以保证每次运行得到的结果是一致的,便于比较和验证。
所以这行代码就像是你在说:“我要用这个逻辑回归工具来判断嫌疑人是不是罪犯,我设置了一个很高的犯错成本,我给了它最多4000次尝试的机会,我选择了一个特别复杂的查找方法来帮助它快速找到答案,并且我要求它每次都按照同样的顺序来处理线索。”
预测
预测样本是否属于目标类别
预测类别是一个二元分类的输出(是或不是)
titTestPred = lrTit.predict(titTestX)
testPredDf = pd.DataFrame({'Real':titTestY,'Pred':titTestPred})
testPredDf
预测样本属于目标类别的具体概率
预测所属类别概率是一个具体的概率值,表示样本属于目标类别的可能性大小
titTestPredProb = lrTit.predict_proba(titTestX)
# 类别顺序与self.classes_一致
testPredProbDf = pd.DataFrame(titTestPredProb, columns=lrTit.classes_)
testPredProbDf
当你使用 predict_proba 方法时,你得到的是一个二维数组,其中每一行对应一个测试样本,每一列对应一个类别的概率。
例如,如果你的问题是“这个电子邮件是垃圾邮件吗?”(二分类问题),那么 predict_proba 方法将返回一个数组,其中每一行对应一个测试电子邮件,第一列是该电子邮件是垃圾邮件的概率,第二列是该电子邮件不是垃圾邮件的概率。