***创建函数时,如果有多个未知参数,可以用*args,在使用时可以用for arg in args:遍历
df的重命名方法:
方法1:r_cx.columns = ['频数']这种重命名方法是直接在原来的dataframe上修改。但需要对所有的列名重命名。
方法2:df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'})
s_r = s.reset_index(drop=False)#.reset_index保留index同时,对index重新排序
一、分布分析
1.定量字段的分布分析
第一步:极差:越小越稳定,越大越不稳定
第二步:频率分布情况:分组区间pd.cut,判断每个区间出现的频率,频数,累计频率,累计频数
r_zj['累计频率%'] = r_zj['累计频率'].apply(lambda x:'%.2f%%' %(x*100))
r_zj.style.bar(subset = ['频率','累计频率'])#表格样式
第三步:画直方图(区间)
x = len(r_zj) y = r_zj['频率'] m = r_zj['频数']
for i,j,k in zip(range(x),y,m):#zip可以有多个值不止两个
plt.text(i-0.1,j+0.01,'%i'%k,color='k')
2.定性字段的分布分析
定性字段:除了和定量一样外还要做个饼图
二、对比分析
1.绝对值的比较:相减 --相互对比在量级上差距不能太大(1)折线图比较(2)多系列柱状图比较 (3)堆叠图正负数比较
2.相对值的比较:相除
(1)结构比较:同时可以反应“强度” → 两个性质不同但有一定联系的总量指标对比,用来说明“强度”、“密度”、“普遍程度” 例如:国内生产总值“元/人”,人口密度“人/平方公里”
a.各组占总体的比重,反应总体的内部结构,b.折线图
(2)比例比较:在分组的基础上,将总体不同部分的指标数值进行对比,a.消费/工资 b.面积图
(3)空间比较(同一时间横向比较):同类现象在同一时间不同空间的指标数值进行对比,反应同类现象在不同空间上的差异程度和现象发展不平衡的状况 a.四个产品在一个月内销售情况的比较 b.柱状图
(4)纵向比较(不同时间):a.计算累计增长量,逐期增长量,定基增长速度=累计增长量/基期水平-1,环比增长速度=报告期/上一期水平-1
b.折线图:同一现象在不同时间上的指标数值进行对比,反应现象的数量随着时间推移而发展变动的程度及趋势
# 最基本方法,计算动态相对数 → 发展速度
# 动态相对数(发展速度) = 某一现象的报告期数值 / 同一现象的基期数值
# 基期:用来比较的基础时期
# 报告期:所要研究的时期,又称计算期
三、统计分析:密度图
对定量数据统计描述,从集中趋势和离中趋势两方面 :平均数、众数、中位数、四分位数、方差
1.集中趋势:算术平均数mean 加权平均数 众数mode、中位数median
2.离中趋势:极差、分位差.describe、方差、标准差.var
四、帕累托分析
(1)先对值由大到小排序,画柱状图
(2)计算累计占比data.cumsum()/data.sum(),画出次坐标轴折线图
(3)求出大于80%的第一个index,即这个index之前都是80%的
(4)求出该index是第几个索引
五、正态分布
正态分布:均值决定位置,标准差决定分布幅度-越胖越离散,越瘦越集中;当均值=0时,标准分布
#集中性:高峰位于正中央,即均值所在位置;对称性:以均值为中心,左右对称;均匀变动性:中间是主要分布点,周围会均匀下降;总面积=1
第一步:直方图初检:密度图、直方图+密度图
fig = plt.figure(figsize=(10,6))
ax1 = fig.add_subplot(2,1,1)
ax1.scatter(s.index,s.values)
ax2 = fig.add_subplot(2,1,2)
s.hist(bins=20,ax=ax2)
s.plot(kind='kde',secondary_y=True,ax=ax2)
第二步:qq图检验:即散点图。将值由小到大排序,横坐标是每个数据对应的百分位p(百分位p[i],p[i]=(i-0.5)/n );纵坐标是对应的值;会出的散点图是否在直线(三分位数-一分位数)上。纵坐标也可以是q值为(值-均值)/标准差,是每个值标准化后的结果;
st = s['value'].describe()
x1,y1 = 0.25,st['25%'] x2,y2 = 0.75,st['25%']
ax3 = fig.add_subplot(3,1,3)
ax3.plot(s_r['p'],s_r['value'],'k.',alpha=0.1)--没有指定什么图形,就是用xy绘制
ax1.plot([x1,x2],[y1,y2],'-r',color='R')
第三步:K-s检验
K_S检验:样本数据累计频数分布f(x)和理论分布g(x)(如正态分布)比较,f(x)-g(x)最大值,p值>0.05接受f(x),p<0.05拒绝f(x)接受g(x)
1. #推导过程:(1)累计频率分布:次数、累计次数、累计频率(2)标准化取值-把非正态分布变成正态分布:(值-均值u)/std标准差(3)查阅标准正态分布,对应出理论值(4)D=累计频率-理论分布的最大值(5)所得出的最大值对照显著性对照表,求出p值是否大于0.05,若大于则满足g(x)
2. #直接K-s检验算法:(1)求均值和标准差(2)导入stats模块,stats.kstest(df['value'],'norm',(u,std))(3)statistic就是D值,pvalue就是p值
from scipy import stats
stats.kstest(df['value'],'norm',(u,std))
六、相关性分布
1.相关性分析:(1)先用简单散点方法看相关性:a.两个变量:正相关、负相关b.多个变量相关性分析:散点矩阵(2)
2.pearson相关系数:必须满足正态分布,通过公式得到系数>0.5就相关
(1)检验正态分布-K_S检验 (2)如果符合正态分布,则求系数:r = data['(x-u1)*(y-u2)'].sum() / (np.sqrt(data['(x-u1)**2'].sum() * data['(y-u2)**2'].sum()))--xy分别为多变量的值(3)通过r得出相关性
#pearson相关系数算法:data.corr()
3.sperman相关系数:适用于非正态分布
(1)将多个变量的列分别按照有小到大排序并列出'秩'(2)求出d=秩1-秩2以及d的平方 (3)rs = 1-6*(data['d2'].sum())/(n*(n**2-1))其中n = len(data)
spearman相关系数算法:data.corr(method='spearman')
七、数据处理
1.缺失值处理:删除记录 数据插补 不处理
(1)判断是否有缺失值:isnull notnull返回布尔型
(2)删除缺失值dropna
(3)填充缺失数据:.fillna(method='pad'/'ffill'用之前填充=backfill/bfill用之后的填充)
(4)替换缺失数据:.replace(old列表,new,inplace)
2.缺失值插补
(1)均值、中位数、众数插补
(2)临近值填充:.fillna(method='pad'/'ffill'用之前填充=backfill/bfill用之后的填充)
(3)拉格朗日插值法:数学知识平面上的n个点可以用多项式表示:y=a0+a1x1+a2x2+...+a(n-1)x(n-1),只要求出a0,a1..的值就可以
from scipy.interpolate import lagrange
x = [3, 6, 9] y = [10, 8, 4]
print(lagrange(x,y))#得到多项式方程,三个值分别为a0,a1,a2
print(lagrange(x,y)(10))
df = pd.DataFrame({'x':np.arange(15)})
df['y'] = lagrange(x,y)(df['x'])#根据(x,y)的值插值新x的新y 值
plt.plot(df['x'],df['y'],linestyle='--',color='k')
例子:#lagrange的实际应用
a.中位数填充缺失值,画密度图
b.不处理,画密度图--作图时自动排除缺失值
c.lagerand插值:缺失值位置前5后5个数据来插值即可
def f(s,n,k=5):--s值,n缺失值位置,k根据前后k个数据插值
y = s[list(range(n-k,n+1+k))]
y = y[y.notnull()]
return lagrange(y.index,list(y))(n)
for i in range(len(data)):
if data.isnull()[i]:
data[i] = f(data,i)
print(f(data,i))
data.dropna(inplace=True)
data.plot(kind='kde',ax=axes[3],style='--k',grid=True,title='lagrange插值')
3.异常值处理:异常值分析:箱型图/3西格玛原则;异常值处理方法:删除/修正填补
3西格玛原则:如果数据服从正态分布,异常值被定义为测定值与平均值偏差超过3倍标准差的值 (正态分布中符合这一原则的p(|x-u|>3西格玛)<=0.03)
步骤:(1)正态分布检验:k-s检验(2)绘制数据的密度曲线和+-3倍标准差的竖线(3)求出异常值和正常值,并画散点图error = data[np.abs(data-u)>3*std] data_c = data[np.abs(data-u)<=3*std]
箱型图--较3西格玛更准确些(1)画出箱型图,确定以内限还是外限定义缺失值(例子以内限)(2)分别计算q1,q3,iqr,内限(3)error大于内限(q3+1.5*iqr) 小于内线(q1-1.5*iqr);正常值:在(q1-1.5*iqr)和(q3+1.5*iqr)之间 (4)画散点图
4.数据标准化
(1)0-1标准化:比z-score用得较多些;
# 将数据的最大最小值记录下来,并通过Max-Min作为基数(即Min=0,Max=1)进行数据的归一化处理
# x = (x - Min) / (Max - Min)
def f(df,*cols):
df_n = df.copy()
for col in cols:
ma = df_n[col].max()
mi = df_n[col].min()
df_n[col+'_n'] = (df_n[col]-mi)/(ma-mi)
return df_n
df_n = f(df,'value1','value2')
应用:value1权重0.6,value2权重0.4,判断那个指标综合状况最好
a.标准化0-1处理 b.根据权重算综合指标,并由大到小排序 c.绘制折线图
(2)z-score标准化:样本从服从一般分布标准化到服从正态分布;数值越大代表离均值越远;在分类和聚类算法中,两个不同数据的相似性:平均水平、离中趋势
#Z分数(z-score),是一个分数与平均数的差再除以标准差的过程 → z=(x-μ)/σ,其中x为某一具体分数,μ为平均数,σ为标准差
#Z值的量代表着原始值和平均值之间的距离,是以标准差为单位计算。在原始分数低于平均值时Z则为负数,反之则为正数
def f_z(df,*cols):
df_n = df.copy()
for col in cols:
u = df_n[col].mean()
std = df_n[col].std()
df_n[col+'_zn'] = (df_n[col]-u)/std
return df_n
f_z(df,'value1','value2')
5.数据连续属性离散化
(1)等宽法:pd.cut(数据,划分,左右开闭,labels组名)
cats.codes#等级标签
cats.categories#每个值所在区间
pd.value_counts(cats)#每个区间的频数
(2)等频法:pd.qcut()相同数量的记录放入区间
三、数学建模
np.random.RandomState → 随机数种子,对于一个随机数发生器,只要该种子(seed)相同,产生的随机数序列就是相同的
监督学习:通过已有的数据训练得出模型,有样本值x和结果值y,包括回归-线性回归(得到具体的连续性数值)和分类-KNN最邻近分类(离散数值)比如:医生看病问症状:回归是通过5个症状的描述来判断拿几天计量的药;分类是通过现有症状判断得的什么病;
非监督学习:没有结果值y,全是样本值(特征量)x;做聚类或降维-PCA主成分分析、K-means聚类
随机算法:蒙特卡洛模拟算法
监督学习-线性回归:指确定两种或两种以上变量间相互依赖的定量关系的统计分析方法,分位线性回归和非线性回归
监督学习-KNN最邻近分类:在距离空间里,如果一个样本最接近的K个邻居里,绝大多数属于某个类别,那么该样本也属于这个类别
非监督学习-PCA主成分分析:无监督算法+基础降维算法,通过线性变换将原始数据变换为一组各维度线性无关的表示,用于提取数据的主要特征分量
主成分分析:(统计分析中属于中间步骤,其实是降维的结果)
降维:假如有100个维度降成10个维度,主要考虑如何提取核心特征量,通过核心特征量描述新的特征
比如现在做一个线性回归,发现参数非常多100个,如果直接做回归拟合导致曲线很复杂甚至会过度拟合,
现在就要把100个参数变为10个参数当成回归因子,就要用到主成分分析
非监督学习-K-means聚类:典型的基于距离的聚类算法
k均值:基于原型、划分的距离技术,发现用户指定个数(k)的簇
以欧式距离作为相似度测度
随机算法-蒙特卡洛模拟: 又称随机抽样,统计试验方法,使用随机数解决计算问题的方法。
将所求解的问题同一定的概率模型联系,用计算机实现统计模拟或抽样,获得问题的相似解
1.回归
#导入线性回归模块
from sklearn.linear_model import LinearRegression
回归分为线性回归和非线性回归
一、线性回归
np.random.RandomState(1) 随机数种子
x=[1,2,3]
将x变为3*1:x[:,np.newaxis]
得:[[1],
[2],
[3] ]
将x变为1*3:x[np.newaxis,:]
得:[[1,2,3]]
1. 一元线性回归https://www.cnblogs.com/nxld/p/6123239.htmlhttps://www.cnblogs.com/magle/p/5881170.html
(1) 构建回归模型:model=LinearRegression()
(2)输入自变量x因变量y:model.fit(xtrain[:,np.newaxis],ytrain)--以矩阵方式传入
(3)拟合结果:斜率model.coef_ 截距model.intercept_
(4)拟合曲线:xtest=np.linespace(0,10,1000) ytest=model.prdeict(xtest[:,np.newaxis]) --预测方法
(5)画出散点图和拟合的直线图
**误差:#误差:拟合的线和实际值相差的值符合均值为0,服从标准差的正态分布
xtrain、ytrain:散点图;xtest、ytest:直线;xtrain,ytest2--用xtrain的拟合直线算出的ytest2:直线,看拟合直线和点的竖直距离,即误差
2.多元线性回归
np.dot(a,b):如果ab为一维,则内积方法求 x1y1+x2y2+x3y3
如果ab为多维,则矩阵相乘法求
3.线性回归模型的评估
from sklearn import metrics 计算均方差
#SSE和方差:拟合数据和原始数据的误差平方和,接近于0拟合越完整(回归线无法解释的偏差)
#MSE均方差:拟合数据和原数据的误差平方和的均值mse = metrics.mean_absolute_error(ytrain,ytest)
#RMSE均方根:MSE的平方根rmse = np.sqrt(mse)
#R-square确定系数:(1)SSR拟合数据与原始数据的均值之差的平方和 (2)SST原始数据和均值之差平方和(反应因变量取值的整体波动)
#SST=SSE+SSR R-square=SSR/SST 取值范围[0,1]越接近1,表明拟合的越好
R平方:r 2= model.score(xtrain[:,np.newaxis],ytrain)
#总结:r2接近于1(大于0.8就很不错了),mse更小的(适用于多个回归模型哪个最好)
#在主成分分析时:如果有10个参数做回归模型1,r2=0.85;把10个参数降维成3个参数成为3元回归模型2,r2=0.93,所以主成分分析后的回归模型优于之前
举例应用:#给定建筑面积和物业费的情况下,预测总价:总价=影响因子1*建筑面积+影响因子2*物业费+回归系数-截距
2.KNN最邻近分类
根据已经分类好的数据建立模型,对未分类的数据进行分类。分类问题用于将事物打标签,标签属于离散值
(1)导入KNN模块并定义模型(2)输入自变量x和因变量y(3)预测
KNN:样本分出N个类别,每个类别在空间上有点,看新的样本和哪个类别最邻近,就属于那个类别
例如:打斗次数x,亲吻次数y,新的样本xy分析出属于那类型电影
a = [18,90]
knn.predict(a)
报错:ValueError: Expected 2D array, got 1D array instead: array=[18 90].
Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.
解答:https://www.jianshu.com/p/60596270e94e
新的sklearn中所有数据都要是二维矩阵,哪怕他是单独一行或一列,要使用reshape做转换
a = np.array(a).reshape(1,-1) #reshape重组 array转化为数组
1. 导入knn模块 from sklearn import neighbors
import warnings
warnings.filterwarnings('ignore')
#忽略发出的警告
建立knn模型 import neighbors.KNeighborsClassifier()
knn.fit(x,y)
得出预测值:knn.predict() 注意:这里需要sklearn为二维矩阵
2. 植物分类(算法模型中有很多数据库,比如植物、房价等)
from sklearn import datasets
iris = datasets.load_iris() 花的属性库
knn=neighbors.KNeighborsClassifier()
knn.fit(x,y)
knn.predict()
3. 合并merge方法:
merge(left,right,how='inner',on,left_on,right_on)
how:inner交集,outer并集,left左连接,right右连接
on:要加入的索引或列,要在左和右中找到
left_on:左
科普:http://datahref.com/archives/169iris是鸢尾花数据集,包含150个样本,对应数据集的每一行,每个样本包含四个特征和样本的类别
3.PCA主成分分析
举例:1000个样本有100(x1,x2...x100)个维度降到10(a1,a1...a10)个维度
a1-a10这10个变量每个都是由100个变量组成的,关系为a1b1+a2b2+...+a10b10
a1=e11x1+e12x2+...+e1100x100
a1是新变量 x1是旧变量
这里的e11是100个原变量x组成变量a1的特征向量
b1是新的a1的特征值
核心:这里的e11是100个原变量x组成变量a1的特征向量,降维前有几维就有几个特征向量
核心: b1是新的a1的特征值,对应降到几维
将b1..b10由大到小排序,并做累计求和,成为贡献率达到85%后,前面几个就是主成分
1. 加载主成分分析模块PCA from sklearn.decomposition import PCA
2.降维n为:pca=PCA(n_components=1)
3.构建模型:pca.fit(原始数据) pca.explained_variance输出特征值b、pca.components_输出特征向量e1、pca.n_components输出成分个数
4.返回降维后的数据:x_pca=pca.transform(df)
5.如果特征值b较多,筛选主成分85%以上:
s=pca.explained_variance_
df = pd.DataFrame({'b':s,'b_sum':s.cumsum()/s.sum()})
4.聚类K-means
https://blog.csdn.net/kevinelstri/article/details/52622960
1. 基于现有样本在距离上的划分,需要先确定样本大致划分为几个类(簇)
比如:现有四个点,定位到簇;再加入几个点,根据位置划分到簇周围并从新计算簇的位置;重复步骤2,直到所有簇不再改变;
缺点:事先要决定划为几个簇
2.from sklearn.datasets.samples_generator import make_blobs:make_blobs聚类数据生成器
x,y_true = make_blobs(n_samples=300, #创建XX条数据
centers =4, #生成4类数据,类别数
cluster_std=0.5, #每个类别的方差,方差越小越聚集,方差越大越分散=[0.2,0.2,0.4,0.7]
random_state=0, #随机数种子
n_features=2)#默认每个样本特征数为2
#x生成数据值,y生成数据对应的类别标签(0,1,2,3)
3.导入K-means模型:from sklearn.cluster import KMeans
4.构建模型: kmeans = KMeans(n_cluster=4)分为多少类/簇
5.kmeans.fit(x) y_kmeans=kmeans.predict(x)生成每个数据聚类后的类别值0,1,2,3
6.cen = kmeans.cluster_centers获取几个不同簇的中心点
总结:#K-means聚类样本数据需要知道本身有多少类(簇n_clusters)才能K-Means分析,便于以后回归或分类
5.随机算法:蒙特卡洛模拟
np.where(condition,xy,)当condition为true,返回x;否则返回y
1. π的计算-xy离中心点的距离是否下雨1,若小于就在园内,不小于在圆外:正方形面积4r方,圆面积πr平方,比值=4π;正方形随机点的数量/圆随机点的数量求出π
(1)np.random.uniform(min,max,n)最小值,最大值,随机个数均匀分布
(2)判断xy是否在正方形内还是圆内:计算xy的点和中心点(0,0)的距离是否小于1
d = np.sqrt((x-a)**2+(y-b)**2)
res = sum(np.where(d<r,1,0))
(3)#导入circle模块 from matplotlib.patches import Circle
circle = Circle(xy=(a,b),radius=r,alpha=0.5,color='gray') #xy圆心 radius半径
axes.add_patch(circle)
plt.grid(True,linestyle='--',linewidth='0.8')
2.积分问题:# 积分的计算:落到灰色领域多少个点 函数y=x的平方,所以只要值小于y=x的平方就可以
xi = np.linspace(0,1,100)
yi = xi**2
plt.plot(xi,yi,'--k')
plt.fill_between(xi,yi,0,color='gray',alpha=0.5,label='area') #填充图表
plt.grid()
3.上厕所问题