社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  机器学习算法

机器学习之pandas的数据处理

衡阳信安 • 2 年前 • 261 次点击  

Abstract

在昨天的初步接触ML以后,我们实现了一个简单的线性模型,它可以做到简单地去拟合一根直线,但是这个直线远远不够,所以从这次开始,我们开始接触更广泛的回归模型并且可视化数据,同时,我们这节还需要学习数据处理,主要是基于pandas的数据处理

Asking the right question of your data

这次我们的数据不再使用之前的糖尿病数据,而是使用美国农协会的某一年的南瓜数据,包括了南瓜产地、日期、价格等等数据,我们需要使用这些数据去预测未来的价格

ML-For-Beginners/US-pumpkins.csv at main · microsoft/ML-For-Beginners (github.com)

Exercise - analyze the pumpkins data

使用pandas这个库来读取excel的数据,这个库其实挺简单的,就是提供了数据表格到python的接口

import pandas as pd

fp = str(pathlib.Path(__file__).parent.resolve())

pumpkins = pd.read_csv(fp + '/US-pumpkins.csv')
frame = pumpkins.head()

我们会输出frame会得到这个表格的前5行数据,展示出来大概如下


接下来,我们想一想价格和日期的关系,很容易就能猜到,其实和年份的关系没有那么多,排除掉如洪涝之类的因素,月份应该才是关键,所以现在我们需要对数据进行预处理,在原始数据中添加月份数据

pumpkins['Month'] = pumpkins.apply(lambda x : x['Date'].split('/')[0], axis=1)

接着,现在的列太多了,我们只需要其中的一部分,比如说价格、最高价、最低价、日期之类的,所以,接着我们过滤出需要的那一部分

import pathlib
import pandas as pd

fp = str(pathlib.Path(__file__).parent.resolve())

pumpkins = pd.read_csv(fp + '/US-pumpkins.csv')

pumpkins['Month'] = pumpkins.apply(lambda x : x['Date'].split('/')[0], axis=1)

selected_columns = ['Package''Month''Low Price''High Price''Date']

pumpkins = pumpkins.drop([i for i in pumpkins.columns if i not in selected_columns], axis=1)

print(pumpkins)

接着,我们只有一个最高价和最低价,并没有实际的价格,所以我们需要预估一下当月的平均价格,这个就简单使用取个中间值吧

pumpkins['Price'] = pumpkins.apply(lambda x : (x['Low Price'] + x['High Price']) / 2, axis=1)

然后就是吧,还有一堆的坑,比如说这个数据表格它的单位还不一样,有的是按个算,有的是按盒算,还有的是按半个算。。所以还需要接着处理数据,其实就是统一单位

pumpkins = pumpkins[pumpkins['Package'].str.contains('bushel', case=True, regex=True)]
pumpkins['Price'] = pumpkins.apply(lambda x : (x['Low Price'] + x['High Price']) / 2, axis=1)

pumpkins.loc[pumpkins['Package'].str.contains('1 1/9'), 'Price'] = pumpkins['Price']/(1 + 1/9)
pumpkins.loc[pumpkins['Package'].str.contains('1/2'), 'Price'] = pumpkins['Price']/(1/2)

搞了这么多,终于可以开始尝试训练模型了,首先还是展示数据,我们有很多年的数据,我们需要把每一年的数据的各个月加起来算平均值,也就是,按月份分组,完成了以后再打印出来

statistics = pumpkins.groupby(['Month'])['Price'].mean().plot(kind='bar')
plt.ylabel('Mean Price')
plt.show()


唯一的缺点就是月份没好好排(改一哈上面的代码就行了,全部的代码如下

import pathlib
import pandas as pd
from matplotlib import pyplot as plt

fp = str(pathlib.Path(__file__).parent.resolve())

pumpkins = pd.read_csv(fp + '/US-pumpkins.csv')
pumpkins = pumpkins[pumpkins['Package'].str.contains('bushel', case=True, regex=True)]


pumpkins['Month'] = pumpkins.apply(lambda x : int(x['Date'].split('/')[0]), axis=1)
selected_columns = ['Package''Month''Low Price''High Price''Date']
pumpkins = pumpkins.drop([i for i in pumpkins.columns if i not in selected_columns], axis=1)

pumpkins['Price'] = pumpkins.apply(lambda x : (x['Low Price'] + x['High Price']) / 2, axis=1)
pumpkins.loc[pumpkins['Package'].str.contains('1 1/9'), 'Price'] = pumpkins['Price']/(1 + 1/9)
pumpkins.loc[pumpkins['Package'].str.contains('1/2'), 'Price'] = pumpkins['Price']/( 1/2)

statistics = pumpkins.groupby(['Month'])['Price'].mean().plot(kind='bar')
plt.ylabel('Mean Price')
plt.show()

除了月份,我们还可以看看以年为单位的某一天,其也可以一定程度展示这些关系


代码上的区别也就是改了一点

def parse(x):
    dts = [int(c) for c in x.split('/')]
    dt = datetime(dts[2], dts[0], dts[1]).timetuple().tm_yday
    return dt

pumpkins['Day'] = pumpkins.apply(lambda x : parse(x=x['Date']), axis=1)

不难看出,年末的时候南瓜价格确实比较低,但是!我们需要注意一点,南瓜的种类对南瓜的价格也有很大的影响,所以最好,我们需要把南瓜的种类分个组如下


发现啊,MINIATURE这种类型的南瓜最贵,PIE TYPE最便宜

colors = ['red''blue''yellow''green']

ax = None
for i, v in enumerate(pumpkins['Variety'].unique()):
    df = pumpkins[pumpkins['Variety'] == v]
    ax = df.plot.scatter('Day''Price', ax = ax, label=v, c=colors[i])

plt.show()

上面搞了那么多,现在终于可以开始尝试做计算和预测了,上面其实更多都是做预处理,没有做什么实质上的工作

首先,如果要训练模型,那么首先需要的就是得到x和y(现在还是线性模型,且只考虑单个变量)

那么,分离出时间和价格,同时注意,我们只训练包含PIE TYPE的南瓜!

pie_pumpkins = pumpkins[pumpkins['Variety'] == 'PIE TYPE']

x = pie_pumpkins['Day'].to_numpy().reshape(-11)
y = pie_pumpkins['Price']

虽然还是很迷惑,pandas的DateFrame类重载了[]操作,实现了这样简便的过滤器,确实厉害,和z3很类似,下一步我们知道了,就是创建训练集和测试集,并简单画一下看看

x_train, x_test, y_train, y_test = model_selection.train_test_split(x, y, test_size=0.2, random_state=0)

line_reg = linear_model.LinearRegression()
line_reg.fit(x_train, y_train)

line_pred = line_reg.predict(x_test)

plt.scatter(x_test, y_test)
plt.scatter(x_train, y_train, color='yellow' )
plt.plot(x_test, line_pred, color='red')

plt.show()

黄色是训练集,蓝色是测试集,我们思考一样,这玩意,它符合线性模型吗????不适合吧,倒不如说,应该是有其他因素的影响(非种类和日期)所以还是有这么大的差异,我们先不管这个影响,试着使用其他的模型,如多项式模型来测试一下

不过我们需要知道的,多项式模型还是可以用线性模型,其基本公式如下

就算是存在如x的平方之类的因素,我们也可以给它简化成

然后sklearn提供的就是pipeline这个东西,我们可以创建一个从PolynomialFeatures到LinearRegression的模型,我们只需要输入一个线性的数据集(这么说可能不太对)就可以得到相应的多维的数据模型,简单说一下就是

我们输入的关系是

其中X和Y满足

然后经过PolynomialFeatures的处理以后(现在假设为二维),这个关系就可以变成

然后x和y存在一个关系,我们可以使用这个线性模型来预测数据,有一说一看到这里的时候我也是挺懵逼的,不过我懵逼的是,这个具体怎么算,不过先不管这个,这个是已经实现好了的

pipeline = make_pipeline(PolynomialFeatures(2), linear_model.LinearRegression())
pipeline.fit(x_train, y_train)

pred = pipeline.predict(x_test)

plt.scatter(x_test, y_test, color='blue')
plt.plot(x_test, pred, color='red')

接下来,我们思考一下如何判断我们模型的优劣?这里需要提到两个判据,一个是方差,这个我们很熟悉了,另一个是决定系数(?

先看看方差吧

然后我们需要计算他们的百分比来更好地展示它

很明显,但这个值越接近0的时候,模型的效果越好

另外一个是决定系数,这玩意的定义如下

R就是决定系数,我们仔细观察会发现 SS_res是预测值偏差,而 SS_tot 是方差,那也就是,若R越接近1,则yi越接近fi,代表模型效果越好,而若R接近0,则说明偏差越大,而我们上面那个模型的R很小,也就是效果很烂,这其实也正常,可以理解,毕竟维度太少了

最后一步,我们需要尝试多维度,把各个维度的影响都加进来,其实这个线性模型就已经帮我们实现了,毕竟线性模型的表达式如下

是可以包含多个x的,只需要给x加上一点数据就可以了,同时,将按日分组换位按月分组

def parse(x):
    dts = [int(c) for c in x.split('/')]
    dt = datetime(dts[2], dts[0], dts[1]).timetuple().tm_mon
    return dt

pumpkins['Month'] = pumpkins.apply(lambda x : parse(x=x['Date']), axis=1)
selected_columns = ['Package''Month''Low Price''High Price''Date''Variety''City Name']
pumpkins = pumpkins.drop([i for i in pumpkins.columns if i not in selected_columns], axis=1)

pumpkins['Price'] = pumpkins.apply(lambda x : (x['Low Price'] + x['High Price']) / 2, axis=1)
pumpkins.loc[pumpkins['Package'].str.contains('1 1/9'), 'Price'] = pumpkins['Price']/(1 + 1/9)
pumpkins.loc[pumpkins['Package'].str.contains('1/2'), 'Price'] = pumpkins['Price']/(1/2)

x = pd.get_dummies(pumpkins['Variety']) \
        .join(pumpkins['Month']) \
        .join(pd.get_dummies(pumpkins['City Name'])) \
        .join(pd.get_dummies(pumpkins['Package']))
y = pumpkins['Price']

接下来,训练模型并预测结果

x_train, x_test, y_train, y_test = model_selection.train_test_split(x, y, test_size=0.2, random_state=0)

line_reg = linear_model.LinearRegression()
line_reg.fit(x_train, y_train)

pred = line_reg.predict(x_test)

最后一步,测试决定系数和方差

score = line_reg.score(x_train, y_train)
mse = np.sqrt(mean_squared_error(y_test, pred)) / np.mean(pred)
print(score)
print(mse)

ok,其中,决定系数为0.94,挺高的,喜欢,mse为0.105,挺低的,喜欢,那么就说明我们这个模型还不错~,当然,还可以更高,使用非线性的多项式模型,仅用2维的多项式模型就可以做到决定系数0.97,mse 0.0825

来自团队学习笔记

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/151750
 
261 次点击