技术专栏丨10大机器学习算法速览,带你开启AI之旅

原文作者:Sunil Ray

译者:TalkingData 张永超

原文链接:https://www.analyticsvidhya.com/blog/2017/09/common-machine-learning-algorithms/

简介

从广义上讲,机器学习算法有三种类型:

监督学习

该算法是由一个目标/结果变量(也成为因变量)组成,该变量可以从一组给定的预测变量中预测出来。使用这些变量的组合,我们可以生成一个由输入映射到所需输出的的函数。该算法的训练过程会尝试将模型的预测准确度提高到训练数据所需的程度。具体的算法有:回归、决策树、随机森林、kNN、Logistic回归等等。

无监督学习

该算法中,没有任何的目标/结果变量以用来预测/估计。基本上用于不同的群体间的聚类,通常该算法用于对不同的群体进行分组。具体的算法有:Apriori算法,K-means等。

强化学习

该算法是比较新的一个机器学习算法分类,使用该算法,机器会被训练来做出一些特定的决策。此时机器会被暴露在一个特定的环境中,通过反复试验不断的训练自己,知道最终得到一个比较好的决策结果。该算法会从过去的经验中学习,并尝试捕捉最佳的结果知识以做出更加准确的决策。典型的算法有:马尔可夫决策过程等。

通用机器学习算法列表

下面是一些通用的机器学习算法,这些算法基本上能够解决大部分的数据相关问题:

1.    线性回归(Linear Regression)

2.    逻辑回归(Logistic Regression)

3.    决策树(Decision Tree)

4.    支持向量机(SVM)

5.    朴素贝叶斯(Naive Bayes)

6.    k近邻(kNN)

7.    k均值(K-Means)

8.    随机森林(Random Forest)

9.    降维算法(Dimensionality Reduction Algorithms)

10.  梯度增强算法(Gradient Boosting algorithms)

GBM

XGBoost

LightGBM

CatBoos

线性回归

线性回归主要用于根据连续的变量来估计实际值(例如:房屋成本,通话次数,总销售额等)。在该算法中,我们通过拟合最佳的分界线来建立独立变量和因变量之间的关系。该最佳的拟合线称为回归线,并可以由线性方程Y = a * X + b表示。例如:我们要求一个五年级的孩子根据班上同学的体重来排序,而不告诉他同学们的具体体重。他会怎么做呢?他可能会根据同学们的身高和体型来判断某个同学的体重,然后进行排序。我们并没有告诉他身高和体型与体重之间的关系,而他已经可以通过眼睛的观察来得到身高和体型与体重之间的关系了,而这个关系是符合上述线性回归的方程的。

在上述方程中:

Y --- 因变量

a --- 倾斜量

X --- 自变量

b --- 截距

系数a和b是基于最小化数据点与回归线之间的距离的平方差的总和而得出的。

假设我们有一些人员的身体和体重的数据,将其绘制在图表中。如下图所示:

这里我们已经找到了最佳的拟合线,其方程表示为y = 0.2811*x + 13.9,为图中黑色线。那么我们就可以使用这个方程来根据某人的身高,得到其体重了。

线性回归主要有两种类型:单一线性回归和多元线性回归。单一线性回归顾名思义,就是仅由一个独立的自变量表征,而多元线性回归由多于一个自变量来表征。在寻找最佳拟合线时,可以拟合多项式或曲线回归。

本文中的代码大部分为演示所用,在实际应用中需要替换甚至重写部分代码,请慎重复制粘贴!

Python code

1# Import Library

2# Import other necessary libraries like pandas, numpy...

3from sklearn import linear_model

4# Load Train and Test datasets

5# Identify feature and response variable(s) and values must be numeric and numpy arrays

6x_train=input_variables_values_training_datasets

7y_train=target_variables_values_training_datasets

8x_test=input_variables_values_test_datasets

9# Create linear regression object

10linear = linear_model.LinearRegression()

11# Train the model using the training sets and check score

12linear.fit(x_train, y_train)

13linear.score(x_train, y_train)

14# Equation coefficient and Intercept

15print('Coefficient: \n', linear.coef_)

16print('Intercept: \n', linear.intercept_)

17# Predict Output

18predicted= linear.predict(x_test)

2逻辑回归

不要被这个名字所糊弄了! 其实逻辑回归并不是回归算法。它基于给定的一组自变量来估计离散值(二进制值,如0/1,是/否,真/假)。简单的说,它通过将数据拟合到logit函数来预测事件发生的可能性。因此,它通常也被称为logit回归。因为它预测了可能性,即概率,因此其输出值在0和1之间。例如:你的朋友给你出了一道难题,并且他并不知道你的知识范围,而你能给出的结果只有能解决或者不能解决。假如这道题是高级物理学科的题目,你可能只有大学本科的经历,你给出能解决的概率可能只有20%,而如何你恰好是一个物理学博士,你给出解决的概率可能就有80%了,这就是逻辑回归。

从数学的含义上讲,逻辑回归就是结果的对数几率被建模为预测变量的线性组合。如下:

1odds = p / (1- p) = probabilityofevent occurrence / probabilityofnotevent occurrence

2ln(odds) = ln(p / (1- p))

3logit(p) = ln(p / (1- p)) = b0+b1X1+b2X2+b3X3....+bkXk

上述公式中,p是存在感兴趣特征的概率。它选择最大化观察样本值的可能性的参数,而不是最小化平方误差的总和(如在普通回归中那样)。

Python code

1# Import Library

2fromsklearn.linear_modelimportLogisticRegression

3# Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset

4# Create logistic regression object

5model = LogisticRegression()

6# Train the model using the training sets and check score

7model.fit(X, y)

8model.score(X, y)

9# Equation coefficient and Intercept

10print('Coefficient: \n', model.coef_)

11print('Intercept: \n', model.intercept_)

12# Predict Output

13predicted= model.predict(x_test)

3决策树

决策树是一种主要用于分类问题的监督学习算法。该算法不仅仅支持分类问题,还支持连续因变量问题。在这个算法中,我们将人口分成两个或更多的齐次集合。这是基于最重要的属性/独立变量来完成的,以尽可能地形成不同的组。

如上图所示,可以看到该算法根据多个属性将一个群体分为了四个不同的群体,以识别“他们是否会参加比赛”。为了分组,它使用各种技术,如基尼,信息增益,卡方,熵等。

另一种理解决策树的绝佳方式是玩一个微软上经典的游戏 --- Jezzball。基本上,你有一个有活动墙壁的房间,你需要创造墙壁,这样最大的区域就会被清理掉。

因此,每一次你使用墙壁来划分房间,你都将试图将一个房间划分为两部分。决策树也非常类似这种方式。

Python code

1# Import Library

2# Import other necessary libraries like pandas, numpy...

3from sklearn import tree

4# Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset

5# Create tree object

6model = tree.DecisionTreeClassifier(criterion='gini')# for classification, here you can change the algorithm as gini or entropy (information gain) by default it is gini  

7# model = tree.DecisionTreeRegressor() for regression

8# Train the model using the training sets and check score

9model.fit(X, y)

10model.score(X, y)

11# Predict Output

12predicted= model.predict(x_test)

4SVM(支持向量机)

SVM是一个分类方法。在该算法中,我们将每个数据项绘制为n维空间中的一个点(其中n是您拥有的要素数),每个要素的值都是特定坐标的值。

例如,如果我们只有个人的身高和头发长度两个特征,我们首先在二维空间中绘制这两个变量,其中每个点有两个坐标(这些坐标被称为支持向量)。

现在,我们将找到一些分割两个不同分类数据组之间线。而这条线将使得两组数据中最近点的距离最远。

在上面所示的例子中,将数据分成两个不同分类组的线是黑线,因为两个最近点离线最远。这条线就是我们的分类器。然后,根据测试数据在线两侧的位置,就可以区分测试数据属于哪个类了。

Python code

1# Import Library

2from sklearn import svm

3# Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset

4# Create SVM classification object

5model = svm.svc()# there is various option associated with it, this is simple for classification. You can refer link, for mo# re detail.

6# Train the model using the training sets and check score

7model.fit(X, y)

8model.score(X, y)

9# Predict Output

10predicted= model.predict(x_test)

5朴素贝叶斯

朴素贝叶斯是一种基于贝叶斯定理的分类技术,假设预测变量之间具有独立性。简而言之,朴素贝叶斯分类器假定类中特定特征的存在与任何其他特征的存在无关。例如,如果果实呈红色,圆形,直径约3英寸,则可认为其为苹果。即使这些特征依赖于彼此或者依赖于其他特征的存在,朴素贝叶斯分类器也会考虑所有这些特性来独立地贡献该水果是苹果的可能性。

朴素贝叶斯模型很容易构建,对于非常大的数据集特别有用。贝叶斯定理提供了一种从P(c),P(x)和P(x | c)计算后验概率P(c | x)的方法。看下面的公式:

这里:

P(c | x)是给定预测器(属性)的类(目标)的后验概率。

P(c)是类的先验概率。

P(x | c)是预测器给定类的概率的可能性。

P(x)是预测变量的先验概率。

例子:让我们用一个例子来理解它。下面我有一个天气和相应的目标变量“是否参加比赛”的训练数据集。现在,我们需要根据天气情况来分类球员是否参加比赛。让我们按照以下步骤来执行它。

将数据集转换为频率表

通过查找像Overcast probability = 0.29和播放概率为0.64的概率来创建Likelihood表。

现在,使用朴素贝叶斯方程来计算每个类别的后验概率。具有最高后验概率的类别是预测的结果。

Python code

1# Import Library

2fromsklearn.naive_bayesimportGaussianNB

3# Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset

4# Create SVM classification object model = GaussianNB() # there is other distribution for multinomial classes like Bernoulli Naive Bayes, Refer link

5# Train the model using the training sets and check score

6model.fit(X, y)

7# Predict Output

8predicted= model.predict(x_test)

6kNN (k-最近邻)

kNN可以用于分类和回归问题。然而,它在业内的分类问题中被更广泛地使用。 K最近邻算法是一个简单的算法,它存储所有可用的案例,并通过其k个邻居的多数投票来分类新案例。被分配给类的情况在距离函数测量的k近邻中最为常见。

这些距离函数可以是欧几里得,曼哈顿,闵可夫斯基和海明距离。前三个函数用于连续函数,第四个函数(Hamming)用于分类变量。如果K = 1,那么该情况被简单地分配给其最近邻居的类别。有时,在执行kNN建模时选择K是一项挑战。

kNN可以很容易地映射到我们的真实生活中。如果你想了解一个你没有信息的人,你可能想知道他的亲密朋友和他进入的圈子并获得他/她的信息!

选择kNN之前需要考虑的事项: * KNN在计算上很耗时 * 在使用kNN时,变量应该被标准化,否则更高的范围变量会偏向它 * 在进入kNN之前要更多地进行数据预处理,如异常值,噪音消除等。

Python code

1# Import Library

2fromsklearn.neighborsimportKNeighborsClassifier

3# Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset

4# Create KNeighbors classifier object model

5KNeighborsClassifier(n_neighbors=6)# default value for n_neighbors is 5

6# Train the model using the training sets and check score

7model.fit(X, y)

8# Predict Output

9predicted= model.predict(x_test)

7K-均值(K-Means)

K-均值是一种解决聚类问题的无监督算法。其过程遵循一个简单的方法,通过一定数量的聚类(假设k个聚类)对给定的数据集进行分类。群集内的数据点与同级群组是同质且异质的。

例如在白纸上随机撒上的墨水, K-均值有点类似这个活动,每一块墨水水渍可以理解为一个群组。

K-means如何形成群集:

K-means为每个簇选取k个点,称为质心。

每个数据点形成具有最接近质心的群集,即k个群集。

根据现有集群成员查找每个集群的质心。这里我们有新的质心。

由于我们有新的质心,请重复步骤2和3.从新质心找到每个数据点的最近距离,并与新的k-簇进行关联。重复这个过程直到收敛发生,即质心不变。

如何确定K的值:

在K-means中,我们有簇,每个簇都有自己的质心。质心与聚类内的数据点之间的差的平方和构成该聚类的平方值的和。另外,当所有群集的平方值总和相加时,群集解决方案的平方和总和为总和。

我们知道,随着群集数量的增加,这个值会持续下降,但是如果您绘制结果,您可能会看到平方距离的总和急剧下降到某个k值,然后再慢得多。在这里,我们可以找到聚类的最佳数量。

Python code

1# Import Library

2from sklearn.cluster import KMeans

3# Assumed you have, X (attributes) for training data set and x_test(attributes) of test_dataset

4# Create KNeighbors classifier object model

5k_means = KMeans(n_clusters=3, random_state=0)

6# Train the model using the training sets and check score

7model.fit(X)

8# Predict Output

9predicted= model.predict(x_test)

8

随机森林

随机森林是一个决策树集合的术语。在随机森林中,集成了多个决策树(所谓的“森林”)。要根据属性对新对象进行分类,每棵树都会给出一个分类,并且该树会为该分类“投票”。森林选择票数最多的分类,即为最终的分类。

每株树种植和生长如下:

如果训练集中的病例数为N,则随机抽取N个病例的样本,但需要更换。这个样本将成为培育树的培训集。

如果有M个输入变量,则指定一个数m << M,以便在每个节点处从M中随机选择m个变量,并且使用这些m上的最佳分割来分割节点。在森林生长期间,m的值保持不变。

每棵树都尽可能地生长。没有修剪。

Python code

1# Import Library

2from sklearn.ensemble import RandomForestClassifier

3# Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset

4# Create Random Forest object

5model= RandomForestClassifier()

6# Train the model using the training sets and check score

7model.fit(X, y)

8# Predict Output

9predicted= model.predict(x_test)

9

维度降低算法

在过去的4-5年里,在每个可能的阶段数据采集呈指数级增长。企业/政府机构/研究机构不仅拥有新的资源,而且还在详细捕获数据。

例如:电子商务公司正在抓住更多有关客户的细节,例如他们的人口统计数据,网络爬行历史,他们喜欢或不喜欢的内容,购买历史记录,反馈信息等等,以便为他们提供比最近的杂货店老板更多的个性化关注。

作为一名数据科学家,我们提供的数据还包含许多功能,这对构建良好的健壮模型听起来不错,但是存在挑战。你如何确定1000或2000年以外的重要变量?在这种情况下,降维算法可以帮助我们连同各种其他算法,如决策树,随机森林,PCA,因子分析,基于相关矩阵的识别,缺失值比等。

Python code

1# Import Library

2from sklearn import decomposition

3# Assumed you have training and test data set as train and test

4# Create PCA obeject pca= decomposition.PCA(n_components=k) #default value of k =min(n_sample, n_features)

5# For Factor analysis

6# fa= decomposition.FactorAnalysis()

7# Reduced the dimension of training dataset using PCA

8train_reduced = pca.fit_transform(train)

9# Reduced the dimension of test dataset

10test_reduced = pca.transform(test)

10梯度下降算法

10.1. GBM

当我们处理大量数据以进行具有高预测能力的预测时,GBM是一种增强算法。 Boosting实际上是一种学习算法集合,它将几个基本估计量的预测结合起来,以提高单个估计量的鲁棒性。它将多个弱预测器或平均预测器组合成强大的预测器。这些提升算法在Kaggle,AV Hackathon,CrowdAnalytix等数据科学竞赛中始终运作良好。

Python code

1# Import Library

2from sklearn.ensemble import GradientBoostingClassifier

3# Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset

4# Create Gradient Boosting Classifier object

5model= GradientBoostingClassifier(n_estimators=100, learning_rate=1.0, max_depth=1, random_state=0)

6# Train the model using the training sets and check score

7model.fit(X, y)

8# Predict Output

9predicted= model.predict(x_test)

10.2. XGBoost

XGBoost是另一个经典的渐变增强算法,被称为在一些Kaggle比赛中获胜的关键性算法。

XGBoost具有非常高的预测能力,使其成为事件精确度的最佳选择,因为它具有线性模型和树学习算法,使得该算法比现有梯度增强技术快近10倍。

支持包括各种目标函数,包括回归,分类和排名。

XGBoost最有趣的事情之一就是它也被称为正规化提升技术。这有助于减少过度装配建模,并且对Scala,Java,R,Python,Julia和C ++等一系列语言提供大量支持。

在许多包含GCE,AWS,Azure和Yarn群集的机器上支持分布式和广泛的培训。 XGBoost还可以与Spark,Flink和其他云数据流系统集成在一起,每次迭代过程中都有内置的交叉验证。

Python code

1from xgboost import XGBClassifier

2from sklearn.model_selection import train_test_split

3from sklearn.metrics import accuracy_score

4X = dataset[:,0:10]

5Y = dataset[:,10:]

6seed = 1

7X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=seed)

8model = XGBClassifier()

9model.fit(X_train, y_train)

10#Make predictions for test data

11y_pred = model.predict(X_test)

10.3. LightGBM

LightGBM是一种梯度提升框架,使用基于树的学习算法。它的设计是分布式和高效的,具有以下优点:

更快的训练速度和更高的效率

降低内存使用量

更好的准确性

支持并行和GPU学习

能够处理大型数据

该框架是一种基于决策树算法的快速高性能梯度提升算法,用于排序、分类和许多其他机器学习任务。它是在Microsoft的分布式机器学习工具包项目下开发的。

由于LightGBM基于决策树算法,因此它将树叶以最佳拟合进行分割。因此,当在Light GBM中的同一片叶上生长时,叶式算法可以比平面式算法减少更多的损失,因此可以获得更好的精度,而现有的任何增强算法都很难达到这些精度。

Python code

1data = np.random.rand(500, 10)# 500 entities, each contains 10 features

2label = np.random.randint(2, size=500)# binary target

3train_data = lgb.Dataset(data, label=label)

4test_data = train_data.create_valid('test.svm')

5param = {'num_leaves':31, 'num_trees':100, 'objective':'binary'}

6param['metric'] = 'auc'

7num_round = 10

8bst = lgb.train(param, train_data, num_round, valid_sets=[test_data])

9bst.save_model('model.txt')

10# 7 entities, each contains 10 features

11data = np.random.rand(7, 10)

12ypred = bst.predict(data)

10.4. Catboost

CatBoost是Yandex最近开源的机器学习算法。它可以轻松地与Google的TensorFlow和Apple的Core ML等深度学习框架相整合。

CatBoost最棒的部分是它不需要像其他ML模型那样的大量数据训练,并且可以处理各种数据格式;不会破坏它的可靠性。

在使用和执行Catboost算法之前,请确保数据中的缺失值已经被处理。

Catboost可以自动处理分类变量而不显示类型转换错误,这有助于您更专注于更好地调整模型。

Python code

1importpandasaspd

2importnumpyasnp

3fromcatboostimportCatBoostRegressor

4#Read training and testing files

5train = pd.read_csv("train.csv")

6test = pd.read_csv("test.csv")

7#Imputing missing values for both train and test

8train.fillna(-999, inplace=True)

9test.fillna(-999,inplace=True)

10#Creating a training set for modeling and validation set to check model performance

11X = train.drop(['Item_Outlet_Sales'], axis=1)

12y = train.Item_Outlet_Sales

13fromsklearn.model_selectionimporttrain_test_split

14X_train, X_validation, y_train, y_validation = train_test_split(X, y, train_size=0.7, random_state=1234)

15categorical_features_indices = np.where(X.dtypes != np.float)[0]

16#importing library and building model

17fromcatboostimportCatBoostRegressormodel=CatBoostRegressor(iterations=50, depth=3, learning_rate=0.1, loss_function='RMSE')

18model.fit(X_train, y_train,cat_features=categorical_features_indices,eval_set=(X_validation, y_validation),plot=True)

19submission = pd.DataFrame()

20submission['Item_Identifier'] = test['Item_Identifier']

21submission['Outlet_Identifier'] = test['Outlet_Identifier']

22submission['Item_Outlet_Sales'] = model.predict(test)

总结

至此,相信你对机器学习的各个主要算法有了一个大概的了解,文中给出了各个算法的逻辑代码,你可以从这里开始,尝试解决一些问题,并在过程中加深理解。关于数据,你可以在网络上找到很多,而且在一些所使用到的Python库中也常内置了各种数据集,你可以查看相应的官方文档查找并直接使用。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • 本系列文章面向深度学习研发者,希望通过Image Caption Generation,一个有意思的具体任务,深入...
    imGeek阅读 1,788评论 0 8
  • 给他杯子里倒满茶,慢慢散发的大麦茶的味道,这是他最爱的味道。他点上烟吸了一口,问我:“你说为什么明...
    小阿童阅读 415评论 2 1
  • CSS Hack 不同的浏览器对某些CSS代码解析会存在一定的差异,因此就会导致不同浏览器下给用户展示的页面效果不...
    zx9426阅读 383评论 0 0
  • 目录 上一章|原来他从未离开 第三十二章 鸾凤和鸣 “好。我跟你一起去。你知道他在什么地方吗?”叶华立即...
    潇湘月明阅读 355评论 1 6
  • “同步是件奢侈的事情”这原本是一个朋友的微信签名,然而今天,因为一些小事对这句话有了些深刻的体会,也越来越能理解这...
    Renalp阅读 247评论 0 0