一、业务场景:
1. 一个汽车销售公司,其客户来店消费金额是否符合正态分布?
答:这个问题可以抽象为统计学的统计推断中的假设检验部分的正态性检验。
2. 如何模拟这些数据的函数特征,怎么看拟合的好不好?
答:这是个拟合问题,视情况用线性拟合和多项式拟合来拟合。通过拟合打分看拟合效果。
3. 这个具体函数能否给出来?
答:可以。
二、下面分四部分来用代码解决上述问题
1. 对数据做正态性判断
2. 对数据做多元线性回归
3. 对数据做多元多项式回归
4. 输出线性回归和多项式回归对应的具体函数(函数包括:组合特征项,特征系数和常数项)
1. 正态性检验(Normality Test)
#三种方法:
#1. 生成数据为浮点数,所以用密度,如果数据是单词出现频率等整数则用直方图比较,根据图形肉眼比较。
#2. 用shapiro-wilk norm test,p-value的值大于0.05可视为满足正态性。
#3. 用qqplot做正态性检验,解读方法是如果qqplot所划散点和直线越接近则是正态分布,否则不是。
#代码
## Generate two data sets
## First Normal, second from a t-distribution
words1 = rnorm(100); words2 = rt(100, df=3)
## Have a look at the densities
plot(density(words1));plot(density(words2))
## Perform the shapiro-wilk test
shapiro.test(words1); shapiro.test(words2)
## Plot using a qqplot
qqnorm(words1);qqline(words1, col = 2)
qqnorm(words2);qqline(words2, col = 2)
参考:
https://stats.stackexchange.com/questions/3136/how-to-perform-a-test-using-r-to-see-if-data-follows-normal-distribution
https://docs.scipy.org/doc/scipy-0.19.0/reference/generated/scipy.stats.shapiro.html
2. 用scikit-learn做多元线性回归
# R-squared表示模型的拟合度好坏,取值为0-1,越接近1越好。
from sklearn.linear_model import LinearRegression
X = [[6, 2], [8, 1], [10, 0], [14, 2], [18, 0]]
y = [[7], [9], [13], [17.5], [18]]
model = LinearRegression()
model.fit(X, y)
X_test = [[8, 2], [9, 0], [11, 2], [16, 2], [12, 0]]
y_test = [[11], [8.5], [15], [18], [11]]
predictions = model.predict(X_test)
for i, prediction in enumerate(predictions):
print('Predicted: %s, Target: %s' % (prediction, y_test[i]))
# 或者用summary(r)查看R-squared,分别查看训练集和测试集
print('R-squared: %.2f' % model.score(X_test, y_test))
print('R-squared: %.2f' % model.score(X, y))
参考:http://blog.csdn.net/SA14023053/article/details/51703204
3. 对数据做多元多项式回归
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import Ridge
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
def f(x):
""" function to approximate by polynomial interpolation"""
return x * np.sin(x)
# generate points used to plot
x_plot = np.linspace(0, 10, 100)
# generate points and keep a subset of them
x = np.linspace(0, 10, 100)
rng = np.random.RandomState(0)
rng.shuffle(x)
x = np.sort(x[:20])
y = f(x)
# create matrix versions of these arrays
X = x[:, np.newaxis]
X_plot = x_plot[:, np.newaxis]
colors = ['teal', 'yellowgreen', 'gold']
lw = 2
plt.plot(x_plot, f(x_plot), color='cornflowerblue', linewidth=lw,
label="ground truth")
plt.scatter(x, y, color='navy', s=30, marker='o', label="training points")
for count, degree in enumerate([3, 4, 5]):
model = make_pipeline(PolynomialFeatures(degree), Ridge())
model.fit(X, y)
y_plot = model.predict(X_plot)
#拟合出来的是函数是个靠近值不是经过值,所以可得到训练集的拟合程度。
print model.named_steps['ridge'].coef_
print('score: %s' % (model.score(X, y)))
plt.plot(x_plot, y_plot, color=colors[count], linewidth=lw,
label="degree %d" % degree)
plt.legend(loc='lower left')
plt.show()
参考:http://scikit-learn.org/stable/auto_examples/linear_model/plot_polynomial_interpolation.html
4. 输出线性回归和多项式回归对应的具体函数
具体函数:函数的组成包括组合特征项,特征系数和常数项。类似y = const + ax1 + bx2 + cx1^2 + dx1x2 + ex2^2。
对于一元/多元,线性/多项式等不同情况,我们只要把函数各组成部分找出来,就能把具体函数列出来。
特征项:
1> 对于单个输入特征x1,线性,度为1, 拟合的函数为y = 1+x1
2> 对于单个输入特征x1,度为2,拟合的函数为y = (1+x1)^2 = 1 + 2x1 + x1^2
3> 对于n个(以2为例)输入特征x1和x2,度为2,拟合的函数为 y = (1+x1+x2)^2 = 1 + 2(x1+x2) + (x1+x2)^2 = 1 + 2x1 + 2x2 + x1^2 + 2x1x2 + x2^2
去掉系数就是组合特征项。
特征系数:model.coef_可得到所有组合特征项的系数。
常数项:用model.predict(0, 0)得到,也就是y - ax1 - bx2 = 常数项
参考:http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.PolynomialFeatures.html