一般流程:数据收集、整理→数据预处理与特征工程(数据清理、集成、规约、变换、特征提取、筛选)→模型的选择与建立→模型的评估与优化。
数据清洗、集成、规约、变换:pandas常用操作以及前文的sklearn.preprocessing
- df.duplicated() :判断各行是重复,False为非重复值。
- df.drop_duplicates():删除重复行
- df.fillna(0):用实数0填充na
- df.dropna():按行删除缺失数据,使用参数axis=0;按列删除缺失值,使用参数axis=1,how = "all" 全部是NA才删,"any"只要有NA就删除
- del df['col1']:直接删除某列
- df.drop([]'col1',……],axis=1):删除指定列,也可以删除指定行
- df.rename(index={'row1':'A'},columns ={'col1':'B'}):重命名索引名和列名
- df.replace():替换df值,前后值可以用字典表,{'1':'A','2:'B'}
- hr_data['col1'].map(function):Series.map,对指定列进行函数转换
- pd.merge(df1,df2,on='col1',how='inner',sort=True):合并两个df,按照共有的列作内连接(交集),outter为外连接(并集),结果排序。
- pd.concat([df1,df2]):多个Series堆叠成多行。
- df1.combine_first(df2):用df2的数据补充df1的缺失值NAN。
- df.read_csv() df.to_csv(): 对csv与txt类型文件进行读取与写入操作
- df.apply(lambda):对行或列的数据进行遍历,并且进行自定义函数或命名函数对数据的处理apply是对已经groupby的数据每一组进行func 运算。可以指定这些series进行相互运算。返回的结果类型是函数中return的类型。
- df.groupby.agg():groupby进行分组后运用agg函数聚合,agg可以对groupby 以后的dataframe应用函数,或者对某个或某几个series分别应用函数。比如 groupedobj.agg({series1:func1},{series 2: func 2})
- df.groupby.transform(func):类似与apply,func可以是函数,函数列表或字典{‘轴名称’,函数名称}(即对指定轴使用指定函数)。transform是对dataframe的每个值进行func运算,dataframe的各series之间不可运算,返回的值结构与被作用的dataframe结构相同。但transfrom能用的func apply一定能用,反之不一定。
- df.to_datetime(format=""):将一列或多列数据合并为datetime格式的数据。
- df.index()、df.set_index()、df.reset_index()、df.reindex()、df.sort_index():查看索引,设置索引,重置索引,按照自定义格式要求重置索引,对索引排序。
特征提取、筛选
1.字典特征提取
类 DictVectorizer 可用于将标准的Python字典(dict)对象列表的要素数组转换为 scikit-learn 估计器使用的 NumPy/SciPy 表示形式。
虽然 Python 的处理速度不是特别快,但Python的dict优点是使用方便,稀疏(不需要存储的特征),并且除了值之外还存储特征名称。
类 DictVectorizer 实现了 “one-of-K” 或 “one-hot” 编码,用于分类(也称为标称,离散)特征。分类功能是 “属性值” 对,其中该值被限制为不排序的可能性的离散列表(例如主题标识符,对象类型,标签,名称…)。
示例,”城市” 是一个分类属性,而 “温度” 是传统的数字特征:
>>> measurements = [
... {'city': 'Dubai', 'temperature': 33.},
... {'city': 'London', 'temperature': 12.},
... {'city': 'San Francisco', 'temperature': 18.},
... ]
>>> from sklearn.feature_extraction import DictVectorizer
>>> vec = DictVectorizer()
>>> vec.fit_transform(measurements).toarray()
array([[ 1., 0., 0., 33.],
[ 0., 1., 0., 12.],
[ 0., 0., 1., 18.]])
>>> vec.get_feature_names()
['city=Dubai', 'city=London', 'city=San Francisco', 'temperature']
类 DictVectorizer 也是对自然语言处理模型中训练序列分类器的有用的表示变换,通常通过提取围绕感兴趣的特定的词的特征窗口来工作。
例如,假设我们有提取我们想要用作训练序列分类器(例如:块)的互补标签的部分语音(PoS)标签的第一算法。以下 dict 可以是在 “坐在垫子上的猫” 的句子,围绕 “坐” 一词提取的这样一个特征窗口:
>>> pos_window = [
... {
... 'word-2': 'the',
... 'pos-2': 'DT',
... 'word-1': 'cat',
... 'pos-1': 'NN',
... 'word+1': 'on',
... 'pos+1': 'PP',
... },
... # 在实际应用中,可以提取许多这样的dict
... ]
该描述可以被矢量化为适合于呈递分类器的稀疏二维矩阵
>>> vec = DictVectorizer()
>>> pos_vectorized = vec.fit_transform(pos_window)
>>> pos_vectorized
<1x6 sparse matrix of type '<... 'numpy.float64'>'
with 6 stored elements in Compressed Sparse ... format>
>>> pos_vectorized.toarray()
array([[ 1., 1., 1., 1., 1., 1.]])
>>> vec.get_feature_names()
['pos+1=PP', 'pos-1=NN', 'pos-2=DT', 'word+1=on', 'word-1=cat', 'word-2=the']
对一组人体数据进行特征值化
from sklearn.feature_extraction import DictVectorizer
def dictVetor():
dict=DictVectorizer()
data=dict.fit_transform([{'身高':180,'体重':160,'头发长度':'short'},
{'身高':170,'体重':120,'头发长度':'short'},
{'身高':165,'体重':100,'头发长度':'long'}])
print(dict.get_feature_names())
print(data)
if __name__=="__main__":
dictVetor()
对dict=DictVectorizer()添加参数sparse=False
输出一个3*4的二维矩阵,3行对应我们提供的字典变量里的三组值,4列对应四个特征,第一行输出体重,第二行输出0/1,0代表不是长发,1代表是长发,第三行与第二行同质,第四行输出身高.
2.文本特征提取
以下这个实例,是对一段文字进行特征值化,将文本数据转换为特征值,并统计出现的次数。
from sklearn.feature_extraction.text import CountVectorizer
vector = CountVectorizer()
res=vector.fit_transform(["Sklearn is simple and efficient tools for predictive data analysis,"
"Accessible to everybody, "
"and reusable in various contexts,"
"Built on NumPy, SciPy, and matplotlib,"
"Open source, commercially usable - BSD license"])
print(vector.get_feature_names())
print(res.toarray())
可以看到该方法对所有单词进行了小写处理并且统计了出现的次数。
对于中文:
from sklearn.feature_extraction.text import CountVectorizer
import jieba
vector = CountVectorizer()
#jieba默认返回迭代器对象,需转换为列表后再转换为字符串
c1=jieba.cut("男性,身高一米八,短头发,喜欢打球")
c2=jieba.cut("男性,身高一米七,短头发,喜欢唱歌")
c3=jieba.cut("女性,身高一米六,长头发,喜欢逛淘宝")
l1=list(c1)
l2=list(c2)
l3=list(c3)
str1="".join(l1)
str2="".join(l2)
str3="".join(l3)
res=vector.fit_transform([str1,str2,str3])
print(vector.get_feature_names())
print(res.toarray())
中文的一段话是没有空格的,使用sklearn直接进行提取会得到比较奇怪的特征值,所以需要先对中文文本进行分词,这里推荐一个库,库名为jieba。
3.图像特征提取
import numpy as np
import matplotlib.pyplot as plt
from sklearn.feature_extraction import image
from sklearn.cluster import spectral_clustering
l = 100
x, y = np.indices((l, l))
center1 = (28, 24)
center2 = (40, 50)
center3 = (67, 58)
center4 = (24, 70)
radius1, radius2, radius3, radius4 = 16, 14, 15, 14
circle1 = (x - center1[0]) ** 2 + (y - center1[1]) ** 2 < radius1 ** 2
circle2 = (x - center2[0]) ** 2 + (y - center2[1]) ** 2 < radius2 ** 2
circle3 = (x - center3[0]) ** 2 + (y - center3[1]) ** 2 < radius3 ** 2
circle4 = (x - center4[0]) ** 2 + (y - center4[1]) ** 2 < radius4 ** 2
# #############################################################################
# 4 circles
img = circle1 + circle2 + circle3 + circle4
mask = img.astype(bool)
img = img.astype(float)
img += 1 + 0.2 * np.random.randn(*img.shape)
graph = image.img_to_graph(img, mask=mask)
graph.data = np.exp(-graph.data / graph.data.std())
labels = spectral_clustering(graph, n_clusters=4, eigen_solver='arpack')
label_im = np.full(mask.shape, -1.)
label_im[mask] = labels
plt.matshow(img)
plt.matshow(label_im)
# #############################################################################
# 2 circles
img = circle1 + circle2
mask = img.astype(bool)
img = img.astype(float)
img += 1 + 0.2 * np.random.randn(*img.shape)
graph = image.img_to_graph(img, mask=mask)
graph.data = np.exp(-graph.data / graph.data.std())
labels = spectral_clustering(graph, n_clusters=2, eigen_solver='arpack')
label_im = np.full(mask.shape, -1.)
label_im[mask] = labels
plt.matshow(img)
plt.matshow(label_im)
plt.show()
在本例中,生成了具有连接圆的图像,并使用光谱聚类来分离圆。
在这些设置中,Spectral clustering方法解决了称为“归一化图切割”的问题:图像被视为连接体素的图,而光谱聚类算法相当于选择定义区域的图切割,同时最小化沿切割和区域的体积。
由于算法试图平衡体积(即平衡区域大小),如果我们取不同大小的圆圈,则分割失败。
此外,由于图像的强度或其梯度没有有用的信息,因此我们选择在仅由梯度弱告知的图上执行光谱聚类。这接近于执行图的 Voronoi 分区。