【常见的内置函数】
①.、enumerate(iterable,start=0)
是python的内置函数,是枚举、列举的意思,对于一个可迭代的(iterable)/可遍历的对象(如列表、字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值.
用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表.如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用*号操作符,可以将元组解压为列表.
filter是将一个序列进行过滤,返回迭代器的对象,去除不满足条件的序列.
是用来判断某一个变量或者是对象是不是属于某种类型的一个函数,如果参数object是classinfo的实例,或者object是classinfo类的子类的一个实例,
返回True.如果object不是一个给定类型的的对象, 则返回结果总是False
用来将字符串str当成有效的表达式来求值并返回计算结果,表达式解析参数expression并作为Python表达式进行求值(从技术上说是一个条件列表),采用globals和locals字典作为全局和局部命名空间.
【常用的句式】
①.、format字符串格式化
format把字符串当成一个模板,通过传入的参数进行格式化,非常实用且强大.
常使用+连接两个字符串.
Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块.其中if...else语句用来执行需要判断的情形.
循环语句就是遍历一个序列,循环去执行某个操作,Python中的循环语句有for和while.
有时需要使用另一个python文件中的脚本,这其实很简单,就像使用import关键字导入任何模块一样.
所说所有的变量都是对象. 对象在python里,其实是一个指针,指向一个数据结构,数据结构里有属性,有方法.
对象通常就是指变量.从面向对象OO的概念来讲,对象是类的一个实例.在python里很简单,对象就是变量.
class A:
myname="class a"
上面就是一个类.不是对象
a=A()
这里变量a就是一个对象.
它有一个属性(类属性),myname,你可以显示出来
print a.myname
所以,你看到一个变量后面跟点一个小数点.那么小数点后面.
基本形式
线性模型(linear model)就是试图通过属性的线性组合来进行预测的函数,基本形式如下:
f(x)=wTx+b
许多非线性模型可在线性模型的基础上通过引入层结构或者高维映射(比如核方法)来解决.线性模型有很好的解释性.
线性回归
线性回归要求均方误差最小:
均方误差有很好的几何意义,它对应了常用的欧式距离(Euclidean distance).基于均方误差最小化来进行模型求解称为最小二乘法(least square method),线性回归中,最小二乘发就是试图找到一条直线,使得所有样本到直线的欧式距离之和最小.
我们把上式写成矩阵的形式:
w?=argmin(y?Xw)T(y?Xw)
这里我们把b融合到w中,X中最后再加一列1.为了求最小值,我们对w求导并令其为0:
当XTX为满秩矩阵(full-rank matrix)时是可逆的.此时:
w=(XTX)?1XTy
令xi=(xi,1),可以得到线性回归模型:
f(xi)=xTi(XTX)?1XTy
①.、什么是多元线性回归模型?
当y值的影响因素不唯一时,采用多元线性回归模型.
pandas 是一个用于数据探索、数据分析和数据处理的python库
[python]?view plain?copy
import?pandas?as?pd
[html]?view plain?copy
pre?name="code"?class="python"#?read?csv?file?directly?from?a?URL?and?save?the?results
data?=?pd.read_csv('/home/lulei/Advertising.csv')
data.head()
上面代码的运行结果:
TV ?Radio ?Newspaper ?Sales
上面显示的结果类似一个电子表格,这个结构称为Pandas的数据帧(data frame),类型全称:pandas.core.frame.DataFrame.
pandas的两个主要数据结构:Series和DataFrame:
Series类似于一维数组,它有一组数据以及一组与之相关的数据标签(即索引)组成.
DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型.DataFrame既有行索引也有列索引,它可以被看做由Series组成的字典.
data.tail()
? ?TV ?Radio ?Newspaper ?Sales
#?check?the?shape?of?the?DataFrame(rows,?colums)
data.shape
查看DataFrame的形状,注意第一列的叫索引,和数据库某个表中的第一列类似.
特征:
TV:对于一个给定市场中单一产品,用于电视上的广告费用(以千为单位)
Radio:在广播媒体上投资的广告费用
Newspaper:用于报纸媒体的广告费用
响应:
Sales:对应产品的销量
注意:这里推荐使用的是seaborn包.网上说这个包的数据可视化效果比较好看.其实seaborn也应该属于matplotlib的内部包.只是需要再次的单独安装.
import?seaborn?as?sns
import?matplotlib.pyplot?as?plt
#?visualize?the?relationship?between?the?features?and?the?response?using?scatterplots
plt.show()#注意必须加上这一句,否则无法显示.
这里选择TV、Radio、Newspaper?作为特征,Sales作为观测值
返回的结果:
plt.show()
结果显示如下:
优点:快速;没有调节参数;可轻易解释;可理解.
缺点:相比其他复杂一些的模型,其预测准确率不是太高,因为它假设特征和响应之间存在确定的线性关系,这种假设对于非线性的关系,线性回归模型显然不能很好的对这种数据建模.
y是响应
b0是截距
b1是x1的系数,以此类推
(1)、使用pandas来构建X(特征向量)和y(标签列)
scikit-learn要求X是一个特征矩阵,y是一个NumPy向量.
pandas构建在NumPy之上.
所以呢,X可以是pandas的DataFrame,y可以是pandas的Series,scikit-learn可以理解这种结构.
#create?a?python?list?of?feature?names
feature_cols?=?['TV',?'Radio',?'Newspaper']
#?use?the?list?to?select?a?subset?of?the?original?DataFrame
X?=?data[feature_cols]
#?equivalent?command?to?do?this?in?one?line
X?=?data[['TV',?'Radio',?'Newspaper']]
print?X.head()
#?check?the?type?and?shape?of?X
print?type(X)
print?X.shape
输出结果如下:
?TV ?Radio ?Newspaper
class 'pandas.core.frame.DataFrame'
#?select?a?Series?from?the?DataFrame
y?=?data['Sales']
#?equivalent?command?that?works?if?there?are?no?spaces?in?the?column?name
y?=?data.Sales
print?y.head()
输出的结果如下:
Name: Sales
from?sklearn.cross_validation?import?train_test_split?#这里是引用了交叉验证
X_train,X_test,?y_train,?y_test?=?train_test_split(X,?y,?random_state=1)
print?X_train.shape
print?y_train.shape
print?X_test.shape
print?y_test.shape
注:上面的结果是由train_test_spilit()得到的,但是我不知道为什么我的版本的sklearn包中居然报错:
处理方法:1、我后来重新安装sklearn包.再一次调用时就没有错误了.
from?sklearn.linear_model?import?LinearRegression
linreg?=?LinearRegression()
model=linreg.fit(X_train,?y_train)
print?model
print?linreg.intercept_
print?linreg.coef_
LinearRegression(copy_X=True, fit_intercept=True, normalize=False)
#?pair?the?feature?names?with?the?coefficients
zip(feature_cols,?linreg.coef_)
输出如下:
如何解释各个特征对应的系数的意义?
y_pred?=?linreg.predict(X_test)
print?y_pred
print?type(y_pred)
type 'numpy.ndarray'
(1) 评价测度
对于分类问题,评价测度是准确率,但这种方法不适用于回归问题.我们使用针对连续数值的评价测度(evaluation metrics).
①.)平均绝对误差(Mean Absolute Error, MAE)
这里我使用RMES.
pre?name="code"?class="python"#计算Sales预测的RMSE
print?type(y_pred),type(y_test)
print?len(y_pred),len(y_test)
print?y_pred.shape,y_test.shape
from?sklearn?import?metrics
import?numpy?as?np
sum_mean=0
for?i?in?range(len(y_pred)):
#?calculate?RMSE?by?hand
print?"RMSE?by?hand:",sum_erro
最后的结果如下:
type 'numpy.ndarray' class 'pandas.core.series.Series'
plt.figure()
plt.plot(range(len(y_pred)),y_pred,'b',label="predict")
plt.plot(range(len(y_pred)),y_test,'r',label="test")
plt.legend(loc="upper?right")?#显示图中的标签
plt.xlabel("the?number?of?sales")
plt.ylabel('value?of?sales')
显示结果如下:(红色的线是真实的值曲线,蓝色的是预测值曲线)
直到这里整个的一次多元线性回归的预测就结束了.
在之前展示的数据中,我们看到Newspaper和销量之间的线性关系竟是负关系(不用惊讶,这是随机特征抽样的结果.换一批抽样的数据就可能为正了),现在我们移除这个特征,看看线性回归预测的结果的RMSE如何?
依然使用我上面的代码,但只需修改下面代码中的一句即可:
最后的到的系数与测度如下:
然后再次使用ROC曲线来观测曲线的整体情况.我们在将Newspaper这个特征移除之后,得到RMSE变小了,说明Newspaper特征可能不适合作为预测销量的特征,于是,我们得到了新的模型.我们还可以通过不同的特征组合得到新的模型,看看最终的误差是如何的.
备注:
之前我提到了这种错误:
这里我给出我自己写的函数:
①.、print()函数:打印字符串;
①.0、s.sppace()函数:判断是否为空格;
①.1、str.replace()函数:替换字符;
............
利用python进行线性回归
理解什么是线性回归
线性回归也被称为最小二乘法回归(Linear Regression, also called Ordinary Least-Squares (OLS) Regression).它的数学模型是这样的:
y = a+ b* x+e
其中,a 被称为常数项或截距;b 被称为模型的回归系数或斜率;e 为误差项.a 和 b 是模型的参数.
当然,模型的参数只能从样本数据中估计出来:
y'= a' + b'* x
我们的目标是选择合适的参数,让这一线性模型最好地拟合观测值.拟合程度越高,模型越好.
那么,此时此刻呢的问题就是,我们如何判断拟合的质量呢?
这一线性模型可以用二维平面上的一条直线来表示,被称为回归线.
模型的拟合程度越高,也即意味着样本点围绕回归线越紧密.
如何计算样本点与回归线之间的紧密程度呢?
高斯和勒让德找到的方法是:被选择的参数,应该使算出来的回归线与观测值之差的平房和最小.用函数表示为:
这被称为最小二乘法.最小二乘法的原理是这样的:当预测值和实际值距离的平方和最小时,就选定模型中的两个参数(a 和 b).这一模型并不一定反映解释变量和反应变量真实的关系.但它的计算成本低;相比复杂模型更容易解释.
模型估计出来后,我们要回答的问题是:
整个模型是否能显著预测因变量的变化?(F 检验)
每个自变量是否能显著预测因变量的变化?(t 检验)
首先回答第一个问题.为了评估模型的拟合程度如何,我们必须有一个可以比较的基线模型.
如果让你预测一个人的体重是多少?在没有任何额外信息的情况下,你可能会用平均值来预测,尽管会存在一定误差,但总比瞎猜好.
现在,如果你知道他的身高信息,你的预测值肯定与平均值不一样.额外信息相比平均值更能准确地预测被预测的变量的能力,就代表模型的解释力大小.
上图中,SSA 代表由自变量 x 引起的 y 的离差平方和,即回归平方和,代表回归模型的解释力;SSE 代表由随机因素引起的 y 的离差平方和,即剩余平方和,代表回归模型未能解释的部分;SST 为总的离差平方和,即我们仅凭 y 的平均值去估计 y 时所产生的误差.
用模型能够解释的变异除以总的变异就是模型的拟合程度:
第二个问题,我们的模型是否显著预测了 y 的变化?
假设 y 与 x 的线性关系不明显,那么 SSA 相对 SSE 占有较大的比例的概率则越小.换句话说,在 y 与 x 无线性关系的前提下,SSA 相对 SSE 的占比越高的概率是越小的,这会呈现一定的概率分布.统计学家告诉我们它满足 F 分布,就像这样:
第三个问题,每个自变量是否能显著预测因变量的变化?换句话说,回归系数是否显著?
回归系数的显著性检验是围绕回归系数的抽样分布(t 分布)来进行的,推断过程类似于整个模型的检验过程,不赘言.
实际上,对于只有一个自变量的一元线性模型,模型的显著性检验和回归系数的检验是一致的,但对于多元线性模型来说,二者就不能等价了.
利用 statsmodels 进行最小二乘回归
#导入相应模块
In [1]: import numpy as np
#将数据导入 pandas 的 dataframe 对象,第一列(年份)作为行标签
#查看头部数据
GNP.deflator ? ? ?GNP ?Unemployed ?Armed.Forces ?Population ?Year ?\
Employed
#设置预测变量和结果变量,用 GNP 预测 Employed
#为模型增加常数项,即回归线在 y 轴上的截距
#执行最小二乘回归,X 可以是 numpy array 或 pandas dataframe(行数等于数据点个数,列数为预测变量个数),y 可以是一维数组(numpy array)或 pandas series
In [10]: est=sm.OLS(y,X)
使用 OLS 对象的 fit() 方法来进行模型拟合
In [11]: est=est.fit()
#查看模型拟合的结果
#查看最终模型的参数
#选择 100 个从最小值到最大值平均分布(equally spaced)的数据点
#计算预测值
#分别给 x 轴和 y 轴命名
多元线性回归(预测变量不止一个)
我们用一条直线来描述一元线性模型中预测变量和结果变量的关系,而在多元回归中,我们将用一个多维(p)空间来拟合多个预测变量.下面表现了两个预测变量的三维图形:商品的销量以及在电视和广播两种不同媒介的广告预算.
数学模型是:
图中,白色的数据点是平面上的点,黑色的数据点事平面下的点.平面的颜色是由对应的商品销量的高低决定的,高是红色,低是蓝色.
利用 statsmodels 进行多元线性回归
In [1]: import pandas as pd
In [10]: est=sm.OLS(y,X).fit()
In [11]: est.summary()
Out[11]:
你也可以使用 statsmodels 的 formula 模块来建立多元回归模型
处理分类变量
性别或地域都属于分类变量.
利用 dataframe 的 pop 方法将 chd 列单独提取出来
sbp ?tobacco ? ldl ?adiposity ?famhist ?typea ?obesity ?alcohol ?\
row.names
age ?chd
famhist
分类变量的编码方式有许多,其中一种编码方式是虚拟变量编码(dummy-encoding),就是把一个 k 个水平的分类变量编码成 k-1 个二分变量.在 statsmodels 中使用 C 函数实现.
处理交互作用
随着教育年限(education)的增长,薪酬 (wage) 会增加吗?这种影响对男性和女性而言是一样的吗?
这里的问题就涉及性别与教育年限的交互作用.
换言之,教育年限对薪酬的影响是男女有别的.
#导入相关模块
#导入数据,存入 dataframe 对象
Wage ?Education ?Sex
由于性别是一个二分变量,我们可以绘制两条回归线,一条是 sex=0(男性),一条是 sex=1(女性)
#绘制散点图
In [10]: plt.ylabel('wage')
#linspace 的作用是生成从最小到最大的均匀分布的 n 个数
以上两条线是平行的.这是因为分类变量只影响回归线的截距,不影响斜率.
此时此刻呢我们可以为回归模型增加交互项来探索交互效应.也就是说,对于两个类别,回归线的斜率是不一样的.
#使用*代表我们的回归模型中除了交互效应,也包括两个变量的主效应;如果只想看交互效应,可以用:代替,但通常不会只看交互效应
参考资料:
DataRobot | Ordinary Least Squares in Python
DataRoboe | Multiple Regression using Statsmodels