day10 knn 线性回归 手写数字识别 分类预测

day10 数据分析

线性回归例子

城市气候与海洋的关系研究

import numpy as np
import pandas as pd
from pandas import DataFrame,Series
import matplotlib.pyplot as plt 
%matplotlib inline  

导入数据各个海滨城市数据

ferrara1 = pd.read_csv('./ferrara_150715.csv')
ferrara2 = pd.read_csv('./ferrara_250715.csv')
ferrara3 = pd.read_csv('./ferrara_270615.csv')
ferrara = pd.concat([ferrara1,ferrara2,ferrara3],ignore_index=True)
ferrara			# 级联 因为属性相同

torino1 = pd.read_csv('./torino_150715.csv')
torino2 = pd.read_csv('./torino_250715.csv')
torino3 = pd.read_csv('./torino_270615.csv')
torino = pd.concat([torino1,torino2,torino3],ignore_index=True) 
.....

数据:1565768816308

faenza.dtypes(多了一列,级联之后需要删除)

Unnamed: 0       int64
temp           float64
humidity         int64
pressure         int64
description     object
dt               int64
wind_speed     float64

加入列表删

citys = [ferrara,torino,mantova,milano,ravenna,asti,bologna,piacenza,cesena,faenza]

for city in citys :
city.drop('Unnamed: 0',axis=1,inplace=True)

1

显示最高温度于离海远近的关系

(观察多个城市)

#获取所有城市中的最高温度数据值
max_temp = []
for city in citys:
    max_temp.append(city['temp'].max())

max_temp

[33.43000000000001,
 34.69,
 34.18000000000001,
 34.81,....

获取所有城市距离海洋的距离数据值

city_dist = []
for city in citys:
city_dist.append(city['dist'].max())

[47, 357, 121, 250, 8, 315, 71, 200, 14, 37]

自变量距离 , 因变量温度

plt.scatter(city_dist, max_temp) # 绘图

1565768952007

2

观察发现,离海近的可以形成一条直线,离海远的也能形成一条直线。

- 分别以100公里和50公里为分界点,划分为离海近和离海远的两组数据(近海:小于100  远海:大于50)

经过分析不可以使用groupby进行分组,必须使用条件判断(表达式)进行分组

s_city_dist = Series(data=city_dist) #所有的城市距离
s_city_dist

近海城市的判断条件

near_condition = s_city_dist<100
near_condition

near_dist = s_city_dist[near_condition]
print(near_dist)

获取近海城市最高温度

s_max_temp = Series(data=max_temp) #所有的最高温度
near_temp = s_max_temp[near_condition]
near_temp

绘制近海距离和温度的关系

plt.scatter(near_dist,near_temp,c='r')

plt.scatter(near_dist,near_temp)

1565769065588

远海也是

获取远海城市的温度和距离的数据值

制定判定远海城市的条件

far_condition = s_city_dist > 50
far_dist = s_city_dist[far_condition]

获取远海城市的最高温度

far_temp = s_max_temp[far_condition]
far_temp

将近海远海的温度和距离关系的散点图绘制到一个散点图中进行显示

plt.scatter(near_dist,near_temp,c='r')
plt.scatter(far_dist,far_temp,c='y',s=100) # 颜色大小

1565769106341

1565769112785

将远海城市的温度和距离关系的散点图进行线性回归
# 导包
from sklearn.linear_model import LinearRegression
# 1 . 创建一个算法模型对象
linear_far = LinearRegression()
linear_near = LinearRegression()
# 2 .将散点(样本)数据代入到算法模型中, 让算法模型去根据数据的特性进行线性回归(计算)
# fit 函数的参数 : X,y
# X : 样本数据中的特征数据(features)  二维
# y : 样本数据中的目标数据(target)

# 针对当前项目来讲: 散点图中的一个点标识的数据即为一个样本数据
# 样本集: 多个样本数据组成一个样本集

# 特征数据的改变会影响目标数据的改变,距离就是特征数据,温度就是目标数据

# 注意: 特征数据必须是一个二维数据
linear_far.fit(far_dist.reshape(-1,1),far_temp)

--->LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)

预测

linear_far.predict(200)

array([34.24476188])
将回归曲线画出

(足够多的点形成一条线)

生成三百个散点

设置300 个散点的轴坐标

xmin = far_dist.min()-20
xmax = far_dist.max()+20
x = np.linspace(xmin, xmax, 300)

predict 参数必须为样本集中的特征数据(二维) # x对应的预测的值 , 距离点最近的

y = linear_far.predict(x.reshape(-1,1))

plt.scatter(x,y,s=10)
plt.scatter(far_dist,far_temp,c='r',s=30)

1565769232430

将近海城市的温度和距离关系进行线性回归

plt.scatter(near_dist,near_temp,c='y',s=80)

linear_near.fit(near_dist.reshape(-1,1),near_temp)
_xmin = near_dist.min()-20
_xmax = near_dist.max()+20
_x = np.linspace(_xmin, _xmax, 300)
_y = linear_near.predict(_x.reshape(-1,1))
plt.scatter(_x,_y,s=10)
plt.scatter(near_dist,near_temp,c='y',s=80)

1565769309566

plt.xlabel('dist')
plt.ylabel('temp')
plt.title('temp&title')
plt.scatter(_x,_y,s=10)
plt.scatter(near_dist,near_temp,c='y',s=80)
plt.scatter(x,y,s=10)
plt.scatter(far_dist,far_temp,c='r',s=30)

1565769324922 机器学习

- 机器学习和AI(人工智能)之间的关联是什么?
    - 机器学习是实现人工智能的一种技术手段
- 算法模型:
    - 特殊的对象。对象内部封装了一个还没有求出解的方程(算法)。
    - 作用:
        - 预测:预测出一个未知的值
        - 分类:将一个未知的事物归到已知的分类中
        - 预测或者分类的结果就是模型对象方程的解
- 样本数据:
    - 组成部分:
        - 特征数据:自变量
        - 目标数据:因变量
    - 样本数据和算法模型对象之间的关联?
        - 可以将样本数据带入到算法模型中,对其内部的方程进行求解操作。一旦模型对象有解了,那么就可以实现分类或者预测的功能。
    - 训练模型:将样本数据带入到算法模型,让其模型对象有解。
    
- 算法模型的分类:
    - 有监督学习:如果算法模型需要的样本数据必须要包含特征数据和目标数据
    - 无监督学习:如果算法模型需要的样本数据只包含特征数据即可
- sklearn模块展开学习
    - 封装好了多种不同的算法模型
    
面积  楼层  采光率  售价
100   3    34%    80w
80   6    89%    100w
导入sklearn,建立线性回归算法模型对象

提取样本

feature = city_dist #列表形式的特征数据
target = city_max_temp #列表形式的目标数据

feature = np.array(feature) #np形式的特征数据
target = np.array(target) #np形式的目标数据

feature.shape

(10,)
from sklearn.linear_model import LinearRegression
#实例化算法模型对象
linner = LinearRegression() # y = wx + b
#训练模型
#X:二维的特征数据
#y:目标数据
linner.fit(feature.reshape((-1,1)),target)
#预测
linner.predict([[175],[201]])

---->array([33.87226813, 34.01981272])

样本集:用于对机器学习算法模型对象进行训练。样本集通常为一个DataFrame。
    - 特征数据:特征数据的变化会影响目标数据的变化。通常为多列。
    - 目标数据:结果。通常为一列。

将远海城市的数据带入到散点图中进行展示,并且进行线性回归

x = np.linspace(0,360,num=100)
y = linner.predict(x.reshape(-1,1))

plt.scatter(city_dist,city_max_temp)
plt.scatter(x,y)
plt.xlabel('距离')
plt.ylabel('最高温度')
plt.title('距离和最高温度之间的关系')

1565769596462

知识点总结:

plt.scatter(city_dist, max_temp)  # 绘图

from sklearn.linear_model import LinearRegression
创建一个算法模型对象
linear_far = LinearRegression()

注意: 特征数据必须是一个二维数据
linear_far.fit(far_dist.reshape(-1,1),far_temp)
linear_far.predict(200)

K-近邻算法(KNN)

如何进行电影分类

众所周知,电影可以按照题材分类,然而题材本身是如何定义的?由谁来判定某部电影属于哪
个题材?也就是说同一题材的电影具有哪些公共特征?这些都是在进行电影分类时必须要考虑的问
题。没有哪个电影人会说自己制作的电影和以前的某部电影类似,但我们确实知道每部电影在风格
上的确有可能会和同题材的电影相近。那么动作片具有哪些共有特征,使得动作片之间非常类似,
而与爱情片存在着明显的差别呢?动作片中也会存在接吻镜头,爱情片中也会存在打斗场景,我们
不能单纯依靠是否存在打斗或者亲吻来判断影片的类型。但是爱情片中的亲吻镜头更多,动作片中
的打斗场景也更频繁,基于此类场景在某部电影中出现的次数可以用来进行电影分类。

本章介绍第一个机器学习算法:K-近邻算法,它非常有效而且易于掌握。

1、k-近邻算法原理

简单地说,K-近邻算法采用测量不同特征值之间的距离方法进行分类。

  • 优点:精度高(计算距离)、对异常值不敏感(单纯根据距离进行分类,会忽略特殊情况)、无数据输入假定(不会对数据预先进行判定)。
  • 缺点:时间复杂度高、空间复杂度高。
  • 适用数据范围:数值型和标称型。

工作原理

存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据
与所属分类的对应关系。输人没有标签的新数据后,将新数据的每个特征与样本集中数据对应的
特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们
只选择样本数据集中前K个最相似的数据,这就是K-近邻算法中K的出处,通常K是不大于20的整数。
最后 ,选择K个最相似数据中出现次数最多的分类,作为新数据的分类

回到前面电影分类的例子,使用K-近邻算法分类爱情片和动作片。有人曾经统计过很多电影的打斗镜头和接吻镜头,下图显示了6部电影的打斗和接吻次数。假如有一部未看过的电影,如何确定它是爱情片还是动作片呢?我们可以使用K-近邻算法来解决这个问题。

1565773360592

首先我们需要知道这个未知电影存在多少个打斗镜头和接吻镜头,上图中问号位置是该未知电影出现的镜头数图形化展示,具体数字参见下表。

1565773370861

即使不知道未知电影属于哪种类型,我们也可以通过某种方法计算出来。首先计算未知电影与样本集中其他电影的距离,如图所示。1565773384459

现在我们得到了样本集中所有电影与未知电影的距离,按照距离递增排序,可以找到K个距 离最近的电影。假定k=3,则三个最靠近的电影依次是California Man、He's Not Really into Dudes、Beautiful Woman。K-近邻算法按照距离最近的三部电影的类型,决定未知电影的类型,而这三部电影全是爱情片,因此我们判定未知电影是爱情片。

欧几里得距离(Euclidean Distance)

欧氏距离是最常见的距离度量,衡量的是多维空间中各个点之间的绝对距离。公式如下:

可以处理多维的1565773423353

2、在scikit-learn库中使用k-近邻算法

  • 分类问题:from sklearn.neighbors import KNeighborsClassifier

0)一个最简单的例子

1.对电影进行分类

import pandas as pd
import numpy as np

data = pd.read_excel('./my_films.xlsx')
data

1565773490231

#样本数据的提取
feature = data[['Action lens','Love lens']]
target = data['target']

print(feature, target)

from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(feature,target)
knn.predict([[19,19]])

---->array(['Love'], dtype=object)

一种简单的方法确定k的值

knn.score(feature,target)

----->0.9166666666666666

2、预测年收入是否大于50K美元

df = pd.read_csv('./adults.txt')
df.head()
df

1565773622945

1565773635985

变量很多

但是和工资目标特征有关的可能是age occupation education_num hours_per_week() 相关

获取年龄、教育程度、职位、每周工作时间作为机器学习数据 获取薪水作为对应结果

样本数据的提取
feature = df[['age','education_num','occupation','hours_per_week']]
target = df['salary']
数据转换,将String类型数据转换为int
s = feature['occupation'].unique()  # 去重,否则数字太多,权重太高
s = feature['occupation']
dic = {}
j = 0 
for i in s :
    dic[i] = j
    j += 1
feature['occupation'] = feature['occupation'].map(dic)  feature.head()
  • 需要数字进行knn运算,计算远近1565773772692

  • 不去重的话,数字覆盖了,造成权重太高1565773783472

  • 去重之后,权重在一位数和二位数都可以1565773791445

知识点 map方法 , 进行数据转换

# 样本数据的拆分  32560  # 为了是正确的数据测试   训练数据 测试数据60
x_train = feature[:32500]
y_train = target[:32500]
x_test = feature[32500:]
y_test = target[32500:]
knn = KNeighborsClassifier(n_neighbors=30)
knn.fit(x_train,y_train)
knn.score(x_test,y_test)

--->0.7868852459016393

使用测试数据进行测试
print(np.array(y_test))
print(knn.predict(x_test))
def funcc(a,b):
    if a == b: 
        return True
    else:
        return False
c = []    
for index,i in enumerate(np.array(y_test)):
    print(funcc(i,knn.predict(x_test)[index]))
    c.append(funcc(i,knn.predict(x_test)[index]))
j = 0     
for i in c:
    if i:
        j+=1
        
print(j) 
print(j/len(c))# 0.7868852459016393

knn.predict([[50,26,0,50]])--->array(['<=50K'], dtype=object)

knn.predict([[30,13,1,40]])--->array(['<=50K'], dtype=object)

结果似乎不对!

知识点总结:

1
data = pd.read_excel('./my_films.xlsx')
#样本数据的提取
feature = data[['Action lens','Love lens']]
target = data['target']
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(feature,target)
knn.predict([[19,19]])

---->array(['Love'], dtype=object)
一种简单的方法确定k的值

knn.score(feature,target)
----->0.9166666666666666

2
String类型数据转换为int
别的操作类似1 

手写数字识别

导包

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.neighbors import KNeighborsClassifier

提炼样本数据

img = plt.imread('./data/3/3_1.bmp')
img
plt.imshow(img)
img.shape # (28, 28) 为什么是二维的呢? 是矢量图?

1565776104587

数据源:

1565776138700

1565776163518

0-9的数字,从0_1 ~ 0_500各种笔迹的,增大正确率

也可以训练车牌号,26个英文字母

提炼样本数据

获得这些数据,加到列表,然后加到np中,np好操作,还有多维

feature = []
target = []
for i in range(0,10):
    for j in range(1,501):
        # ./data/3/3_1.bmp
        img_path = f'./data/{i}/{i}_{j}.bmp'
        img_arr = plt.imread(img_path)
        feature.append(img_arr)
        target.append(i) # 目标特征对应  1-9 数字
特征数据和目标数据
feature.shape  

feature = np.array(feature)
feature.shape
target = np.array(target)
target.shape

将样本打乱 ,否则前面都是1后面都是9 太有规律了
但是还要将特征数据和目标数据对应,用seed的相同处理

np.random.seed(3)
np.random.shuffle(feature)
np.random.seed(3)
np.random.shuffle(target)
feature.shape
变形

因为只支持二维,特征数据 ,对于调用的数据也要符合二维

# ValueError: Found array with dim 3. Estimator expected <= 2.
feature = feature.reshape(5000,784) # 28*28
feature.shape

---->(5000, 28, 28)

获得训练数据和测试数据
x_train = feature[:4950]
y_train = target[:4950]
x_test = feature[4950:]
y_test = target[4950:]
实例化模型对象, 训练
knn = KNeighborsClassifier(n_neighbors=15)
knn.fit(x_train,y_train)
knn.score(x_test,y_test)

---->0.92

保存训练好模型

,方便下次不再麻烦训练,随时用

from sklearn.externals import joblib
joblib.dump(knn,'./digist_knn.m')

---->['./digist_knn.m']

调用训练好模型
knn = joblib.load('./digist_knn.m')
knn

---->

KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
metric_params=None, n_jobs=1, n_neighbors=15, p=2,
weights='uniform')

使用测试数据测试模型的精准度

print('已知分类', y_test)
print('模型分类结果',knn.predict(x_test))

---->

已知分类 [5 9 1 7 7 8 2 7 3 0 4 2 2 5 3 7 0 9 7 5 9 0 9 9 3 2 4 2 6 7 0 6 2 0 5 1 7
8 1 0 0 9 1 3 2 3 9 2 3 8]
模型分类结果 [5 9 1 7 7 8 2 7 3 0 1 2 2 5 3 7 0 1 7 5 9 0 9 9 3 2 4 2 6 1 0 6 2 0 5 1 9
8 1 0 0 9 1 3 2 3 9 2 3 8]

将外部图片代入模型进行识别
img_arr = plt.imread('./数字.jpg')
plt.imshow(img_arr)

1565776547440

截取测试样本

four = img_arr[100:160,0:60]
plt.imshow(four)

1565776584912

four.shape

---->(60, 60, 3)

基于mean降维的例子

exam = [[22,22],[333,333]]
exam = np.array(exam)
exam.shape
exam = exam.mean(axis=1) # 求平均值成1列了 
exam.shape
exam

---->array([ 22., 333.])

1降维操作
four = four.mean(axis=2)
four.shape

---->(60, 60)

2像素的等比例压缩
import scipy.ndimage as ndimage
four = ndimage.zoom(four,zoom=(28/60,28/60))
four.shape

--->(28, 28)

plt.imshow(four)

1565776696262

因为是一行784 列

3测试数据还要变形
four = four.reshape((1,784))
four.shape

---->(1, 784)

结果展示:

knn.predict(four)

--->array([4])

知识点总结:

img = plt.imread('./data/3/3_1.bmp')
plt.imshow(img)
feature = np.array(feature)# feature是列表
保存模型
from sklearn.externals import joblib
joblib.dump(knn,'./digist_knn.m')
调用模型
knn = joblib.load('./digist_knn.m')
截取图形
four = img_arr[100:160,0:60]
用mean降维
four = four.mean(axis=2)
等比例压缩
import scipy.ndimage as ndimage
four = ndimage.zoom(four,zoom=(28/60,28/60))

posted @ 2019-08-14 18:06  learnacode  阅读(429)  评论(0编辑  收藏  举报