tensorflow练习:鸢尾花种类预测,加州房价预测
Project description
# 说明文档
`iris.py`是鸢尾花预测模型
`cali_house.py`是加州房价预测模型
## 鸢尾花预测模型
### 1、数据处理
数据集包含150个数据集(其中120个是训练集`iris_training.csv`,30个是测试集`iris_test.csv`),分为3类(Setosa,Versicolour,Virginica),每类50个数据,每个数据包含4个属性:花萼长度,花萼宽度,花瓣长度,花瓣宽度。
120,4,setosa,versicolor,virginica
6.4,2.8,5.6,2.2,2
5.0,2.3,3.3,1.0,1
4.9,2.5,4.5,1.7,2
. . . . .
. . . . .
. . . . .
4.4,2.9,1.4,0.2,0
4.8,3.0,1.4,0.1,0
5.5,2.4,3.7,1.0,1
由于标签是鸢尾花的类别,因此将标签转换成独热编码[1, 0, 0], [0, 1, 0], [0, 0, 1]
### 2、建立模型
采用tensorflow建立一个简单的线性模型:
W = tf.Variable(tf.zeros([4, 3]))
b = tf.Variable(tf.zeros([3]) + 0.01)
output = tf.nn.softmax(tf.matmul(xs, W) + b)
输入通过一层网络后直接接入一个`softmax`函数后输出
损失函数为交叉熵:
loss = -tf.reduce_sum(ys * tf.log(output + 1e-10))
采用梯度下降法最小化`loss`,学习率设置为`0.001`:
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)
### 3、模型训练
模型建立好后,通过`tf.global_variables_initializer()`对变量进行初始化
模型总共训练1000次,每100次输出`loss`查看训练过程
for i in range(1000):
sess.run(train_step, feed_dict={xs: x_train, ys: y_train})
if i % 100 == 0:
print('Loss(train set):%.2f' % (sess.run(loss, feed_dict={xs: x_train, ys: y_train})))
### 4、鸢尾花种类预测
模型训练完毕之后,即可将测试集输入模型进行预测。由于预测结果是独热编码,所以准确率计算使用`tf.argmax()`函数来实现。返回值是预测结果中最大值的索引,由于独热编码的性质,返回的索引值即为类别。
然后使用`tf.equal()`判断是否与实际类别一致(返回值为bool型)。所以需要通过一个`tf.cast()`函数来转换为[0, 1]值,最后取平均值求出准确率。
access = tf.equal(tf.argmax(output, 1), tf.argmax(ys, 1))
accuracy = tf.reduce_mean(tf.cast(access, "float"))
### 5、结果
最后我们在训练集上以及测试集都得到一个较满意的结果
--------------------开始训练模型----------------
Loss(train set):125.14
Loss(train set):67.55
Loss(train set):30.55
Loss(train set):23.07
Loss(train set):20.45
Loss(train set):18.60
Loss(train set):17.22
Loss(train set):16.14
Loss(train set):15.28
Loss(train set):14.57
--------------------训练结束--------------------
********************性能评价********************
训练集准确率: 0.975
测试集准确率: 0.96666664
## 加州房价预测模型
### 1、数据预处理
加州房价的数据有20640个样本,特征值有9个,median_house_value作为输出结果。首先使用`describe()`来初步观察数据。
import pandas as pd
features = pd.read_csv('D:/tensorflow_exercise/data/housing.csv')
print(features.describe())
>>>
total_bedrooms population households median_income
count 20433 20640 20640 20640
mean 537.870553 1425.476744 499.539680 3.870671
std 421.385070 1132.462122 382.329753 1.899822
min 1.000000 3.000000 1.000000 0.499900
以上只展示了部分统计数据,不过可以看到`total_bedrooms`有一部分缺省值,因此我们删去有缺省值的数据。考虑到可能会有重复的数据,所以还需要去掉重复的样本。
nan = features.dropna(subset=['total_bedrooms'], axis=0) # 去除缺省值
repeat = nan.drop_duplicates() # 去掉重复值样本
### 2、特征工程
在`housing.csv`里面,前面两个特征是经度(longitude)和纬度(latitude),属于数值型特征。离散的经度纬度对于房价预测似乎没什么重要信息,因此我们对经度纬度进行分箱并合并为独热编码。
我们可以看看之前的统计信息:
longitude latitude
count 20640 20640
mean -119.569704 35.631861
std 2.003532 2.135952
min -124.350000 32.540000
max -114.310000 41.950000
可以知道经度的范围大概在(-124.35, -114.31)之间,纬度的范围大概在(32.54, 41.95)之间。我们以1°为区间分别对经度和纬度进行分箱。
pd.cut(longitude, range(-125, -112), right=False)
pd.cut(latitude, range(31, 43), right=False)
然而单独考虑经度或是纬度都没有太大的意义,因此我们将这两个特征交叉组合成一个特征,这个特征仍采用独热编码,它的长度为132。
在这些特征中,`ocean_proximity`是字符型特征:NEAR BAY, NEAR OCEAN, ISLAND, INLAND, <1H OCEAN。因此通过`get_dummies()`将其转换为独热编码。
再者,对于`total_rooms`,`population`我们可以用人均房间数`rooms_per_person`来表达他们之间的关系,通过简单的运算即可求出:
def rooms_per_person(data): # 合成新特征:人均房间数 = 总房间数 / 总人数
rooms_per_person = data.apply(lambda x: x['total_rooms'] / x['population'], axis=1) # 计算特征值
rooms_per_person[np.abs(rooms_per_person) > 5] = 5 # 对异常值进行截断处理
rooms_per_person = rooms_per_person.rename('rooms_per_person') # 特征名称
return rooms_per_person
计算新特征之后我们重新进行统计,发现有些特征值不合常理,因此对于新特征做截断处理,把人均房间数限制在(0, 5)之间。
### 3、特征值归一化
再来观察数据情况:
households median_income
count 20640 20640
mean 499.539680 3.870671
std 382.329753 1.899822
min 1.000000 0.499900
25% 280.000000 2.563400
50% 409.000000 3.534800
75% 605.000000 4.743250
max 6082.000000 15.000100
可以看到对于不同特征,他们的值可能差别会非常大,如果直接建立模型,可能造成模型在数值大的特征上投入更多精力,会造成结果偏拟合。
因此需要对特征进行归一化:
normalized = (value - mean) / std
### 4、建立模型
同样采用线性层:
W = tf.Variable(tf.zeros([142, 1]))
b = tf.Variable(tf.zeros([1]) + 0.01)
output = tf.matmul(xs, W) + b
损失函数用平方误差:
loss = tf.reduce_mean(tf.square(ys - output))
梯度下降法(learning rate = 0.003)最小化损失函数:
train_step = tf.train.GradientDescentOptimizer(0.003).minimize(loss)
### 5、训练模型
进行特征工程之后,得到一个更为精炼的数据集,将数据集随机划分为训练集和测试集:
from sklearn.model_selection import train_test_split
data = np.array(pd.read_csv('D:/tensorflow_exercise/data/housing_features.csv'))
x_train, x_test, y_train, y_test = train_test_split(data[:, :-1], data[:, -1], test_size=0.25, random_state=2018)
划分比例为3:1,得到的训练集有15325个样本,测试集有5108个样本。
训练次数20000次,每1000次输出误差:
for i in range(20000):
sess.run(train_step, feed_dict={xs: x_train, ys: y_train})
if i % 1000 == 0:
print('Loss(train set):%.2f' % (sess.run(loss, feed_dict={xs: x_train, ys: y_train})))
### 6、房价预测
最终的训练结果:`Loss(train set):0.32`
将训练集输入模型,得到预测结果,通过真实-预测关系图来反应模型的性能,同时得到`Loss(test set):0.31`
![result](house_value_prediction.PNG)
`iris.py`是鸢尾花预测模型
`cali_house.py`是加州房价预测模型
## 鸢尾花预测模型
### 1、数据处理
数据集包含150个数据集(其中120个是训练集`iris_training.csv`,30个是测试集`iris_test.csv`),分为3类(Setosa,Versicolour,Virginica),每类50个数据,每个数据包含4个属性:花萼长度,花萼宽度,花瓣长度,花瓣宽度。
120,4,setosa,versicolor,virginica
6.4,2.8,5.6,2.2,2
5.0,2.3,3.3,1.0,1
4.9,2.5,4.5,1.7,2
. . . . .
. . . . .
. . . . .
4.4,2.9,1.4,0.2,0
4.8,3.0,1.4,0.1,0
5.5,2.4,3.7,1.0,1
由于标签是鸢尾花的类别,因此将标签转换成独热编码[1, 0, 0], [0, 1, 0], [0, 0, 1]
### 2、建立模型
采用tensorflow建立一个简单的线性模型:
W = tf.Variable(tf.zeros([4, 3]))
b = tf.Variable(tf.zeros([3]) + 0.01)
output = tf.nn.softmax(tf.matmul(xs, W) + b)
输入通过一层网络后直接接入一个`softmax`函数后输出
损失函数为交叉熵:
loss = -tf.reduce_sum(ys * tf.log(output + 1e-10))
采用梯度下降法最小化`loss`,学习率设置为`0.001`:
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)
### 3、模型训练
模型建立好后,通过`tf.global_variables_initializer()`对变量进行初始化
模型总共训练1000次,每100次输出`loss`查看训练过程
for i in range(1000):
sess.run(train_step, feed_dict={xs: x_train, ys: y_train})
if i % 100 == 0:
print('Loss(train set):%.2f' % (sess.run(loss, feed_dict={xs: x_train, ys: y_train})))
### 4、鸢尾花种类预测
模型训练完毕之后,即可将测试集输入模型进行预测。由于预测结果是独热编码,所以准确率计算使用`tf.argmax()`函数来实现。返回值是预测结果中最大值的索引,由于独热编码的性质,返回的索引值即为类别。
然后使用`tf.equal()`判断是否与实际类别一致(返回值为bool型)。所以需要通过一个`tf.cast()`函数来转换为[0, 1]值,最后取平均值求出准确率。
access = tf.equal(tf.argmax(output, 1), tf.argmax(ys, 1))
accuracy = tf.reduce_mean(tf.cast(access, "float"))
### 5、结果
最后我们在训练集上以及测试集都得到一个较满意的结果
--------------------开始训练模型----------------
Loss(train set):125.14
Loss(train set):67.55
Loss(train set):30.55
Loss(train set):23.07
Loss(train set):20.45
Loss(train set):18.60
Loss(train set):17.22
Loss(train set):16.14
Loss(train set):15.28
Loss(train set):14.57
--------------------训练结束--------------------
********************性能评价********************
训练集准确率: 0.975
测试集准确率: 0.96666664
## 加州房价预测模型
### 1、数据预处理
加州房价的数据有20640个样本,特征值有9个,median_house_value作为输出结果。首先使用`describe()`来初步观察数据。
import pandas as pd
features = pd.read_csv('D:/tensorflow_exercise/data/housing.csv')
print(features.describe())
>>>
total_bedrooms population households median_income
count 20433 20640 20640 20640
mean 537.870553 1425.476744 499.539680 3.870671
std 421.385070 1132.462122 382.329753 1.899822
min 1.000000 3.000000 1.000000 0.499900
以上只展示了部分统计数据,不过可以看到`total_bedrooms`有一部分缺省值,因此我们删去有缺省值的数据。考虑到可能会有重复的数据,所以还需要去掉重复的样本。
nan = features.dropna(subset=['total_bedrooms'], axis=0) # 去除缺省值
repeat = nan.drop_duplicates() # 去掉重复值样本
### 2、特征工程
在`housing.csv`里面,前面两个特征是经度(longitude)和纬度(latitude),属于数值型特征。离散的经度纬度对于房价预测似乎没什么重要信息,因此我们对经度纬度进行分箱并合并为独热编码。
我们可以看看之前的统计信息:
longitude latitude
count 20640 20640
mean -119.569704 35.631861
std 2.003532 2.135952
min -124.350000 32.540000
max -114.310000 41.950000
可以知道经度的范围大概在(-124.35, -114.31)之间,纬度的范围大概在(32.54, 41.95)之间。我们以1°为区间分别对经度和纬度进行分箱。
pd.cut(longitude, range(-125, -112), right=False)
pd.cut(latitude, range(31, 43), right=False)
然而单独考虑经度或是纬度都没有太大的意义,因此我们将这两个特征交叉组合成一个特征,这个特征仍采用独热编码,它的长度为132。
在这些特征中,`ocean_proximity`是字符型特征:NEAR BAY, NEAR OCEAN, ISLAND, INLAND, <1H OCEAN。因此通过`get_dummies()`将其转换为独热编码。
再者,对于`total_rooms`,`population`我们可以用人均房间数`rooms_per_person`来表达他们之间的关系,通过简单的运算即可求出:
def rooms_per_person(data): # 合成新特征:人均房间数 = 总房间数 / 总人数
rooms_per_person = data.apply(lambda x: x['total_rooms'] / x['population'], axis=1) # 计算特征值
rooms_per_person[np.abs(rooms_per_person) > 5] = 5 # 对异常值进行截断处理
rooms_per_person = rooms_per_person.rename('rooms_per_person') # 特征名称
return rooms_per_person
计算新特征之后我们重新进行统计,发现有些特征值不合常理,因此对于新特征做截断处理,把人均房间数限制在(0, 5)之间。
### 3、特征值归一化
再来观察数据情况:
households median_income
count 20640 20640
mean 499.539680 3.870671
std 382.329753 1.899822
min 1.000000 0.499900
25% 280.000000 2.563400
50% 409.000000 3.534800
75% 605.000000 4.743250
max 6082.000000 15.000100
可以看到对于不同特征,他们的值可能差别会非常大,如果直接建立模型,可能造成模型在数值大的特征上投入更多精力,会造成结果偏拟合。
因此需要对特征进行归一化:
normalized = (value - mean) / std
### 4、建立模型
同样采用线性层:
W = tf.Variable(tf.zeros([142, 1]))
b = tf.Variable(tf.zeros([1]) + 0.01)
output = tf.matmul(xs, W) + b
损失函数用平方误差:
loss = tf.reduce_mean(tf.square(ys - output))
梯度下降法(learning rate = 0.003)最小化损失函数:
train_step = tf.train.GradientDescentOptimizer(0.003).minimize(loss)
### 5、训练模型
进行特征工程之后,得到一个更为精炼的数据集,将数据集随机划分为训练集和测试集:
from sklearn.model_selection import train_test_split
data = np.array(pd.read_csv('D:/tensorflow_exercise/data/housing_features.csv'))
x_train, x_test, y_train, y_test = train_test_split(data[:, :-1], data[:, -1], test_size=0.25, random_state=2018)
划分比例为3:1,得到的训练集有15325个样本,测试集有5108个样本。
训练次数20000次,每1000次输出误差:
for i in range(20000):
sess.run(train_step, feed_dict={xs: x_train, ys: y_train})
if i % 1000 == 0:
print('Loss(train set):%.2f' % (sess.run(loss, feed_dict={xs: x_train, ys: y_train})))
### 6、房价预测
最终的训练结果:`Loss(train set):0.32`
将训练集输入模型,得到预测结果,通过真实-预测关系图来反应模型的性能,同时得到`Loss(test set):0.31`
![result](house_value_prediction.PNG)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
tensorflow-exercise-hx-1.0.1.tar.gz
(408.1 kB
view hashes)
Close
Hashes for tensorflow-exercise-hx-1.0.1.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7c50b25464c0006c94f573a68007e5747b61f0f110d98380d336fcc0ba3f03ae |
|
MD5 | d8728aac188e152605c93b108d9e03ed |
|
BLAKE2b-256 | 048e6457a54e1ff771c066827629c477591a743795ebc7e3524e68279e1e03dc |