概率论,是研究随机现象数量规律的数学分支。随机现象是相对于决定性现象而言的,例如太阳东升西落。随机现象是指在基本条件不变的情况下,每一次试验或观察前,不能肯定会出现哪种结果,呈现出偶然性。例如,掷一硬币,可能出现正面或反面。
数理统计是数学的一个分支,分为描述统计和推断统计。它以概率论为基础,研究大量随机现象的统计规律性。描述统计的任务是搜集资料,进行整理、分组,编制次数分配表,绘制次数分配曲线,计算各种特征指标,以描述资料分布的集中趋势、离中趋势和次数分布的偏斜度等。推断统计是在描述统计的基础上,根据样本资料归纳出的规律性,对总体进行推断和预测。
(描述统计——>推断统计)
计算机角度的机器学习和统计角度的机器学习,对一些名称的定义可能会有些不同。
例如
| 机器学习 | 统计机器学习 |
|---|---|
| Unsupervised Learning (无监督学习) | Clustering 聚类 |
| Supervised Learning 监督学习 | 回归分析 |
| Semi-Supervised Learning | … |
| Reinforcement Learning | … |
| … | … |
分类数据:职业、地址、性别
连续数据:年龄、收入
分类数据(但有顺序含义):High school ,BSc,MSc,PhD
Y的变量类型决定了问题,以及用什么方法解决问题

什么时候用统计方法、什么时候用机器学习、什么时候用机器学习呢?

只有特征和样本量都很大(样本量超过200,特征超过20)的时候,我们考虑机器学习的方法。
除此之外,经典的统计方法或者统计学习方法几乎可以解决所有问题。(当然了,机器学习也可以用,但是工程上没有必要)
模型在不同数据量场景下的效果:

心法:定(任务,方法同数据准备阶段,通过数据量和预测任务来判断)、数、模、训、测、上
数:分析(任务)、理解、清晰、构建、选择、提取
模:模型、损失、优化器 (基于数据量和预测类型选择模型。)
训练:迭代、调参、降损失
预测房价、很明显的线性回归任务,而且特征数目少于20,首选线性回归。
#1 问题分析
#(房价预测,回归任务,)
from sklearn import datasets
boston = datasets.load_boston()
print(boston.DESCR)
boston.shape
#分析(分析Y的类型,判断问题类型)
y = boston.target
y = pd.DataFrame(y)
y.describe()
# 理解
house = boston.data
house = pd.DataFrame(house,columns=['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',
'TAX', 'PTRATIO', 'B', 'LSTAT'])
house.info()# 查看基本的描述统计
house.describe()
Data Set Characteristics:
:Number of Instances: 506
:Number of Attributes: 13 numeric/categorical predictive. Median Value (attribute 14) is usually the target.
:Attribute Information (in order):
- CRIM per capita crime rate by town
- ZN proportion of residential land zoned for lots over 25,000 sq.ft.
- INDUS proportion of non-retail business acres per town
- CHAS Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)
- NOX nitric oxides concentration (parts per 10 million)
- RM average number of rooms per dwelling
- AGE proportion of owner-occupied units built prior to 1940
- DIS weighted distances to five Boston employment centres
- RAD index of accessibility to radial highways
- TAX full-value property-tax rate per $10,000
- PTRATIO pupil-teacher ratio by town
- B 1000(Bk - 0.63)^2 where Bk is the proportion of black people by town
- LSTAT % lower status of the population
- MEDV Median value of owner-occupied homes in $1000's


通过分析可知,房价标签是连续数据,因此是回归任务。
研究思路:
先看首先研究单变量的数据类型、分布情况、是否有离群值、是否有缺失值等情况,
再研究变量之间的关系:相关性分析等。
house_data.head()
house_data.info()
house_data.describe()



通过这几张基本统计表,我们可以看:

上述这些统计的结果可以为下一步,特征清洗做准备。
参考资料
https://blog.csdn.net/laffycat/article/details/125883973
http://t.csdn.cn/lGF1A
https://blog.csdn.net/qq_37596349/article/details/105378996
DataFrame绘制直方图
DataFrame.hist(data, column=None, by=None, grid=True, xlabelsize=None, xrot=None, ylabelsize=None, yrot=None, ax=None, sharex=False, sharey=False, figsize=None, layout=None, bins=10, **kwds)
figsize:指要创建的图形的尺寸(以英寸为单位)。默认情况下, 它使用matplotlib.rcParams中的值。
bins:默认值10。它是指要使用的直方图bin的数量。如果给出整数值, 则它将返回bin +1 bin边缘的计算值。(从图上看,这个参数决定了柱状图的粗细,bins越大,图中的柱子越细。
import seaborn as sns
# house[['CHAS', 'RAD']].hist()
house_data[['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',
'TAX', 'PTRATIO', 'B', 'LSTAT','price']].hist(figsize = (10, 15))

scatter plot matrix 绘制方法
绘制方法1:
# 绘制scatter plot matrix散点图矩阵
pd.plotting.scatter_matrix(house_data, alpha=0.3, figsize=(14,10),diagonal='hist') for
# diagonal : {'hist', 'kde'} 在对角线上选择“kde”和“hist”来进行核密度估计或直方图绘制。

绘制方法2:
import seaborn as sns
# 任意两个变量间的相关性散点图
sns.set()
cols = house_data.columns # 罗列出数据集的所有列
sns.pairplot(house_data[cols], size = 2.5) # 成对画出任意两列的散点图
plt.show() # 显示函数

从可视化的角度来研究变量之间的相关性,最简单的方法就是将两个特征对应的坐标点在坐标系下描述出来,研究他们的变化趋势,每一个点的坐标是一个二元组
(
X
A
(
i
)
,
X
B
(
i
)
)
(X_{A}^{(i)},X_{B}^{(i)})
(XA(i),XB(i)),其中
X
A
(
i
)
X_{A}^{(i)}
XA(i)表示第
i
i
i个样本特征
A
A
A的值,而
X
A
(
i
)
X_{A}^{(i)}
XA(i)表示第
i
i
i个样本特征
B
B
B的值.
从上面的图像可以看出,有些变量实际上是有相似(A高B高)的分布情况的,或者相反的分布情况的(A高B低),这样的性质称为变量之间的相关性。 (注意,这里不考虑标签的相关性)
相关性一般有两种情况:

sns.pairplot(house_data[["AGE", "DIS"]], size = 3) #size是子图的大小

其次,可以看那些趋势明显比较单调,但是不太像直线,而是类似“对数函数”的图像,例如图中的DIS和NOX,因为这类图像,只要对数化,就可以得到类似直线的效果,那么也可以被处理.
成对画出任意两列的散点图(带对数处理)
sns.pairplot(np.log(house[["NOX", "DIS"]]), size = 3) #size是子图的大小

最后,还需关注最后一行(列)与其他行(列)的关系,也就是特征与标签的关系,如果这两者出现较强相关性,那么我们需要留意这些特征,因为这些特征对标签有着比较直接的关系,例如RM和LSTAT
成对画出任意两列的散点图(带对数处理)
sns.pairplot(np.log(house_data[["RM", "LSTAT", "price"]]), size = 3) #size是子图的大小

通过图像
我们发现一个问题,就是最上面price=50的电很奇怪,因此它刚好就是50,有点太奇怪了,不高不低,然后我们去翻记录资料,发现>50的全部标记为50了,因此这些数据对应我们分析来说肯定是不友好的,所以需要删除掉.
通过散点图矩阵,我们可以确定哪些变量(通过左对角线看:大多数长尾分布的都需要转换)应该转化为对数尺度(注意,一旦转换,则对应的标签也需要转换),并且对于相关行较高的变量我们可以进行删减,但是相关性通过图像确定不够客观,我们考虑通过相关系数的热土来查看,见下文.
除了先用图,对相关性进行基本的分析外,我们可以用数据继续对相关性进行定量描述.
协方差

计算协方差 house.cov()#只有数值型变量才能算,类别或文本需要编码后才能计算.

但是协方差只能看出正相关和负相关,其大小并没有意义,这是因为每个特征的量纲不同,直接乘积后求期望,所得到的量纲又是不尽相同,因此我们需要对其做“无量纲化”处理
相关系数
计算相关系数:
def Corr(X, Y):
'''
计算随机变量X,Y的相关系数.
X: np.array or pd.Series.
Y: np.array or pd.Series.
'''
COV_XY = np.cov(X, Y) #协方差矩阵
std_X = np.std(X) #X的标准差
std_Y = np.std(Y) #Y的标准差
Corr_Matrix = COV_XY / (std_X * std_Y)
return Corr_Matrix
# (np.cov(house['AGE'], house['DIS'])/ ((np.std(house['AGE']) * np.std(house['DIS']))))[0,1]
# 利用自己实现的函数进行单项相关系数的计算
Corr(house['AGE'], house['DIS'])
# 直接计算相关性系数
Corr_Matrix = house.corr()
Corr_Matrix
#correlation matrix
f, ax = plt.subplots(figsize=(12, 9)) # 设置画布
sns.heatmap(Corr_Matrix, vmax=.8, square=True # 画热力图


从相关系数的热图当中,我们可以看出哪些变量是高度相关的,对于高度相关的变量,我们希望在回归模型中去除某个或者某些变量.
注意
基于对数据的分析和理解,我们拟采用线性回归来构建房价越模型.
下面这一部分是数据准备的工作:
import numpy as np
import pandas as pd
from sklearn import datasets
boston = datasets.load_boston() #波士顿房价数据集,预测房价,因此是回归任务
x = boston.data[:,5]
y = boston.target
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=626)
print(x_train.shape)
print(y_train.shape)
print(x_test.shape)
print(y_test.shape)
x_train = x_train.reshape(-1,1)
y_train = y_train.reshape(-1,1)
x_test = x_test.reshape(-1,1)
y_test = y_test.reshape(-1,1)
from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(x_train, y_train)
lin_reg.intercept_ #截距
lin_reg.coef_ #系数
plt.scatter(x_train, y_train) # 画散点图
plt.plot(x_train, lin_reg.predict(x_train), color='r') #画线图
plt.show() #展示图片
回归模型中,模型的测试和评估指标如下

y_predict = lin_reg.predict(x_test)
## MSE
mse_test = np.sum((y_predict - y_test)**2) / len(y_test)
mse_test
## RMSE
from math import sqrt
rmse_test = sqrt(mse_test)
rmse_test
## MAE
mae_test = np.sum(np.absolute(y_predict-y_test)) / len(y_test)
mae_test
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
print(mean_squared_error(y_test, y_predict))
print(mean_absolute_error(y_test, y_predict))
## R^2 (下面是三种输出相关性系数R^2的方式)
1 - mean_squared_error(y_test, y_predict) / np.var(y_test)
from sklearn.metrics import r2_score
r2_score(y_test, y_predict)
lin_reg.score(x_test, y_test)
补充正则化线性回归的相关算法:
X = boston.data
y = boston.target
X.shape
y.shape
X = X[y < 50.0]
y = y[y < 50.0]
# Ridge
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=626)
from sklearn.linear_model import Ridge
ridge_reg = Ridge(alpha=1, solver='cholesky', random_state=626)
ridge_reg.fit(X_train, y_train)
ridge_reg.intercept_
ridge_reg.coef_
ridge_reg.predict(X_test)
# Lasso
from sklearn.linear_model import Lasso
lasso_reg = Lasso(alpha=0.1)
lasso_reg.fit(X_train, y_train).coef_
lasso_reg.predict(X_test)
#Elastic Net
from sklearn.linear_model import ElasticNet
elastic_net = ElasticNet(alpha=0.1, l1_ratio=0.5)
elastic_net.fit(X_train, y_train)
# elastic_net.predict(y_test)
elastic_net.coef_
但是,一些1维的线性回归模型不够用,我们引入多项式回归.
Polynomial Regression (多项式回归)
example 1:
np.random.seed(626)
m = 100
X = 6 * np.random.rand(m,1) - 3
y = 0.5 * X**2 + X + 2 + np.random.randn(m,1)
plt.plot(X, y, 'b.')
plt.xlabel("$x_1$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.show()
from sklearn.preprocessing import PolynomialFeatures
poly_features = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly_features.fit_transform(X)
X[0:5]
X_poly[0:5]
lin_reg = LinearRegression()
lin_reg.fit(X_poly, y)
lin_reg.intercept_, lin_reg.coef_
example2:
X_new = np.linspace(-3,3,100).reshape(100,1)
X_new_poly = poly_features.transform(X_new)
y_new = lin_reg.predict(X_new_poly)
plt.plot(X, y, 'b.')
plt.plot(X_new, y_new, 'r-', linewidth=2, label='Prediction')
plt.xlabel("$x_1$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.legend(loc='upper left', fontsize=14)
plt.axis([-3,3,0,10])
plt.show()
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
def PolynomialRegression(degree):
return Pipeline([
('poly', PolynomialFeatures(degree=degree)),
('std_scaler', StandardScaler()),
('lin_reg', LinearRegression())
])
模型评估常用三件套
X = boston.data
y = boston.target
X = X[y < 50.0]
y = y[y < 50.0]
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=10)
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
train_score = []
test_score = []
for i in range(1, 76):
lin_reg = LinearRegression()
lin_reg.fit(X_train[:i], y_train[:i])
y_train_predict = lin_reg.predict(X_train[:i])
train_score.append(mean_squared_error(y_train[:i], y_train_predict))
y_test_predict = lin_reg.predict(X_test)
test_score.append(mean_squared_error(y_test, y_test_predict))
绘制损失(均方误差)下降曲线图像(学习曲线)
plt.plot([i for i in range(1, 76)], np.sqrt(train_score), label="train")
plt.plot([i for i in range(1, 76)], np.sqrt(test_score), label="test")
plt.legend()
plt.show()

def plot_learning_curve(algo, X_train, X_test, y_train, y_test):
train_score = []
test_score = []
for i in range(1, len(X_train)+1):
algo.fit(X_train[:i], y_train[:i])
y_train_predict = algo.predict(X_train[:i])
train_score.append(mean_squared_error(y_train[:i], y_train_predict))
y_test_predict = algo.predict(X_test)
test_score.append(mean_squared_error(y_test, y_test_predict))
plt.plot([i for i in range(1, len(X_train)+1)],
np.sqrt(train_score), label="train")
plt.plot([i for i in range(1, len(X_train)+1)],
np.sqrt(test_score), label="test")
plt.legend()
plt.axis([0, len(X_train)+1, 0, 4])
plt.show()
## underfitted model
plot_learning_curve(LinearRegression(), X_train, X_test, y_train, y_test)

## proper model (合适的模型)
poly2_reg = PolynomialRegression(degree=2)
plot_learning_curve(poly2_reg, X_train, X_test, y_train, y_test)

## overfitted model 过拟合模型,多项式的项数选择太多
poly20_reg = PolynomialRegression(degree=20)
plot_learning_curve(poly20_reg, X_train, X_test, y_train, y_test)

## CV
from sklearn.model_selection import cross_val_score
Other Related Methodologies(其他相关方法)