1.概述
1.1能做什么
传统预测
图像识别
自然语言处理
1.2什么是机器学习
数据
模型
预测
从历史数据当中得到规律,那这些历史数据是怎么样的格式?
1.2.1数据集构成
特征值+目标值
1.3机器学习算法分类
监督学习:
目标值:类别=分类问题
目标值:连续型数据=回归问题
分类;k-近邻算法、贝叶斯算法、决策树与随机森林、逻辑回归
回归:线性回归、岭回归
无监督学习
目标值:无=聚类
聚类:k-means
2开发流程:
1)获取数据
学习阶段可用数据集:1.scikit-leran 2.kaggle 3.UCI
2)数据处理
3)特征工程
4)使用机器学习算法训练得到模型
5)模型评估
6)应用
2.1获取数据
scikit-learn数据集使用:
sklearn.datasets:加载获取流行数据集(获取的数据为字典类型)
datasets.load_*() 获取小规模数据集
datasets.fetch_*(data_home=None) 获取大规模数据集
具体使用方法示例:
2.2数据集划分:
训练数据:用于训练构建模型
测试数据:进行模型验证,评估模型【占比20~30%】
API:
from sklearn.model_selection import train_test_split
返回值一定按照这个顺序:x_train,x_test,y_train,y_test
2.3特征工程
2.3.1特征提取
将任意数据(如文本和图像)转换为可用于机器学习的数字特征
1)字典特征提取-类别->one-hot编码【属于哪一类别对应位置为1】
API:
from sklearn.feature_extraction import DicVectorizer
当spares=TRUE时输出sparse稀疏矩阵:将非零值位置表示出来
2)文本特征提取--统计样本特征词出现个数
API:
from sklearn.feature_extraction.text import CountVectorizer
标点符号和单个字母不计,stop_word停用词,停止某个词的分类
中文文本提取
1.通过空格来区分单词,对于中文而言,单词间就没有空格,因此需要多一步操作。这里调用一个能够分词的库: jieba
import jieba
def cut_word(text):
"""
进行中文分词:"我爱北京天安门" --> "我 爱 北京 天安门"
"""
return " ".join(list(jieba.cut(text)))
#join函数,就是将text中文本加入空格。
#中文特征提取代码
def count_chinese_demo2():
"""
中文文本特征抽取,自动分词
:return:
"""
# 将中文文本进行分词
data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
data_new = []
for sent in data:
data_new.append(cut_word(sent))
# print(data_new)
# 1、实例化一个转换器类
transfer = CountVectorizer(stop_words=["一种", "所以"])
# 2、调用fit_transform
data_final = transfer.fit_transform(data_new)
print("data_new:\n", data_final.toarray())
print("特征名字:\n", transfer.get_feature_names())
return None
2.根据词的重要性特征提取
def tfidf_demo():
"""
用TF-IDF的方法进行文本特征抽取
:return:
"""
# 将中文文本进行分词
data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
data_new = []
for sent in data:
data_new.append(cut_word(sent))
# print(data_new)
# 1、实例化一个转换器类
transfer = TfidfVectorizer(stop_words=["一种", "所以"])
# 2、调用fit_transform
data_final = transfer.fit_transform(data_new)
print("data_new:\n", data_final.toarray())
print("特征名字:\n", transfer.get_feature_names())
return None
2.3.2特征预处理
sklearn.preprocessing 其实就是数据的缩放,避免数据相差过大
1)归一化
公式:
#pandas数据分析库
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
def minmax_demo():
"""
归一化
:return:
"""
# 1、获取数据
data = pd.read_csv("dating.txt")
data = data.iloc[:, :3] #只取数据的前三列数据
print("data:\n", data)
# 2、实例化一个转换器类,feature_range归一范围
transfer = MinMaxScaler(feature_range=[2, 3])
# 3、调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
2)标准化
-
对于归一化来说:如果出现异常点,影响了最大值和最小值,那么结果显然会发生改变
-
对于标准化来说:如果出现异常点,由于具有一定数据量,少量的异常点对于平均值的影响并不大,从而方差改变较小
公式:
import pandas as pd
from sklearn.preprocessing import StandardScaler
def stand_demo():
"""
标准化
:return:
"""
# 1、获取数据
data = pd.read_csv("dating.txt")
data = data.iloc[:, :3]
print("data:\n", data)
# 2、实例化一个转换器类
transfer = StandardScaler()
# 3、调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
2.3.3特征降维
降低特征个数,使得特征与特征不相关
数据中含有冗余特征,需要从特征中找到主要特征
1)低方差过滤
2)相关系数
pandas也可以计算相关系数,这里用的是scipy
Python numpy,scipy,pandas这些库的区别是什么? - 知乎
相关性很高的话:选择其中一个、加权求和、主成分分析
from sklearn.feature_selectioarn.decomposition import PCA
from scipy.stats import pearsonr
def variance_demo():
"""
过滤低方差特征
:return:
"""
# 1、获取数据
data = pd.read_csv("factor_returns.csv")
data = data.iloc[:, 1:-2]
print("data:\n", data)
# 2、实例化一个转换器类
transfer = VarianceThreshold(threshold=10) #去除低方差数据
# 3、调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new, data_new.shape)
# 计算某两个变量之间的相关系数
r1 = pearsonr(data["pe_ratio"], data["pb_ratio"])
print("相关系数:\n", r1)
r2 = pearsonr(data['revenue'], data['total_expense'])
print("revenue与total_expense之间的相关性:\n", r2)
plt.figure(figsize=[20, 8], dpi=100) # figsize 设定fig的长宽高
plt.scatter(data['revenue'], data['total_expense'])
plt.show()
return None
3)主成分分析(PCA)降维:
from sklearn.decomposition import PCA
def pca_demo():
"""
PCA降维
:return:
"""
data = [[2,8,4,5], [6,3,0,8], [5,4,9,1]]
# 1、实例化一个转换器类
#n_components=小数, 表示保留百分之多少的信息
#整数;减少到多少特征
transfer = PCA(n_components=0.95)
# 2、调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
3.机器学习算法训练
3.1转换器与预估器
1)转换器-特征工程
#1.实例化transfer
#2.transfer.fit_transform计算
2)估计器-sklearn机器学习算法的实现
#1.实例化estimator
#2.estimator.fit(x_train,y_train)计算
#3模型评估
a.直接对比真实值和预测值
y_predict=estimator.predict(x_test)
y_test==y_predict
b.计算准确率
accuracy=estimator.score(x_test,y_test)
3.2 k-近邻算法
核心思想:你的“邻居”决定你的类别
API:
以鸢尾花种类预测作为KNN算法的案例: 1)获取数据 2)数据集划分 3)特征工程——标准化 4)KNN预估器流程 5)模型评估
def knn_iris():
"""
用KNN算法对鸢尾花进行分类
:return:
流程:
1.获取数据
2.数据集划分
3.特征工程, 标准化
4.KNN预估器流程
5.模型评估
"""
# 1)获取数据
iris = load_iris()
# 2)划分数据集
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)#random_state 随机数种子
# 3)特征工程:标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test) #这里不是用fit_transform,因为要统一标准
#x_train和x_test需要使用同一个标准差和方差进行计算。fit是用于计算标准差和方差,因为要和train一致
#因此test这里不用fit
# 4)KNN算法预估器
estimator = KNeighborsClassifier(n_neighbors=3) #n_neighbors 就是K的数值
#注意:这里只使用到了fit,就是相当于训练,输入训练集的输入x和训练集的目标值y
estimator.fit(x_train, y_train)
# 5)模型评估
# 方法1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 方法2:计算准确率
score = estimator.score(x_test, y_test)
print("准确率为:\n", score)
return None
3.3模型选择与调优
交叉验证
训练数据分为训练集和验证集,将数据划分为几份,其中一份为验证集,进过4组测试,每次都更换不同的验证集,取平均值为最终结果,叫做4折交叉验证
超参数搜索-网格搜索
手动修改k复杂,可以设定参数组合
# 参数准备
param_dict = {"n_neighbors": [1, 3, 5, 7, 9, 11]}
estimator = GridSearchCV(estimator, param_grid=param_dict, cv=10) # 验证集
estimator.fit(x_train, y_train)
最佳结果:在验证集中的结果,和估计器的准确率算的对象不一样
facebook位置签到案例
import pandas as pd
# 数据集划分
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
#因为是导入csv数据文件,所以使用Pandas库来进行处理。
# 1、获取数据
data = pd.read_csv("./FBlocation/train.csv") #看你自己train.csv在哪一个文件夹中
#数据处理(筛选数据)
# 1)缩小数据范围 data.query
data = data.query("x < 2.5 & x > 2 & y < 1.5 & y > 1.0")
# 2)处理时间特征 to_datetime
time_value = pd.to_datetime(data["time"], unit="s") #将其转换成年月日
date = pd.DatetimeIndex(time_value) #要把数据插入到列表中
#将时间数据插入data中
data["day"] = date.day
data["weekday"] = date.weekday
data["hour"] = date.hour
# 3)过滤签到次数少的地点
#这里groupuby 计算的是place_id相同的, 其他row_id那些全部都是一样的数
place_count = data.groupby("place_id").count()["row_id"]
#place_count > 3 这里输出的是满足条件的布尔值,True和False
place_count[place_count > 3].head()
data_final = data[data["place_id"].isin([place_count > 3].index.values)] #去取出place_count>3的索引,然后data[index],将那些数值取出
# 筛选特征值和目标值,将原本数据转成特征和目标值
x = data_final[["x", "y", "accuracy", "day", "weekday", "hour"]]
y = data_final["place_id"]
#特征工程
x_train, x_test, y_train, y_test = train_test_split(x, y)
# 3)特征工程:标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4)KNN算法预估器
estimator = KNeighborsClassifier()
# 加入网格搜索与交叉验证
# 参数准备
param_dict = {"n_neighbors": [3, 5, 7, 9]}
estimator = GridSearchCV(estimator, param_grid=param_dict, cv=3)
estimator.fit(x_train, y_train)
# 5)模型评估
# 方法1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 方法2:计算准确率
score = estimator.score(x_test, y_test)
print("准确率为:\n", score)
# 最佳参数:best_params_
print("最佳参数:\n", estimator.best_params_)
# 最佳结果:best_score_
print("最佳结果:\n", estimator.best_score_)
# 最佳估计器:best_estimator_
print("最佳估计器:\n", estimator.best_estimator_)
# 交叉验证结果:cv_results_
print("交叉验证结果:\n", estimator.cv_results_)
3.4过拟合和欠拟合
欠拟合:训练数据误差太大
原因:学习到的数据太少
解决方法:增加特征数据
过拟合:测试数据误差太大
原因:原始数据太多,存在嘈杂特征
解决方法:正则化,提高数据的泛化能力
正则化:L1或者L2,一般使用L2正则化,削弱某一特征影响