导入数据分析工具包
import numpy as np
import pandas as pd #用于数据分析
import matplotlib.pyplot as plt #可能是 Python 2D-绘图领域使用最广泛的套件。
#它能让使用者很轻松地将数据图形化,并且提供多样化的输出格式
import seaborn as sns #python中的一个可视化库,是对matplotlib进行二次封装而成
from scipy import stats
import warnings
warnings.filterwarnings("ignore") # 忽略警告
%matplotlib inline #有了%matplotlib inline 就可以省掉plt.show()了
matplotlib举例
import numpy as np
import matplotlib.pyplot as plt
X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C,S = np.cos(X), np.sin(X)
plt.plot(X,C)
plt.plot(X,S)
plt.show()
忽略警告详解
https://blog.csdn.net/TeFuirnever/article/details/94122670
数据读取
train_data_file = "./zhengqi_train.txt"
test_data_file = "./zhengqi_test.txt"
train_data = pd.read_csv(train_data_file, sep='\t', encoding='utf-8')
test_data = pd.read_csv(test_data_file, sep='\t', encoding='utf-8')
pycharn显示变量
勾选使用python控制台运行,重启pycharm,即可看到读取的数据
训练数据总览
train_data.describe()
统计值变量说明:
count:数量统计,此列共有多plt.boxplot函数少有效值
unipue:不同的值有多少个
std:标准差
min:最小值
25%:四分之一分位数
50%:二分之一分位数
75%:四分之三分位数
max:最大值
mean:均值
plt.figure(figsize=(18, 10))
plt.boxplot(x=train_data.values,labels=train_data.columns)
plt.hlines([-7.5, 7.5], 0, 40, colors='r')
plt.show()
plt.figure
plt.boxplot
箱型图,白圈为异常值,上下横线最大最小值,中间三个线从上到下依次为75、50、25percentile
异常值分析
plt.figure(figsize=(18, 10))
plt.boxplot(x=train_data.values,labels=train_data.columns)
plt.hlines([-7.5, 7.5], 0, 40, colors='r')
plt.show()
最大最小值归一化
from sklearn import preprocessing
features_columns = [col for col in train_data.columns if col not in ['target']]
min_max_scaler = preprocessing.MinMaxScaler()
min_max_scaler = min_max_scaler.fit(train_data[features_columns])
#先拟合fit,找到该part的整体指标,如均值、方差、最大值最小值等
train_data_scaler = min_max_scaler.transform(train_data[features_columns])
test_data_scaler = min_max_scaler.transform(test_data[features_columns])
#fit的基础上,进行标准化,降维,归一化等操作
train_data_scaler = pd.DataFrame(train_data_scaler)
train_data_scaler.columns = features_columns
test_data_scaler = pd.DataFrame(test_data_scaler)
test_data_scaler.columns = features_columns
train_data_scaler['target'] = train_data['target']
sklearn preprocessing
机器学习中的数据预处理(sklearn preprocessing) - 知乎 (zhihu.com)
sklearn.preprocessing.scale(X, axis=0, with_mean=True, with_std=True, copy=True)
- X:数组或者矩阵
- axis:int类型,初始值为0,axis用来计算均值和标准方差。如果是0,则单独的标准化每个特征(列),如果是1,则标准化每个观测样本(行)。
- with_mean:boolean类型,默认为True,表示将数据均值规范到0。
- with_std:boolean类型,默认为True,表示将数据方差规范到1。
MinMaxScaler 最小-最大规范化对原始数据进行线性变换,变换到[0,1]区间
使用的时候需要先.fit然后再.transform
pd.DataFrame()函数
data = {
'state':['Ohio','Ohio','Ohio','Nevada','Nevada'],
'year':[2000,2001,2002,2001,2002],
'pop':[1.5,1.7,3.6,2.4,2.9]
}
frame = pd.DataFrame(data)
frame
#输出
pop state year
0 1.5 Ohio 2000
1 1.7 Ohio 2001
2 3.6 Ohio 2002
3 2.4 Nevada 2001
4 2.9 Nevada 2002
查看训练集数据和测试集数据分布情况
dist_cols = 6
dist_rows = len(test_data_scaler.columns)
plt.figure(figsize=(4*dist_cols,4*dist_rows))
for i, col in enumerate(test_data_scaler.columns):
ax=plt.subplot(dist_rows,dist_cols,i+1)
ax = sns.kdeplot(train_data_scaler[col], color="Red", shade=True)
ax = sns.kdeplot(test_data_scaler[col], color="Blue", shade=True)
ax.set_xlabel(col)
ax.set_ylabel("Frequency")
ax = ax.legend(["train","test"])
plt.show()
enumerate() 函数
用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中
enumerate(sequence, [start=0])
- sequence -- 一个序列、迭代器或其他支持迭代对象。
- start -- 下标起始位置的值。
>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>> list(enumerate(seasons, start=1)) # 下标从 1 开始
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
sns.kdeplot() 核密度估计图
核密度估计是概率论上用来估计未知的密度函数,属于非参数检验,通过核密度估计图可以比较直观的看出样本数据本身的分布特征
查看特征'V5', 'V17', 'V28', 'V22', 'V11', 'V9'数据的数据分布
drop_col = 6
drop_row = 1
plt.figure(figsize=(5*drop_col,5*drop_row))
for i, col in enumerate(["V5","V9","V11","V17","V22","V28"]):
ax =plt.subplot(drop_row,drop_col,i+1)
ax = sns.kdeplot(train_data_scaler[col], color="Red", shade=True)
ax= sns.kdeplot(test_data_scaler[col], color="Blue", shade=True)
ax.set_xlabel(col)
ax.set_ylabel("Frequency")
ax = ax.legend(["train","test"])
plt.show()
特征相关性
plt.figure(figsize=(20, 16))
column = train_data_scaler.columns.tolist()
mcorr = train_data_scaler[column].corr(method="spearman")
mask = np.zeros_like(mcorr, dtype=np.bool)
mask[np.triu_indices_from(mask)] = True
cmap = sns.diverging_palette(220, 10, as_cmap=True)
g = sns.heatmap(mcorr, mask=mask, cmap=cmap, square=True, annot=True, fmt='0.2f')
plt.show()
.tolist()
将矩阵转换成列表
python tolist() - 知乎 (zhihu.com)
.corr相关系数函数
.corr
(method='pearson', min_periods=1)
method:可选值为{‘pearson’, ‘kendall’, ‘spearman’}
pearson:Pearson相关系数来衡量两个数据集合是否在一条线上面,即针对线性数据的相关系数计算,针对非线性数据便会有误差。
kendall:用于反映分类变量相关性的指标,即针对无序序列的相关系数,非正太分布的数据
spearman:非线性的,非正太分布的数据的相关系数
min_periods:样本最少的数据量
np.zeros_like(a)
生成一个和你所给数组a
相同shape
的全0
数组
numpy.triu(arr, k=0)
返回矩阵的上三角,此时下三角的元素全为0,k=0表示主对角线的位置,k=1表示主对角右移1,k=-1表示对角线左移1
np.triu_indices_from(arr, k=0)
即返回上三角矩阵的index(行列)
sns.heatmap()
mask的作用是屏蔽右上角的数据
特征降维
相关性分析
mcorr=mcorr.abs()
numerical_corr=mcorr[mcorr['target']>0.1]['target']
#只取target列>0.1的行,后面的['target']表示将'target'列
#满足前置要求的数据提取出来
print(numerical_corr.sort_values(ascending=False))
#升序排列
index0 = numerical_corr.sort_values(ascending=False).index
#将提取数据所属列,存放到index0中
print(train_data_scaler[index0].corr('spearman'))
.sort_values()排序函数
(by=‘##’,axis=0,ascending=True, inplace=False, na_position=‘last’)
index0:
相关性初筛
features_corr = numerical_corr.sort_values(ascending=False).reset_index()
features_corr.columns = ['features_and_target', 'corr']
features_corr_select = features_corr[features_corr['corr']>0.3] # 筛选出大于相关性大于0.3的特征
print(features_corr_select)
select_features = [col for col in features_corr_select['features_and_target'] if col not in ['target']]
new_train_data_corr_select = train_data_scaler[select_features+['target']]
new_test_data_corr_select = test_data_scaler[select_features]
.reset_index()
reset前 reset后
features_corr.columns
多重共线性分析
from statsmodels.stats.outliers_influence import variance_inflation_factor #多重共线性方差膨胀因子
#多重共线性
new_numerical=['V0', 'V2', 'V3', 'V4', 'V5', 'V6', 'V10','V11',
'V13', 'V15', 'V16', 'V18', 'V19', 'V20', 'V22','V24','V30', 'V31', 'V37']
X=np.matrix(train_data_scaler[new_numerical])
VIF_list=[variance_inflation_factor(X, i) for i in range(X.shape[1])]
#矩阵的列数
VIF_list
多重共线性
一看就懂的多重共线性 - 知乎 (zhihu.com)
np.matrix()创建矩阵
主成分分析(PCA)原理详解 - 知乎 (zhihu.com)PCA去除多重共线性 降维
from sklearn.decomposition import PCA #主成分分析法
#PCA方法降维
#保持90%的信息
pca = PCA(n_components=0.9)
new_train_pca_90 = pca.fit_transform(train_data_scaler.iloc[:,0:-1])
#使用iloc去掉了最后一列'target'
new_test_pca_90 = pca.transform(test_data_scaler)
new_train_pca_90 = pd.DataFrame(new_train_pca_90)
new_test_pca_90 = pd.DataFrame(new_test_pca_90)
new_train_pca_90['target'] = train_data_scaler['target']
#加入'target'列
new_train_pca_90.describe()
主成分分析(PCA)原理详解 - 知乎 (zhihu.com)
sklearn.decomposition.PCA(n_components=None, copy=True, whiten=False)
iloc[ ]函数
[a:b,c:d]取a到b行,c到d列
线性回归
导入相关库
from sklearn.linear_model import LinearRegression #线性回归
from sklearn.neighbors import KNeighborsRegressor #K近邻回归
from sklearn.tree import DecisionTreeRegressor #决策树回归
from sklearn.ensemble import RandomForestRegressor #随机森林回归
from sklearn.svm import SVR #支持向量回归
import lightgbm as lgb #lightGbm模型
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import train_test_split # 切分数据
from sklearn.metrics import mean_squared_error #评价指标
线性回归sklearn.linear_model.LinearRegression()
fit_intercept :(截距)默认为True,可选False
normalize :(标准化) 默认为True,可选False
copy_X :(复制X数据)默认为True,可选False。如果选False会覆盖原数
n_jobs :(计算性能)默认为1,可选int,工作使用的数量计算。
K近邻回归KNeighborsRegressor
n_neighbors:KNN中的k值,默认为5;
weights :用于标识每个样本的近邻样本的权重,可选择"uniform",“distance” 或自定义权重。默认"uniform",所有最近邻样本权重都一样。如果是"distance",则权重和距离成反比例;如果样本的分布是比较成簇的,即各类样本都在相对分开的簇中时,我们用默认的"uniform"就可以了,如果样本的分布比较乱,规律不好寻找,选择"distance"是一个比较好的选择;
algorithm :限定半径最近邻法使用的算法,可选‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’。
leaf_size :这个值控制了使用kd树或者球树时, 停止建子树的叶子节点数量的阈值。这个值越小,则生成的kc树或者球树就越大,层数越深,建树时间越长,反之,则生成的kd树或者球树会小,层数较浅,建树时间较短。默认是30。这个值一般依赖于样本的数量,随着样本数量的增加,这个值必须要增加,否则不光建树预测的时间长,还容易过拟合。可以通过交叉验证来选择一个适中的值。当然,如果使用的算法是蛮力实现,则这个参数可以忽略
metric,p :距离度量(前面介绍过),默认闵可夫斯基距离 “minkowski”(p=1为曼哈顿距离, p=2为欧式距离);
metric_params:距离度量其他附属参数(具体我也不知道,一般用得少);
n_jobs :并行处理任务数,主要用于多核CPU时的并行处理,加快建立KNN树和预测搜索的速度。n_jobs= -1,即所有的CPU核都参与计算。
切分训练数据和线下验证数据
#采用 pca 保留16维特征的数据
new_train_pca_16 = new_train_pca_16.fillna(0)
train = new_train_pca_16[new_test_pca_16.columns]
target = new_train_pca_16['target']
# 切分数据 训练数据80% 验证数据20%
train_data,test_data,train_target,test_target=train_test_split(train,target,test_size=0.2,random_state=0)
多元线性回归模型
clf = LinearRegression()
clf.fit(train_data, train_target)
score = mean_squared_error(test_target, clf.predict(test_data))
print("LinearRegression: ", score)
- SSE(和方差、误差平方和):The sum of squares due to error
- MSE(均方差、方差):Mean squared error
- RMSE(均方根、标准差):Root mean squared error
train_score = []
test_score = []
# 给予不同的数据量,查看模型的学习效果
for i in range(10, len(train_data)+1, 10):
lin_reg = LinearRegression()
lin_reg.fit(train_data[:i], train_target[:i])
#取train_data里的i行数据进行拟合
# LinearRegression().fit(X_train[:i], y_train[:i])
# 查看模型的预测情况:两种,模型基于训练数据集预测的情况(可以理解为模型拟合训练数据集的情况),模型基于测试数据集预测的情况
# 此处使用 lin_reg.predict(X_train[:i]),为训练模型的全部数据集
y_train_predict = lin_reg.predict(train_data[:i])
train_score.append(mean_squared_error(train_target[:i], y_train_predict))
#每循环一次就在train_score里面加入一个MSE
y_test_predict = lin_reg.predict(test_data)
test_score.append(mean_squared_error(test_target, y_test_predict))
#每循环一次就在test_score里面加入一个MSE
# np.sqrt(train_score):将列表 train_score 中的数开平方
plt.plot([i for i in range(1, len(train_score)+1)], train_score, label='train')
plt.plot([i for i in range(1, len(test_score)+1)], test_score, label='test')
# plt.legend():显示图例(如图形的 label);
plt.legend()
plt.show()
list.append(element)
向列表末尾追加元素
def plot_learning_curve(algo, X_train, X_test, y_train, y_test):
"""绘制学习曲线:只需要传入算法(或实例对象)、X_train、X_test、y_train、y_test"""
"""当使用该函数时传入算法,该算法的变量要进行实例化,
如:PolynomialRegression(degree=2),变量 degree 要进行实例化"""
train_score = []
test_score = []
for i in range(10, len(X_train)+1, 10):
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(train_score)+1)],
train_score, label="train")
plt.plot([i for i in range(1, len(test_score)+1)],
test_score, label="test")
plt.legend()
plt.show()
此段程序执行结果与使用LinearRegression()函数一样
K近邻回归
for i in range(3,20):
clf = KNeighborsRegressor(n_neighbors=i) # 最近三个
clf.fit(train_data, train_target)
score = mean_squared_error(test_target, clf.predict(test_data))
print("KNeighborsRegressor: ", score)
一文搞懂k近邻(k-NN)算法(一) - 知乎 (zhihu.com)
决策树回归
clf = DecisionTreeRegressor()
clf.fit(train_data, train_target)
score = mean_squared_error(test_target, clf.predict(test_data))
print("DecisionTreeRegressor: ", score)
随机森林回归
clf = RandomForestRegressor(n_estimators=200) # 200棵树模型
clf.fit(train_data, train_target)
score = mean_squared_error(test_target, clf.predict(test_data))
print("RandomForestRegressor: ", score)
随机森林回归算法在对数据维度要求相对较低(几十维),同时对准确性要求较高的场景下使用。例如,预测Twitter的某一话题的热度,可以使用随机森林回归模型来处理。模型的输入可以是话题的特征,比如话题在某时刻产生的讨论组数量、参与该话题讨论的人数和话题关注度等。模型的输出是平均每小时的活跃讨论组的数量,是一个正的浮点数,值越大热度越高。