文章目录
一、字典特征抽取
将字典类型数据转换成矩阵形式(One-hot编码)
from sklearn.feature_extraction import DictVectorizer
def dictvec():
# 实例化,sparse为False时直接打印矩阵
dict = DictVectorizer(sparse=False)
# 调用fit_transform,将数据特征值化
data = dict.fit_transform([
{
'city':'北京', 'temperature':100},
{
'city': '上海', 'temperature': 60},
{
'city': '深圳', 'temperature': 50},
])
print(dict.get_feature_names())
print(data) # data为特征值化的结果
print(dict.inverse_transform(data)) # 根据特征矩阵还原成字典(用列表封装)
二、文本特征抽取
1. 统计单词出现的次数
from sklearn.feature_extraction.text import CountVectorizer
def countvec():
cv = CountVectorizer()
data = cv.fit_transform([
"I am Leo",
"I am a Algorithm Engineer"
])
print(cv.get_feature_names())
print(data.toarray())
cv = CountVectorizer()
data = cv.fit_transform([
"人生苦短,我 用 Python"
])
print(cv.get_feature_names())
print(data.toarray())
2. 对中文分词后进行特征抽取
from sklearn.feature_extraction.text import CountVectorizer
import jieba
def cutWord(s1, s2):
res1 = jieba.cut(s1)
res2 = jieba.cut(s2)
# 转换成list后转换为字符串
str1 = ' '.join(list(res1))
str2 = ' '.join(list(res2))
return str1, str2
def countvec():
s1 = '今天很残酷,明天更残酷,后天很美好,但绝大多数人都死在明天晚上'
s2 = '人类目前最远能发现到300亿光年的宇宙,也就是我们看到的其实是300亿年以前的宇宙,' \
'到底宇宙有多大,目前无法证实'
str1, str2 = cutWord(s1, s2)
print('分词结果:')
print(str1)
print(str2)
cv = CountVectorizer()
data = cv.fit_transform([str1, str2])
print('特征抽取结果:')
print(cv.get_feature_names())
print(data.toarray())
if __name__ == '__main__':
countvec()
分词后进行特征值化,可根据每个词出现的次数分析文章的类别、情感等
三、TF-IDF文本分析
基本思想: 如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为该词或短语具有很好的类别区分能力,适合用于分类
TF:Term Frequency,词的频率
IDF:Inverse Document Frequency,逆文档频率
公式:
i d f = l o g ( 总 文 档 数 量 该 词 出 现 的 文 档 数 量 ) \qquad\qquad\qquad idf = log(\frac{总文档数量}{该词出现的文档数量}) idf=log(该词出现的文档数量总文档数量)
TF-IDF的作用: 用于评估一个词对于一个语料库中的一份文档的重要程度
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba
def cutWord(s1, s2):
res1 = jieba.cut(s1)
res2 = jieba.cut(s2)
# 转换成list后转换为字符串
str1 = ' '.join(list(res1))
str2 = ' '.join(list(res2))
return str1, str2
def tfidfVec():
s1 = '今天很残酷,明天更残酷,后天很美好,但绝大多数人都死在明天晚上'
s2 = '人类目前最远能发现到300亿光年的宇宙,也就是我们看到的其实是300亿年以前的宇宙,' \
'到底宇宙有多大,目前无法证实'
str1, str2 = cutWord(s1, s2)
tfidf = TfidfVectorizer()
data = tfidf.fit_transform([str1, str2])
print()
print('特征抽取结果:')
print(tfidf.get_feature_names())
print(data.toarray()) # 矩阵中的元素值就是tf * idf的结果
四、特征预处理
1. 归一化
特点:通过对原始数据进行变换映射到某特定区间
公式:
x 1 = x − m i n m a x − m i n x 2 = x 1 ( x m a x − x m i n ) + x m i n \qquad x^1 = \frac{x-min}{max-min}\qquad x^{2}=x^1(x_{max}-x_{min})+x_{min} x1=max−minx−minx2=x1(xmax−xmin)+xmin
注:作用与每一列, m a x max max为一列的最大值, m i n min min为一列的最小值,那么 x 2 x^2 x2为最终结果, x m a x 和 x m i n x_{max}和x_{min} xmax和xmin分别为指定区间的上下限。一般为0和1
作用:引入归一化,是由于在不同评价指标(特征指标)中,其量纲或是量纲单位往往不同,变化区间处于不同的数量级,若不进行归一化,可能导致某些指标被忽视,影响到数据分析的结果
from sklearn.preprocessing import minmax_scale
def minMax():
mm = MinMaxScaler(feature_range=(0,1)) # 指定缩放范围,默认[0,1]
# 每一列表示一个特征
data = mm.fit_transform([
[90,2,10,40],
[60,4,15,45],
[75,3,13,46]
])
print(data)
注: 异常点对影响 x m i n x_{min} xmin和 x m a x x_{max} xmax影响较大,所以这种方法的鲁棒性很差,只适合小数据场景
2. 标准化
特点:把原始数据变换到 均值为0,标准差为1 的范围内
公式: X = x − m e a n σ X=\frac{x-mean}{\sigma} X=σx−mean
注:作用于每一列, m e a n mean mean为平均值, σ \sigma σ为标准差。由于异常点数量相对于正常点较少,故对平均值影响不大,对方差影响也较小。
from sklearn.preprocessing import StandardScaler
def standard():
std = StandardScaler()
data = std.fit_transform([
[90, 2, 10, 40],
[60, 4, 15, 45],
[75, 3, 13, 46]
])
print(data)
五、缺失值处理
1. 删除: 若每列或每行数据缺失值达到一定的比例,建议放弃该行或该列
2. 填补:可用缺失值所在的行或列的平均值、中位数填补
from sklearn.impute import SimpleImputer
import numpy as np
def processMiss():
pm = SimpleImputer(missing_values=np.nan, strategy='mean')
data = pm.fit_transform([
[1,2],
[np.nan, 3],
[7,6]
])
print(data)
注:在 s k l e a r n . i m p u t e . S i m p l e I m p u t e r sklearn.impute.SimpleImputer sklearn.impute.SimpleImputer中, S i m p l e I m p u t e r SimpleImputer SimpleImputer的参数如下,缺失值默认就是 n p . n a n np.nan np.nan,且默认用平均值填补。
def __init__(self, missing_values=np.nan, strategy="mean",fill_value=None, verbose=0, copy=True, add_indicator=False)
六、数据降维
1. 特征选择
什么是特征选择:
特征选择就是从所有特征中选择一部分作为训练集特征,特征在选择前和选择后可以改变值、也可以不改变值。
特征选择的原因:
- 冗余:部分特征的相关度高,容易消耗计算性能
- 噪声:部分特征对预测结果没有影响,不用参与计算
from sklearn.feature_selection import VarianceThreshold
def deleteLowVar():
"""
删除方差小的特征
"""
var = VarianceThreshold(threshold=0.0)
# 将方差小于threshold的特征删除
data = var.fit_transform([
[0,2,0,3],
[0,1,4,3],
[0,1,1,3]
])
print(data)
2. 主成分分析(PCA)
本质:PCA是一种分析、简化数据集的技术
目的 :压缩数据维数,尽可能降低原数据的维数(复杂度),损失少量信息
作用:可以削减回归分析或者聚类分析中特征的数量
将二维特征降成一维:
PCA语法: P C A . f i t _ t r a n s f o r m ( X ) PCA.fit\_transform(X) PCA.fit_transform(X)
- X X X:numpy array格式的数据[n_samples, n_features]
- 返回值:转换后 指定维度的array
- n _ c o n p o n e n t s n\_conponents n_conponents:若给的参数是小数,则表示保留的信息量。若给的参数是整数,则表示保留的特征数量。
from sklearn.decomposition import PCA
def pca():
"""
主成分分析,进行特征降维
"""
pca = PCA(n_components=0.9) # 信息量保留90%
data = pca.fit_transform([
[2,8,4,5],
[6,3,0,8],
[5,4,9,1]
])
print(data)
七、案例:探究用户对物品类别的喜好细分降维
- 数据来源:用户对物品喜好数据
- 数据说明:
-
order_products__prior.csv:订单与商品信息
- 字段:order_id, product_id, add_to_cart_order, reordered
-
products.csv:商品信息
- 字段:product_id, product_name, aisle_id, department_id
-
orders.csv:用户的订单信息
- 字段:order_id,user_id,eval_set,order_number,….
-
aisles.csv:商品所属具体物品类别
- 字段: aisle_id, aisle
from sklearn.decomposition import PCA
import pandas as pd
def main():
prior = pd.read_csv('order_products__prior.csv')
products = pd.read_csv('products.csv')
orders = pd.read_csv('orders.csv')
aisles = pd.read_csv('aisles.csv')
# 1、开始合并表
temp = pd.merge(prior, products, on=['product_id', 'product_id'])
temp = pd.merge(temp, orders, on=['order_id', 'order_id'])
data = pd.merge(temp, aisles, on=['order_id', 'order_id'])
# 2、交叉表处理,把user_id和aisle进行分组
table = pd.crosstab(data["user_id"], data["aisle"])
# 3、主成分分析进行降维
transfer = PCA(n_components=0.95)
res = transfer.fit_transform(table)
print(res.shape)
if __name__ == '__main__':
main()
八、案例:KNN预测居民签到位置
- 数据来源:相关数据
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
import pandas as pd
def knncls():
"""
KNN预测居民签到位置
"""
# 读取数据
data = pd.read_csv('train.csv')
# 处理数据
# 1、缩小数据范围
data = data.query('x > 1.0 & x < 1.5 & y > 2.0 & y < 2.5')
# 2、处理时间的数据,将时间戳转换为 "年-月-日 时-分-秒" 的形式
time_value = pd.to_datetime(data['time'], unit='s')
# 3、把日期格式转换成字典格式
time_value = pd.DatetimeIndex(time_value)
# 4、构造一些特征
data['day'] = time_value.day
data['hour'] = time_value.hour
data['weekday'] = time_value.weekday
# 5、删除时间戳time,axis=1表示按列删除
data = data.drop(['time'], axis=1)
# 删除签到数量少于n个的目标
place_count = data.groupby('place_id').count()
# reset_index()把place_id单独作为一个特征
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_train, 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) # 不需要再fit
# 开始KNN算法
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(x_train, y_train)
# 得到预测结果
y_predict = knn.predict(x_test)
print('预测的目标签到位置为:',y_predict)
# 通过x_test得到预测值,再和真实值比较,得到准确率
print('预测的准确率为:',knn.score(x_test, y_test))
if __name__ == '__main__':
knncls()