机器学习算法分类
- 监督学习(预测) 特征值+目标值
- 分类: k-近邻算法、贝叶斯分类、决策树与随机森林、逻辑回归、神经网络
- 回归: 线性回归、领回归
- 标注: 隐马尔可夫模型
- 无监督学习 特征值
- 聚类 k-means
开发流程: 建立模型:根据数据类型划分应用种类
- 原始数据明确问题做什么
- 数据的基本处理:pda去处理数据(缺失值,合并表……)
- 特征工程(特征进行处理) 分类、回归
- 找到合适算法去进行预测
- 模型的评估,判定效果
数据集:sklearn中带有一些数据集
from sklearn.datasets import load_boston
boston=load_boston()
print(boston.data)
print(boston.target)
print(boston.DESCR)
特征选择:
特征选择是什么?
特征选择就是单纯地从提取到的所有特征中选择部分特征作为训练集特征,特征在选择前和选择后可以改变值、也不改变值,但是选择后的特征维数肯定比选择前小,毕竟我们只选择了其中的一部分特征。
主要方法(三大武器):
- Filter(过滤式):VarianceThreshold
- Embedded(嵌入式):正则化、决策树
- Wrapper(包裹式)
数据处理:
数值型数据:标准缩放:1、归一化 2、标准化 3、缺失值
类别型数据:one-hot编码
时间类型:时间的切分
对于归一化来说:如果出现异常点,影响了最大值和最小值,结果显然会发生改变
对于标准化来说:如果出现异常点,由于具有一定数据量,少量的异常点对于平均值的影响并不大,从而方差改变较小。
归一化公式:
#特征提取,特征处理
#导入包
from sklearn.feature_extraction.text import CountVectorizer,TfidfVectorizer
import jieba
from sklearn.preprocessing import MinMaxScaler,StandardScaler
from sklearn.impute import SimpleImputer
import numpy as np
#实例化CountVectorizer
vector=CountVectorizer()
#调用fit_transfom输入并转换数据
res=vector.fit_transform(["life is short,i like python ","life is too long,i dislike python"])
#打印结果
# print(vector.get_feature_names())
# print(res.toarray())
from sklearn.feature_extraction import DictVectorizer
def dictvec():
"""
字典数据提取
:return:
"""
#实例化
# dict = DictVectorizer()
dict=DictVectorizer(sparse=False)
#调用fit_transform
data=dict.fit_transform([{'city':'beijing','data':35},{'city':'changchun','data':90},{'city':'shenyang','data':66}])
print(dict.get_feature_names())
print(dict.inverse_transform(data))
print(data)
def countvec():
"""
对文本进行特征值化
:return:
"""
cv=CountVectorizer()
# data=cv.fit_transform(["life is short,i like python ", "life is too long,i dislike python"])
data=cv.fit_transform(["人生 苦短,我用 Python ", "人生 漫长,不用 Python"])#要先对中文分词,
print(cv.get_feature_names())#统计所有文章当中的所有的词,重复的只做一次统计
print(data.toarray())
def cutword():
"""
分词
:return:
"""
con1=jieba.cut("今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。")
con2=jieba.cut(" 如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。")
con3=jieba.cut("今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。")
#转化成列表
content1=list(con1)
content2=list(con2)
content3=list(con3)
#把列表转化成字符串
c1=' '.join(content1)
c2=' '.join(content2)
c3=' '.join(content3)
return c1,c2,c3
def tfidfvec():
"""
tf*idf(重要性)
:return:
"""
c1,c2,c3=cutword()
print(c1,c2,c3)
tf = TfidfVectorizer()
data = tf.fit_transform([c1,c2,c3]) # 要先对中文分词,
print(tf.get_feature_names()) # 统计所有文章当中的所有的词,重复的只做一次统计
print(data.toarray())
def hanzivec():
"""
中文特征值化
:return:
"""
c1,c2,c3=cutword()
print(c1,c2,c3)
cv = CountVectorizer()
data = cv.fit_transform([c1,c2,c3]) # 要先对中文分词,
print(cv.get_feature_names()) # 统计所有文章当中的所有的词,重复的只做一次统计
print(data.toarray())
def mm():
"""
归一化处理:目的:是让某一个特征对最终结果不会造成更大的影响
:return:
"""
# mm=MinMaxScaler()
mm=MinMaxScaler(feature_range=(2,3))
data=mm.fit_transform([[90,2,10,40],[60,4,15,45],
[75,3,13,46]])
print(data)
def stand():
"""
标准化缩放
:return:
"""
std=StandardScaler()
data=std.fit_transform([[1,-1,3],[2,4,2],[4,6,-1]])
print(data)
def im():
"""
缺失值处理
:return:
"""
im=SimpleImputer(strategy="mean")
data=im.fit_transform([[1,2],[np.nan,3],[7,6]])
print(data)
if __name__ == '__main__':
# dictvec()
# countvec()
# hanzivec()
# tfidfvec()
# mm()
# stand()
im()
降维:
from sklearn.feature_selection import VarianceThreshold
from sklearn.decomposition import PCA
def var():
"""
特征选择:删除低方差的特征
:return:
"""
var=VarianceThreshold(threshold=0.0)
data=var.fit_transform([[0,2,0,3],[0,1,4,3],[0,1,1,3]])
print(data)
def pca():
"""
主成成分分析进行特征降维
:return:
"""
pca=PCA(n_components=0.9)
data=pca.fit_transform([[2,8,4,5],[6,3,0,8],[5,4,9,1]])
print(data)
if __name__ == '__main__':
# var()
pca()
K近邻(欧式距离):
朴素贝叶斯:
k-近邻算法优缺点:
- 优点
- 简单,易于理解,易于实现,无需估计参数,无需训练
- 缺点
- 懒惰算法,对测试样本分类时的计算量大,内存开销大
- 必须指定k值,k值选择不当则分类精度不能保证
- 使用场景:小数据场景,几千~几万样本,具体场景具体业务去测试
朴素贝叶斯分类优缺点:
- 优点:
- 朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率
- 对缺失数据不太敏感,算法比较简单,常用于文本分类
- 分类准确度高,速度快
- 缺点:
- 由于使用了样本属性独立性的假设,所以如果样本属性有关联时其效果不好
精确率(Precision)与召回率(Recall)
精确率:预测结果为正例样本中真实为正例的比例
召回率:真实为正例的样本中预测结果为正例的比例
正例 | 假例 | |
正例 | 真正例TP | 伪反例FN |
假例 | 伪正例FP | 真反例TN |
K近邻莺尾花分类:
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
iris=load_iris()
# print(iris.target_names)
x=iris.data
y=iris.target
#150代表样本,4代表属性 花萼长、宽;花瓣长、宽
print(x.shape)
#将数据划分,一分为二;一部分用于训练,另一部分用于测试
#将顺序打乱
index=np.arange(150)
# print(index)
#打乱数据
np.random.shuffle(index)
# print(index)
#150个数据将打乱顺序100个取出来,算法学习,留下50个使用算法预测(验证算法是否可靠)
#应用到实际中,要获取现实中的数据,算法对数据进行分类
x_train,x_test=x[index[:100]],x[index[100:]]
y_train,y_test=y[index[:100]],y[index[100:]]
knn=KNeighborsClassifier(n_neighbors=5)
knn.fit(x_train,y_train)
y_predict=knn.predict(x_test)
#对比,看算法 预测的和真实值的结果,是否对应
#对应,大部分正确,算法没问题
#否则,效果不好
print("预测值",y_predict)
print("真实值",y_test)
#预测效果
print(knn.score(x_test,y_test))
K近邻和朴素贝叶斯案例:
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import pandas as pd
from sklearn.datasets import fetch_20newsgroups
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics import classification_report
def knncls():
"""
K-近邻预测用户签到位置
:return:
"""
#读取数据
data=pd.read_csv('train.csv')
print(data.head(10))
#处理数据
#1.缩小数据,查询数据筛选
data=data.query("x>1.0 & x<1.25 & y >2.5 & y<2.7")
time_value=pd.to_datetime(data["time"],unit='s')
#把日期格式转化成 字典格式
time_value=pd.DatetimeIndex(time_value)
#构造一些特征值
data['day']=time_value.day
data['hour']=time_value.hour
data["weekday"]=time_value.weekday
#把时间戳特征删除
data=data.drop(["time"],axis=1)
print(data)
#把签到数量少于n个目标位置删除
place_count=data.groupy('place_id').count()
tf=place_count[place_count.row_id>3].reset_index()
data=data[data['place_id'].isin(tf.place_id)]
#取出数据中的特征值和目标值
y=data['place_id']
x=data.drop(["place_id"],axis=1)
#进行数据的分割
x_train,x_test,y_tarin,y_test=train_test_split(x,y,test_size=0.25)
#特征工程(标准化)
std=StandardScaler()
#对测试集和训练集的特征值进行标准化
x_train=std.fit_transform(x_train)
x_test=std.transform(x_test)
#进行算法流程 超参数
knn=KNeighborsClassifier(n_neighbors=5)
#fit,predict,score
knn.fit(x_train,y_tarin)
#得出预测结果
y_predict=knn.predict(x_test)
print("预测的目标签到位置为:",y_predict)
#得出准确率
print("预测的准确率:",knn.score(x_test,y_test))
def naviebayes():
"""
朴素贝叶斯进行分类
:return:
"""
news=fetch_20newsgroups(subset='all')
#进行数据分割
x_train,x_test,y_train,y_test=train_test_split(news.data,news.target,test_size=0.25)
#对数据特征值进行抽取
tf=TfidfVectorizer()
#以训练集当中的词列表进行每篇文章重要性统计
x_train=tf.fit_transform(x_train)
print(tf.get_feature_names())
x_test=tf.transform(x_test)
#进行朴素贝叶斯算法的预测
mlt=MultinomialNB(alpha=1.0)
# print(x_train.toarray())
mlt.fit(x_train,y_train)
y_predict=mlt.predict(x_test)
# print("预测的文章类别为",y_predict)
#得出准确率
print("准确率为:",mlt.score(x_test,y_test))
print("每个类别的精确率和召回率:",classification_report(y_test,y_predict,target_names=news.target_names))
if __name__ == '__main__':
# knncls()
naviebayes()
决策树的优缺点以及改进:
- 优点
- 简单的理解和解释,树木可视化
- 需要很少的数据准备,其他技术需要数据归一化
- 缺点
- 决策树学习者可以创建不能很好地推广数据的过于复杂的树,这被称为过拟合。
- 改进
- 剪枝cart算法(决策树API当中已经实现,随机森林参数调优有相关介绍)
- 随机森林
随机森林的优点:
- 在当前所有算法中,具有极好的准确率
- 能够有效地运行在大数据集上
- 能够处理具有高维特征的输入样本,而且不需要降维
- 能够评估各个特征在分类问题上的重要性
决策树与随机森林
import pandas as pd
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier,export_graphviz
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
def decision():
"""
决策树对泰坦尼克号进行预测生死
:return:
"""
#获取数据
titan=pd.read_csv("tantaic/titanic_train.csv",encoding="utf-8")
print(titan.head(8))
#处理数据,找出特征值和目标值
x=titan[['Pclass','Age','Sex']]
y=titan['Survived']
print(x)
#缺失值处理
x['Age'].fillna(x['Age'].mean(),inplace=True)
# x["Embarked"].fillna("S",inplace=True)
#分割数据集到训练集和数据集
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25)
#进行处理(特征工程) one hot 编码
dict=DictVectorizer(sparse=False)
x_train=dict.fit_transform(x_train.to_dict(orient="records"))
print(dict.get_feature_names())
x_test=dict.transform(x_test.to_dict(orient="records"))
print(x_train)
#用决策树进行预测
# dec=DecisionTreeClassifier(max_depth=5)
# dec.fit(x_train,y_train)
# #预测准确率
# print("预测的准确率:",dec.score(x_test,y_test))
#
# #导出决策树的结构
# export_graphviz(dec,out_file='tree.dot',feature_names=["年龄",'Pclass','女性','男性'])
#用随机森林进行预测(超参数调优)
rf=RandomForestClassifier()
param={"n_estimators":[120,200,300,500,800,1200],"max_depth":[5,8,15,25,30]}
#网格搜索与交叉验证
gc=GridSearchCV(rf,param_grid=param,cv=2)
gc.fit(x_train,y_train)
print("准确率:",gc.score(x_test,y_test))
print("选择的参数模型:",gc.best_params_)
if __name__ == '__main__':
decision()
线性回归器是最为简单、易用的回归模型。从某种程度上限制了使用,尽管如此,在不知道特征之间关系的前提下,我们仍然使用线性回归器作为大多数系统的首要选择。
小规模数据:LinearRegression(不能解决拟合问题)
大规模数据:SGDRegressor
过拟合原因以及解决办法
- 原因
- 原始特征过多,存在一些嘈杂特征,模型过于复杂是因为模型尝试去兼顾各个测试数据点
- 解决办法:
- 进行特征选择,消除关联性大的特征
- 交叉验证(让所有数据都有过训练)
- 正则化
sklearn模型的保存和加载
from sklearn.externals import joblib
保存和加载API
保存:joblib.dump(rf,'test.pkl')
加载:estimator=joblib.load("test.pkl")
领回归
线性回归LinearRegression与Ridge对比:
领回归:回归得到的回归系数更符合实际,更可靠。另外,能让估计参数的波动范围变小,变的更稳定。在存在病态数据偏多的研究中有较大的实用价值。
线性回归预测房价
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression,SGDRegressor,Ridge
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
from sklearn.externals import joblib
def mylinear():
"""
线性回归直接预测房子价格
:return:
"""
#获取数据
lb=load_boston()
#分割数据集到训练集和测试集
x_train,x_test,y_train,y_test=train_test_split(lb.data,lb.target,test_size=0.25)
# print(y_train,y_test)
#进行标准化处理
#特征值和目标值都要标准化处理,实例化两个标准化API
std_x=StandardScaler()
x_train=std_x.fit_transform(x_train)
x_test=std_x.transform(x_test)
#目标值
std_y=StandardScaler()
y_train=std_y.fit_transform(y_train.reshape(-1,1))
y_test=std_y.transform(y_test.reshape(-1,1))
#estimator预测
#正规方程求解方程预测
"""
lr=LinearRegression()
lr.fit(x_train,y_train)
print(lr.coef_)
#保存训练好的模型
joblib.dump(lr,"./tmp/test.pkl")
#预测测试集的房价
y_lr_predict=lr.predict(x_test)
y_lr_predict=std_y.inverse_transform(y_lr_predict)
print("正规方程每个房子的预测价格:",y_lr_predict)
print("正规方程的均方误差:",mean_squared_error(std_y.inverse_transform(y_test),y_lr_predict))
"""
#使用模型预测
model=joblib.load("./tmp/test.pkl")
y_predict=std_y.inverse_transform(model.predict(x_test))
print("保存的模型预测的结果:",y_predict)
#梯度下降进行房价预测
sgd = SGDRegressor()
sgd.fit(x_train, y_train)
print(sgd.coef_)
# 预测测试集的房价
y_sgd_predict = sgd.predict(x_test)
y_sgd_predict = std_y.inverse_transform(y_sgd_predict)
print("梯度下降每个房子的预测价格:", y_sgd_predict)
print("梯度下降正规方程的均方误差:", mean_squared_error(std_y.inverse_transform(y_test), y_sgd_predict))
# 领回归进行房价预测
rd = Ridge(alpha=1.0)#alpha正则化力度
rd.fit(x_train, y_train)
print(rd.coef_)
# 预测测试集的房价
y_rd_predict = rd.predict(x_test)
y_rd_predict = std_y.inverse_transform(y_rd_predict)
print("领回归每个房子的预测价格:", y_rd_predict)
print("领回归正规方程的均方误差:", mean_squared_error(std_y.inverse_transform(y_test), y_rd_predict))
if __name__ == '__main__':
mylinear()
LogisticRegression
- 应用:广告点击率预测、是否患病、金融诈骗、是否为虚假账号
- 优点:适合需要得到一个分类概率的场景,简单,速度快
- 缺点:不好处理多分类问题
逻辑回归预测癌症
from sklearn.linear_model import LogisticRegression
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import classification_report
def logistic():
"""
逻辑回归做二分类进行癌症预测
:return:
"""
#构造列标签名字
column=["Sample code number","Clump Thickness","Uniformity of Cell Size",
"Uniformity of Cell Shape","Marginal Adhesion","Single Epithelial Cell Size",
"Bare Nuclei ","Bland Chromatin","Normal Nucleoli","Mitoses","Class"]
#读取数据
data=pd.read_csv("./breast-cancer/breast-cancer-wisconsin.data",names=column)
print(data.head())
#缺失值处理
data=data.replace(to_replace='?',value=np.nan)
data=data.dropna()
#进行数据的分割
x_train,x_test,y_train,y_test=train_test_split(data[column[1:10]],data[column[10]],test_size=0.25)
#进行标准化处理
std=StandardScaler()
x_train=std.fit_transform(x_train)
x_test=std.transform(x_test)
#逻辑回归预测
lg=LogisticRegression(C=1.0)
lg.fit(x_train,y_train)
print(lg.coef_)
y_predict=lg.predict(x_test)
print("准确率:",lg.score(x_test,y_test))
print("召回率:",classification_report(y_test,y_predict,labels=[2,4],target_names=['良性','恶性']))
if __name__ == '__main__':
logistic()
K-Means聚类
# coding: utf-8
# In[11]:
import pandas as pd
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
# In[2]:
mt=pd.read_csv('merage.csv',encoding="utf-8")
# In[3]:
#交叉表(特殊的分组工具)
cross=pd.crosstab(mt['user_id'],mt['aisle'])
# In[4]:
#进行主成分分析
pca=PCA(n_components=0.9)
# In[5]:
data=pca.fit_transform(cross)
# In[8]:
#样本数量减少
x=data[:500]
# In[9]:
x.shape
# In[12]:
#假设用户一共分为4个类别
km=KMeans(n_clusters=4)
# In[13]:
km.fit(x)
# In[14]:
predict=km.predict(x)
# In[15]:
predict
# In[16]:
#显示聚类结果
import matplotlib.pyplot as plt
# In[17]:
plt.figure(figsize=(10,10))
# In[18]:
#建立四个颜色的列表
# In[20]:
colored=["green","orange","blue","purple"]
# In[22]:
colr=[colored[i]for i in predict]
plt.scatter(x[:,1],x[:,20],color=colr)
plt.xlabel("1")
plt.ylabel("20")
plt.show()
# In[23]:
from sklearn.metrics import silhouette_score
# In[24]:
silhouette_score(x,predict)